{"version":3,"file":"getSwaggerData.mjs","sources":[""],"sourcesContent":["import type { HttpHandler } from \"msw\";\r\nimport { HttpMethods } from \"msw\";\r\nimport { setupServer } from \"msw/node\";\r\nimport type { OpenAPIV3, OpenAPIV3_1 } from \"openapi-types\";\r\nimport type { TContentTypes } from \"./contentTypes\";\r\nimport { contentTypes } from \"./contentTypes\";\r\nimport type { THttpHandlerWithExtendedInfo } from \"./httpHandler\";\r\n\r\nexport interface ISwaggerOptions {\r\n  handlers: THttpHandlerWithExtendedInfo[];\r\n  meta: OpenAPIV3_1.InfoObject;\r\n  basePath?: string;\r\n  servers?: OpenAPIV3_1.ServerObject[];\r\n  security?: OpenAPIV3_1.SecurityRequirementObject[];\r\n  queries: {\r\n    name: string;\r\n    value: string | number;\r\n  }[];\r\n}\r\n\r\nconst defaultMeta: ISwaggerOptions[\"meta\"] = {\r\n  title: \"API\",\r\n  description: \"\",\r\n  version: \"1.0.0\",\r\n  summary: \"API Документация\",\r\n  termsOfService: \"\",\r\n  contact: { name: \"Support\", url: \"\", email: \"\" },\r\n  license: { name: \"MIT\", url: \"\" },\r\n};\r\n\r\n\r\nconst getResultInfo = async (url: string, init: RequestInit, defaultQueries: ISwaggerOptions[\"queries\"] = []) => {\r\n\r\n  let body: OpenAPIV3_1.RequestBodyObject;\r\n\r\n  if (!init.body) {\r\n    delete init.body;\r\n  }\r\n\r\n  return await fetch(url, init)\r\n    .then(async (resp) => {\r\n      const status = resp.status;\r\n      const headers = resp?.headers ?? new Headers();\r\n      const contentType = headers.get(\"content-type\") || contentTypes.json;\r\n      const parameters: OpenAPIV3_1.ParameterObject[] = [];\r\n\r\n      const getMock = async () => {\r\n        switch (contentType) {\r\n          case contentTypes.json:\r\n            return resp.json();\r\n          case contentTypes.binary:\r\n            return resp.arrayBuffer();\r\n          case contentTypes.formData:\r\n            return resp.formData();\r\n          default:\r\n            return resp.text();\r\n        }\r\n      };\r\n\r\n      const searchParams = new URL(url).searchParams;\r\n      const mock = await getMock();\r\n\r\n      defaultQueries.forEach(({ name }) => {\r\n        searchParams.delete(name);\r\n      });\r\n\r\n      // search params\r\n      searchParams.forEach((value, key) => {\r\n        const item: OpenAPIV3_1.ParameterObject = {\r\n          in: \"query\",\r\n          name: key,\r\n          schema: {\r\n            type: \"string\",\r\n          },\r\n          example: value,\r\n        };\r\n        parameters.push(item);\r\n      });\r\n\r\n      // path params\r\n      const pathParameters = url.match(/\\/:([^\\/]*)/g);\r\n      if (pathParameters) {\r\n        pathParameters.forEach((param) => {\r\n          const paramName = param.replace(\"/:\", \"\");\r\n          parameters.push({\r\n            in: \"path\",\r\n            name: paramName,\r\n            schema: {\r\n              type: \"string\",\r\n            },\r\n            example: `{${paramName}}`,\r\n          });\r\n        });\r\n      }\r\n\r\n      // headers\r\n      headers.forEach((value, key) => {\r\n        parameters.push({\r\n          in: \"header\",\r\n          name: key,\r\n          schema: {\r\n            type: \"string\",\r\n          },\r\n          example: value,\r\n        });\r\n      });\r\n\r\n      // body\r\n      if (!!init.body && (init.method === HttpMethods.POST || init.method === HttpMethods.PUT || init.method === HttpMethods.PATCH)) {\r\n        try {\r\n          const parsedBody =\r\n            contentType === contentTypes.json && typeof init.body === \"string\"\r\n              ? JSON.parse(init.body)\r\n              : init.body;\r\n          body = {\r\n            required: true,\r\n            content: {\r\n              [contentType]: {\r\n                schema: getInferSchema(parsedBody),\r\n                example: parsedBody,\r\n              },\r\n            },\r\n          };\r\n        } catch (e) {\r\n          console.error(\"[getResultInfo] Failed to parse request body:\", e);\r\n        }\r\n      }\r\n\r\n\r\n      const base = url.split(\"?\")[0];\r\n\r\n      return {\r\n        status, mock, base, contentType, parameters, body,\r\n      };\r\n    })\r\n    .catch((err) => {\r\n      console.error(`[getSwaggerData] Failed to fetch url \"${url}\":`, err);\r\n      return null;\r\n    });\r\n};\r\n\r\n/**\r\n * Infer an OpenAPI schema for a given value.\r\n * @returns {OpenAPIV3_1.SchemaObject}\r\n */\r\nconst getInferSchema = (value: unknown): OpenAPIV3_1.SchemaObject => {\r\n  if (value === null) {\r\n    return { type: \"null\" as const };\r\n  }\r\n\r\n  // Handle arrays\r\n  if (Array.isArray(value)) {\r\n    if (value.length === 0) {\r\n      // Empty array\r\n      return {\r\n        type: \"array\",\r\n        items: {}, // OpenAPI allows an empty schema object if the array is empty\r\n      };\r\n    }\r\n\r\n    // Map each item's schema\r\n    const itemSchemas = value.map((item) => getInferSchema(item));\r\n\r\n    // Deduplicate schemas for homogeneous arrays\r\n    const uniqueSchemas = Array.from(\r\n      new Set(itemSchemas.map((schema) => JSON.stringify(schema)))\r\n    ).map((schemaStr) => JSON.parse(schemaStr));\r\n\r\n    if (uniqueSchemas.length === 1) {\r\n      // Homogeneous array: single schema for items\r\n      return {\r\n        type: \"array\",\r\n        items: uniqueSchemas[0], // Unique schema for all items\r\n      };\r\n    } else {\r\n      // Heterogeneous array: multiple schemas using `oneOf`\r\n      return {\r\n        type: \"array\",\r\n        items: {\r\n          oneOf: uniqueSchemas,\r\n        },\r\n      };\r\n    }\r\n  }\r\n\r\n  // Handle primitive types and objects\r\n  switch (typeof value) {\r\n    case \"string\":\r\n      return { type: \"string\" };\r\n    case \"number\":\r\n      return { type: Number.isInteger(value) ? \"integer\" : \"number\" };\r\n    case \"boolean\":\r\n      return { type: \"boolean\" };\r\n    case \"object\":\r\n      if (value !== null) {\r\n        const properties: Record<string, OpenAPIV3_1.SchemaObject> = {};\r\n        Object.entries(value).forEach(([ key, val ]) => {\r\n          properties[key] = getInferSchema(val);\r\n        });\r\n\r\n        return {\r\n          type: \"object\",\r\n          properties,\r\n          additionalProperties: false, // Disallow additional untyped fields\r\n        };\r\n      }\r\n      return { type: \"null\" };\r\n    default:\r\n      // Fallback for unsupported types\r\n      return {};\r\n  }\r\n};\r\n\r\n/**\r\n * Main function to return OpenAPI Schema based on content type and data.\r\n * @returns {OpenAPIV3_1.SchemaObject}\r\n */\r\nconst getSchema = (type: TContentTypes, data: unknown): OpenAPIV3_1.SchemaObject => {\r\n  switch (type) {\r\n    case contentTypes.json:\r\n      return getInferSchema(data);\r\n\r\n    case contentTypes.html:\r\n    case contentTypes.plain:\r\n      return {\r\n        type: \"string\",\r\n      };\r\n\r\n    case contentTypes.binary:\r\n      return {\r\n        type: \"string\",\r\n        format: \"binary\",\r\n      };\r\n\r\n    default:\r\n      return {\r\n        type: \"null\",\r\n      };\r\n  }\r\n};\r\n\r\n\r\nconst getResponsesFromHandler = async (handler: THttpHandlerWithExtendedInfo, queries: ISwaggerOptions[\"queries\"]): Promise<{\r\n  content: OpenAPIV3_1.ResponsesObject & OpenAPIV3.ResponsesObject;\r\n  params: OpenAPIV3_1.ParameterObject[];\r\n  body?: OpenAPIV3_1.RequestBodyObject & OpenAPIV3.RequestBodyObject;\r\n}> => {\r\n\r\n  const {\r\n    type = contentTypes.json,\r\n    path,\r\n    method,\r\n    mock,\r\n    body,\r\n  } = handler.info;\r\n\r\n  const url = path?.toString() ?? \"\";\r\n\r\n  const init = {\r\n    method: method?.toString() ?? \"GET\" as const,\r\n    body,\r\n  };\r\n\r\n  let requestBody;\r\n  let params: OpenAPIV3_1.ParameterObject[] = [];\r\n\r\n  const content: OpenAPIV3_1.ResponsesObject & OpenAPIV3.ResponsesObject = {};\r\n\r\n  await Promise.allSettled([\r\n    // main\r\n    getResultInfo(url, init, queries),\r\n    // with custom queries only for functions as mocks\r\n    typeof mock === \"function\" ? queries.map(async ({ name, value }) => {\r\n      let urlWithParams = url;\r\n      try {\r\n        const url = new URL(urlWithParams);\r\n        url.searchParams.set(name, value.toString());\r\n        urlWithParams = url.href;\r\n      } catch (e) {\r\n        console.error(`[getSwaggerData] Can't append query params to url \"${url}\":`, e);\r\n      }\r\n      return getResultInfo(urlWithParams, init, queries);\r\n    }) : [],\r\n  ].flat())\r\n    .then((results) => results\r\n      .filter((res) => res.status === \"fulfilled\")\r\n      .map((res) => res.value))\r\n    .then((results) => {\r\n      results.forEach((result) => {\r\n        if (result) {\r\n          const {\r\n            status, mock, contentType, parameters, body,\r\n          } = result;\r\n          params = parameters;\r\n          requestBody = body;\r\n          content[status] = {\r\n            description: \"\",\r\n            content: {\r\n              [type]: {\r\n                example: mock,\r\n                schema: getSchema(contentType, mock),\r\n              } as OpenAPIV3.MediaTypeObject,\r\n            },\r\n          };\r\n        }\r\n      });\r\n      return Promise.resolve();\r\n    });\r\n\r\n  const result: {\r\n    content: OpenAPIV3_1.ResponsesObject & OpenAPIV3.ResponsesObject;\r\n    params: OpenAPIV3_1.ParameterObject[];\r\n    body?: OpenAPIV3_1.RequestBodyObject & OpenAPIV3.RequestBodyObject;\r\n  } = {\r\n    content,\r\n    params,\r\n  };\r\n\r\n  if (requestBody) {\r\n    result.body = requestBody;\r\n  }\r\n\r\n  return Promise.resolve(result);\r\n};\r\n\r\n/**\r\n * Генерирует OpenAPI 3.1.0 спецификацию из MSW handlers\r\n * @returns {Promise<OpenAPIV3_1.Document>}\r\n * @example\r\n * import { getApiMock, getSwaggerData } from \"@delement/ui/utils/msw\";\r\n *\r\n * const schema = await getSwaggerData({\r\n *   handlers: [getApiMock({ endpoint: \"/ping\", mock: { ok: true } })],\r\n *   meta: { title: \"API\", version: \"1.0.0\" },\r\n *   queries: [],\r\n * });\r\n */\r\nexport async function getSwaggerData({\r\n  handlers,\r\n  meta = defaultMeta,\r\n  basePath = \"\",\r\n  servers = [],\r\n  security = [],\r\n  queries = [],\r\n}: ISwaggerOptions): Promise<OpenAPIV3_1.Document> {\r\n\r\n  const paths: OpenAPIV3_1.PathsObject = {};\r\n\r\n  const server = setupServer(...handlers as HttpHandler[]);\r\n  server.listen();\r\n\r\n  try {\r\n    const listHandlers = server.listHandlers();\r\n\r\n    if (!listHandlers.length) {\r\n      throw new Error(\"[getSwaggerData] Can't parse mocks\");\r\n    }\r\n\r\n    console.debug(`[getSwaggerData] Found ${listHandlers.length} mocks:`, (Array.from(listHandlers) as unknown as THttpHandlerWithExtendedInfo[])\r\n      .filter((HttpHandler) => (HttpHandler).info !== undefined)\r\n      .map((HttpHandler) => HttpHandler.info?.header));\r\n\r\n    await Promise.all(handlers.map(async (handler) => {\r\n\r\n      const info = handler.info as { path?: string; method?: string; } & THttpHandlerWithExtendedInfo[\"info\"] | undefined;\r\n\r\n      if (!info?.path || !info?.method) {\r\n        console.error(\"[getSwaggerData] Skipping handler: missing path or method information\", info);\r\n        return;\r\n      }\r\n\r\n      // Clean the path by removing any URL origin (scheme, host, port)\r\n      let cleanPath = info.path;\r\n\r\n      // If the path looks like an absolute URL (or protocol-relative), parse it.\r\n      if (cleanPath.startsWith(\"http://\") || cleanPath.startsWith(\"https://\") || cleanPath.startsWith(\"//\")) {\r\n        try {\r\n          const url = new URL(cleanPath.startsWith(\"//\") ? `https:${cleanPath}` : cleanPath);\r\n          cleanPath = url.pathname;\r\n        } catch {\r\n          // Keep original if parsing fails\r\n        }\r\n      }\r\n\r\n      // Strip any query string that might have slipped through.\r\n      cleanPath = cleanPath.split(\"?\")[0];\r\n\r\n      // Ensure the final path starts with a single slash.\r\n      const fullPath = `${basePath}/${cleanPath}`\r\n        .replace(/\\/+/g, \"/\") // collapse multiple slashes\r\n        .replace(/\\/$/, \"\") // remove trailing slash (OpenAPI prefers no trailing slash)\r\n        || \"/\"; // fallback to root\r\n\r\n      const method = info.method.toLowerCase() as Lowercase<OpenAPIV3_1.HttpMethods>;\r\n\r\n      const { content, params, body } = await getResponsesFromHandler(handler, queries);\r\n\r\n      if (!paths[fullPath]) {\r\n        paths[fullPath] = {};\r\n      }\r\n\r\n      paths[fullPath][method] = {\r\n        description: info?.description ?? \"\",\r\n        tags: info?.tags ?? [],\r\n        summary: `${method.toUpperCase()} ${fullPath}`,\r\n        parameters: params,\r\n        responses: content,\r\n      };\r\n\r\n      if (body) {\r\n        paths[fullPath][method].requestBody = body;\r\n      }\r\n\r\n      return Promise.resolve();\r\n    }));\r\n\r\n    return {\r\n      openapi: \"3.1.0\",\r\n      info: {\r\n        ...defaultMeta,\r\n        ...(meta || {}),\r\n      },\r\n      servers,\r\n      paths,\r\n      components: {\r\n        schemas: {\r\n          SuccessIndicator: {\r\n            type: \"boolean\",\r\n          },\r\n          Modals: {\r\n            type: \"array\",\r\n            items: {\r\n              type: \"object\",\r\n              properties: {\r\n                header: {\r\n                  type: \"string\",\r\n                },\r\n                content: {\r\n                  type: \"string\",\r\n                },\r\n              },\r\n            },\r\n          },\r\n          Errors: {\r\n            type: \"array\",\r\n            items: {\r\n              type: \"string\",\r\n            },\r\n          },\r\n          SuccessResponse: {\r\n            type: \"object\",\r\n            properties: {\r\n              isSuccess: {\r\n                $ref: \"#/components/schemas/SuccessIndicator\",\r\n              },\r\n              modals: {\r\n                $ref: \"#/components/schemas/Modals\",\r\n              },\r\n              data: {\r\n                type: \"object\",\r\n              },\r\n            },\r\n          },\r\n          ErrorResponse: {\r\n            type: \"object\",\r\n            properties: {\r\n              isSuccess: {\r\n                $ref: \"#/components/schemas/SuccessIndicator\",\r\n              },\r\n              errors: {\r\n                $ref: \"#/components/schemas/Errors\",\r\n              },\r\n            },\r\n          },\r\n        },\r\n      },\r\n      security,\r\n    };\r\n  } finally {\r\n    server.close();\r\n  }\r\n}\r\n"],"names":["defaultMeta","title","description","version","summary","termsOfService","contact","name","url","email","license","getResultInfo","async","init","defaultQueries","body","fetch","then","status","resp","headers","Headers","contentType","get","contentTypes","json","parameters","getMock","binary","arrayBuffer","formData","text","searchParams","URL","mock","forEach","delete","value","key","item","in","schema","type","example","push","pathParameters","match","param","paramName","replace","method","HttpMethods","POST","PUT","PATCH","parsedBody","JSON","parse","required","content","getInferSchema","e","console","error","base","split","catch","err","Array","isArray","length","items","itemSchemas","map","uniqueSchemas","from","Set","stringify","schemaStr","oneOf","Number","isInteger","properties","Object","entries","val","additionalProperties","getSchema","data","html","plain","format","getResponsesFromHandler","handler","queries","path","info","toString","requestBody","params","Promise","allSettled","urlWithParams","set","href","flat","results","filter","res","result","resolve","getSwaggerData","handlers","meta","basePath","servers","security","paths","server","setupServer","listen","listHandlers","Error","debug","HttpHandler","undefined","header","all","cleanPath","startsWith","pathname","fullPath","toLowerCase","tags","toUpperCase","responses","openapi","components","schemas","SuccessIndicator","Modals","Errors","SuccessResponse","isSuccess","$ref","modals","ErrorResponse","errors","close"],"mappings":"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"}