@visulima/api-platform 1.2.15 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/{chunk-CFLRDDCI.mjs → chunk-KJPWKW4M.mjs} +4 -4
- package/dist/{chunk-CFLRDDCI.mjs.map → chunk-KJPWKW4M.mjs.map} +1 -1
- package/dist/{chunk-JBHGHBWN.js → chunk-Z6VLWWDV.js} +5 -5
- package/dist/chunk-Z6VLWWDV.js.map +1 -0
- package/dist/framework/next/index-server.js +2 -2
- package/dist/framework/next/index-server.mjs +1 -1
- package/dist/index-server.js +4 -4
- package/dist/index-server.mjs +2 -2
- package/package.json +45 -44
- package/dist/chunk-JBHGHBWN.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## @visulima/api-platform [2.0.0](https://github.com/visulima/visulima/compare/@visulima/api-platform@1.2.15...@visulima/api-platform@2.0.0) (2023-08-28)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### ⚠ BREAKING CHANGES
|
|
5
|
+
|
|
6
|
+
* update minimum Node.js version requirement to 18
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* refactor query parsing and update dependencies ([#203](https://github.com/visulima/visulima/issues/203)) ([cf77427](https://github.com/visulima/visulima/commit/cf7742795f970ebeeb5da22a82fd17750028ee87))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Dependencies
|
|
15
|
+
|
|
16
|
+
* **@visulima/connect:** upgraded to 2.0.0
|
|
17
|
+
* **@visulima/jsdoc-open-api:** upgraded to 2.0.0
|
|
18
|
+
* **@visulima/crud:** upgraded to 2.0.0
|
|
19
|
+
* **@visulima/readdir:** upgraded to 2.0.0
|
|
20
|
+
|
|
1
21
|
## @visulima/api-platform [1.2.15](https://github.com/visulima/visulima/compare/@visulima/api-platform@1.2.14...@visulima/api-platform@1.2.15) (2023-07-31)
|
|
2
22
|
|
|
3
23
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { stringify } from 'yaml';
|
|
2
2
|
import { existsSync, readFileSync } from 'fs';
|
|
3
|
-
import
|
|
3
|
+
import v from 'path';
|
|
4
4
|
import { modelsToOpenApi } from '@visulima/crud';
|
|
5
5
|
import S from 'debug';
|
|
6
6
|
import A from 'lodash.merge';
|
|
7
7
|
import R from 'jstoxml';
|
|
8
8
|
|
|
9
|
-
var u=e=>stringify(e,{indent:2}),
|
|
9
|
+
var u=e=>stringify(e,{indent:2}),j=u;var b=e=>e.toLowerCase().replaceAll(/[^\s\w]/g," ").trimEnd().replaceAll(/\s+|_/g,"-").replaceAll(/\b\w/g,n=>n.toUpperCase());var P="application/json",d=(e,n,s)=>{e.responses[n].content===void 0&&(e.responses[n].content={}),e.responses[n].content?.[s]===void 0&&(e.responses[n].content[s]={});},x=(e,n,s)=>{typeof e.components!="object"&&(e.components={}),typeof e.components.schemas!="object"&&(e.components.schemas={}),e.components.schemas[n]===void 0&&(e.components.schemas[n]=s);},w=(e,n,s,o,f)=>{d(e,n,s),e.responses[n].content?.[s]?.schema===void 0&&(e.responses[n].content[s].schema={}),e.responses[n].content[s].schema=f?{items:{$ref:`#/components/schemas/${o}`},type:"array"}:{$ref:`#/components/schemas/${o}`};},h=(e,n,s,o,f,p)=>{let a,t;return Object.entries(n.content).forEach(([c,r])=>{if(typeof r.schema=="object"){let{schema:i}=r;c===P&&r.examples!==void 0?t=r.examples:c===P&&r.example!==void 0&&(a=r.example);let l=i.type==="array";Object.entries(s??{}).forEach(([O,I])=>{if(!I)return;let g;i?.$ref===void 0?(g=`${b(o.trim().replace("/",""))}${O==="application/ld+json"?".jsonld":""}`,x(f,g,i)):g=i.$ref.replace("#/components/schemas/",""),w(e,p,O,g,l);});}}),{example:a,examples:t}},E=(e,n,s,o,f,p)=>{Object.keys(n.content).forEach(a=>{a!==P&&Object.entries(o??{}).forEach(([t,c])=>{if(!c)return;d(e,s,t),e.responses[s].content?.[t]?.example===void 0&&(e.responses[s].content[t].example={});let r=!1;f.forEach(({regex:i,transformer:l})=>{!r&&i.test(t)&&(e.responses[s].content[t].example=l(p),r=!0);}),r||(e.responses[s].content[t].example=p);});});},M=(e,n,s)=>{typeof e.components!="object"&&(e.components={}),typeof e.components.examples!="object"&&(e.components.examples={}),e.components.examples[n]===void 0&&s[n]!==void 0&&(e.components.examples[n]=s[n]);},T=(e,n,s,o,f,p)=>{d(n,s,o),n.responses[s].content?.[o]?.examples===void 0&&(n.responses[s].content[o].examples={});let a={};Object.entries(p).forEach(([t,c])=>{let r=!1;f.forEach(({regex:i,transformer:l})=>{if(!r&&i.test(o)){let O="";e.components?.examples?.[t]?O=e.components.examples[t].value:c.$ref?O=(e.components?.examples?.[c.$ref.replace("#/components/examples/","")]).value:typeof c.value=="string"&&(O=c.value),a[t]={value:l(O)},r=!0;}}),r||(a[t]=e.components?.examples?.[t]===void 0?c:{$ref:`#/components/examples/${t}`});}),n.responses[s].content[o].examples=a;},C=(e,n,s,o,f,p,a,t)=>{let c=`${b(p.trim().replace("/",""))}`;Object.keys(o.content).forEach(r=>{r!==P&&Object.entries(f??{}).forEach(([i,l])=>{l&&(M(e,c,t),T(e,n,s,i,a,t));});});};function m(e,n,s=[{regex:/xml/,transformer:o=>R.toXML(o,{header:!0,indent:" "})},{regex:/yaml|yml/,transformer:o=>stringify(o,{indent:2})}]){return typeof e=="object"&&typeof e.paths=="object"&&Object.entries(e.paths).forEach(([o,f])=>{Object.values(f).forEach(p=>{typeof p.responses=="object"&&Object.entries(p.responses).forEach(([a,t])=>{if(typeof t.content=="object"){let{example:c,examples:r}=h(p,t,n,o,e,a);c!==void 0?E(p,t,a,n,s,c):r!==void 0&&C(e,p,a,t,n,o,s,r);}});});}),e}var H=S("visulima:api-platform:swagger:crud:get-static-properties-swagger"),J=(e={})=>{let{allowedMediaTypes:n={"application/json":!0},crud:s,specs:o,swaggerFilePath:f}=e;return async(p,a)=>{let t=v.join(process.cwd(),f??"swagger/swagger.json");if(!existsSync(t))throw new Error(`Swagger file not found at "${t}".`);let c=readFileSync(t,"utf8"),r=m(JSON.parse(c),n),i={};if(s!==void 0)try{let O=await modelsToOpenApi(s);i={components:{examples:O.examples,schemas:O.schemas},paths:O.paths,tags:O.tags},i=m(i,n),H(JSON.stringify(i,null,2)),r=A(r,i);}catch(O){throw console.log(O),new Error("Please install @visulima/crud to use the crud swagger generator.")}Array.isArray(o)&&o.forEach(O=>{r=A(r,m(O,n));});let l;typeof p.headers.accept=="string"&&/yaml|yml/.test(p.headers.accept)?(a.setHeader("Content-Type",p.headers.accept),l=j(r)):(a.setHeader("Content-Type","application/json"),l=JSON.stringify(r,null,2)),a.statusCode=200,a.end(l);}},N=J;
|
|
10
10
|
|
|
11
|
-
export { b as a,
|
|
11
|
+
export { b as a, j as b, N as c };
|
|
12
12
|
//# sourceMappingURL=out.js.map
|
|
13
|
-
//# sourceMappingURL=chunk-
|
|
13
|
+
//# sourceMappingURL=chunk-KJPWKW4M.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/serializers/transformer/yaml.ts","../src/swagger/api/swagger-handler.ts","../src/swagger/extend-swagger-spec.ts","../src/utils.ts"],"names":["stringify","yamlTransformer","data","yaml_default","existsSync","readFileSync","path","modelsToOpenApi","debug","merge","xml","toHeaderCase","string_","c","jsonMediaType","prepareStatusContent","methodSpec","status","mediaType","extendComponentSchemas","spec","schemaName","schema","extendResponseSchema","schemaIsArray","extendSwaggerWithMediaTypeSchema","responseSpec","allowedMediaTypes","pathKey","example","examples","mediaName","contentSpec","allowed","extendSwaggerWithMediaTypeExample","transformers","transformed","regex","transformer","extendComponentExamples","exampleName","prepareResponseExamples","transformedExamples","extendSwaggerWithMediaTypeExamples","examplesName","extendSwaggerSpec","value","pathSpec","swaggerCrudDebug","swaggerHandler","options","crud","specs","swaggerFilePath","request","response","swaggerPath","fileContents","crudSwagger","modelsOpenApi","error","swagger_handler_default"],"mappings":"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","sourcesContent":["import { stringify } from \"yaml\";\n\nimport type { Serializer } from \"../types\";\n\nconst yamlTransformer: Serializer = (data) => stringify(data, { indent: 2 });\n\nexport default yamlTransformer;\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport type { ModelsToOpenApiParameters, SwaggerModelsConfig } from \"@visulima/crud\";\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { modelsToOpenApi } from \"@visulima/crud\";\nimport debug from \"debug\";\n// eslint-disable-next-line no-restricted-imports\nimport merge from \"lodash.merge\";\nimport type { OpenAPIV3 } from \"openapi-types\";\n\nimport yamlTransformer from \"../../serializers/transformer/yaml\";\nimport extendSwaggerSpec from \"../extend-swagger-spec\";\n\nconst swaggerCrudDebug = debug(\"visulima:api-platform:swagger:crud:get-static-properties-swagger\");\n\nconst swaggerHandler = <M extends string, PrismaClient>(\n // eslint-disable-next-line no-use-before-define\n options: Partial<SwaggerHandlerOptions<M, PrismaClient>> = {},\n): ((request: IncomingMessage, response: ServerResponse) => Promise<void>) => {\n const {\n allowedMediaTypes = {\n \"application/json\": true,\n },\n crud,\n specs,\n swaggerFilePath,\n } = options;\n\n return async <Request extends IncomingMessage, Response extends ServerResponse>(request: Request, response: Response) => {\n const swaggerPath = path.join(process.cwd(), swaggerFilePath ?? \"swagger/swagger.json\");\n\n if (!existsSync(swaggerPath)) {\n throw new Error(`Swagger file not found at \"${swaggerPath}\".`);\n }\n\n const fileContents = readFileSync(swaggerPath, \"utf8\");\n\n let spec = extendSwaggerSpec(JSON.parse(fileContents) as OpenAPIV3.Document, allowedMediaTypes) as OpenAPIV3.Document;\n let crudSwagger: Partial<OpenAPIV3.Document> = {};\n\n if (crud !== undefined) {\n try {\n const modelsOpenApi = await modelsToOpenApi(crud);\n\n crudSwagger = {\n components: { examples: modelsOpenApi.examples, schemas: modelsOpenApi.schemas },\n paths: modelsOpenApi.paths,\n tags: modelsOpenApi.tags,\n };\n\n crudSwagger = extendSwaggerSpec(crudSwagger, allowedMediaTypes);\n\n swaggerCrudDebug(JSON.stringify(crudSwagger, null, 2));\n\n spec = merge(spec, crudSwagger);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.log(error);\n\n throw new Error(\"Please install @visulima/crud to use the crud swagger generator.\");\n }\n }\n\n if (Array.isArray(specs)) {\n specs.forEach((value) => {\n spec = merge(spec, extendSwaggerSpec(value, allowedMediaTypes));\n });\n }\n\n let data: Buffer | Uint8Array | string;\n\n if (typeof request.headers.accept === \"string\" && /yaml|yml/.test(request.headers.accept)) {\n response.setHeader(\"Content-Type\", request.headers.accept);\n\n data = yamlTransformer(spec);\n } else {\n response.setHeader(\"Content-Type\", \"application/json\");\n\n data = JSON.stringify(spec, null, 2);\n }\n\n response.statusCode = 200;\n response.end(data);\n };\n};\n\nexport interface SwaggerHandlerOptions<M extends string, PrismaClient> {\n allowedMediaTypes: Record<string, boolean>;\n crud: Exclude<ModelsToOpenApiParameters<M, PrismaClient>, \"swagger\"> & {\n swagger?: {\n models?: SwaggerModelsConfig<M>;\n };\n };\n specs?: Partial<OpenAPIV3.Document>[];\n swaggerFilePath: string;\n}\n\nexport default swaggerHandler;\n","import type { XmlElement } from \"jstoxml\";\nimport xml from \"jstoxml\";\nimport type { OpenAPIV3 } from \"openapi-types\";\nimport { stringify } from \"yaml\";\n\nimport { toHeaderCase } from \"../utils\";\n\ntype Transformers = { regex: RegExp; transformer: (data: any) => string }[];\n\nconst jsonMediaType = \"application/json\";\n\nconst prepareStatusContent = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string) => {\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content === undefined) {\n // eslint-disable-next-line no-param-reassign\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content = {};\n }\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType] === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] = {} as OpenAPIV3.MediaTypeObject;\n }\n};\n\nconst extendComponentSchemas = (spec: Partial<OpenAPIV3.Document>, schemaName: string, schema: OpenAPIV3.SchemaObject) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.schemas !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas = {};\n }\n\n if (spec.components.schemas[schemaName] === undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas[schemaName] = schema;\n }\n};\n\nconst extendResponseSchema = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string, schemaName: string, schemaIsArray: boolean) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.schema === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n {} as OpenAPIV3.SchemaObject;\n }\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n schemaIsArray\n ? {\n items: {\n $ref: `#/components/schemas/${schemaName}`,\n },\n type: \"array\",\n }\n : {\n $ref: `#/components/schemas/${schemaName}`,\n };\n};\n\nconst extendSwaggerWithMediaTypeSchema = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n spec: Partial<OpenAPIV3.Document>,\n status: string,\n): {\n example?: any;\n examples?: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>;\n} => {\n let example: any | undefined;\n let examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> | undefined;\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n Object.entries(responseSpec.content as object).forEach(([mediaName, contentSpec]) => {\n if (typeof contentSpec.schema === \"object\") {\n const { schema } = contentSpec;\n\n if (mediaName === jsonMediaType && contentSpec.examples !== undefined) {\n examples = contentSpec.examples;\n } else if (mediaName === jsonMediaType && contentSpec.example !== undefined) {\n example = contentSpec.example;\n }\n\n const schemaIsArray = (schema as OpenAPIV3.SchemaObject).type === \"array\";\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n let schemaName: string;\n\n if (schema?.$ref === undefined) {\n schemaName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}${mediaType === \"application/ld+json\" ? \".jsonld\" : \"\"}`;\n\n extendComponentSchemas(spec as OpenAPIV3.Document, schemaName, schema as OpenAPIV3.SchemaObject);\n } else {\n schemaName = (schema as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/schemas/\", \"\");\n }\n\n extendResponseSchema(methodSpec, status, mediaType, schemaName, schemaIsArray);\n });\n }\n });\n\n return { example, examples };\n};\n\nconst extendSwaggerWithMediaTypeExample = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n status: string,\n allowedMediaTypes: Record<string, boolean> | undefined,\n transformers: Transformers,\n example: any,\n) => {\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.example === undefined\n ) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n {};\n }\n\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n transformer(example);\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n example;\n }\n });\n });\n};\n\nconst extendComponentExamples = (\n spec: Partial<OpenAPIV3.Document>,\n exampleName: string,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.examples !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples = {};\n }\n\n if (spec.components.examples[exampleName] === undefined && examples[exampleName] !== undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples[exampleName] = examples[exampleName] as OpenAPIV3.ExampleObject;\n }\n};\n\nconst prepareResponseExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n mediaType: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n // eslint-disable-next-line sonarjs/cognitive-complexity\n) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.examples === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n {};\n }\n\n const transformedExamples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> = {};\n\n Object.entries(examples).forEach(([exampleName, example]) => {\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n let data: any = \"\";\n\n if (spec.components?.examples?.[exampleName]) {\n data = (spec.components.examples[exampleName] as OpenAPIV3.ExampleObject).value;\n } else if ((example as OpenAPIV3.ReferenceObject).$ref) {\n data = (\n spec.components?.examples?.[\n (example as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/examples/\", \"\")\n ] as OpenAPIV3.ExampleObject\n ).value;\n } else if (typeof (example as OpenAPIV3.ExampleObject).value === \"string\") {\n data = (example as OpenAPIV3.ExampleObject).value;\n }\n\n transformedExamples[exampleName] = {\n value: transformer(data),\n };\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n transformedExamples[exampleName] =\n spec.components?.examples?.[exampleName] === undefined\n ? example\n : {\n $ref: `#/components/examples/${exampleName}`,\n };\n }\n });\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n transformedExamples;\n};\n\nconst extendSwaggerWithMediaTypeExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n const examplesName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}`;\n\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n extendComponentExamples(spec, examplesName, examples);\n\n prepareResponseExamples(spec, methodSpec, status, mediaType, transformers, examples);\n });\n });\n};\n\n// eslint-disable-next-line sonarjs/cognitive-complexity\nexport default function extendSwaggerSpec(\n spec: Partial<OpenAPIV3.Document>,\n allowedMediaTypes?: Record<string, boolean>,\n transformers: Transformers = [\n {\n regex: /xml/,\n transformer: (value: XmlElement | XmlElement[] | undefined) =>\n xml.toXML(value, {\n header: true,\n indent: \" \",\n }),\n },\n {\n regex: /yaml|yml/,\n transformer: (value) => stringify(value, { indent: 2 }),\n },\n ],\n): Partial<OpenAPIV3.Document> {\n if (typeof spec === \"object\" && typeof spec.paths === \"object\") {\n Object.entries(spec.paths).forEach(([pathKey, pathSpec]) => {\n Object.values(pathSpec as OpenAPIV3.OperationObject & OpenAPIV3.PathsObject).forEach((methodSpec) => {\n if (typeof (methodSpec as OpenAPIV3.OperationObject).responses === \"object\") {\n Object.entries((methodSpec as OpenAPIV3.OperationObject).responses).forEach(([status, responseSpec]) => {\n if (typeof (responseSpec as OpenAPIV3.ResponseObject).content === \"object\") {\n const { example, examples } = extendSwaggerWithMediaTypeSchema(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n spec,\n status,\n );\n\n if (example !== undefined) {\n extendSwaggerWithMediaTypeExample(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n status,\n allowedMediaTypes,\n transformers,\n example,\n );\n } else if (examples !== undefined) {\n extendSwaggerWithMediaTypeExamples(\n spec,\n methodSpec as OpenAPIV3.OperationObject,\n status,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n transformers,\n examples,\n );\n }\n }\n });\n }\n });\n });\n }\n\n return spec;\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { parse as urlParse } from \"node:url\";\n\ntype IncomingApiRequest<TApiRequest = IncomingMessage> = TApiRequest & {\n body?: any;\n query?: any;\n};\n\nexport const jsonResponse = (response: ServerResponse, status: number, data?: unknown): void => {\n response.statusCode = status;\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(data ? JSON.stringify(data) : \"\");\n};\n\nexport const parseBody = async (request: IncomingApiRequest): Promise<any> => {\n if (request.body) {\n return request.body;\n }\n\n const buffers = [];\n\n // eslint-disable-next-line no-restricted-syntax\n for await (const chunk of request) {\n buffers.push(chunk);\n }\n\n const data = Buffer.concat(buffers).toString();\n\n return data ? JSON.parse(data) : null;\n};\n\nexport const parseQuery = (request: IncomingApiRequest): unknown => {\n if (request.query) {\n return request.query;\n }\n\n return urlParse(request.url ?? \"\", true).query;\n};\n\nexport const toHeaderCase = (string_: string): string =>\n string_\n .toLowerCase()\n .replaceAll(/[^\\s\\w]/g, \" \") // Remove all non-word characters\n .trimEnd() // Remove trailing spaces\n .replaceAll(/\\s+|_/g, \"-\") // Replace multiple spaces or underline with a single hyphen\n .replaceAll(/\\b\\w/g, (c) => c.toUpperCase());\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/serializers/transformer/yaml.ts","../src/swagger/api/swagger-handler.ts","../src/swagger/extend-swagger-spec.ts","../src/utils.ts"],"names":["stringify","yamlTransformer","data","yaml_default","existsSync","readFileSync","path","modelsToOpenApi","debug","merge","xml","toHeaderCase","string_","c","jsonMediaType","prepareStatusContent","methodSpec","status","mediaType","extendComponentSchemas","spec","schemaName","schema","extendResponseSchema","schemaIsArray","extendSwaggerWithMediaTypeSchema","responseSpec","allowedMediaTypes","pathKey","example","examples","mediaName","contentSpec","allowed","extendSwaggerWithMediaTypeExample","transformers","transformed","regex","transformer","extendComponentExamples","exampleName","prepareResponseExamples","transformedExamples","extendSwaggerWithMediaTypeExamples","examplesName","extendSwaggerSpec","value","pathSpec","swaggerCrudDebug","swaggerHandler","options","crud","specs","swaggerFilePath","request","response","swaggerPath","fileContents","crudSwagger","modelsOpenApi","error","swagger_handler_default"],"mappings":"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","sourcesContent":["import { stringify } from \"yaml\";\n\nimport type { Serializer } from \"../types\";\n\nconst yamlTransformer: Serializer = (data) => stringify(data, { indent: 2 });\n\nexport default yamlTransformer;\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport type { ModelsToOpenApiParameters, SwaggerModelsConfig } from \"@visulima/crud\";\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { modelsToOpenApi } from \"@visulima/crud\";\nimport debug from \"debug\";\n// eslint-disable-next-line no-restricted-imports\nimport merge from \"lodash.merge\";\nimport type { OpenAPIV3 } from \"openapi-types\";\n\nimport yamlTransformer from \"../../serializers/transformer/yaml\";\nimport extendSwaggerSpec from \"../extend-swagger-spec\";\n\nconst swaggerCrudDebug = debug(\"visulima:api-platform:swagger:crud:get-static-properties-swagger\");\n\nconst swaggerHandler = <M extends string, PrismaClient>(\n // eslint-disable-next-line no-use-before-define\n options: Partial<SwaggerHandlerOptions<M, PrismaClient>> = {},\n): ((request: IncomingMessage, response: ServerResponse) => Promise<void>) => {\n const {\n allowedMediaTypes = {\n \"application/json\": true,\n },\n crud,\n specs,\n swaggerFilePath,\n } = options;\n\n return async <Request extends IncomingMessage, Response extends ServerResponse>(request: Request, response: Response) => {\n const swaggerPath = path.join(process.cwd(), swaggerFilePath ?? \"swagger/swagger.json\");\n\n if (!existsSync(swaggerPath)) {\n throw new Error(`Swagger file not found at \"${swaggerPath}\".`);\n }\n\n const fileContents = readFileSync(swaggerPath, \"utf8\");\n\n let spec = extendSwaggerSpec(JSON.parse(fileContents) as OpenAPIV3.Document, allowedMediaTypes) as OpenAPIV3.Document;\n let crudSwagger: Partial<OpenAPIV3.Document> = {};\n\n if (crud !== undefined) {\n try {\n const modelsOpenApi = await modelsToOpenApi(crud);\n\n crudSwagger = {\n components: { examples: modelsOpenApi.examples, schemas: modelsOpenApi.schemas },\n paths: modelsOpenApi.paths,\n tags: modelsOpenApi.tags,\n };\n\n crudSwagger = extendSwaggerSpec(crudSwagger, allowedMediaTypes);\n\n swaggerCrudDebug(JSON.stringify(crudSwagger, null, 2));\n\n spec = merge(spec, crudSwagger);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.log(error);\n\n throw new Error(\"Please install @visulima/crud to use the crud swagger generator.\");\n }\n }\n\n if (Array.isArray(specs)) {\n specs.forEach((value) => {\n spec = merge(spec, extendSwaggerSpec(value, allowedMediaTypes));\n });\n }\n\n let data: Buffer | Uint8Array | string;\n\n if (typeof request.headers.accept === \"string\" && /yaml|yml/.test(request.headers.accept)) {\n response.setHeader(\"Content-Type\", request.headers.accept);\n\n data = yamlTransformer(spec);\n } else {\n response.setHeader(\"Content-Type\", \"application/json\");\n\n data = JSON.stringify(spec, null, 2);\n }\n\n response.statusCode = 200;\n response.end(data);\n };\n};\n\nexport interface SwaggerHandlerOptions<M extends string, PrismaClient> {\n allowedMediaTypes: Record<string, boolean>;\n crud: Exclude<ModelsToOpenApiParameters<M, PrismaClient>, \"swagger\"> & {\n swagger?: {\n models?: SwaggerModelsConfig<M>;\n };\n };\n specs?: Partial<OpenAPIV3.Document>[];\n swaggerFilePath: string;\n}\n\nexport default swaggerHandler;\n","import type { XmlElement } from \"jstoxml\";\nimport xml from \"jstoxml\";\nimport type { OpenAPIV3 } from \"openapi-types\";\nimport { stringify } from \"yaml\";\n\nimport { toHeaderCase } from \"../utils\";\n\ntype Transformers = { regex: RegExp; transformer: (data: any) => string }[];\n\nconst jsonMediaType = \"application/json\";\n\nconst prepareStatusContent = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string) => {\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content === undefined) {\n // eslint-disable-next-line no-param-reassign\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content = {};\n }\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType] === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] = {} as OpenAPIV3.MediaTypeObject;\n }\n};\n\nconst extendComponentSchemas = (spec: Partial<OpenAPIV3.Document>, schemaName: string, schema: OpenAPIV3.SchemaObject) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.schemas !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas = {};\n }\n\n if (spec.components.schemas[schemaName] === undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas[schemaName] = schema;\n }\n};\n\nconst extendResponseSchema = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string, schemaName: string, schemaIsArray: boolean) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.schema === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n {} as OpenAPIV3.SchemaObject;\n }\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n schemaIsArray\n ? {\n items: {\n $ref: `#/components/schemas/${schemaName}`,\n },\n type: \"array\",\n }\n : {\n $ref: `#/components/schemas/${schemaName}`,\n };\n};\n\nconst extendSwaggerWithMediaTypeSchema = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n spec: Partial<OpenAPIV3.Document>,\n status: string,\n): {\n example?: any;\n examples?: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>;\n} => {\n let example: any | undefined;\n let examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> | undefined;\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n Object.entries(responseSpec.content as object).forEach(([mediaName, contentSpec]) => {\n if (typeof contentSpec.schema === \"object\") {\n const { schema } = contentSpec;\n\n if (mediaName === jsonMediaType && contentSpec.examples !== undefined) {\n examples = contentSpec.examples;\n } else if (mediaName === jsonMediaType && contentSpec.example !== undefined) {\n example = contentSpec.example;\n }\n\n const schemaIsArray = (schema as OpenAPIV3.SchemaObject).type === \"array\";\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n let schemaName: string;\n\n if (schema?.$ref === undefined) {\n schemaName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}${mediaType === \"application/ld+json\" ? \".jsonld\" : \"\"}`;\n\n extendComponentSchemas(spec as OpenAPIV3.Document, schemaName, schema as OpenAPIV3.SchemaObject);\n } else {\n schemaName = (schema as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/schemas/\", \"\");\n }\n\n extendResponseSchema(methodSpec, status, mediaType, schemaName, schemaIsArray);\n });\n }\n });\n\n return { example, examples };\n};\n\nconst extendSwaggerWithMediaTypeExample = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n status: string,\n allowedMediaTypes: Record<string, boolean> | undefined,\n transformers: Transformers,\n example: any,\n) => {\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.example === undefined\n ) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n {};\n }\n\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n transformer(example);\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n example;\n }\n });\n });\n};\n\nconst extendComponentExamples = (\n spec: Partial<OpenAPIV3.Document>,\n exampleName: string,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.examples !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples = {};\n }\n\n if (spec.components.examples[exampleName] === undefined && examples[exampleName] !== undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples[exampleName] = examples[exampleName] as OpenAPIV3.ExampleObject;\n }\n};\n\nconst prepareResponseExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n mediaType: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n // eslint-disable-next-line sonarjs/cognitive-complexity\n) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.examples === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n {};\n }\n\n const transformedExamples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> = {};\n\n Object.entries(examples).forEach(([exampleName, example]) => {\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n let data: any = \"\";\n\n if (spec.components?.examples?.[exampleName]) {\n data = (spec.components.examples[exampleName] as OpenAPIV3.ExampleObject).value;\n } else if ((example as OpenAPIV3.ReferenceObject).$ref) {\n data = (\n spec.components?.examples?.[\n (example as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/examples/\", \"\")\n ] as OpenAPIV3.ExampleObject\n ).value;\n } else if (typeof (example as OpenAPIV3.ExampleObject).value === \"string\") {\n data = (example as OpenAPIV3.ExampleObject).value;\n }\n\n transformedExamples[exampleName] = {\n value: transformer(data),\n };\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n transformedExamples[exampleName] =\n spec.components?.examples?.[exampleName] === undefined\n ? example\n : {\n $ref: `#/components/examples/${exampleName}`,\n };\n }\n });\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n transformedExamples;\n};\n\nconst extendSwaggerWithMediaTypeExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n const examplesName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}`;\n\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n extendComponentExamples(spec, examplesName, examples);\n\n prepareResponseExamples(spec, methodSpec, status, mediaType, transformers, examples);\n });\n });\n};\n\n// eslint-disable-next-line sonarjs/cognitive-complexity\nexport default function extendSwaggerSpec(\n spec: Partial<OpenAPIV3.Document>,\n allowedMediaTypes?: Record<string, boolean>,\n transformers: Transformers = [\n {\n regex: /xml/,\n transformer: (value: XmlElement | XmlElement[] | undefined) =>\n xml.toXML(value, {\n header: true,\n indent: \" \",\n }),\n },\n {\n regex: /yaml|yml/,\n transformer: (value) => stringify(value, { indent: 2 }),\n },\n ],\n): Partial<OpenAPIV3.Document> {\n if (typeof spec === \"object\" && typeof spec.paths === \"object\") {\n Object.entries(spec.paths).forEach(([pathKey, pathSpec]) => {\n Object.values(pathSpec as OpenAPIV3.OperationObject & OpenAPIV3.PathsObject).forEach((methodSpec) => {\n if (typeof (methodSpec as OpenAPIV3.OperationObject).responses === \"object\") {\n Object.entries((methodSpec as OpenAPIV3.OperationObject).responses).forEach(([status, responseSpec]) => {\n if (typeof (responseSpec as OpenAPIV3.ResponseObject).content === \"object\") {\n const { example, examples } = extendSwaggerWithMediaTypeSchema(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n spec,\n status,\n );\n\n if (example !== undefined) {\n extendSwaggerWithMediaTypeExample(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n status,\n allowedMediaTypes,\n transformers,\n example,\n );\n } else if (examples !== undefined) {\n extendSwaggerWithMediaTypeExamples(\n spec,\n methodSpec as OpenAPIV3.OperationObject,\n status,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n transformers,\n examples,\n );\n }\n }\n });\n }\n });\n });\n }\n\n return spec;\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { URL } from \"node:url\";\n\ntype IncomingApiRequest<TApiRequest = IncomingMessage> = TApiRequest & {\n body?: any;\n query?: any;\n};\n\nexport const jsonResponse = (response: ServerResponse, status: number, data?: unknown): void => {\n response.statusCode = status;\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(data ? JSON.stringify(data) : \"\");\n};\n\nexport const parseBody = async (request: IncomingApiRequest): Promise<any> => {\n if (request.body) {\n return request.body;\n }\n\n const buffers = [];\n\n // eslint-disable-next-line no-restricted-syntax\n for await (const chunk of request) {\n buffers.push(chunk);\n }\n\n const data = Buffer.concat(buffers).toString();\n\n return data ? JSON.parse(data) : null;\n};\n\nexport const parseQuery = (request: IncomingApiRequest): Record<string, unknown> => {\n if (request.query) {\n return request.query;\n }\n\n if (!request.url) {\n return {};\n }\n\n // Note: Fake protocol is required to parse query string\n const url = new URL(`https://${request.headers.host?.replace(/\\/$/, \"\")}/${request.url}`);\n\n return Object.fromEntries(url.searchParams.entries());\n};\n\nexport const toHeaderCase = (string_: string): string =>\n string_\n .toLowerCase()\n .replaceAll(/[^\\s\\w]/g, \" \") // Remove all non-word characters\n .trimEnd() // Remove trailing spaces\n .replaceAll(/\\s+|_/g, \"-\") // Replace multiple spaces or underline with a single hyphen\n .replaceAll(/\\b\\w/g, (c) => c.toUpperCase());\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var yaml = require('yaml');
|
|
4
4
|
var fs = require('fs');
|
|
5
|
-
var
|
|
5
|
+
var v = require('path');
|
|
6
6
|
var crud = require('@visulima/crud');
|
|
7
7
|
var S = require('debug');
|
|
8
8
|
var A = require('lodash.merge');
|
|
@@ -11,15 +11,15 @@ require('url');
|
|
|
11
11
|
|
|
12
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var v__default = /*#__PURE__*/_interopDefault(v);
|
|
15
15
|
var S__default = /*#__PURE__*/_interopDefault(S);
|
|
16
16
|
var A__default = /*#__PURE__*/_interopDefault(A);
|
|
17
17
|
var R__default = /*#__PURE__*/_interopDefault(R);
|
|
18
18
|
|
|
19
|
-
var u=e=>yaml.stringify(e,{indent:2}),
|
|
19
|
+
var u=e=>yaml.stringify(e,{indent:2}),j=u;var b=e=>e.toLowerCase().replaceAll(/[^\s\w]/g," ").trimEnd().replaceAll(/\s+|_/g,"-").replaceAll(/\b\w/g,n=>n.toUpperCase());var P="application/json",d=(e,n,s)=>{e.responses[n].content===void 0&&(e.responses[n].content={}),e.responses[n].content?.[s]===void 0&&(e.responses[n].content[s]={});},x=(e,n,s)=>{typeof e.components!="object"&&(e.components={}),typeof e.components.schemas!="object"&&(e.components.schemas={}),e.components.schemas[n]===void 0&&(e.components.schemas[n]=s);},w=(e,n,s,o,f)=>{d(e,n,s),e.responses[n].content?.[s]?.schema===void 0&&(e.responses[n].content[s].schema={}),e.responses[n].content[s].schema=f?{items:{$ref:`#/components/schemas/${o}`},type:"array"}:{$ref:`#/components/schemas/${o}`};},h=(e,n,s,o,f,p)=>{let a,t;return Object.entries(n.content).forEach(([c,r])=>{if(typeof r.schema=="object"){let{schema:i}=r;c===P&&r.examples!==void 0?t=r.examples:c===P&&r.example!==void 0&&(a=r.example);let l=i.type==="array";Object.entries(s??{}).forEach(([O,I])=>{if(!I)return;let g;i?.$ref===void 0?(g=`${b(o.trim().replace("/",""))}${O==="application/ld+json"?".jsonld":""}`,x(f,g,i)):g=i.$ref.replace("#/components/schemas/",""),w(e,p,O,g,l);});}}),{example:a,examples:t}},E=(e,n,s,o,f,p)=>{Object.keys(n.content).forEach(a=>{a!==P&&Object.entries(o??{}).forEach(([t,c])=>{if(!c)return;d(e,s,t),e.responses[s].content?.[t]?.example===void 0&&(e.responses[s].content[t].example={});let r=!1;f.forEach(({regex:i,transformer:l})=>{!r&&i.test(t)&&(e.responses[s].content[t].example=l(p),r=!0);}),r||(e.responses[s].content[t].example=p);});});},M=(e,n,s)=>{typeof e.components!="object"&&(e.components={}),typeof e.components.examples!="object"&&(e.components.examples={}),e.components.examples[n]===void 0&&s[n]!==void 0&&(e.components.examples[n]=s[n]);},T=(e,n,s,o,f,p)=>{d(n,s,o),n.responses[s].content?.[o]?.examples===void 0&&(n.responses[s].content[o].examples={});let a={};Object.entries(p).forEach(([t,c])=>{let r=!1;f.forEach(({regex:i,transformer:l})=>{if(!r&&i.test(o)){let O="";e.components?.examples?.[t]?O=e.components.examples[t].value:c.$ref?O=(e.components?.examples?.[c.$ref.replace("#/components/examples/","")]).value:typeof c.value=="string"&&(O=c.value),a[t]={value:l(O)},r=!0;}}),r||(a[t]=e.components?.examples?.[t]===void 0?c:{$ref:`#/components/examples/${t}`});}),n.responses[s].content[o].examples=a;},C=(e,n,s,o,f,p,a,t)=>{let c=`${b(p.trim().replace("/",""))}`;Object.keys(o.content).forEach(r=>{r!==P&&Object.entries(f??{}).forEach(([i,l])=>{l&&(M(e,c,t),T(e,n,s,i,a,t));});});};function m(e,n,s=[{regex:/xml/,transformer:o=>R__default.default.toXML(o,{header:!0,indent:" "})},{regex:/yaml|yml/,transformer:o=>yaml.stringify(o,{indent:2})}]){return typeof e=="object"&&typeof e.paths=="object"&&Object.entries(e.paths).forEach(([o,f])=>{Object.values(f).forEach(p=>{typeof p.responses=="object"&&Object.entries(p.responses).forEach(([a,t])=>{if(typeof t.content=="object"){let{example:c,examples:r}=h(p,t,n,o,e,a);c!==void 0?E(p,t,a,n,s,c):r!==void 0&&C(e,p,a,t,n,o,s,r);}});});}),e}var H=S__default.default("visulima:api-platform:swagger:crud:get-static-properties-swagger"),J=(e={})=>{let{allowedMediaTypes:n={"application/json":!0},crud:s,specs:o,swaggerFilePath:f}=e;return async(p,a)=>{let t=v__default.default.join(process.cwd(),f??"swagger/swagger.json");if(!fs.existsSync(t))throw new Error(`Swagger file not found at "${t}".`);let c=fs.readFileSync(t,"utf8"),r=m(JSON.parse(c),n),i={};if(s!==void 0)try{let O=await crud.modelsToOpenApi(s);i={components:{examples:O.examples,schemas:O.schemas},paths:O.paths,tags:O.tags},i=m(i,n),H(JSON.stringify(i,null,2)),r=A__default.default(r,i);}catch(O){throw console.log(O),new Error("Please install @visulima/crud to use the crud swagger generator.")}Array.isArray(o)&&o.forEach(O=>{r=A__default.default(r,m(O,n));});let l;typeof p.headers.accept=="string"&&/yaml|yml/.test(p.headers.accept)?(a.setHeader("Content-Type",p.headers.accept),l=j(r)):(a.setHeader("Content-Type","application/json"),l=JSON.stringify(r,null,2)),a.statusCode=200,a.end(l);}},ne=J;
|
|
20
20
|
|
|
21
21
|
exports.a = b;
|
|
22
|
-
exports.b =
|
|
22
|
+
exports.b = j;
|
|
23
23
|
exports.c = ne;
|
|
24
24
|
//# sourceMappingURL=out.js.map
|
|
25
|
-
//# sourceMappingURL=chunk-
|
|
25
|
+
//# sourceMappingURL=chunk-Z6VLWWDV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/serializers/transformer/yaml.ts","../src/swagger/api/swagger-handler.ts","../src/swagger/extend-swagger-spec.ts","../src/utils.ts"],"names":["stringify","yamlTransformer","data","yaml_default","existsSync","readFileSync","path","modelsToOpenApi","debug","merge","xml","URL","toHeaderCase","string_","c","jsonMediaType","prepareStatusContent","methodSpec","status","mediaType","extendComponentSchemas","spec","schemaName","schema","extendResponseSchema","schemaIsArray","extendSwaggerWithMediaTypeSchema","responseSpec","allowedMediaTypes","pathKey","example","examples","mediaName","contentSpec","allowed","extendSwaggerWithMediaTypeExample","transformers","transformed","regex","transformer","extendComponentExamples","exampleName","prepareResponseExamples","transformedExamples","extendSwaggerWithMediaTypeExamples","examplesName","extendSwaggerSpec","value","pathSpec","swaggerCrudDebug","swaggerHandler","options","crud","specs","swaggerFilePath","request","response","swaggerPath","fileContents","crudSwagger","modelsOpenApi","error","swagger_handler_default"],"mappings":"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","sourcesContent":["import { stringify } from \"yaml\";\n\nimport type { Serializer } from \"../types\";\n\nconst yamlTransformer: Serializer = (data) => stringify(data, { indent: 2 });\n\nexport default yamlTransformer;\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport type { ModelsToOpenApiParameters, SwaggerModelsConfig } from \"@visulima/crud\";\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { modelsToOpenApi } from \"@visulima/crud\";\nimport debug from \"debug\";\n// eslint-disable-next-line no-restricted-imports\nimport merge from \"lodash.merge\";\nimport type { OpenAPIV3 } from \"openapi-types\";\n\nimport yamlTransformer from \"../../serializers/transformer/yaml\";\nimport extendSwaggerSpec from \"../extend-swagger-spec\";\n\nconst swaggerCrudDebug = debug(\"visulima:api-platform:swagger:crud:get-static-properties-swagger\");\n\nconst swaggerHandler = <M extends string, PrismaClient>(\n // eslint-disable-next-line no-use-before-define\n options: Partial<SwaggerHandlerOptions<M, PrismaClient>> = {},\n): ((request: IncomingMessage, response: ServerResponse) => Promise<void>) => {\n const {\n allowedMediaTypes = {\n \"application/json\": true,\n },\n crud,\n specs,\n swaggerFilePath,\n } = options;\n\n return async <Request extends IncomingMessage, Response extends ServerResponse>(request: Request, response: Response) => {\n const swaggerPath = path.join(process.cwd(), swaggerFilePath ?? \"swagger/swagger.json\");\n\n if (!existsSync(swaggerPath)) {\n throw new Error(`Swagger file not found at \"${swaggerPath}\".`);\n }\n\n const fileContents = readFileSync(swaggerPath, \"utf8\");\n\n let spec = extendSwaggerSpec(JSON.parse(fileContents) as OpenAPIV3.Document, allowedMediaTypes) as OpenAPIV3.Document;\n let crudSwagger: Partial<OpenAPIV3.Document> = {};\n\n if (crud !== undefined) {\n try {\n const modelsOpenApi = await modelsToOpenApi(crud);\n\n crudSwagger = {\n components: { examples: modelsOpenApi.examples, schemas: modelsOpenApi.schemas },\n paths: modelsOpenApi.paths,\n tags: modelsOpenApi.tags,\n };\n\n crudSwagger = extendSwaggerSpec(crudSwagger, allowedMediaTypes);\n\n swaggerCrudDebug(JSON.stringify(crudSwagger, null, 2));\n\n spec = merge(spec, crudSwagger);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.log(error);\n\n throw new Error(\"Please install @visulima/crud to use the crud swagger generator.\");\n }\n }\n\n if (Array.isArray(specs)) {\n specs.forEach((value) => {\n spec = merge(spec, extendSwaggerSpec(value, allowedMediaTypes));\n });\n }\n\n let data: Buffer | Uint8Array | string;\n\n if (typeof request.headers.accept === \"string\" && /yaml|yml/.test(request.headers.accept)) {\n response.setHeader(\"Content-Type\", request.headers.accept);\n\n data = yamlTransformer(spec);\n } else {\n response.setHeader(\"Content-Type\", \"application/json\");\n\n data = JSON.stringify(spec, null, 2);\n }\n\n response.statusCode = 200;\n response.end(data);\n };\n};\n\nexport interface SwaggerHandlerOptions<M extends string, PrismaClient> {\n allowedMediaTypes: Record<string, boolean>;\n crud: Exclude<ModelsToOpenApiParameters<M, PrismaClient>, \"swagger\"> & {\n swagger?: {\n models?: SwaggerModelsConfig<M>;\n };\n };\n specs?: Partial<OpenAPIV3.Document>[];\n swaggerFilePath: string;\n}\n\nexport default swaggerHandler;\n","import type { XmlElement } from \"jstoxml\";\nimport xml from \"jstoxml\";\nimport type { OpenAPIV3 } from \"openapi-types\";\nimport { stringify } from \"yaml\";\n\nimport { toHeaderCase } from \"../utils\";\n\ntype Transformers = { regex: RegExp; transformer: (data: any) => string }[];\n\nconst jsonMediaType = \"application/json\";\n\nconst prepareStatusContent = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string) => {\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content === undefined) {\n // eslint-disable-next-line no-param-reassign\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content = {};\n }\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType] === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] = {} as OpenAPIV3.MediaTypeObject;\n }\n};\n\nconst extendComponentSchemas = (spec: Partial<OpenAPIV3.Document>, schemaName: string, schema: OpenAPIV3.SchemaObject) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.schemas !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas = {};\n }\n\n if (spec.components.schemas[schemaName] === undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas[schemaName] = schema;\n }\n};\n\nconst extendResponseSchema = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string, schemaName: string, schemaIsArray: boolean) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.schema === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n {} as OpenAPIV3.SchemaObject;\n }\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n schemaIsArray\n ? {\n items: {\n $ref: `#/components/schemas/${schemaName}`,\n },\n type: \"array\",\n }\n : {\n $ref: `#/components/schemas/${schemaName}`,\n };\n};\n\nconst extendSwaggerWithMediaTypeSchema = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n spec: Partial<OpenAPIV3.Document>,\n status: string,\n): {\n example?: any;\n examples?: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>;\n} => {\n let example: any | undefined;\n let examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> | undefined;\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n Object.entries(responseSpec.content as object).forEach(([mediaName, contentSpec]) => {\n if (typeof contentSpec.schema === \"object\") {\n const { schema } = contentSpec;\n\n if (mediaName === jsonMediaType && contentSpec.examples !== undefined) {\n examples = contentSpec.examples;\n } else if (mediaName === jsonMediaType && contentSpec.example !== undefined) {\n example = contentSpec.example;\n }\n\n const schemaIsArray = (schema as OpenAPIV3.SchemaObject).type === \"array\";\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n let schemaName: string;\n\n if (schema?.$ref === undefined) {\n schemaName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}${mediaType === \"application/ld+json\" ? \".jsonld\" : \"\"}`;\n\n extendComponentSchemas(spec as OpenAPIV3.Document, schemaName, schema as OpenAPIV3.SchemaObject);\n } else {\n schemaName = (schema as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/schemas/\", \"\");\n }\n\n extendResponseSchema(methodSpec, status, mediaType, schemaName, schemaIsArray);\n });\n }\n });\n\n return { example, examples };\n};\n\nconst extendSwaggerWithMediaTypeExample = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n status: string,\n allowedMediaTypes: Record<string, boolean> | undefined,\n transformers: Transformers,\n example: any,\n) => {\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.example === undefined\n ) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n {};\n }\n\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n transformer(example);\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n example;\n }\n });\n });\n};\n\nconst extendComponentExamples = (\n spec: Partial<OpenAPIV3.Document>,\n exampleName: string,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.examples !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples = {};\n }\n\n if (spec.components.examples[exampleName] === undefined && examples[exampleName] !== undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples[exampleName] = examples[exampleName] as OpenAPIV3.ExampleObject;\n }\n};\n\nconst prepareResponseExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n mediaType: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n // eslint-disable-next-line sonarjs/cognitive-complexity\n) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.examples === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n {};\n }\n\n const transformedExamples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> = {};\n\n Object.entries(examples).forEach(([exampleName, example]) => {\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n let data: any = \"\";\n\n if (spec.components?.examples?.[exampleName]) {\n data = (spec.components.examples[exampleName] as OpenAPIV3.ExampleObject).value;\n } else if ((example as OpenAPIV3.ReferenceObject).$ref) {\n data = (\n spec.components?.examples?.[\n (example as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/examples/\", \"\")\n ] as OpenAPIV3.ExampleObject\n ).value;\n } else if (typeof (example as OpenAPIV3.ExampleObject).value === \"string\") {\n data = (example as OpenAPIV3.ExampleObject).value;\n }\n\n transformedExamples[exampleName] = {\n value: transformer(data),\n };\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n transformedExamples[exampleName] =\n spec.components?.examples?.[exampleName] === undefined\n ? example\n : {\n $ref: `#/components/examples/${exampleName}`,\n };\n }\n });\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n transformedExamples;\n};\n\nconst extendSwaggerWithMediaTypeExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n const examplesName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}`;\n\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n extendComponentExamples(spec, examplesName, examples);\n\n prepareResponseExamples(spec, methodSpec, status, mediaType, transformers, examples);\n });\n });\n};\n\n// eslint-disable-next-line sonarjs/cognitive-complexity\nexport default function extendSwaggerSpec(\n spec: Partial<OpenAPIV3.Document>,\n allowedMediaTypes?: Record<string, boolean>,\n transformers: Transformers = [\n {\n regex: /xml/,\n transformer: (value: XmlElement | XmlElement[] | undefined) =>\n xml.toXML(value, {\n header: true,\n indent: \" \",\n }),\n },\n {\n regex: /yaml|yml/,\n transformer: (value) => stringify(value, { indent: 2 }),\n },\n ],\n): Partial<OpenAPIV3.Document> {\n if (typeof spec === \"object\" && typeof spec.paths === \"object\") {\n Object.entries(spec.paths).forEach(([pathKey, pathSpec]) => {\n Object.values(pathSpec as OpenAPIV3.OperationObject & OpenAPIV3.PathsObject).forEach((methodSpec) => {\n if (typeof (methodSpec as OpenAPIV3.OperationObject).responses === \"object\") {\n Object.entries((methodSpec as OpenAPIV3.OperationObject).responses).forEach(([status, responseSpec]) => {\n if (typeof (responseSpec as OpenAPIV3.ResponseObject).content === \"object\") {\n const { example, examples } = extendSwaggerWithMediaTypeSchema(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n spec,\n status,\n );\n\n if (example !== undefined) {\n extendSwaggerWithMediaTypeExample(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n status,\n allowedMediaTypes,\n transformers,\n example,\n );\n } else if (examples !== undefined) {\n extendSwaggerWithMediaTypeExamples(\n spec,\n methodSpec as OpenAPIV3.OperationObject,\n status,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n transformers,\n examples,\n );\n }\n }\n });\n }\n });\n });\n }\n\n return spec;\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { URL } from \"node:url\";\n\ntype IncomingApiRequest<TApiRequest = IncomingMessage> = TApiRequest & {\n body?: any;\n query?: any;\n};\n\nexport const jsonResponse = (response: ServerResponse, status: number, data?: unknown): void => {\n response.statusCode = status;\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(data ? JSON.stringify(data) : \"\");\n};\n\nexport const parseBody = async (request: IncomingApiRequest): Promise<any> => {\n if (request.body) {\n return request.body;\n }\n\n const buffers = [];\n\n // eslint-disable-next-line no-restricted-syntax\n for await (const chunk of request) {\n buffers.push(chunk);\n }\n\n const data = Buffer.concat(buffers).toString();\n\n return data ? JSON.parse(data) : null;\n};\n\nexport const parseQuery = (request: IncomingApiRequest): Record<string, unknown> => {\n if (request.query) {\n return request.query;\n }\n\n if (!request.url) {\n return {};\n }\n\n // Note: Fake protocol is required to parse query string\n const url = new URL(`https://${request.headers.host?.replace(/\\/$/, \"\")}/${request.url}`);\n\n return Object.fromEntries(url.searchParams.entries());\n};\n\nexport const toHeaderCase = (string_: string): string =>\n string_\n .toLowerCase()\n .replaceAll(/[^\\s\\w]/g, \" \") // Remove all non-word characters\n .trimEnd() // Remove trailing spaces\n .replaceAll(/\\s+|_/g, \"-\") // Replace multiple spaces or underline with a single hyphen\n .replaceAll(/\\b\\w/g, (c) => c.toUpperCase());\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkZ6VLWWDV_js = require('../../chunk-Z6VLWWDV.js');
|
|
4
4
|
var chunk3GKT5H3V_js = require('../../chunk-3GKT5H3V.js');
|
|
5
5
|
require('../../chunk-4D6JZ4TL.js');
|
|
6
6
|
var l = require('fs');
|
|
@@ -12,7 +12,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
12
12
|
var l__default = /*#__PURE__*/_interopDefault(l);
|
|
13
13
|
var d__default = /*#__PURE__*/_interopDefault(d);
|
|
14
14
|
|
|
15
|
-
var f=(t={})=>
|
|
15
|
+
var f=(t={})=>chunkZ6VLWWDV_js.c(t),m=f;var u=({definition:t,output:r="swagger/swagger.json",sources:s,verbose:p})=>o=>({...o,webpack:(e,i)=>{if(!i.isServer)return e;if(r.startsWith("/")&&(r=r.slice(1)),!r.endsWith(".json"))throw new Error("The output path must end with .json");return e={...e,plugins:[...e.plugins,new jsdocOpenApi.SwaggerCompilerPlugin(`${i.dir}/${r}`,s.map(g=>{let a=d__default.default.join(i.dir,g.replace("./",""));return l__default.default.lstatSync(a).isDirectory(),a}),{openapi:"3.0.0",...t},{verbose:p})]},typeof o.webpack=="function"?o.webpack(e,i):e}}),c=u;
|
|
16
16
|
|
|
17
17
|
Object.defineProperty(exports, 'getSwaggerStaticProps', {
|
|
18
18
|
enumerable: true,
|
package/dist/index-server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkWYXGSYH5_js = require('./chunk-WYXGSYH5.js');
|
|
4
|
-
var
|
|
4
|
+
var chunkZ6VLWWDV_js = require('./chunk-Z6VLWWDV.js');
|
|
5
5
|
require('./chunk-4D6JZ4TL.js');
|
|
6
6
|
var connect = require('@visulima/connect');
|
|
7
7
|
var O = require('http-errors');
|
|
@@ -21,7 +21,7 @@ var $__default = /*#__PURE__*/_interopDefault($);
|
|
|
21
21
|
var G__default = /*#__PURE__*/_interopDefault(G);
|
|
22
22
|
var ae__default = /*#__PURE__*/_interopDefault(ae);
|
|
23
23
|
|
|
24
|
-
var f=(e,o)=>{let t=o.headers??{};Object.keys(t).forEach(r=>{e.setHeader(r,t[r]);});},p=(e,o)=>{e.setHeader("content-type","application/json; charset=utf-8"),e.end(JSON.stringify(o));},u=(e,o)=>{o.statusCode!==void 0&&(e.statusCode=o.statusCode),o.status!==void 0&&(e.statusCode=o.status),e.statusCode<400&&(e.statusCode=httpStatusCodes.StatusCodes.INTERNAL_SERVER_ERROR);};var v="An error occurred",J=(e,o,t)=>{if(u(t,e),f(t,e),e instanceof y__default.default.JapiError||y__default.default.JapiError.isLikeJapiError(e)){let r=new y__default.default.ErrorSerializer;p(t,r.serialize(e));}else if(e instanceof O.HttpError){let{message:r,statusCode:n,title:a}=e;p(t,{errors:[{code:n,title:a||httpStatusCodes.getReasonPhrase(n)||v,detail:r}]});}else {let{message:r}=e;p(t,{errors:[{code:"500",title:httpStatusCodes.getReasonPhrase(t.statusCode)||v,detail:r}]});}},z=J;var A="https://tools.ietf.org/html/rfc2616#section-10",M="An error occurred",W=(e,o,t)=>{let{message:r,stack:n}=e;if(e instanceof O.HttpError){let{expose:a,statusCode:s,title:i,type:d}=e;t.statusCode=s,f(t,e),p(t,{type:d||A,title:i||httpStatusCodes.getReasonPhrase(s)||M,details:r,...a?{trace:n}:{}});}else u(t,e),p(t,{type:A,title:httpStatusCodes.getReasonPhrase(t.statusCode)||M,details:r,...e.expose?{trace:n}:{}});},C=W;var x=(e,o)=>async(t,r,n)=>{let a=r.headers.accept,s=C;a==="application/vnd.api+json"&&(s=z);for(let{handler:i,regex:d}of e)if(d.test(a)){s=i;break}t.expose=o,s(t,r,n);},h=async(e,o,t)=>{let r=[...new Set(t.map(n=>n.method))].join(", ");throw o.setHeader("Allow",r),o.statusCode=405,O__default.default(405,`No route with [${e.method}] method found.`)};var I={alpn:"ALPN","c-pep":"C-PEP","c-pep-info":"C-PEP-Info","caldav-timezones":"CalDAV-Timezones","content-id":"Content-ID","content-md5":"Content-MD5",dasl:"DASL",dav:"DAV",dnt:"DNT",etag:"ETag",getprofile:"GetProfile","http2-settings":"HTTP2-Settings","last-event-id":"Last-Event-ID","mime-version":"MIME-Version","optional-www-authenticate":"Optional-WWW-Authenticate","sec-webSocket-key":"Sec-WebSocket-Key","sec-webSocket-protocol":"Sec-WebSocket-Protocol","sec-webSocket-version":"Sec-WebSocket-Version","sec-websocket-accept":"Sec-WebSocket-Accept","sec-websocket-extensions":"Sec-WebSocket-Extensions",slug:"SLUG",tcn:"TCN",te:"TE",ttl:"TTL","www-authenticate":"WWW-Authenticate","x-att-deviceid":"X-ATT-DeviceId","x-dnsprefetch-control":"X-DNSPrefetch-Control","x-uidh":"X-UIDH"},X=(e,o)=>{let t=e.toLowerCase();return o?I[t]?I[t]:t.split("-").map(r=>r[0]?.toUpperCase()+r.slice(1)).join("-"):t},K={canonical:!1,normalizeHeaderKey:X},Z=e=>{let o={...K,...e};return async(t,r,n)=>{let a={},s={};return Object.keys(t.headers).forEach(i=>{a[i]=t.headers[i];let d=o.normalizeHeaderKey(i,o.canonical);d&&(s[d]=t.headers[i]);}),t.headers=s,t.rawHeaders=a,n()}},H=Z;var B=e=>{if(typeof e!="string")return !1;try{let o=JSON.parse(e),t=Object.prototype.toString.call(o);return t==="[object Object]"||t==="[object Array]"}catch{return !1}},S=B;var _=e=>G__default.default.toXML(e,{header:!0,indent:" "}),R=_;var g="Content-Type",Q=(e,o,t,r,n)=>{if(typeof t.getHeader(g)=="string")return r;let i=[...$__default.default(o).types(),n.defaultContentType],d=r,w=!1;return i.forEach(l=>{e.forEach(({regex:q,serializer:P})=>{q.test(l)&&(t.setHeader(g,l),d=P(d),w=!0);}),w||(/yaml|yml/.test(l)?(t.setHeader(g,l),d=
|
|
24
|
+
var f=(e,o)=>{let t=o.headers??{};Object.keys(t).forEach(r=>{e.setHeader(r,t[r]);});},p=(e,o)=>{e.setHeader("content-type","application/json; charset=utf-8"),e.end(JSON.stringify(o));},u=(e,o)=>{o.statusCode!==void 0&&(e.statusCode=o.statusCode),o.status!==void 0&&(e.statusCode=o.status),e.statusCode<400&&(e.statusCode=httpStatusCodes.StatusCodes.INTERNAL_SERVER_ERROR);};var v="An error occurred",J=(e,o,t)=>{if(u(t,e),f(t,e),e instanceof y__default.default.JapiError||y__default.default.JapiError.isLikeJapiError(e)){let r=new y__default.default.ErrorSerializer;p(t,r.serialize(e));}else if(e instanceof O.HttpError){let{message:r,statusCode:n,title:a}=e;p(t,{errors:[{code:n,title:a||httpStatusCodes.getReasonPhrase(n)||v,detail:r}]});}else {let{message:r}=e;p(t,{errors:[{code:"500",title:httpStatusCodes.getReasonPhrase(t.statusCode)||v,detail:r}]});}},z=J;var A="https://tools.ietf.org/html/rfc2616#section-10",M="An error occurred",W=(e,o,t)=>{let{message:r,stack:n}=e;if(e instanceof O.HttpError){let{expose:a,statusCode:s,title:i,type:d}=e;t.statusCode=s,f(t,e),p(t,{type:d||A,title:i||httpStatusCodes.getReasonPhrase(s)||M,details:r,...a?{trace:n}:{}});}else u(t,e),p(t,{type:A,title:httpStatusCodes.getReasonPhrase(t.statusCode)||M,details:r,...e.expose?{trace:n}:{}});},C=W;var x=(e,o)=>async(t,r,n)=>{let a=r.headers.accept,s=C;a==="application/vnd.api+json"&&(s=z);for(let{handler:i,regex:d}of e)if(d.test(a)){s=i;break}t.expose=o,s(t,r,n);},h=async(e,o,t)=>{let r=[...new Set(t.map(n=>n.method))].join(", ");throw o.setHeader("Allow",r),o.statusCode=405,O__default.default(405,`No route with [${e.method}] method found.`)};var I={alpn:"ALPN","c-pep":"C-PEP","c-pep-info":"C-PEP-Info","caldav-timezones":"CalDAV-Timezones","content-id":"Content-ID","content-md5":"Content-MD5",dasl:"DASL",dav:"DAV",dnt:"DNT",etag:"ETag",getprofile:"GetProfile","http2-settings":"HTTP2-Settings","last-event-id":"Last-Event-ID","mime-version":"MIME-Version","optional-www-authenticate":"Optional-WWW-Authenticate","sec-webSocket-key":"Sec-WebSocket-Key","sec-webSocket-protocol":"Sec-WebSocket-Protocol","sec-webSocket-version":"Sec-WebSocket-Version","sec-websocket-accept":"Sec-WebSocket-Accept","sec-websocket-extensions":"Sec-WebSocket-Extensions",slug:"SLUG",tcn:"TCN",te:"TE",ttl:"TTL","www-authenticate":"WWW-Authenticate","x-att-deviceid":"X-ATT-DeviceId","x-dnsprefetch-control":"X-DNSPrefetch-Control","x-uidh":"X-UIDH"},X=(e,o)=>{let t=e.toLowerCase();return o?I[t]?I[t]:t.split("-").map(r=>r[0]?.toUpperCase()+r.slice(1)).join("-"):t},K={canonical:!1,normalizeHeaderKey:X},Z=e=>{let o={...K,...e};return async(t,r,n)=>{let a={},s={};return Object.keys(t.headers).forEach(i=>{a[i]=t.headers[i];let d=o.normalizeHeaderKey(i,o.canonical);d&&(s[d]=t.headers[i]);}),t.headers=s,t.rawHeaders=a,n()}},H=Z;var B=e=>{if(typeof e!="string")return !1;try{let o=JSON.parse(e),t=Object.prototype.toString.call(o);return t==="[object Object]"||t==="[object Array]"}catch{return !1}},S=B;var _=e=>G__default.default.toXML(e,{header:!0,indent:" "}),R=_;var g="Content-Type",Q=(e,o,t,r,n)=>{if(typeof t.getHeader(g)=="string")return r;let i=[...$__default.default(o).types(),n.defaultContentType],d=r,w=!1;return i.forEach(l=>{e.forEach(({regex:q,serializer:P})=>{q.test(l)&&(t.setHeader(g,l),d=P(d),w=!0);}),w||(/yaml|yml/.test(l)?(t.setHeader(g,l),d=chunkZ6VLWWDV_js.b(S(r)?JSON.parse(r):r)):l.includes("xml")&&(t.setHeader(g,l),d=R({[chunkZ6VLWWDV_js.a(`${o.url?.replace("/api/","")}`.trim())]:S(r)?JSON.parse(r):r})));}),d},c=Q;var ee=Y__default.default("api-platform:connect:serializers-middleware"),te=(e=[],o="application/json; charset=utf-8")=>async(t,r,n)=>{if(typeof r.send=="function"){let a=r.send;r.send=s=>{r.send=a,s=c(e,t,r,s,{defaultContentType:o}),r.send(s);};}else if(typeof r.json=="function")ee("response.json() is not supported by @visulima/api-platform serializer. Use response.send() or response.end() instead.");else {let a=r.end;r.end=(s,...i)=>(r.end=a,s=c(e,t,r,s,{defaultContentType:o}),r.end(s,...i));}return n()},E=te;var oe=(e={})=>new connect.NodeRouter({onError:x(e.errorHandlers??[],e.showTrace??!1),onNoMatch:h}).use(H(e.middlewares?.["http-header-normalizer"]??{})).use(E(e.middlewares?.serializers?.serializers??[],e.middlewares?.serializers?.defaultContentType??"application/json; charset=utf-8")),se=oe;var ie=e=>connect.expressWrapper(ae__default.default(e)),de=ie;var pe=e=>e.ip??e.headers["x-forwarded-for"]??e.headers["x-real-ip"]??e.socket.remoteAddress,le=(e,o)=>async(t,r,n)=>{let a=pe(t);if(a===void 0)throw O__default.default(400,"Missing IP");try{let s=await e.consume(a),i={"Retry-After":Math.round(s.msBeforeNext/1e3)||1,"X-RateLimit-Remaining":s.remainingPoints,"X-RateLimit-Reset":new Date(Date.now()+s.msBeforeNext).toISOString(),...o};Object.keys(i).forEach(d=>{r.setHeader(d,i[d]);}),await n();}catch{throw O__default.default(429,"Too Many Requests")}},ce=le;
|
|
25
25
|
|
|
26
26
|
Object.defineProperty(exports, 'dateIn', {
|
|
27
27
|
enumerable: true,
|
|
@@ -37,11 +37,11 @@ Object.defineProperty(exports, 'zod', {
|
|
|
37
37
|
});
|
|
38
38
|
Object.defineProperty(exports, 'swaggerHandler', {
|
|
39
39
|
enumerable: true,
|
|
40
|
-
get: function () { return
|
|
40
|
+
get: function () { return chunkZ6VLWWDV_js.c; }
|
|
41
41
|
});
|
|
42
42
|
Object.defineProperty(exports, 'yamlTransformer', {
|
|
43
43
|
enumerable: true,
|
|
44
|
-
get: function () { return
|
|
44
|
+
get: function () { return chunkZ6VLWWDV_js.b; }
|
|
45
45
|
});
|
|
46
46
|
Object.defineProperty(exports, 'EdgeRouter', {
|
|
47
47
|
enumerable: true,
|
package/dist/index-server.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { a as dateIn, b as dateOut, c as zod } from './chunk-AB7BFRZY.mjs';
|
|
2
|
-
import { b, a } from './chunk-
|
|
3
|
-
export { c as swaggerHandler, b as yamlTransformer } from './chunk-
|
|
2
|
+
import { b, a } from './chunk-KJPWKW4M.mjs';
|
|
3
|
+
export { c as swaggerHandler, b as yamlTransformer } from './chunk-KJPWKW4M.mjs';
|
|
4
4
|
import './chunk-XIJ2ZQRX.mjs';
|
|
5
5
|
import { NodeRouter, expressWrapper } from '@visulima/connect';
|
|
6
6
|
export { EdgeRouter, NodeRouter, Router, createEdgeRouter, expressWrapper, sendJson, withZod } from '@visulima/connect';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/api-platform",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Visulima API platform is a set of tools to build and consume web APIs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"anolilab",
|
|
@@ -115,90 +115,91 @@
|
|
|
115
115
|
"test:watch": "vitest"
|
|
116
116
|
},
|
|
117
117
|
"dependencies": {
|
|
118
|
-
"@visulima/connect": "
|
|
119
|
-
"@visulima/jsdoc-open-api": "
|
|
118
|
+
"@visulima/connect": "2.0.0",
|
|
119
|
+
"@visulima/jsdoc-open-api": "2.0.0",
|
|
120
120
|
"accepts": "^1.3.8",
|
|
121
121
|
"debug": "^4.3.4",
|
|
122
122
|
"http-errors": "^2.0.0",
|
|
123
123
|
"http-status-codes": "^2.2.0",
|
|
124
|
-
"jstoxml": "^3.2.
|
|
124
|
+
"jstoxml": "^3.2.8",
|
|
125
125
|
"lodash.merge": "^4.6.2",
|
|
126
126
|
"schema-dts": "^1.1.2",
|
|
127
|
-
"ts-japi": "^1.8.
|
|
127
|
+
"ts-japi": "^1.8.1",
|
|
128
128
|
"yaml": "^2.3.1",
|
|
129
|
-
"zod-to-ts": "^1.
|
|
129
|
+
"zod-to-ts": "^1.2.0"
|
|
130
130
|
},
|
|
131
131
|
"devDependencies": {
|
|
132
|
-
"@anolilab/eslint-config": "^11.
|
|
133
|
-
"@anolilab/prettier-config": "^5.0.
|
|
134
|
-
"@anolilab/semantic-release-preset": "^6.0.
|
|
132
|
+
"@anolilab/eslint-config": "^11.3.3",
|
|
133
|
+
"@anolilab/prettier-config": "^5.0.3",
|
|
134
|
+
"@anolilab/semantic-release-preset": "^6.0.4",
|
|
135
135
|
"@arthurgeron/eslint-plugin-react-usememo": "^1.1.4",
|
|
136
136
|
"@hapi/hapi": "^21.3.2",
|
|
137
137
|
"@koa/router": "^12.0.0",
|
|
138
|
-
"@secretlint/secretlint-rule-preset-recommend": "^7.0.
|
|
138
|
+
"@secretlint/secretlint-rule-preset-recommend": "^7.0.7",
|
|
139
139
|
"@testing-library/react": "^14.0.0",
|
|
140
140
|
"@testing-library/react-hooks": "^8.0.1",
|
|
141
|
-
"@total-typescript/ts-reset": "^0.
|
|
141
|
+
"@total-typescript/ts-reset": "^0.5.1",
|
|
142
142
|
"@types/accepts": "^1.3.5",
|
|
143
143
|
"@types/cors": "^2.8.13",
|
|
144
144
|
"@types/debug": "^4.1.8",
|
|
145
145
|
"@types/express": "^4.17.17",
|
|
146
|
-
"@types/express-serve-static-core": "^4.17.
|
|
146
|
+
"@types/express-serve-static-core": "^4.17.36",
|
|
147
147
|
"@types/http-errors": "^2.0.1",
|
|
148
148
|
"@types/jstoxml": "^2.0.2",
|
|
149
149
|
"@types/koa": "^2.13.8",
|
|
150
150
|
"@types/koa__router": "^12.0.0",
|
|
151
151
|
"@types/lodash.merge": "^4.6.7",
|
|
152
152
|
"@types/lodash.set": "^4.3.7",
|
|
153
|
-
"@types/node": "18.
|
|
153
|
+
"@types/node": "18.17.1",
|
|
154
154
|
"@types/qs": "^6.9.7",
|
|
155
|
-
"@types/react": "^18.2.
|
|
155
|
+
"@types/react": "^18.2.21",
|
|
156
156
|
"@types/react-dom": "^18.2.7",
|
|
157
157
|
"@types/swagger-ui-react": "^4.18.0",
|
|
158
|
-
"@types/webpack": "^5.28.
|
|
159
|
-
"@visulima/crud": "
|
|
160
|
-
"@visulima/readdir": "
|
|
161
|
-
"@vitest/coverage-v8": "^0.
|
|
162
|
-
"chalk": "5.
|
|
158
|
+
"@types/webpack": "^5.28.2",
|
|
159
|
+
"@visulima/crud": "2.0.0",
|
|
160
|
+
"@visulima/readdir": "2.0.0",
|
|
161
|
+
"@vitest/coverage-v8": "^0.34.3",
|
|
162
|
+
"chalk": "5.3.0",
|
|
163
163
|
"commander": "^11.0.0",
|
|
164
|
-
"core-js": "^3.32.
|
|
164
|
+
"core-js": "^3.32.1",
|
|
165
165
|
"cors": "^2.8.5",
|
|
166
166
|
"cross-env": "^7.0.3",
|
|
167
|
-
"eslint": "^8.
|
|
167
|
+
"eslint": "^8.48.0",
|
|
168
168
|
"eslint-plugin-etc": "^2.0.3",
|
|
169
169
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
170
|
-
"eslint-plugin-mdx": "^2.
|
|
171
|
-
"eslint-plugin-react": "7.33.
|
|
170
|
+
"eslint-plugin-mdx": "^2.2.0",
|
|
171
|
+
"eslint-plugin-react": "7.33.2",
|
|
172
172
|
"eslint-plugin-react-hooks": "4.6.0",
|
|
173
|
-
"eslint-plugin-testing-library": "^
|
|
173
|
+
"eslint-plugin-testing-library": "^6.0.1",
|
|
174
174
|
"eslint-plugin-vitest": "^0.2.8",
|
|
175
|
+
"eslint-plugin-vitest-globals": "^1.4.0",
|
|
175
176
|
"eslint-plugin-zod": "^1.4.0",
|
|
176
177
|
"express": "^4.18.2",
|
|
177
|
-
"fastify": "^4.
|
|
178
|
+
"fastify": "^4.22.0",
|
|
178
179
|
"koa": "^2.14.2",
|
|
179
180
|
"mobx": "^6.10.0",
|
|
180
|
-
"next": "^13.4.
|
|
181
|
+
"next": "^13.4.12",
|
|
181
182
|
"next-test-api-route-handler": "^4.0.0-canary.1",
|
|
182
|
-
"node-mocks-http": "^1.
|
|
183
|
+
"node-mocks-http": "^1.13.0",
|
|
183
184
|
"openapi-types": "^12.1.3",
|
|
184
|
-
"prettier": "^3.0.
|
|
185
|
+
"prettier": "^3.0.2",
|
|
185
186
|
"rate-limiter-flexible": "^2.4.2",
|
|
186
187
|
"react": "^18.2.0",
|
|
187
188
|
"react-dom": "^18.2.0",
|
|
188
|
-
"redoc": "^2.
|
|
189
|
+
"redoc": "^2.1.1",
|
|
189
190
|
"rimraf": "^5.0.1",
|
|
190
|
-
"secretlint": "7.0.
|
|
191
|
-
"semantic-release": "^21.
|
|
191
|
+
"secretlint": "7.0.7",
|
|
192
|
+
"semantic-release": "^21.1.1",
|
|
192
193
|
"sort-package-json": "^2.5.1",
|
|
193
|
-
"styled-components": "^6.0.
|
|
194
|
+
"styled-components": "^6.0.7",
|
|
194
195
|
"swagger-ui-dist": "^4.19.1",
|
|
195
196
|
"swagger-ui-react": "^4.19.1",
|
|
196
|
-
"tsup": "^7.
|
|
197
|
-
"type-fest": "^4.
|
|
198
|
-
"typescript": "^5.
|
|
199
|
-
"vitest": "^0.
|
|
197
|
+
"tsup": "^7.2.0",
|
|
198
|
+
"type-fest": "^4.3.1",
|
|
199
|
+
"typescript": "^5.2.2",
|
|
200
|
+
"vitest": "^0.34.3",
|
|
200
201
|
"webpack": "^5.88.2",
|
|
201
|
-
"zod": "^3.
|
|
202
|
+
"zod": "^3.22.2"
|
|
202
203
|
},
|
|
203
204
|
"peerDependencies": {
|
|
204
205
|
"react": "^18.2.0",
|
|
@@ -208,23 +209,23 @@
|
|
|
208
209
|
"optionalDependencies": {
|
|
209
210
|
"@hapi/hapi": "^21.3.2",
|
|
210
211
|
"@koa/router": "^12.0.0",
|
|
211
|
-
"@visulima/crud": "
|
|
212
|
-
"@visulima/readdir": "
|
|
213
|
-
"chalk": "5.
|
|
212
|
+
"@visulima/crud": "2.0.0",
|
|
213
|
+
"@visulima/readdir": "2.0.0",
|
|
214
|
+
"chalk": "5.3.0",
|
|
214
215
|
"commander": "^11.0.0",
|
|
215
216
|
"cors": "^2.8.5",
|
|
216
217
|
"express": "^4.18.2",
|
|
217
|
-
"fastify": "^4.
|
|
218
|
+
"fastify": "^4.22.0",
|
|
218
219
|
"koa": "^2.14.2",
|
|
219
|
-
"next": "^13.4.
|
|
220
|
+
"next": "^13.4.12",
|
|
220
221
|
"rate-limiter-flexible": "^2.4.2",
|
|
221
|
-
"redoc": "^2.
|
|
222
|
+
"redoc": "^2.1.1",
|
|
222
223
|
"swagger-ui-dist": "^4.19.1",
|
|
223
224
|
"swagger-ui-react": "^4.19.1",
|
|
224
225
|
"webpack": "^5.88.2"
|
|
225
226
|
},
|
|
226
227
|
"engines": {
|
|
227
|
-
"node": ">=
|
|
228
|
+
"node": ">=18.* <=20.*"
|
|
228
229
|
},
|
|
229
230
|
"publishConfig": {
|
|
230
231
|
"access": "public",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/serializers/transformer/yaml.ts","../src/swagger/api/swagger-handler.ts","../src/swagger/extend-swagger-spec.ts","../src/utils.ts"],"names":["stringify","yamlTransformer","data","yaml_default","existsSync","readFileSync","path","modelsToOpenApi","debug","merge","xml","urlParse","toHeaderCase","string_","c","jsonMediaType","prepareStatusContent","methodSpec","status","mediaType","extendComponentSchemas","spec","schemaName","schema","extendResponseSchema","schemaIsArray","extendSwaggerWithMediaTypeSchema","responseSpec","allowedMediaTypes","pathKey","example","examples","mediaName","contentSpec","allowed","extendSwaggerWithMediaTypeExample","transformers","transformed","regex","transformer","extendComponentExamples","exampleName","prepareResponseExamples","transformedExamples","extendSwaggerWithMediaTypeExamples","examplesName","extendSwaggerSpec","value","pathSpec","swaggerCrudDebug","swaggerHandler","options","crud","specs","swaggerFilePath","request","response","swaggerPath","fileContents","crudSwagger","modelsOpenApi","error","swagger_handler_default"],"mappings":"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","sourcesContent":["import { stringify } from \"yaml\";\n\nimport type { Serializer } from \"../types\";\n\nconst yamlTransformer: Serializer = (data) => stringify(data, { indent: 2 });\n\nexport default yamlTransformer;\n","import { existsSync, readFileSync } from \"node:fs\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport type { ModelsToOpenApiParameters, SwaggerModelsConfig } from \"@visulima/crud\";\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { modelsToOpenApi } from \"@visulima/crud\";\nimport debug from \"debug\";\n// eslint-disable-next-line no-restricted-imports\nimport merge from \"lodash.merge\";\nimport type { OpenAPIV3 } from \"openapi-types\";\n\nimport yamlTransformer from \"../../serializers/transformer/yaml\";\nimport extendSwaggerSpec from \"../extend-swagger-spec\";\n\nconst swaggerCrudDebug = debug(\"visulima:api-platform:swagger:crud:get-static-properties-swagger\");\n\nconst swaggerHandler = <M extends string, PrismaClient>(\n // eslint-disable-next-line no-use-before-define\n options: Partial<SwaggerHandlerOptions<M, PrismaClient>> = {},\n): ((request: IncomingMessage, response: ServerResponse) => Promise<void>) => {\n const {\n allowedMediaTypes = {\n \"application/json\": true,\n },\n crud,\n specs,\n swaggerFilePath,\n } = options;\n\n return async <Request extends IncomingMessage, Response extends ServerResponse>(request: Request, response: Response) => {\n const swaggerPath = path.join(process.cwd(), swaggerFilePath ?? \"swagger/swagger.json\");\n\n if (!existsSync(swaggerPath)) {\n throw new Error(`Swagger file not found at \"${swaggerPath}\".`);\n }\n\n const fileContents = readFileSync(swaggerPath, \"utf8\");\n\n let spec = extendSwaggerSpec(JSON.parse(fileContents) as OpenAPIV3.Document, allowedMediaTypes) as OpenAPIV3.Document;\n let crudSwagger: Partial<OpenAPIV3.Document> = {};\n\n if (crud !== undefined) {\n try {\n const modelsOpenApi = await modelsToOpenApi(crud);\n\n crudSwagger = {\n components: { examples: modelsOpenApi.examples, schemas: modelsOpenApi.schemas },\n paths: modelsOpenApi.paths,\n tags: modelsOpenApi.tags,\n };\n\n crudSwagger = extendSwaggerSpec(crudSwagger, allowedMediaTypes);\n\n swaggerCrudDebug(JSON.stringify(crudSwagger, null, 2));\n\n spec = merge(spec, crudSwagger);\n } catch (error) {\n // eslint-disable-next-line no-console\n console.log(error);\n\n throw new Error(\"Please install @visulima/crud to use the crud swagger generator.\");\n }\n }\n\n if (Array.isArray(specs)) {\n specs.forEach((value) => {\n spec = merge(spec, extendSwaggerSpec(value, allowedMediaTypes));\n });\n }\n\n let data: Buffer | Uint8Array | string;\n\n if (typeof request.headers.accept === \"string\" && /yaml|yml/.test(request.headers.accept)) {\n response.setHeader(\"Content-Type\", request.headers.accept);\n\n data = yamlTransformer(spec);\n } else {\n response.setHeader(\"Content-Type\", \"application/json\");\n\n data = JSON.stringify(spec, null, 2);\n }\n\n response.statusCode = 200;\n response.end(data);\n };\n};\n\nexport interface SwaggerHandlerOptions<M extends string, PrismaClient> {\n allowedMediaTypes: Record<string, boolean>;\n crud: Exclude<ModelsToOpenApiParameters<M, PrismaClient>, \"swagger\"> & {\n swagger?: {\n models?: SwaggerModelsConfig<M>;\n };\n };\n specs?: Partial<OpenAPIV3.Document>[];\n swaggerFilePath: string;\n}\n\nexport default swaggerHandler;\n","import type { XmlElement } from \"jstoxml\";\nimport xml from \"jstoxml\";\nimport type { OpenAPIV3 } from \"openapi-types\";\nimport { stringify } from \"yaml\";\n\nimport { toHeaderCase } from \"../utils\";\n\ntype Transformers = { regex: RegExp; transformer: (data: any) => string }[];\n\nconst jsonMediaType = \"application/json\";\n\nconst prepareStatusContent = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string) => {\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content === undefined) {\n // eslint-disable-next-line no-param-reassign\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content = {};\n }\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType] === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] = {} as OpenAPIV3.MediaTypeObject;\n }\n};\n\nconst extendComponentSchemas = (spec: Partial<OpenAPIV3.Document>, schemaName: string, schema: OpenAPIV3.SchemaObject) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.schemas !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas = {};\n }\n\n if (spec.components.schemas[schemaName] === undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.schemas[schemaName] = schema;\n }\n};\n\nconst extendResponseSchema = (methodSpec: OpenAPIV3.OperationObject, status: string, mediaType: string, schemaName: string, schemaIsArray: boolean) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.schema === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n {} as OpenAPIV3.SchemaObject;\n }\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).schema =\n schemaIsArray\n ? {\n items: {\n $ref: `#/components/schemas/${schemaName}`,\n },\n type: \"array\",\n }\n : {\n $ref: `#/components/schemas/${schemaName}`,\n };\n};\n\nconst extendSwaggerWithMediaTypeSchema = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n spec: Partial<OpenAPIV3.Document>,\n status: string,\n): {\n example?: any;\n examples?: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>;\n} => {\n let example: any | undefined;\n let examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> | undefined;\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n Object.entries(responseSpec.content as object).forEach(([mediaName, contentSpec]) => {\n if (typeof contentSpec.schema === \"object\") {\n const { schema } = contentSpec;\n\n if (mediaName === jsonMediaType && contentSpec.examples !== undefined) {\n examples = contentSpec.examples;\n } else if (mediaName === jsonMediaType && contentSpec.example !== undefined) {\n example = contentSpec.example;\n }\n\n const schemaIsArray = (schema as OpenAPIV3.SchemaObject).type === \"array\";\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n let schemaName: string;\n\n if (schema?.$ref === undefined) {\n schemaName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}${mediaType === \"application/ld+json\" ? \".jsonld\" : \"\"}`;\n\n extendComponentSchemas(spec as OpenAPIV3.Document, schemaName, schema as OpenAPIV3.SchemaObject);\n } else {\n schemaName = (schema as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/schemas/\", \"\");\n }\n\n extendResponseSchema(methodSpec, status, mediaType, schemaName, schemaIsArray);\n });\n }\n });\n\n return { example, examples };\n};\n\nconst extendSwaggerWithMediaTypeExample = (\n methodSpec: OpenAPIV3.OperationObject,\n responseSpec: OpenAPIV3.ResponseObject,\n status: string,\n allowedMediaTypes: Record<string, boolean> | undefined,\n transformers: Transformers,\n example: any,\n) => {\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (\n ((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.example === undefined\n ) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n {};\n }\n\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n transformer(example);\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).example =\n example;\n }\n });\n });\n};\n\nconst extendComponentExamples = (\n spec: Partial<OpenAPIV3.Document>,\n exampleName: string,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n if (typeof spec.components !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components = {};\n }\n\n if (typeof spec.components.examples !== \"object\") {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples = {};\n }\n\n if (spec.components.examples[exampleName] === undefined && examples[exampleName] !== undefined) {\n // eslint-disable-next-line no-param-reassign\n spec.components.examples[exampleName] = examples[exampleName] as OpenAPIV3.ExampleObject;\n }\n};\n\nconst prepareResponseExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n mediaType: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n // eslint-disable-next-line sonarjs/cognitive-complexity\n) => {\n prepareStatusContent(methodSpec, status, mediaType);\n\n if (((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content?.[mediaType]?.examples === undefined) {\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n {};\n }\n\n const transformedExamples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject> = {};\n\n Object.entries(examples).forEach(([exampleName, example]) => {\n let transformed = false;\n\n transformers.forEach(({ regex, transformer }) => {\n if (!transformed && regex.test(mediaType)) {\n let data: any = \"\";\n\n if (spec.components?.examples?.[exampleName]) {\n data = (spec.components.examples[exampleName] as OpenAPIV3.ExampleObject).value;\n } else if ((example as OpenAPIV3.ReferenceObject).$ref) {\n data = (\n spec.components?.examples?.[\n (example as OpenAPIV3.ReferenceObject).$ref.replace(\"#/components/examples/\", \"\")\n ] as OpenAPIV3.ExampleObject\n ).value;\n } else if (typeof (example as OpenAPIV3.ExampleObject).value === \"string\") {\n data = (example as OpenAPIV3.ExampleObject).value;\n }\n\n transformedExamples[exampleName] = {\n value: transformer(data),\n };\n\n transformed = true;\n }\n });\n\n if (!transformed) {\n transformedExamples[exampleName] =\n spec.components?.examples?.[exampleName] === undefined\n ? example\n : {\n $ref: `#/components/examples/${exampleName}`,\n };\n }\n });\n\n // prettier-ignore\n // eslint-disable-next-line no-param-reassign\n ((((methodSpec.responses as unknown as OpenAPIV3.ResponsesObject)[status] as OpenAPIV3.ResponseObject).content as Record<\n string,\n OpenAPIV3.MediaTypeObject\n >)[\n mediaType\n ] as OpenAPIV3.MediaTypeObject).examples =\n transformedExamples;\n};\n\nconst extendSwaggerWithMediaTypeExamples = (\n spec: Partial<OpenAPIV3.Document>,\n methodSpec: OpenAPIV3.OperationObject,\n status: string,\n responseSpec: OpenAPIV3.ResponseObject,\n allowedMediaTypes: Record<string, boolean> | undefined,\n pathKey: string,\n transformers: Transformers,\n examples: Record<string, OpenAPIV3.ExampleObject | OpenAPIV3.ReferenceObject>,\n) => {\n const examplesName = `${toHeaderCase(pathKey.trim().replace(\"/\", \"\"))}`;\n\n Object.keys(responseSpec.content as object).forEach((mediaName) => {\n if (mediaName === jsonMediaType) {\n return;\n }\n\n Object.entries(allowedMediaTypes ?? {}).forEach(([mediaType, allowed]) => {\n if (!allowed) {\n return;\n }\n\n extendComponentExamples(spec, examplesName, examples);\n\n prepareResponseExamples(spec, methodSpec, status, mediaType, transformers, examples);\n });\n });\n};\n\n// eslint-disable-next-line sonarjs/cognitive-complexity\nexport default function extendSwaggerSpec(\n spec: Partial<OpenAPIV3.Document>,\n allowedMediaTypes?: Record<string, boolean>,\n transformers: Transformers = [\n {\n regex: /xml/,\n transformer: (value: XmlElement | XmlElement[] | undefined) =>\n xml.toXML(value, {\n header: true,\n indent: \" \",\n }),\n },\n {\n regex: /yaml|yml/,\n transformer: (value) => stringify(value, { indent: 2 }),\n },\n ],\n): Partial<OpenAPIV3.Document> {\n if (typeof spec === \"object\" && typeof spec.paths === \"object\") {\n Object.entries(spec.paths).forEach(([pathKey, pathSpec]) => {\n Object.values(pathSpec as OpenAPIV3.OperationObject & OpenAPIV3.PathsObject).forEach((methodSpec) => {\n if (typeof (methodSpec as OpenAPIV3.OperationObject).responses === \"object\") {\n Object.entries((methodSpec as OpenAPIV3.OperationObject).responses).forEach(([status, responseSpec]) => {\n if (typeof (responseSpec as OpenAPIV3.ResponseObject).content === \"object\") {\n const { example, examples } = extendSwaggerWithMediaTypeSchema(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n spec,\n status,\n );\n\n if (example !== undefined) {\n extendSwaggerWithMediaTypeExample(\n methodSpec as OpenAPIV3.OperationObject,\n responseSpec as OpenAPIV3.ResponseObject,\n status,\n allowedMediaTypes,\n transformers,\n example,\n );\n } else if (examples !== undefined) {\n extendSwaggerWithMediaTypeExamples(\n spec,\n methodSpec as OpenAPIV3.OperationObject,\n status,\n responseSpec as OpenAPIV3.ResponseObject,\n allowedMediaTypes,\n pathKey,\n transformers,\n examples,\n );\n }\n }\n });\n }\n });\n });\n }\n\n return spec;\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { parse as urlParse } from \"node:url\";\n\ntype IncomingApiRequest<TApiRequest = IncomingMessage> = TApiRequest & {\n body?: any;\n query?: any;\n};\n\nexport const jsonResponse = (response: ServerResponse, status: number, data?: unknown): void => {\n response.statusCode = status;\n response.setHeader(\"Content-Type\", \"application/json\");\n response.end(data ? JSON.stringify(data) : \"\");\n};\n\nexport const parseBody = async (request: IncomingApiRequest): Promise<any> => {\n if (request.body) {\n return request.body;\n }\n\n const buffers = [];\n\n // eslint-disable-next-line no-restricted-syntax\n for await (const chunk of request) {\n buffers.push(chunk);\n }\n\n const data = Buffer.concat(buffers).toString();\n\n return data ? JSON.parse(data) : null;\n};\n\nexport const parseQuery = (request: IncomingApiRequest): unknown => {\n if (request.query) {\n return request.query;\n }\n\n return urlParse(request.url ?? \"\", true).query;\n};\n\nexport const toHeaderCase = (string_: string): string =>\n string_\n .toLowerCase()\n .replaceAll(/[^\\s\\w]/g, \" \") // Remove all non-word characters\n .trimEnd() // Remove trailing spaces\n .replaceAll(/\\s+|_/g, \"-\") // Replace multiple spaces or underline with a single hyphen\n .replaceAll(/\\b\\w/g, (c) => c.toUpperCase());\n"]}
|