@visulima/jsdoc-open-api 1.3.7 → 1.3.8
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 +7 -0
- package/dist/{chunk-QWSNJU2Q.mjs → chunk-4BGSTSHH.mjs} +2 -2
- package/dist/{chunk-U3XIMVTY.js → chunk-5U2PT3WZ.js} +10 -9
- package/dist/chunk-5U2PT3WZ.js.map +1 -0
- package/dist/{chunk-NIOKTLFL.js → chunk-6BASRGSS.js} +4 -4
- package/dist/{chunk-FJGGXQ64.mjs → chunk-SXATCZ56.mjs} +5 -5
- package/dist/chunk-SXATCZ56.mjs.map +1 -0
- package/dist/cli/commander/index.js +3 -3
- package/dist/cli/commander/index.mjs +2 -2
- package/dist/cli/index.js +4 -4
- package/dist/cli/index.mjs +2 -2
- package/dist/index.js +7 -7
- package/dist/index.mjs +2 -2
- package/package.json +6 -6
- package/dist/chunk-FJGGXQ64.mjs.map +0 -1
- package/dist/chunk-U3XIMVTY.js.map +0 -1
- /package/dist/{chunk-QWSNJU2Q.mjs.map → chunk-4BGSTSHH.mjs.map} +0 -0
- /package/dist/{chunk-NIOKTLFL.js.map → chunk-6BASRGSS.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## @visulima/jsdoc-open-api [1.3.8](https://github.com/visulima/visulima/compare/@visulima/jsdoc-open-api@1.3.7...@visulima/jsdoc-open-api@1.3.8) (2023-06-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* wrong import of the new validator ([73a3e89](https://github.com/visulima/visulima/commit/73a3e8944590b8a158db7afcb5cc0baa0632775b))
|
|
7
|
+
|
|
1
8
|
## @visulima/jsdoc-open-api [1.3.7](https://github.com/visulima/visulima/compare/@visulima/jsdoc-open-api@1.3.6...@visulima/jsdoc-open-api@1.3.7) (2023-05-31)
|
|
2
9
|
|
|
3
10
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a, c, d, e, f } from './chunk-
|
|
1
|
+
import { a, c, d, e, f } from './chunk-SXATCZ56.mjs';
|
|
2
2
|
import { existsSync, realpathSync, writeFileSync, lstatSync, mkdirSync } from 'fs';
|
|
3
3
|
import v from 'read-pkg-up';
|
|
4
4
|
import { collect } from '@visulima/readdir';
|
|
@@ -47,4 +47,4 @@ Swagger specification is ready, check the "${i}" file.`);},G=_;
|
|
|
47
47
|
|
|
48
48
|
export { E as a, G as b };
|
|
49
49
|
//# sourceMappingURL=out.js.map
|
|
50
|
-
//# sourceMappingURL=chunk-
|
|
50
|
+
//# sourceMappingURL=chunk-4BGSTSHH.mjs.map
|
|
@@ -5,7 +5,7 @@ var v = require('path');
|
|
|
5
5
|
var w = require('yaml');
|
|
6
6
|
var commentParser = require('comment-parser');
|
|
7
7
|
var D = require('lodash.mergewith');
|
|
8
|
-
var
|
|
8
|
+
var H = require('@stoplight/spectral-core');
|
|
9
9
|
var spectralRulesets = require('@stoplight/spectral-rulesets');
|
|
10
10
|
|
|
11
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -13,21 +13,22 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
13
13
|
var v__default = /*#__PURE__*/_interopDefault(v);
|
|
14
14
|
var w__default = /*#__PURE__*/_interopDefault(w);
|
|
15
15
|
var D__default = /*#__PURE__*/_interopDefault(D);
|
|
16
|
+
var H__default = /*#__PURE__*/_interopDefault(H);
|
|
16
17
|
|
|
17
|
-
var E=(t,s)=>{Object.keys(s).forEach(r=>{t[r]===void 0?t[r]={...s[r]}:Object.keys(s[r]).forEach(e=>{t[r][e]={...t[r][e],...s[r][e]};});});},y=E;var u=class{constructor(s){this.openapi=s.openapi,this.info=s.info,this.servers=s.servers,this.paths=s.paths??{},this.components=s.components,this.security=s.security,this.tags=s.tags,this.externalDocs=s.externalDocs;}addData(s){s.forEach(r=>{let{paths:e,components:i,...n}=r;y(this,{paths:e??{},components:i??{}}),Object.entries(n).forEach(([o,a])=>{this[o]=a;});});}},
|
|
18
|
+
var E=(t,s)=>{Object.keys(s).forEach(r=>{t[r]===void 0?t[r]={...s[r]}:Object.keys(s[r]).forEach(e=>{t[r][e]={...t[r][e],...s[r][e]};});});},y=E;var u=class{constructor(s){this.openapi=s.openapi,this.info=s.info,this.servers=s.servers,this.paths=s.paths??{},this.components=s.components,this.security=s.security,this.tags=s.tags,this.externalDocs=s.externalDocs;}addData(s){s.forEach(r=>{let{paths:e,components:i,...n}=r;y(this,{paths:e??{},components:i??{}}),Object.entries(n).forEach(([o,a])=>{this[o]=a;});});}},Z=u;function A(t){return t.split(/\r\n|\r|\n/).filter(e=>/^\s*(#\s*.*)?$/.test(e)?!1:e.trim().length>0).length}var g=A;var h=new Set(["openapi","info","servers","security","tags","externalDocs","components","paths"]),l=class extends Error{},$=(t,s,r)=>{let e=fs.readFileSync(t,{encoding:"utf8"}),i=v__default.default.extname(t);if(i===".yaml"||i===".yml"){let n=w__default.default.parse(e),o=Object.keys(n).filter(a=>!h.has(a));if(o.length>0){let a=new l(`Unexpected keys: ${o.join(", ")}`);throw a.filePath=t,a}if(Object.keys(n).some(a=>h.has(a))){let a=g(e);return [{spec:n,loc:a}]}return []}try{return s(e,r)}catch(n){throw n.filePath=t,n}},ie=$;var k=(t,s)=>{if(Array.isArray(t))return [...t,...s]},m=k;function C(t){t.security&&(t.security=Object.keys(t.security).map(s=>({[s]:t.security[s]})));}var I=new Set(["integer","number","string","boolean","object","array"]),b={int32:"integer",int64:"integer",float:"number",double:"number",date:"string","date-time":"string",password:"string",byte:"string",binary:"string"};function q(t){let s=t.type,r=s.endsWith("[]"),e=s.replace(/\[]$/,""),i=I.has(e),n=Object.keys(b).includes(e),o;if(t.default)switch(e){case"integer":case"int32":case"int64":{o=Number.parseInt(t.default,10);break}case"number":case"double":case"float":{o=Number.parseFloat(t.default);break}default:{o=t.default;break}}let a;i?a={type:e,default:o}:n?a={type:b[e],format:e,default:o}:a={$ref:`#/components/schemas/${e}`};let c=r?{type:"array",items:{...a}}:{...a};e===""&&(c=void 0);let p=t.description.trim().replace(/^- /,"");return p===""&&(p=void 0),{name:t.name,description:p,required:!t.optional,schema:c,rawType:s}}function L(t,s){return t.map(r=>{let e=q(r),i="";switch(e.name&&(i+=e.name),e.description&&(i+=` ${e.description.trim()}`),r.tag){case"operationId":case"summary":case"description":return {[r.tag]:i};case"deprecated":return {deprecated:!0};case"externalDocs":return {externalDocs:{url:e.name,description:e.description}};case"server":return {servers:[{url:e.name,description:e.description}]};case"tag":return {tags:[i]};case"cookieParam":case"headerParam":case"queryParam":case"pathParam":return {parameters:[{name:e.name,in:r.tag.replace(/Param$/,""),description:e.description,required:e.required,schema:e.schema}]};case"bodyContent":return {requestBody:{content:{[e.name.replace("*\\/*","*/*")]:{schema:e.schema}}}};case"bodyExample":{let[n,o]=e.name.split(".");return {requestBody:{content:{[n]:{examples:{[o]:{$ref:`#/components/examples/${e.rawType}`}}}}}}}case"bodyDescription":return {requestBody:{description:i}};case"bodyRequired":return {requestBody:{required:!0}};case"response":return {responses:{[e.name]:{description:e.description}}};case"callback":return {callbacks:{[e.name]:{$ref:`#/components/callbacks/${e.rawType}`}}};case"responseContent":{let[n,o]=e.name.split(".");return {responses:{[n]:{content:{[o]:{schema:e.schema}}}}}}case"responseHeaderComponent":{let[n,o]=e.name.split(".");return {responses:{[n]:{headers:{[o]:{$ref:`#/components/headers/${e.rawType}`}}}}}}case"responseHeader":{let[n,o]=e.name.split(".");return {responses:{[n]:{headers:{[o]:{description:e.description,schema:e.schema}}}}}}case"responseExample":{let[n,o,a]=e.name.split(".");return {responses:{[n]:{content:{[o]:{examples:{[a]:{$ref:`#/components/examples/${e.rawType}`}}}}}}}}case"responseLink":{let[n,o]=e.name.split(".");return {responses:{[n]:{links:{[o]:{$ref:`#/components/links/${e.rawType}`}}}}}}case"bodyComponent":return {requestBody:{$ref:`#/components/requestBodies/${e.rawType}`}};case"responseComponent":return {responses:{[e.name]:{$ref:`#/components/responses/${e.rawType}`}}};case"paramComponent":return {parameters:[{$ref:`#/components/parameters/${e.rawType}`}]};case"security":{let[n,o]=e.name.split("."),a=[];return o&&(a=[o]),{security:{[n]:a}}}default:return {}}})}var R=(t,s)=>{let r=/^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \/.*$/;return commentParser.parse(t,{spacing:"preserve"}).filter(i=>r.test(i.description.trim())).map(i=>{let n=i.tags.length+1,o=D__default.default({},...L(i.tags),m);C(o);let[a,c]=i.description.split(" "),p={[c.trim()]:{[a.toLowerCase().trim()]:{...o}}};return {spec:JSON.parse(JSON.stringify({paths:p})),loc:n}})},le=R;var d=(t,s)=>D__default.default({},t,s,(r,e)=>e===null?r:void 0),O=t=>Object.keys(t).map(s=>t[s]).every(s=>typeof s=="object"&&Object.keys(s).every(r=>!(r in s))),f=(t,s)=>s.some(r=>t.name===r.name),j=t=>{switch(t.tag){case"openapi":return "v3";case"asyncapi":return "v4";case"swagger":return "v2";default:return "v2"}};var N=(t,s,r)=>{if(r==="x-webhooks"&&(t[r]=s[r]),r.startsWith("x-"))return;if(["components","consumes","produces","paths","schemas","securityDefinitions","responses","parameters","definitions","channels"].includes(r))Object.keys(s[r]).forEach(i=>{t[r][i]=d(t[r][i],s[r][i]);});else if(r==="tags"){let{tags:i}=s;Array.isArray(i)?i.forEach(n=>{f(n,t.tags)||t.tags.push(n);}):f(i,t.tags)||t.tags.push(i);}else if(r==="security"){let{security:i}=s;t.security=i;}else r.startsWith("/")&&(t.paths[r]=d(t.paths[r],s[r]));},x=N;var z={v2:["paths","definitions","responses","parameters","securityDefinitions"],v3:["paths","definitions","responses","parameters","securityDefinitions","components"],v4:["components","channels"]},F=(t,s)=>t.map(r=>{if((r.tag==="openapi"||r.tag==="swagger"||r.tag==="asyncapi")&&r.description!==""){let e=w__default.default.parseDocument(r.description);if(e.errors.length>0){e.errors.map(a=>{let c=a;return c.annotation=r.description,c});let o="Error parsing YAML in @openapi spec:";throw o+=s?e.errors.map(a=>`${a.toString()}
|
|
18
19
|
Imbedded within:
|
|
19
20
|
\`\`\`
|
|
20
21
|
${a.annotation?.replace(/\n/g,`
|
|
21
22
|
`)}
|
|
22
23
|
\`\`\``).join(`
|
|
23
24
|
`):e.errors.map(a=>a.toString()).join(`
|
|
24
|
-
`),new Error(o)}let i=e.toJSON(),n={tags:[]};return z[j(r)].forEach(o=>{n[o]=n[o]||{};}),Object.keys(i).forEach(o=>{x(n,i,o);}),n}return {}}),J=(t,s)=>commentParser.parse(t,{spacing:"preserve"}).map(e=>{let i=e.tags.length+1,n=D__default.default({},...F(e.tags,s),m);return ["definitions","responses","parameters","securityDefinitions","components","tags"].forEach(a=>{n[a]!==void 0&&O(n[a])&&delete n[a];}),{spec:JSON.parse(JSON.stringify(n)),loc:i}}),
|
|
25
|
+
`),new Error(o)}let i=e.toJSON(),n={tags:[]};return z[j(r)].forEach(o=>{n[o]=n[o]||{};}),Object.keys(i).forEach(o=>{x(n,i,o);}),n}return {}}),J=(t,s)=>commentParser.parse(t,{spacing:"preserve"}).map(e=>{let i=e.tags.length+1,n=D__default.default({},...F(e.tags,s),m);return ["definitions","responses","parameters","securityDefinitions","components","tags"].forEach(a=>{n[a]!==void 0&&O(n[a])&&delete n[a];}),{spec:JSON.parse(JSON.stringify(n)),loc:i}}),Ae=J;var{Spectral:G}=H__default.default,S=new G;S.setRuleset({extends:[spectralRulesets.oas,spectralRulesets.asyncapi]});var _=async t=>{let s="";return typeof t=="object"?s=t.info.title:typeof t=="string"&&(s=t),S.run(t).then(r=>(r.forEach(e=>{if(e.code==="unrecognized-format")throw new Error(`Could not validate OpenAPI Specification '${s}'. ${e.message}`);if(e.severity<1)throw new Error(`Invalid OpenAPI Specification '${s}'. [${e.path.join(".")}] ${e.message}`)}),r)).catch(r=>{throw new Error(`Could not validate OpenAPI Specification '${s}'. ${r.message}`)})},$e=_;
|
|
25
26
|
|
|
26
|
-
exports.a =
|
|
27
|
+
exports.a = Z;
|
|
27
28
|
exports.b = g;
|
|
28
|
-
exports.c =
|
|
29
|
-
exports.d =
|
|
30
|
-
exports.e =
|
|
31
|
-
exports.f =
|
|
29
|
+
exports.c = ie;
|
|
30
|
+
exports.d = le;
|
|
31
|
+
exports.e = Ae;
|
|
32
|
+
exports.f = $e;
|
|
32
33
|
//# sourceMappingURL=out.js.map
|
|
33
|
-
//# sourceMappingURL=chunk-
|
|
34
|
+
//# sourceMappingURL=chunk-5U2PT3WZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/util/object-merge.ts","../src/spec-builder.ts","../src/util/yaml-loc.ts","../src/parse-file.ts","../src/jsdoc/comments-to-open-api.ts","../src/util/customizer.ts","../src/swagger-jsdoc/comments-to-open-api.ts","../src/swagger-jsdoc/utils.ts","../src/swagger-jsdoc/organize-swagger-object.ts","../src/validate.ts"],"names":["objectMerge","a","b","key","subKey","object_merge_default","SpecBuilder","baseDefinition","parsedFile","file","paths","components","rest","value","spec_builder_default","yamlLoc","string","line","yaml_loc_default","readFileSync","path","yaml","ALLOWED_KEYS","ParseError","parseFile","commentsToOpenApi","verbose","fileContent","extension","spec","invalidKeys","error","loc","parse_file_default","parseComments","mergeWith","customizer","objectValue","sourceValue","customizer_default","fixSecurityObject","thing","primitiveTypes","formatMap","parseDescription","tag","rawType","isArray","parsedType","isPrimitive","isFormat","defaultValue","rootType","schema","description","tagsToObjects","tags","parsedResponse","nameAndDescription","contentType","example","status","header","link","security","scopeItem","scope","fileContents","openAPIRegex","comment","result","method","pathsObject","comments_to_open_api_default","mergeDeep","first","second","hasEmptyProperty","object","keyObject","isTagPresentInTags","targetTag","getSwaggerVersionFromSpec","organizeSwaggerObject","swaggerObject","annotation","property","definition","organize_swagger_object_default","specificationTemplate","specs","parsed","newError","errorString","parsedDocument","specification","spectralCore","asyncapi","oas","OASValidator","validator","validate","title","results","validate_default"],"mappings":"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","sourcesContent":["const objectMerge = <T>(a: T, b: T): void => {\n Object.keys(b as object).forEach((key) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (a[key as keyof typeof b] === undefined) {\n // eslint-disable-next-line no-param-reassign\n a[key as keyof typeof b] = {\n ...b[key as keyof typeof b],\n };\n } else {\n Object.keys(b[key as keyof typeof b] as object).forEach((subKey) => {\n // eslint-disable-next-line no-param-reassign\n (a[key as keyof typeof b] as { [key: string]: object })[subKey] = {\n ...(a[key as keyof typeof b] as { [key: string]: object })[subKey],\n ...(b[key as keyof typeof b] as { [key: string]: object })[subKey],\n };\n });\n }\n });\n};\n\nexport default objectMerge;\n","import type {\n BaseDefinition,\n ComponentsObject,\n ExternalDocumentationObject,\n InfoObject,\n OpenApiObject,\n PathsObject,\n SecurityRequirementObject,\n ServerObject,\n TagObject,\n} from \"./exported.d\";\nimport objectMerge from \"./util/object-merge\";\n\nclass SpecBuilder implements OpenApiObject {\n public openapi: string;\n\n public info: InfoObject;\n\n public servers?: ServerObject[];\n\n public paths: PathsObject;\n\n public components?: ComponentsObject;\n\n public security?: SecurityRequirementObject[];\n\n public tags?: TagObject[];\n\n public externalDocs?: ExternalDocumentationObject;\n\n public constructor(baseDefinition: BaseDefinition) {\n this.openapi = baseDefinition.openapi;\n this.info = baseDefinition.info;\n this.servers = baseDefinition.servers;\n this.paths = baseDefinition.paths ?? {};\n this.components = baseDefinition.components;\n this.security = baseDefinition.security;\n this.tags = baseDefinition.tags;\n this.externalDocs = baseDefinition.externalDocs;\n }\n\n public addData(parsedFile: OpenApiObject[]): void {\n parsedFile.forEach((file) => {\n const { paths, components, ...rest } = file;\n\n // only merge paths and components\n objectMerge(this, {\n paths: paths ?? {},\n components: components ?? {},\n } as OpenApiObject);\n\n // overwrite everything else:\n Object.entries(rest).forEach(([key, value]) => {\n // @ts-expect-error\n this[key as keyof OpenApiObject] = value;\n });\n });\n }\n}\n\nexport default SpecBuilder;\n","function yamlLoc(string: string): number {\n // Break string into lines.\n const split = string.split(/\\r\\n|\\r|\\n/);\n\n const filtered = split.filter((line) => {\n // Remove comments.\n if (/^\\s*(#\\s*.*)?$/.test(line)) {\n return false;\n }\n // Remove empty lines.\n return line.trim().length > 0;\n });\n\n return filtered.length;\n}\n\nexport default yamlLoc;\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"./exported.d\";\nimport yamlLoc from \"./util/yaml-loc\";\n\nconst ALLOWED_KEYS = new Set([\"openapi\", \"info\", \"servers\", \"security\", \"tags\", \"externalDocs\", \"components\", \"paths\"]);\n\nclass ParseError extends Error {\n public filePath?: string;\n}\n\nconst parseFile = (\n file: string,\n commentsToOpenApi: (fileContent: string, verbose?: boolean) => { spec: OpenApiObject; loc: number }[],\n verbose?: boolean,\n): { spec: OpenApiObject; loc: number }[] => {\n const fileContent = readFileSync(file, { encoding: \"utf8\" });\n const extension = path.extname(file);\n\n if (extension === \".yaml\" || extension === \".yml\") {\n const spec = yaml.parse(fileContent);\n const invalidKeys = Object.keys(spec).filter((key) => !ALLOWED_KEYS.has(key));\n\n if (invalidKeys.length > 0) {\n const error = new ParseError(`Unexpected keys: ${invalidKeys.join(\", \")}`);\n\n error.filePath = file;\n\n throw error;\n }\n\n if (Object.keys(spec).some((key) => ALLOWED_KEYS.has(key))) {\n const loc = yamlLoc(fileContent);\n\n return [{ spec, loc }];\n }\n\n return [];\n }\n\n try {\n return commentsToOpenApi(fileContent, verbose);\n } catch (error: any) {\n error.filePath = file;\n\n throw error;\n }\n};\n\nexport default parseFile;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\nimport type { OpenApiObject, PathsObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\n\n// The security object has a bizare setup...\nfunction fixSecurityObject(thing: any) {\n if (thing.security) {\n // eslint-disable-next-line no-param-reassign\n thing.security = Object.keys(thing.security).map((s) => {\n return {\n [s]: thing.security[s],\n };\n });\n }\n}\n\nconst primitiveTypes = new Set([\"integer\", \"number\", \"string\", \"boolean\", \"object\", \"array\"]);\n\nconst formatMap: { [key: string]: string } = {\n int32: \"integer\",\n int64: \"integer\",\n float: \"number\",\n double: \"number\",\n date: \"string\",\n \"date-time\": \"string\",\n password: \"string\",\n byte: \"string\",\n binary: \"string\",\n};\n\nfunction parseDescription(tag: Spec): { name: string; description: string | undefined; required: boolean; schema: object | undefined; rawType: string } {\n const rawType = tag.type;\n const isArray = rawType.endsWith(\"[]\");\n const parsedType = rawType.replace(/\\[]$/, \"\");\n\n const isPrimitive = primitiveTypes.has(parsedType);\n const isFormat = Object.keys(formatMap).includes(parsedType);\n\n let defaultValue;\n\n if (tag.default) {\n switch (parsedType) {\n case \"integer\":\n case \"int32\":\n case \"int64\": {\n defaultValue = Number.parseInt(tag.default, 10);\n break;\n }\n case \"number\":\n case \"double\":\n case \"float\": {\n defaultValue = Number.parseFloat(tag.default);\n break;\n }\n default: {\n defaultValue = tag.default;\n break;\n }\n }\n }\n\n let rootType;\n\n if (isPrimitive) {\n rootType = { type: parsedType, default: defaultValue };\n } else if (isFormat) {\n rootType = {\n type: formatMap[parsedType],\n format: parsedType,\n default: defaultValue,\n };\n } else {\n rootType = { $ref: `#/components/schemas/${parsedType}` };\n }\n\n let schema: object | undefined = isArray\n ? {\n type: \"array\",\n items: {\n ...rootType,\n },\n }\n : {\n ...rootType,\n };\n\n if (parsedType === \"\") {\n schema = undefined;\n }\n\n // remove the optional dash from the description.\n let description: string | undefined = tag.description.trim().replace(/^- /, \"\");\n\n if (description === \"\") {\n description = undefined;\n }\n\n return {\n name: tag.name,\n description,\n required: !tag.optional,\n schema,\n rawType,\n };\n}\n\n// @ts-expect-error\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction tagsToObjects(tags: Spec[], verbose?: boolean) {\n return tags.map((tag) => {\n const parsedResponse = parseDescription(tag);\n\n // Some ops only have a `description`, merge `name` and `description`\n // for these.\n let nameAndDescription = \"\";\n\n if (parsedResponse.name) {\n nameAndDescription += parsedResponse.name;\n }\n\n if (parsedResponse.description) {\n nameAndDescription += ` ${parsedResponse.description.trim()}`;\n }\n\n switch (tag.tag) {\n case \"operationId\":\n case \"summary\":\n case \"description\": {\n return { [tag.tag]: nameAndDescription };\n }\n\n case \"deprecated\": {\n return { deprecated: true };\n }\n\n case \"externalDocs\": {\n return {\n externalDocs: {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n };\n }\n\n case \"server\": {\n return {\n servers: [\n {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n ],\n };\n }\n\n case \"tag\": {\n return { tags: [nameAndDescription] };\n }\n\n case \"cookieParam\":\n case \"headerParam\":\n case \"queryParam\":\n case \"pathParam\": {\n return {\n parameters: [\n {\n name: parsedResponse.name,\n in: tag.tag.replace(/Param$/, \"\"),\n description: parsedResponse.description,\n required: parsedResponse.required,\n schema: parsedResponse.schema,\n },\n ],\n };\n }\n\n case \"bodyContent\": {\n return {\n requestBody: {\n content: {\n [parsedResponse.name.replace(\"*\\\\/*\", \"*/*\")]: {\n schema: parsedResponse.schema,\n },\n },\n },\n };\n }\n\n case \"bodyExample\": {\n const [contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n requestBody: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n };\n }\n\n case \"bodyDescription\": {\n return { requestBody: { description: nameAndDescription } };\n }\n\n case \"bodyRequired\": {\n return { requestBody: { required: true } };\n }\n\n case \"response\": {\n return {\n responses: {\n [parsedResponse.name]: {\n description: parsedResponse.description,\n },\n },\n };\n }\n\n case \"callback\": {\n return {\n callbacks: {\n [parsedResponse.name]: {\n $ref: `#/components/callbacks/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"responseContent\": {\n const [status, contentType] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeaderComponent\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n $ref: `#/components/headers/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeader\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n description: parsedResponse.description,\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseExample\": {\n const [status, contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n },\n };\n }\n\n case \"responseLink\": {\n const [status, link] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n links: {\n [link as string]: {\n $ref: `#/components/links/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"bodyComponent\": {\n return {\n requestBody: {\n $ref: `#/components/requestBodies/${parsedResponse.rawType}`,\n },\n };\n }\n\n case \"responseComponent\": {\n return {\n responses: {\n [parsedResponse.name]: {\n $ref: `#/components/responses/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"paramComponent\": {\n return {\n parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }],\n };\n }\n\n case \"security\": {\n const [security, scopeItem] = parsedResponse.name.split(\".\");\n\n let scope: string[] = [];\n\n if (scopeItem) {\n scope = [scopeItem];\n }\n\n return {\n security: { [security as string]: scope },\n };\n }\n\n default: {\n return {};\n }\n }\n });\n}\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const openAPIRegex = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \\/.*$/;\n\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments\n .filter((comment) => openAPIRegex.test(comment.description.trim()))\n .map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n fixSecurityObject(result);\n\n const [method, path]: string[] = comment.description.split(\" \");\n\n const pathsObject: PathsObject = {\n [(path as string).trim()]: {\n [(method as string).toLowerCase().trim()]: {\n ...result,\n },\n },\n };\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","const customizer = (objectValue: unknown, sourceValue: Array<unknown>): unknown[] | undefined => {\n if (Array.isArray(objectValue)) {\n return [...objectValue, ...sourceValue];\n }\n // eslint-disable-next-line unicorn/no-useless-undefined\n return undefined;\n};\n\nexport default customizer;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\nimport type { YAMLError } from \"yaml\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\nimport organizeSwaggerObject from \"./organize-swagger-object\";\nimport { getSwaggerVersionFromSpec, hasEmptyProperty } from \"./utils\";\n\nconst specificationTemplate = {\n v2: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\"],\n v3: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\"],\n v4: [\"components\", \"channels\"],\n};\n\ntype ExtendedYAMLError = YAMLError & { annotation?: string };\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst tagsToObjects = (specs: Spec[], verbose?: boolean) => specs.map((spec: Spec) => {\n if ((spec.tag === \"openapi\" || spec.tag === \"swagger\" || spec.tag === \"asyncapi\") && spec.description !== \"\") {\n const parsed = yaml.parseDocument(spec.description);\n\n if (parsed.errors.length > 0) {\n // eslint-disable-next-line sonarjs/no-ignored-return\n parsed.errors.map<ExtendedYAMLError>((error) => {\n const newError: ExtendedYAMLError = error;\n\n newError.annotation = spec.description;\n\n return newError;\n });\n\n let errorString = \"Error parsing YAML in @openapi spec:\";\n\n errorString += verbose\n ? (parsed.errors as ExtendedYAMLError[])\n .map((error) => `${error.toString()}\\nImbedded within:\\n\\`\\`\\`\\n ${error.annotation?.replace(/\\n/g, \"\\n \")}\\n\\`\\`\\``)\n .join(\"\\n\")\n : parsed.errors.map((error) => error.toString()).join(\"\\n\");\n\n throw new Error(errorString);\n }\n\n const parsedDocument = parsed.toJSON();\n const specification: Record<string, any> = {\n tags: [],\n };\n\n specificationTemplate[getSwaggerVersionFromSpec(spec)].forEach((property) => {\n specification[property] = specification[property] || {};\n });\n\n Object.keys(parsedDocument).forEach((property) => {\n organizeSwaggerObject(specification, parsedDocument, property);\n });\n\n return specification;\n }\n\n return {};\n});\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments.map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n [\"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\", \"tags\"].forEach((property) => {\n if (result[property] !== undefined && hasEmptyProperty(result[property])) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete result[property];\n }\n });\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify(result));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","import type { Spec } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\n/**\n * A recursive deep-merge that ignores null values when merging.\n * This returns the merged object and does not mutate.\n * @param {object} first the first object to get merged\n * @param {object} second the second object to get merged\n */\nexport const mergeDeep = (first?: object, second?: object): object => mergeWith({}, first, second, (a, b) => (b === null ? a : undefined));\n\n/**\n * Checks if there is any properties of the input object which are an empty object\n * @param {object} object - the object to check\n * @returns boolean\n */\nexport const hasEmptyProperty = (object: Record<string, any>): boolean => Object.keys(object)\n .map((key) => object[key])\n .every((keyObject) => typeof keyObject === \"object\" && Object.keys(keyObject).every((key) => !(key in keyObject)));\n\n/**\n * @param {object} tag\n * @param {array} tags\n * @returns boolean\n */\nexport const isTagPresentInTags = (tag: Spec, tags: Spec[]): boolean => tags.some((targetTag) => tag.name === targetTag.name);\n\nexport const getSwaggerVersionFromSpec = (tag: Spec): \"v2\" | \"v3\" | \"v4\" => {\n switch (tag.tag) {\n case \"openapi\": {\n return \"v3\";\n }\n case \"asyncapi\": {\n return \"v4\";\n }\n case \"swagger\": {\n return \"v2\";\n }\n default: {\n return \"v2\";\n }\n }\n};\n","import { isTagPresentInTags, mergeDeep } from \"./utils\";\n\n/**\n * @param {object} swaggerObject\n * @param {object} annotation\n * @param {string} property\n */\n// eslint-disable-next-line sonarjs/no-duplicate-string\nconst organizeSwaggerObject = (swaggerObject: Record<string, any>, annotation: Record<string, any>, property: string): void => {\n // Root property on purpose.\n // eslint-disable-next-line no-secrets/no-secrets\n // @see https://github.com/OAI/OpenAPI-Specification/blob/master/proposals/002_Webhooks.md#proposed-solution\n if (property === \"x-webhooks\") {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property] = annotation[property];\n }\n\n // Other extensions can be in varying places depending on different vendors and opinions.\n // The following return makes it so that they are not put in `paths` in the last case.\n // New specific extensions will need to be handled on case-by-case if to be included in `paths`.\n if (property.startsWith(\"x-\")) {\n return;\n }\n\n const commonProperties = [\n \"components\",\n \"consumes\",\n \"produces\",\n \"paths\",\n \"schemas\",\n \"securityDefinitions\",\n \"responses\",\n \"parameters\",\n \"definitions\",\n \"channels\",\n ];\n\n if (commonProperties.includes(property)) {\n Object.keys(annotation[property]).forEach((definition) => {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property][definition] = mergeDeep(swaggerObject[property][definition], annotation[property][definition]);\n });\n } else if (property === \"tags\") {\n const { tags } = annotation;\n\n if (Array.isArray(tags)) {\n tags.forEach((tag) => {\n if (!isTagPresentInTags(tag, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tag);\n }\n });\n } else if (!isTagPresentInTags(tags, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tags);\n }\n } else if (property === \"security\") {\n const { security } = annotation;\n\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"security\"] = security;\n } else if (property.startsWith(\"/\")) {\n // Paths which are not defined as \"paths\" property, starting with a slash \"/\"\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"paths\"][property] = mergeDeep(swaggerObject[\"paths\"][property], annotation[property]);\n }\n};\n\nexport default organizeSwaggerObject;\n","import type { ISpectralDiagnostic } from \"@stoplight/spectral-core\";\nimport spectralCore from \"@stoplight/spectral-core\";\nimport type { IDocument, IParsedResult } from \"@stoplight/spectral-core/dist/document\";\nimport { asyncapi, oas } from \"@stoplight/spectral-rulesets\";\n\nconst { Spectral: OASValidator } = spectralCore;\nconst validator = new OASValidator();\n\nvalidator.setRuleset({\n // @ts-expect-error: TS2322\n extends: [oas, asyncapi],\n});\n\nconst validate = async (spec: IDocument | IParsedResult | Record<string, unknown> | string): Promise<ISpectralDiagnostic[]> => {\n let title = \"\";\n\n if (typeof spec === \"object\") {\n title = (spec as { info: { title: string } }).info.title;\n } else if (typeof spec === \"string\") {\n title = spec;\n }\n\n return validator\n .run(spec)\n .then((results) => {\n results.forEach((result) => {\n // Ensure there are no errors about no format being matched\n if (result.code === \"unrecognized-format\") {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${result.message}`);\n }\n\n if (result.severity < 1) {\n throw new Error(`Invalid OpenAPI Specification '${title}'. [${result.path.join(\".\")}] ${result.message}`);\n }\n });\n\n return results;\n })\n .catch((error) => {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${error.message}`);\n });\n};\n\nexport default validate;\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk5U2PT3WZ_js = require('./chunk-5U2PT3WZ.js');
|
|
4
4
|
var fs = require('fs');
|
|
5
5
|
var v = require('read-pkg-up');
|
|
6
6
|
var readdir = require('@visulima/readdir');
|
|
@@ -48,11 +48,11 @@ var S=(r,l=process.cwd())=>{if(fs.existsSync(r))throw new Error("Config file alr
|
|
|
48
48
|
},
|
|
49
49
|
};
|
|
50
50
|
`),console.log(`Created "${r}"`);},E=S;var _=async(r,l,e)=>{let o={exclude:[],swaggerDefinition:{}};try{let s=await import(url.pathToFileURL(path.normalize(e.config??r)).href);s?.default&&(s=s.default),o=s;}catch{throw new Error(`No config file found, on: ${e.config??".openapirc.js"}
|
|
51
|
-
`)}let n=new y__default.default.MultiBar({clearOnComplete:!1,hideCursor:!0,format:"{value}/{total} | {bar} | {filename}"},y__default.default.Presets.shades_grey),t=new
|
|
52
|
-
Found ${a.length} files in ${s}`),e.veryVerbose&&console.log(a);let w=n.create(a.length,0);a.forEach(c=>{e.verbose&&console.log(`Parsing file ${c}`),w.increment(1,{filename:s});let j=
|
|
51
|
+
`)}let n=new y__default.default.MultiBar({clearOnComplete:!1,hideCursor:!0,format:"{value}/{total} | {bar} | {filename}"},y__default.default.Presets.shades_grey),t=new chunk5U2PT3WZ_js.a(o.swaggerDefinition);for await(let s of l){fs.lstatSync(s).isDirectory();let a=await readdir.collect(s,{skip:[...o.exclude,"node_modules/**"],extensions:o.extensions??[".js",".cjs",".mjs",".ts",".tsx",".jsx",".yaml",".yml"],followSymlinks:o.followSymlinks??!1,match:o.include,minimatchOptions:{match:{debug:e.verbose,matchBase:!0},skip:{debug:e.verbose,matchBase:!0}}});(e.verbose??e.veryVerbose)&&console.log(`
|
|
52
|
+
Found ${a.length} files in ${s}`),e.veryVerbose&&console.log(a);let w=n.create(a.length,0);a.forEach(c=>{e.verbose&&console.log(`Parsing file ${c}`),w.increment(1,{filename:s});let j=chunk5U2PT3WZ_js.c(c,chunk5U2PT3WZ_js.d,e.verbose);t.addData(j.map(m=>m.spec));let k=chunk5U2PT3WZ_js.c(c,chunk5U2PT3WZ_js.e,e.verbose);t.addData(k.map(m=>m.spec));});}e.verbose&&console.log("Validating swagger spec"),e.veryVerbose&&console.log(JSON.stringify(t,null,2)),await chunk5U2PT3WZ_js.f(JSON.parse(JSON.stringify(t)));let i=e.output??"swagger.json";n.stop(),e.verbose&&console.log(`Written swagger spec to "${i}" file`),fs.mkdirSync(path.dirname(i),{recursive:!0}),fs.writeFileSync(i,JSON.stringify(t,null,2)),console.log(`
|
|
53
53
|
Swagger specification is ready, check the "${i}" file.`);},G=_;
|
|
54
54
|
|
|
55
55
|
exports.a = E;
|
|
56
56
|
exports.b = G;
|
|
57
57
|
//# sourceMappingURL=out.js.map
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
58
|
+
//# sourceMappingURL=chunk-6BASRGSS.js.map
|
|
@@ -3,18 +3,18 @@ import v from 'path';
|
|
|
3
3
|
import w from 'yaml';
|
|
4
4
|
import { parse } from 'comment-parser';
|
|
5
5
|
import D from 'lodash.mergewith';
|
|
6
|
-
import
|
|
6
|
+
import H from '@stoplight/spectral-core';
|
|
7
7
|
import { oas, asyncapi } from '@stoplight/spectral-rulesets';
|
|
8
8
|
|
|
9
|
-
var E=(t,s)=>{Object.keys(s).forEach(r=>{t[r]===void 0?t[r]={...s[r]}:Object.keys(s[r]).forEach(e=>{t[r][e]={...t[r][e],...s[r][e]};});});},y=E;var u=class{constructor(s){this.openapi=s.openapi,this.info=s.info,this.servers=s.servers,this.paths=s.paths??{},this.components=s.components,this.security=s.security,this.tags=s.tags,this.externalDocs=s.externalDocs;}addData(s){s.forEach(r=>{let{paths:e,components:i,...n}=r;y(this,{paths:e??{},components:i??{}}),Object.entries(n).forEach(([o,a])=>{this[o]=a;});});}},
|
|
9
|
+
var E=(t,s)=>{Object.keys(s).forEach(r=>{t[r]===void 0?t[r]={...s[r]}:Object.keys(s[r]).forEach(e=>{t[r][e]={...t[r][e],...s[r][e]};});});},y=E;var u=class{constructor(s){this.openapi=s.openapi,this.info=s.info,this.servers=s.servers,this.paths=s.paths??{},this.components=s.components,this.security=s.security,this.tags=s.tags,this.externalDocs=s.externalDocs;}addData(s){s.forEach(r=>{let{paths:e,components:i,...n}=r;y(this,{paths:e??{},components:i??{}}),Object.entries(n).forEach(([o,a])=>{this[o]=a;});});}},Z=u;function A(t){return t.split(/\r\n|\r|\n/).filter(e=>/^\s*(#\s*.*)?$/.test(e)?!1:e.trim().length>0).length}var g=A;var h=new Set(["openapi","info","servers","security","tags","externalDocs","components","paths"]),l=class extends Error{},$=(t,s,r)=>{let e=readFileSync(t,{encoding:"utf8"}),i=v.extname(t);if(i===".yaml"||i===".yml"){let n=w.parse(e),o=Object.keys(n).filter(a=>!h.has(a));if(o.length>0){let a=new l(`Unexpected keys: ${o.join(", ")}`);throw a.filePath=t,a}if(Object.keys(n).some(a=>h.has(a))){let a=g(e);return [{spec:n,loc:a}]}return []}try{return s(e,r)}catch(n){throw n.filePath=t,n}},ie=$;var k=(t,s)=>{if(Array.isArray(t))return [...t,...s]},m=k;function C(t){t.security&&(t.security=Object.keys(t.security).map(s=>({[s]:t.security[s]})));}var I=new Set(["integer","number","string","boolean","object","array"]),b={int32:"integer",int64:"integer",float:"number",double:"number",date:"string","date-time":"string",password:"string",byte:"string",binary:"string"};function q(t){let s=t.type,r=s.endsWith("[]"),e=s.replace(/\[]$/,""),i=I.has(e),n=Object.keys(b).includes(e),o;if(t.default)switch(e){case"integer":case"int32":case"int64":{o=Number.parseInt(t.default,10);break}case"number":case"double":case"float":{o=Number.parseFloat(t.default);break}default:{o=t.default;break}}let a;i?a={type:e,default:o}:n?a={type:b[e],format:e,default:o}:a={$ref:`#/components/schemas/${e}`};let c=r?{type:"array",items:{...a}}:{...a};e===""&&(c=void 0);let p=t.description.trim().replace(/^- /,"");return p===""&&(p=void 0),{name:t.name,description:p,required:!t.optional,schema:c,rawType:s}}function L(t,s){return t.map(r=>{let e=q(r),i="";switch(e.name&&(i+=e.name),e.description&&(i+=` ${e.description.trim()}`),r.tag){case"operationId":case"summary":case"description":return {[r.tag]:i};case"deprecated":return {deprecated:!0};case"externalDocs":return {externalDocs:{url:e.name,description:e.description}};case"server":return {servers:[{url:e.name,description:e.description}]};case"tag":return {tags:[i]};case"cookieParam":case"headerParam":case"queryParam":case"pathParam":return {parameters:[{name:e.name,in:r.tag.replace(/Param$/,""),description:e.description,required:e.required,schema:e.schema}]};case"bodyContent":return {requestBody:{content:{[e.name.replace("*\\/*","*/*")]:{schema:e.schema}}}};case"bodyExample":{let[n,o]=e.name.split(".");return {requestBody:{content:{[n]:{examples:{[o]:{$ref:`#/components/examples/${e.rawType}`}}}}}}}case"bodyDescription":return {requestBody:{description:i}};case"bodyRequired":return {requestBody:{required:!0}};case"response":return {responses:{[e.name]:{description:e.description}}};case"callback":return {callbacks:{[e.name]:{$ref:`#/components/callbacks/${e.rawType}`}}};case"responseContent":{let[n,o]=e.name.split(".");return {responses:{[n]:{content:{[o]:{schema:e.schema}}}}}}case"responseHeaderComponent":{let[n,o]=e.name.split(".");return {responses:{[n]:{headers:{[o]:{$ref:`#/components/headers/${e.rawType}`}}}}}}case"responseHeader":{let[n,o]=e.name.split(".");return {responses:{[n]:{headers:{[o]:{description:e.description,schema:e.schema}}}}}}case"responseExample":{let[n,o,a]=e.name.split(".");return {responses:{[n]:{content:{[o]:{examples:{[a]:{$ref:`#/components/examples/${e.rawType}`}}}}}}}}case"responseLink":{let[n,o]=e.name.split(".");return {responses:{[n]:{links:{[o]:{$ref:`#/components/links/${e.rawType}`}}}}}}case"bodyComponent":return {requestBody:{$ref:`#/components/requestBodies/${e.rawType}`}};case"responseComponent":return {responses:{[e.name]:{$ref:`#/components/responses/${e.rawType}`}}};case"paramComponent":return {parameters:[{$ref:`#/components/parameters/${e.rawType}`}]};case"security":{let[n,o]=e.name.split("."),a=[];return o&&(a=[o]),{security:{[n]:a}}}default:return {}}})}var R=(t,s)=>{let r=/^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \/.*$/;return parse(t,{spacing:"preserve"}).filter(i=>r.test(i.description.trim())).map(i=>{let n=i.tags.length+1,o=D({},...L(i.tags),m);C(o);let[a,c]=i.description.split(" "),p={[c.trim()]:{[a.toLowerCase().trim()]:{...o}}};return {spec:JSON.parse(JSON.stringify({paths:p})),loc:n}})},le=R;var d=(t,s)=>D({},t,s,(r,e)=>e===null?r:void 0),O=t=>Object.keys(t).map(s=>t[s]).every(s=>typeof s=="object"&&Object.keys(s).every(r=>!(r in s))),f=(t,s)=>s.some(r=>t.name===r.name),j=t=>{switch(t.tag){case"openapi":return "v3";case"asyncapi":return "v4";case"swagger":return "v2";default:return "v2"}};var N=(t,s,r)=>{if(r==="x-webhooks"&&(t[r]=s[r]),r.startsWith("x-"))return;if(["components","consumes","produces","paths","schemas","securityDefinitions","responses","parameters","definitions","channels"].includes(r))Object.keys(s[r]).forEach(i=>{t[r][i]=d(t[r][i],s[r][i]);});else if(r==="tags"){let{tags:i}=s;Array.isArray(i)?i.forEach(n=>{f(n,t.tags)||t.tags.push(n);}):f(i,t.tags)||t.tags.push(i);}else if(r==="security"){let{security:i}=s;t.security=i;}else r.startsWith("/")&&(t.paths[r]=d(t.paths[r],s[r]));},x=N;var z={v2:["paths","definitions","responses","parameters","securityDefinitions"],v3:["paths","definitions","responses","parameters","securityDefinitions","components"],v4:["components","channels"]},F=(t,s)=>t.map(r=>{if((r.tag==="openapi"||r.tag==="swagger"||r.tag==="asyncapi")&&r.description!==""){let e=w.parseDocument(r.description);if(e.errors.length>0){e.errors.map(a=>{let c=a;return c.annotation=r.description,c});let o="Error parsing YAML in @openapi spec:";throw o+=s?e.errors.map(a=>`${a.toString()}
|
|
10
10
|
Imbedded within:
|
|
11
11
|
\`\`\`
|
|
12
12
|
${a.annotation?.replace(/\n/g,`
|
|
13
13
|
`)}
|
|
14
14
|
\`\`\``).join(`
|
|
15
15
|
`):e.errors.map(a=>a.toString()).join(`
|
|
16
|
-
`),new Error(o)}let i=e.toJSON(),n={tags:[]};return z[j(r)].forEach(o=>{n[o]=n[o]||{};}),Object.keys(i).forEach(o=>{x(n,i,o);}),n}return {}}),J=(t,s)=>parse(t,{spacing:"preserve"}).map(e=>{let i=e.tags.length+1,n=D({},...F(e.tags,s),m);return ["definitions","responses","parameters","securityDefinitions","components","tags"].forEach(a=>{n[a]!==void 0&&O(n[a])&&delete n[a];}),{spec:JSON.parse(JSON.stringify(n)),loc:i}}),
|
|
16
|
+
`),new Error(o)}let i=e.toJSON(),n={tags:[]};return z[j(r)].forEach(o=>{n[o]=n[o]||{};}),Object.keys(i).forEach(o=>{x(n,i,o);}),n}return {}}),J=(t,s)=>parse(t,{spacing:"preserve"}).map(e=>{let i=e.tags.length+1,n=D({},...F(e.tags,s),m);return ["definitions","responses","parameters","securityDefinitions","components","tags"].forEach(a=>{n[a]!==void 0&&O(n[a])&&delete n[a];}),{spec:JSON.parse(JSON.stringify(n)),loc:i}}),Ae=J;var{Spectral:G}=H,S=new G;S.setRuleset({extends:[oas,asyncapi]});var _=async t=>{let s="";return typeof t=="object"?s=t.info.title:typeof t=="string"&&(s=t),S.run(t).then(r=>(r.forEach(e=>{if(e.code==="unrecognized-format")throw new Error(`Could not validate OpenAPI Specification '${s}'. ${e.message}`);if(e.severity<1)throw new Error(`Invalid OpenAPI Specification '${s}'. [${e.path.join(".")}] ${e.message}`)}),r)).catch(r=>{throw new Error(`Could not validate OpenAPI Specification '${s}'. ${r.message}`)})},$e=_;
|
|
17
17
|
|
|
18
|
-
export {
|
|
18
|
+
export { Z as a, g as b, ie as c, le as d, Ae as e, $e as f };
|
|
19
19
|
//# sourceMappingURL=out.js.map
|
|
20
|
-
//# sourceMappingURL=chunk-
|
|
20
|
+
//# sourceMappingURL=chunk-SXATCZ56.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/util/object-merge.ts","../src/spec-builder.ts","../src/util/yaml-loc.ts","../src/parse-file.ts","../src/jsdoc/comments-to-open-api.ts","../src/util/customizer.ts","../src/swagger-jsdoc/comments-to-open-api.ts","../src/swagger-jsdoc/utils.ts","../src/swagger-jsdoc/organize-swagger-object.ts","../src/validate.ts"],"names":["objectMerge","a","b","key","subKey","object_merge_default","SpecBuilder","baseDefinition","parsedFile","file","paths","components","rest","value","spec_builder_default","yamlLoc","string","line","yaml_loc_default","readFileSync","path","yaml","ALLOWED_KEYS","ParseError","parseFile","commentsToOpenApi","verbose","fileContent","extension","spec","invalidKeys","error","loc","parse_file_default","parseComments","mergeWith","customizer","objectValue","sourceValue","customizer_default","fixSecurityObject","thing","primitiveTypes","formatMap","parseDescription","tag","rawType","isArray","parsedType","isPrimitive","isFormat","defaultValue","rootType","schema","description","tagsToObjects","tags","parsedResponse","nameAndDescription","contentType","example","status","header","link","security","scopeItem","scope","fileContents","openAPIRegex","comment","result","method","pathsObject","comments_to_open_api_default","mergeDeep","first","second","hasEmptyProperty","object","keyObject","isTagPresentInTags","targetTag","getSwaggerVersionFromSpec","organizeSwaggerObject","swaggerObject","annotation","property","definition","organize_swagger_object_default","specificationTemplate","specs","parsed","newError","errorString","parsedDocument","specification","spectralCore","asyncapi","oas","OASValidator","validator","validate","title","results","validate_default"],"mappings":"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","sourcesContent":["const objectMerge = <T>(a: T, b: T): void => {\n Object.keys(b as object).forEach((key) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (a[key as keyof typeof b] === undefined) {\n // eslint-disable-next-line no-param-reassign\n a[key as keyof typeof b] = {\n ...b[key as keyof typeof b],\n };\n } else {\n Object.keys(b[key as keyof typeof b] as object).forEach((subKey) => {\n // eslint-disable-next-line no-param-reassign\n (a[key as keyof typeof b] as { [key: string]: object })[subKey] = {\n ...(a[key as keyof typeof b] as { [key: string]: object })[subKey],\n ...(b[key as keyof typeof b] as { [key: string]: object })[subKey],\n };\n });\n }\n });\n};\n\nexport default objectMerge;\n","import type {\n BaseDefinition,\n ComponentsObject,\n ExternalDocumentationObject,\n InfoObject,\n OpenApiObject,\n PathsObject,\n SecurityRequirementObject,\n ServerObject,\n TagObject,\n} from \"./exported.d\";\nimport objectMerge from \"./util/object-merge\";\n\nclass SpecBuilder implements OpenApiObject {\n public openapi: string;\n\n public info: InfoObject;\n\n public servers?: ServerObject[];\n\n public paths: PathsObject;\n\n public components?: ComponentsObject;\n\n public security?: SecurityRequirementObject[];\n\n public tags?: TagObject[];\n\n public externalDocs?: ExternalDocumentationObject;\n\n public constructor(baseDefinition: BaseDefinition) {\n this.openapi = baseDefinition.openapi;\n this.info = baseDefinition.info;\n this.servers = baseDefinition.servers;\n this.paths = baseDefinition.paths ?? {};\n this.components = baseDefinition.components;\n this.security = baseDefinition.security;\n this.tags = baseDefinition.tags;\n this.externalDocs = baseDefinition.externalDocs;\n }\n\n public addData(parsedFile: OpenApiObject[]): void {\n parsedFile.forEach((file) => {\n const { paths, components, ...rest } = file;\n\n // only merge paths and components\n objectMerge(this, {\n paths: paths ?? {},\n components: components ?? {},\n } as OpenApiObject);\n\n // overwrite everything else:\n Object.entries(rest).forEach(([key, value]) => {\n // @ts-expect-error\n this[key as keyof OpenApiObject] = value;\n });\n });\n }\n}\n\nexport default SpecBuilder;\n","function yamlLoc(string: string): number {\n // Break string into lines.\n const split = string.split(/\\r\\n|\\r|\\n/);\n\n const filtered = split.filter((line) => {\n // Remove comments.\n if (/^\\s*(#\\s*.*)?$/.test(line)) {\n return false;\n }\n // Remove empty lines.\n return line.trim().length > 0;\n });\n\n return filtered.length;\n}\n\nexport default yamlLoc;\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"./exported.d\";\nimport yamlLoc from \"./util/yaml-loc\";\n\nconst ALLOWED_KEYS = new Set([\"openapi\", \"info\", \"servers\", \"security\", \"tags\", \"externalDocs\", \"components\", \"paths\"]);\n\nclass ParseError extends Error {\n public filePath?: string;\n}\n\nconst parseFile = (\n file: string,\n commentsToOpenApi: (fileContent: string, verbose?: boolean) => { spec: OpenApiObject; loc: number }[],\n verbose?: boolean,\n): { spec: OpenApiObject; loc: number }[] => {\n const fileContent = readFileSync(file, { encoding: \"utf8\" });\n const extension = path.extname(file);\n\n if (extension === \".yaml\" || extension === \".yml\") {\n const spec = yaml.parse(fileContent);\n const invalidKeys = Object.keys(spec).filter((key) => !ALLOWED_KEYS.has(key));\n\n if (invalidKeys.length > 0) {\n const error = new ParseError(`Unexpected keys: ${invalidKeys.join(\", \")}`);\n\n error.filePath = file;\n\n throw error;\n }\n\n if (Object.keys(spec).some((key) => ALLOWED_KEYS.has(key))) {\n const loc = yamlLoc(fileContent);\n\n return [{ spec, loc }];\n }\n\n return [];\n }\n\n try {\n return commentsToOpenApi(fileContent, verbose);\n } catch (error: any) {\n error.filePath = file;\n\n throw error;\n }\n};\n\nexport default parseFile;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\nimport type { OpenApiObject, PathsObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\n\n// The security object has a bizare setup...\nfunction fixSecurityObject(thing: any) {\n if (thing.security) {\n // eslint-disable-next-line no-param-reassign\n thing.security = Object.keys(thing.security).map((s) => {\n return {\n [s]: thing.security[s],\n };\n });\n }\n}\n\nconst primitiveTypes = new Set([\"integer\", \"number\", \"string\", \"boolean\", \"object\", \"array\"]);\n\nconst formatMap: { [key: string]: string } = {\n int32: \"integer\",\n int64: \"integer\",\n float: \"number\",\n double: \"number\",\n date: \"string\",\n \"date-time\": \"string\",\n password: \"string\",\n byte: \"string\",\n binary: \"string\",\n};\n\nfunction parseDescription(tag: Spec): { name: string; description: string | undefined; required: boolean; schema: object | undefined; rawType: string } {\n const rawType = tag.type;\n const isArray = rawType.endsWith(\"[]\");\n const parsedType = rawType.replace(/\\[]$/, \"\");\n\n const isPrimitive = primitiveTypes.has(parsedType);\n const isFormat = Object.keys(formatMap).includes(parsedType);\n\n let defaultValue;\n\n if (tag.default) {\n switch (parsedType) {\n case \"integer\":\n case \"int32\":\n case \"int64\": {\n defaultValue = Number.parseInt(tag.default, 10);\n break;\n }\n case \"number\":\n case \"double\":\n case \"float\": {\n defaultValue = Number.parseFloat(tag.default);\n break;\n }\n default: {\n defaultValue = tag.default;\n break;\n }\n }\n }\n\n let rootType;\n\n if (isPrimitive) {\n rootType = { type: parsedType, default: defaultValue };\n } else if (isFormat) {\n rootType = {\n type: formatMap[parsedType],\n format: parsedType,\n default: defaultValue,\n };\n } else {\n rootType = { $ref: `#/components/schemas/${parsedType}` };\n }\n\n let schema: object | undefined = isArray\n ? {\n type: \"array\",\n items: {\n ...rootType,\n },\n }\n : {\n ...rootType,\n };\n\n if (parsedType === \"\") {\n schema = undefined;\n }\n\n // remove the optional dash from the description.\n let description: string | undefined = tag.description.trim().replace(/^- /, \"\");\n\n if (description === \"\") {\n description = undefined;\n }\n\n return {\n name: tag.name,\n description,\n required: !tag.optional,\n schema,\n rawType,\n };\n}\n\n// @ts-expect-error\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction tagsToObjects(tags: Spec[], verbose?: boolean) {\n return tags.map((tag) => {\n const parsedResponse = parseDescription(tag);\n\n // Some ops only have a `description`, merge `name` and `description`\n // for these.\n let nameAndDescription = \"\";\n\n if (parsedResponse.name) {\n nameAndDescription += parsedResponse.name;\n }\n\n if (parsedResponse.description) {\n nameAndDescription += ` ${parsedResponse.description.trim()}`;\n }\n\n switch (tag.tag) {\n case \"operationId\":\n case \"summary\":\n case \"description\": {\n return { [tag.tag]: nameAndDescription };\n }\n\n case \"deprecated\": {\n return { deprecated: true };\n }\n\n case \"externalDocs\": {\n return {\n externalDocs: {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n };\n }\n\n case \"server\": {\n return {\n servers: [\n {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n ],\n };\n }\n\n case \"tag\": {\n return { tags: [nameAndDescription] };\n }\n\n case \"cookieParam\":\n case \"headerParam\":\n case \"queryParam\":\n case \"pathParam\": {\n return {\n parameters: [\n {\n name: parsedResponse.name,\n in: tag.tag.replace(/Param$/, \"\"),\n description: parsedResponse.description,\n required: parsedResponse.required,\n schema: parsedResponse.schema,\n },\n ],\n };\n }\n\n case \"bodyContent\": {\n return {\n requestBody: {\n content: {\n [parsedResponse.name.replace(\"*\\\\/*\", \"*/*\")]: {\n schema: parsedResponse.schema,\n },\n },\n },\n };\n }\n\n case \"bodyExample\": {\n const [contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n requestBody: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n };\n }\n\n case \"bodyDescription\": {\n return { requestBody: { description: nameAndDescription } };\n }\n\n case \"bodyRequired\": {\n return { requestBody: { required: true } };\n }\n\n case \"response\": {\n return {\n responses: {\n [parsedResponse.name]: {\n description: parsedResponse.description,\n },\n },\n };\n }\n\n case \"callback\": {\n return {\n callbacks: {\n [parsedResponse.name]: {\n $ref: `#/components/callbacks/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"responseContent\": {\n const [status, contentType] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeaderComponent\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n $ref: `#/components/headers/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeader\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n description: parsedResponse.description,\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseExample\": {\n const [status, contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n },\n };\n }\n\n case \"responseLink\": {\n const [status, link] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n links: {\n [link as string]: {\n $ref: `#/components/links/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"bodyComponent\": {\n return {\n requestBody: {\n $ref: `#/components/requestBodies/${parsedResponse.rawType}`,\n },\n };\n }\n\n case \"responseComponent\": {\n return {\n responses: {\n [parsedResponse.name]: {\n $ref: `#/components/responses/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"paramComponent\": {\n return {\n parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }],\n };\n }\n\n case \"security\": {\n const [security, scopeItem] = parsedResponse.name.split(\".\");\n\n let scope: string[] = [];\n\n if (scopeItem) {\n scope = [scopeItem];\n }\n\n return {\n security: { [security as string]: scope },\n };\n }\n\n default: {\n return {};\n }\n }\n });\n}\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const openAPIRegex = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \\/.*$/;\n\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments\n .filter((comment) => openAPIRegex.test(comment.description.trim()))\n .map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n fixSecurityObject(result);\n\n const [method, path]: string[] = comment.description.split(\" \");\n\n const pathsObject: PathsObject = {\n [(path as string).trim()]: {\n [(method as string).toLowerCase().trim()]: {\n ...result,\n },\n },\n };\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","const customizer = (objectValue: unknown, sourceValue: Array<unknown>): unknown[] | undefined => {\n if (Array.isArray(objectValue)) {\n return [...objectValue, ...sourceValue];\n }\n // eslint-disable-next-line unicorn/no-useless-undefined\n return undefined;\n};\n\nexport default customizer;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\nimport type { YAMLError } from \"yaml\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\nimport organizeSwaggerObject from \"./organize-swagger-object\";\nimport { getSwaggerVersionFromSpec, hasEmptyProperty } from \"./utils\";\n\nconst specificationTemplate = {\n v2: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\"],\n v3: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\"],\n v4: [\"components\", \"channels\"],\n};\n\ntype ExtendedYAMLError = YAMLError & { annotation?: string };\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst tagsToObjects = (specs: Spec[], verbose?: boolean) => specs.map((spec: Spec) => {\n if ((spec.tag === \"openapi\" || spec.tag === \"swagger\" || spec.tag === \"asyncapi\") && spec.description !== \"\") {\n const parsed = yaml.parseDocument(spec.description);\n\n if (parsed.errors.length > 0) {\n // eslint-disable-next-line sonarjs/no-ignored-return\n parsed.errors.map<ExtendedYAMLError>((error) => {\n const newError: ExtendedYAMLError = error;\n\n newError.annotation = spec.description;\n\n return newError;\n });\n\n let errorString = \"Error parsing YAML in @openapi spec:\";\n\n errorString += verbose\n ? (parsed.errors as ExtendedYAMLError[])\n .map((error) => `${error.toString()}\\nImbedded within:\\n\\`\\`\\`\\n ${error.annotation?.replace(/\\n/g, \"\\n \")}\\n\\`\\`\\``)\n .join(\"\\n\")\n : parsed.errors.map((error) => error.toString()).join(\"\\n\");\n\n throw new Error(errorString);\n }\n\n const parsedDocument = parsed.toJSON();\n const specification: Record<string, any> = {\n tags: [],\n };\n\n specificationTemplate[getSwaggerVersionFromSpec(spec)].forEach((property) => {\n specification[property] = specification[property] || {};\n });\n\n Object.keys(parsedDocument).forEach((property) => {\n organizeSwaggerObject(specification, parsedDocument, property);\n });\n\n return specification;\n }\n\n return {};\n});\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments.map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n [\"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\", \"tags\"].forEach((property) => {\n if (result[property] !== undefined && hasEmptyProperty(result[property])) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete result[property];\n }\n });\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify(result));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","import type { Spec } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\n/**\n * A recursive deep-merge that ignores null values when merging.\n * This returns the merged object and does not mutate.\n * @param {object} first the first object to get merged\n * @param {object} second the second object to get merged\n */\nexport const mergeDeep = (first?: object, second?: object): object => mergeWith({}, first, second, (a, b) => (b === null ? a : undefined));\n\n/**\n * Checks if there is any properties of the input object which are an empty object\n * @param {object} object - the object to check\n * @returns boolean\n */\nexport const hasEmptyProperty = (object: Record<string, any>): boolean => Object.keys(object)\n .map((key) => object[key])\n .every((keyObject) => typeof keyObject === \"object\" && Object.keys(keyObject).every((key) => !(key in keyObject)));\n\n/**\n * @param {object} tag\n * @param {array} tags\n * @returns boolean\n */\nexport const isTagPresentInTags = (tag: Spec, tags: Spec[]): boolean => tags.some((targetTag) => tag.name === targetTag.name);\n\nexport const getSwaggerVersionFromSpec = (tag: Spec): \"v2\" | \"v3\" | \"v4\" => {\n switch (tag.tag) {\n case \"openapi\": {\n return \"v3\";\n }\n case \"asyncapi\": {\n return \"v4\";\n }\n case \"swagger\": {\n return \"v2\";\n }\n default: {\n return \"v2\";\n }\n }\n};\n","import { isTagPresentInTags, mergeDeep } from \"./utils\";\n\n/**\n * @param {object} swaggerObject\n * @param {object} annotation\n * @param {string} property\n */\n// eslint-disable-next-line sonarjs/no-duplicate-string\nconst organizeSwaggerObject = (swaggerObject: Record<string, any>, annotation: Record<string, any>, property: string): void => {\n // Root property on purpose.\n // eslint-disable-next-line no-secrets/no-secrets\n // @see https://github.com/OAI/OpenAPI-Specification/blob/master/proposals/002_Webhooks.md#proposed-solution\n if (property === \"x-webhooks\") {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property] = annotation[property];\n }\n\n // Other extensions can be in varying places depending on different vendors and opinions.\n // The following return makes it so that they are not put in `paths` in the last case.\n // New specific extensions will need to be handled on case-by-case if to be included in `paths`.\n if (property.startsWith(\"x-\")) {\n return;\n }\n\n const commonProperties = [\n \"components\",\n \"consumes\",\n \"produces\",\n \"paths\",\n \"schemas\",\n \"securityDefinitions\",\n \"responses\",\n \"parameters\",\n \"definitions\",\n \"channels\",\n ];\n\n if (commonProperties.includes(property)) {\n Object.keys(annotation[property]).forEach((definition) => {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property][definition] = mergeDeep(swaggerObject[property][definition], annotation[property][definition]);\n });\n } else if (property === \"tags\") {\n const { tags } = annotation;\n\n if (Array.isArray(tags)) {\n tags.forEach((tag) => {\n if (!isTagPresentInTags(tag, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tag);\n }\n });\n } else if (!isTagPresentInTags(tags, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tags);\n }\n } else if (property === \"security\") {\n const { security } = annotation;\n\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"security\"] = security;\n } else if (property.startsWith(\"/\")) {\n // Paths which are not defined as \"paths\" property, starting with a slash \"/\"\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"paths\"][property] = mergeDeep(swaggerObject[\"paths\"][property], annotation[property]);\n }\n};\n\nexport default organizeSwaggerObject;\n","import type { ISpectralDiagnostic } from \"@stoplight/spectral-core\";\nimport spectralCore from \"@stoplight/spectral-core\";\nimport type { IDocument, IParsedResult } from \"@stoplight/spectral-core/dist/document\";\nimport { asyncapi, oas } from \"@stoplight/spectral-rulesets\";\n\nconst { Spectral: OASValidator } = spectralCore;\nconst validator = new OASValidator();\n\nvalidator.setRuleset({\n // @ts-expect-error: TS2322\n extends: [oas, asyncapi],\n});\n\nconst validate = async (spec: IDocument | IParsedResult | Record<string, unknown> | string): Promise<ISpectralDiagnostic[]> => {\n let title = \"\";\n\n if (typeof spec === \"object\") {\n title = (spec as { info: { title: string } }).info.title;\n } else if (typeof spec === \"string\") {\n title = spec;\n }\n\n return validator\n .run(spec)\n .then((results) => {\n results.forEach((result) => {\n // Ensure there are no errors about no format being matched\n if (result.code === \"unrecognized-format\") {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${result.message}`);\n }\n\n if (result.severity < 1) {\n throw new Error(`Invalid OpenAPI Specification '${title}'. [${result.path.join(\".\")}] ${result.message}`);\n }\n });\n\n return results;\n })\n .catch((error) => {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${error.message}`);\n });\n};\n\nexport default validate;\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../../chunk-
|
|
3
|
+
var chunk6BASRGSS_js = require('../../chunk-6BASRGSS.js');
|
|
4
|
+
require('../../chunk-5U2PT3WZ.js');
|
|
5
5
|
var process = require('process');
|
|
6
6
|
|
|
7
|
-
var s=(o,e="init",t="Inits a pre-configured @visulima/jsdoc-open-api config file.",r=".openapirc.js")=>{o.command(e).description(t).action(()=>{try{
|
|
7
|
+
var s=(o,e="init",t="Inits a pre-configured @visulima/jsdoc-open-api config file.",r=".openapirc.js")=>{o.command(e).description(t).action(()=>{try{chunk6BASRGSS_js.a(r);}catch(n){console.error(n),process.exit(1);}});},c=s;var f=(o,e="generate",t=".openapirc.js")=>{o.command(e).description("Generates OpenAPI (Swagger) documentation from JSDoc's").usage("[options] <path ...>").argument("[path ...]","Paths to files or directories to parse").option("-c, --config [.openapirc.js]","@visulima/jsdoc-open-api config file path.").option("-o, --output [swaggerSpec.json]","Output swagger specification.").option("-v, --verbose","Verbose output.").option("-vv, --very-verbose","Very verbose output.").action(async(r,n)=>{try{await chunk6BASRGSS_js.b(t,r,n);}catch(m){console.error(m),process.exit(1);}});},g=f;
|
|
8
8
|
|
|
9
9
|
exports.generateCommand = g;
|
|
10
10
|
exports.initCommand = c;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a, b } from '../../chunk-
|
|
2
|
-
import '../../chunk-
|
|
1
|
+
import { a, b } from '../../chunk-4BGSTSHH.mjs';
|
|
2
|
+
import '../../chunk-SXATCZ56.mjs';
|
|
3
3
|
import { exit } from 'process';
|
|
4
4
|
|
|
5
5
|
var s=(o,e="init",t="Inits a pre-configured @visulima/jsdoc-open-api config file.",r=".openapirc.js")=>{o.command(e).description(t).action(()=>{try{a(r);}catch(n){console.error(n),exit(1);}});},c=s;var f=(o,e="generate",t=".openapirc.js")=>{o.command(e).description("Generates OpenAPI (Swagger) documentation from JSDoc's").usage("[options] <path ...>").argument("[path ...]","Paths to files or directories to parse").option("-c, --config [.openapirc.js]","@visulima/jsdoc-open-api config file path.").option("-o, --output [swaggerSpec.json]","Output swagger specification.").option("-v, --verbose","Verbose output.").option("-vv, --very-verbose","Very verbose output.").action(async(r,n)=>{try{await b(t,r,n);}catch(m){console.error(m),exit(1);}});},g=f;
|
package/dist/cli/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
3
|
+
var chunk6BASRGSS_js = require('../chunk-6BASRGSS.js');
|
|
4
|
+
require('../chunk-5U2PT3WZ.js');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, 'generateCommand', {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunk6BASRGSS_js.b; }
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(exports, 'initCommand', {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunk6BASRGSS_js.a; }
|
|
15
15
|
});
|
|
16
16
|
//# sourceMappingURL=out.js.map
|
|
17
17
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { b as generateCommand, a as initCommand } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { b as generateCommand, a as initCommand } from '../chunk-4BGSTSHH.mjs';
|
|
2
|
+
import '../chunk-SXATCZ56.mjs';
|
|
3
3
|
//# sourceMappingURL=out.js.map
|
|
4
4
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk5U2PT3WZ_js = require('./chunk-5U2PT3WZ.js');
|
|
4
4
|
var readdir = require('@visulima/readdir');
|
|
5
5
|
var fs = require('fs');
|
|
6
6
|
var path = require('path');
|
|
7
7
|
var process = require('process');
|
|
8
8
|
|
|
9
|
-
var O=["coverage/**",".github/**","packages/*/test{,s}/**","**/*.d.ts","test{,s}/**","test{,-*}.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}","**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}","**/__tests__/**","**/{ava,babel,nyc}.config.{js,cjs,mjs}","**/jest.config.{js,cjs,mjs,ts}","**/{karma,rollup,webpack}.config.js","**/.{eslint,mocha}rc.{js,cjs}","**/.{travis,yarnrc}.yml","**/{docker-compose,docker}.yml","**/.yamllint.{yaml,yml}","**/node_modules/**","**/pnpm-lock.yaml","**/pnpm-workspace.yaml","**/{package,package-lock}.json","**/yarn.lock","**/package.json5","**/.next/**"],b=t=>{t&&(console.error(t),process.exit(1));},d=class{constructor(r,u,i,e){this.assetsPath=r,this.swaggerDefinition=i,this.sources=u,this.verbose=e.verbose??!1,this.ignore=e.ignore??[];}apply(r){r.hooks.make.tapAsync("SwaggerCompilerPlugin",async(u,i)=>{console.log("Build paused, switching to swagger build");let e=new
|
|
9
|
+
var O=["coverage/**",".github/**","packages/*/test{,s}/**","**/*.d.ts","test{,s}/**","test{,-*}.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}","**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}","**/__tests__/**","**/{ava,babel,nyc}.config.{js,cjs,mjs}","**/jest.config.{js,cjs,mjs,ts}","**/{karma,rollup,webpack}.config.js","**/.{eslint,mocha}rc.{js,cjs}","**/.{travis,yarnrc}.yml","**/{docker-compose,docker}.yml","**/.yamllint.{yaml,yml}","**/node_modules/**","**/pnpm-lock.yaml","**/pnpm-workspace.yaml","**/{package,package-lock}.json","**/yarn.lock","**/package.json5","**/.next/**"],b=t=>{t&&(console.error(t),process.exit(1));},d=class{constructor(r,u,i,e){this.assetsPath=r,this.swaggerDefinition=i,this.sources=u,this.verbose=e.verbose??!1,this.ignore=e.ignore??[];}apply(r){r.hooks.make.tapAsync("SwaggerCompilerPlugin",async(u,i)=>{console.log("Build paused, switching to swagger build");let e=new chunk5U2PT3WZ_js.a(this.swaggerDefinition);for await(let s of this.sources){let a=await readdir.collect(s,{skip:[...this.ignore,...O],extensions:[".js",".cjs",".mjs",".ts",".tsx",".jsx",".yaml",".yml"],includeDirs:!1,minimatchOptions:{match:{debug:this.verbose,matchBase:!0},skip:{debug:this.verbose,matchBase:!0}}});this.verbose&&(console.log(`Found ${a.length} files in ${s}`),console.log(a)),a.forEach(n=>{this.verbose&&console.log(`Parsing file ${n}`);try{let l=chunk5U2PT3WZ_js.c(n,chunk5U2PT3WZ_js.d,this.verbose);e.addData(l.map(c=>c.spec));let j=chunk5U2PT3WZ_js.c(n,chunk5U2PT3WZ_js.e,this.verbose);e.addData(j.map(c=>c.spec));}catch(l){console.error(l),process.exit(1);}});}try{this.verbose&&(console.log("Validating swagger spec"),console.log(JSON.stringify(e,null,2))),await chunk5U2PT3WZ_js.f(JSON.parse(JSON.stringify(e)));}catch(s){console.error(s.toJSON()),process.exit(1);}let{assetsPath:y}=this;fs.mkdir(path.dirname(y),{recursive:!0},s=>{s&&b(s),fs.writeFile(y,JSON.stringify(e,null,2),b);}),this.verbose&&console.log(`Written swagger spec to "${this.assetsPath}" file`),console.log("switching back to normal build"),i();});}},B=d;
|
|
10
10
|
|
|
11
11
|
Object.defineProperty(exports, 'SpecBuilder', {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunk5U2PT3WZ_js.a; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, 'jsDocumentCommentsToOpenApi', {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunk5U2PT3WZ_js.d; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, 'parseFile', {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunk5U2PT3WZ_js.c; }
|
|
22
22
|
});
|
|
23
23
|
Object.defineProperty(exports, 'swaggerJsDocumentCommentsToOpenApi', {
|
|
24
24
|
enumerable: true,
|
|
25
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunk5U2PT3WZ_js.e; }
|
|
26
26
|
});
|
|
27
27
|
Object.defineProperty(exports, 'yamlLoc', {
|
|
28
28
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunk5U2PT3WZ_js.b; }
|
|
30
30
|
});
|
|
31
31
|
exports.SwaggerCompilerPlugin = B;
|
|
32
32
|
//# sourceMappingURL=out.js.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a, c, d as d$1, e, f } from './chunk-
|
|
2
|
-
export { a as SpecBuilder, d as jsDocumentCommentsToOpenApi, c as parseFile, e as swaggerJsDocumentCommentsToOpenApi, b as yamlLoc } from './chunk-
|
|
1
|
+
import { a, c, d as d$1, e, f } from './chunk-SXATCZ56.mjs';
|
|
2
|
+
export { a as SpecBuilder, d as jsDocumentCommentsToOpenApi, c as parseFile, e as swaggerJsDocumentCommentsToOpenApi, b as yamlLoc } from './chunk-SXATCZ56.mjs';
|
|
3
3
|
import { collect } from '@visulima/readdir';
|
|
4
4
|
import { mkdir, writeFile } from 'fs';
|
|
5
5
|
import { dirname } from 'path';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visulima/jsdoc-open-api",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"description": "Generates swagger doc based on JSDoc.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"visulima",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"build:prod": "cross-env NODE_ENV=production tsup",
|
|
77
77
|
"clean": "rimraf node_modules dist .eslintcache",
|
|
78
78
|
"coverage": "vitest run --coverage",
|
|
79
|
-
"dev": "pnpm
|
|
79
|
+
"dev": "pnpm run build --watch",
|
|
80
80
|
"lint:eslint": "cross-env NO_LOGS=true eslint . --ext js,jsx,ts,tsx --max-warnings=0 --config .eslintrc.cjs --cache --cache-strategy content .",
|
|
81
81
|
"lint:eslint:fix": "pnpm run lint:eslint --fix",
|
|
82
82
|
"test": "vitest run",
|
|
@@ -92,17 +92,17 @@
|
|
|
92
92
|
"yaml": "^2.3.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@stoplight/types": "^13.15.0",
|
|
96
95
|
"@anolilab/eslint-config": "^5.0.5",
|
|
97
96
|
"@anolilab/semantic-release-preset": "^2.2.1",
|
|
98
97
|
"@rushstack/eslint-plugin-security": "^0.6.0",
|
|
98
|
+
"@stoplight/types": "^13.15.0",
|
|
99
99
|
"@types/cli-progress": "^3.11.0",
|
|
100
100
|
"@types/http-errors": "^2.0.1",
|
|
101
101
|
"@types/lodash.mergewith": "^4.6.7",
|
|
102
102
|
"@types/node": "18.16.16",
|
|
103
103
|
"@types/webpack": "^5.28.1",
|
|
104
|
-
"@typescript-eslint/eslint-plugin": "^5.59.
|
|
105
|
-
"@typescript-eslint/parser": "^5.59.
|
|
104
|
+
"@typescript-eslint/eslint-plugin": "^5.59.8",
|
|
105
|
+
"@typescript-eslint/parser": "^5.59.8",
|
|
106
106
|
"@vitest/coverage-c8": "^0.31.1",
|
|
107
107
|
"c8": "^7.14.0",
|
|
108
108
|
"cli-progress": "^3.12.0",
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
"optionalDependencies": {
|
|
141
141
|
"cli-progress": "^3.12.0",
|
|
142
142
|
"commander": "^10.0.1",
|
|
143
|
-
"webpack": "^5.
|
|
143
|
+
"webpack": "^5.85.0"
|
|
144
144
|
},
|
|
145
145
|
"engines": {
|
|
146
146
|
"node": ">=16.18.0 <=20.*"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/util/object-merge.ts","../src/spec-builder.ts","../src/util/yaml-loc.ts","../src/parse-file.ts","../src/jsdoc/comments-to-open-api.ts","../src/util/customizer.ts","../src/swagger-jsdoc/comments-to-open-api.ts","../src/swagger-jsdoc/utils.ts","../src/swagger-jsdoc/organize-swagger-object.ts","../src/validate.ts"],"names":["objectMerge","a","b","key","subKey","object_merge_default","SpecBuilder","baseDefinition","parsedFile","file","paths","components","rest","value","spec_builder_default","yamlLoc","string","line","yaml_loc_default","readFileSync","path","yaml","ALLOWED_KEYS","ParseError","parseFile","commentsToOpenApi","verbose","fileContent","extension","spec","invalidKeys","error","loc","parse_file_default","parseComments","mergeWith","customizer","objectValue","sourceValue","customizer_default","fixSecurityObject","thing","primitiveTypes","formatMap","parseDescription","tag","rawType","isArray","parsedType","isPrimitive","isFormat","defaultValue","rootType","schema","description","tagsToObjects","tags","parsedResponse","nameAndDescription","contentType","example","status","header","link","security","scopeItem","scope","fileContents","openAPIRegex","comment","result","method","pathsObject","comments_to_open_api_default","mergeDeep","first","second","hasEmptyProperty","object","keyObject","isTagPresentInTags","targetTag","getSwaggerVersionFromSpec","organizeSwaggerObject","swaggerObject","annotation","property","definition","organize_swagger_object_default","specificationTemplate","specs","parsed","newError","errorString","parsedDocument","specification","OASValidator","asyncapi","oas","validator","validate","title","results","validate_default"],"mappings":"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","sourcesContent":["const objectMerge = <T>(a: T, b: T): void => {\n Object.keys(b as object).forEach((key) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (a[key as keyof typeof b] === undefined) {\n // eslint-disable-next-line no-param-reassign\n a[key as keyof typeof b] = {\n ...b[key as keyof typeof b],\n };\n } else {\n Object.keys(b[key as keyof typeof b] as object).forEach((subKey) => {\n // eslint-disable-next-line no-param-reassign\n (a[key as keyof typeof b] as { [key: string]: object })[subKey] = {\n ...(a[key as keyof typeof b] as { [key: string]: object })[subKey],\n ...(b[key as keyof typeof b] as { [key: string]: object })[subKey],\n };\n });\n }\n });\n};\n\nexport default objectMerge;\n","import type {\n BaseDefinition,\n ComponentsObject,\n ExternalDocumentationObject,\n InfoObject,\n OpenApiObject,\n PathsObject,\n SecurityRequirementObject,\n ServerObject,\n TagObject,\n} from \"./exported.d\";\nimport objectMerge from \"./util/object-merge\";\n\nclass SpecBuilder implements OpenApiObject {\n public openapi: string;\n\n public info: InfoObject;\n\n public servers?: ServerObject[];\n\n public paths: PathsObject;\n\n public components?: ComponentsObject;\n\n public security?: SecurityRequirementObject[];\n\n public tags?: TagObject[];\n\n public externalDocs?: ExternalDocumentationObject;\n\n public constructor(baseDefinition: BaseDefinition) {\n this.openapi = baseDefinition.openapi;\n this.info = baseDefinition.info;\n this.servers = baseDefinition.servers;\n this.paths = baseDefinition.paths ?? {};\n this.components = baseDefinition.components;\n this.security = baseDefinition.security;\n this.tags = baseDefinition.tags;\n this.externalDocs = baseDefinition.externalDocs;\n }\n\n public addData(parsedFile: OpenApiObject[]): void {\n parsedFile.forEach((file) => {\n const { paths, components, ...rest } = file;\n\n // only merge paths and components\n objectMerge(this, {\n paths: paths ?? {},\n components: components ?? {},\n } as OpenApiObject);\n\n // overwrite everything else:\n Object.entries(rest).forEach(([key, value]) => {\n // @ts-expect-error\n this[key as keyof OpenApiObject] = value;\n });\n });\n }\n}\n\nexport default SpecBuilder;\n","function yamlLoc(string: string): number {\n // Break string into lines.\n const split = string.split(/\\r\\n|\\r|\\n/);\n\n const filtered = split.filter((line) => {\n // Remove comments.\n if (/^\\s*(#\\s*.*)?$/.test(line)) {\n return false;\n }\n // Remove empty lines.\n return line.trim().length > 0;\n });\n\n return filtered.length;\n}\n\nexport default yamlLoc;\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"./exported.d\";\nimport yamlLoc from \"./util/yaml-loc\";\n\nconst ALLOWED_KEYS = new Set([\"openapi\", \"info\", \"servers\", \"security\", \"tags\", \"externalDocs\", \"components\", \"paths\"]);\n\nclass ParseError extends Error {\n public filePath?: string;\n}\n\nconst parseFile = (\n file: string,\n commentsToOpenApi: (fileContent: string, verbose?: boolean) => { spec: OpenApiObject; loc: number }[],\n verbose?: boolean,\n): { spec: OpenApiObject; loc: number }[] => {\n const fileContent = readFileSync(file, { encoding: \"utf8\" });\n const extension = path.extname(file);\n\n if (extension === \".yaml\" || extension === \".yml\") {\n const spec = yaml.parse(fileContent);\n const invalidKeys = Object.keys(spec).filter((key) => !ALLOWED_KEYS.has(key));\n\n if (invalidKeys.length > 0) {\n const error = new ParseError(`Unexpected keys: ${invalidKeys.join(\", \")}`);\n\n error.filePath = file;\n\n throw error;\n }\n\n if (Object.keys(spec).some((key) => ALLOWED_KEYS.has(key))) {\n const loc = yamlLoc(fileContent);\n\n return [{ spec, loc }];\n }\n\n return [];\n }\n\n try {\n return commentsToOpenApi(fileContent, verbose);\n } catch (error: any) {\n error.filePath = file;\n\n throw error;\n }\n};\n\nexport default parseFile;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\nimport type { OpenApiObject, PathsObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\n\n// The security object has a bizare setup...\nfunction fixSecurityObject(thing: any) {\n if (thing.security) {\n // eslint-disable-next-line no-param-reassign\n thing.security = Object.keys(thing.security).map((s) => {\n return {\n [s]: thing.security[s],\n };\n });\n }\n}\n\nconst primitiveTypes = new Set([\"integer\", \"number\", \"string\", \"boolean\", \"object\", \"array\"]);\n\nconst formatMap: { [key: string]: string } = {\n int32: \"integer\",\n int64: \"integer\",\n float: \"number\",\n double: \"number\",\n date: \"string\",\n \"date-time\": \"string\",\n password: \"string\",\n byte: \"string\",\n binary: \"string\",\n};\n\nfunction parseDescription(tag: Spec): { name: string; description: string | undefined; required: boolean; schema: object | undefined; rawType: string } {\n const rawType = tag.type;\n const isArray = rawType.endsWith(\"[]\");\n const parsedType = rawType.replace(/\\[]$/, \"\");\n\n const isPrimitive = primitiveTypes.has(parsedType);\n const isFormat = Object.keys(formatMap).includes(parsedType);\n\n let defaultValue;\n\n if (tag.default) {\n switch (parsedType) {\n case \"integer\":\n case \"int32\":\n case \"int64\": {\n defaultValue = Number.parseInt(tag.default, 10);\n break;\n }\n case \"number\":\n case \"double\":\n case \"float\": {\n defaultValue = Number.parseFloat(tag.default);\n break;\n }\n default: {\n defaultValue = tag.default;\n break;\n }\n }\n }\n\n let rootType;\n\n if (isPrimitive) {\n rootType = { type: parsedType, default: defaultValue };\n } else if (isFormat) {\n rootType = {\n type: formatMap[parsedType],\n format: parsedType,\n default: defaultValue,\n };\n } else {\n rootType = { $ref: `#/components/schemas/${parsedType}` };\n }\n\n let schema: object | undefined = isArray\n ? {\n type: \"array\",\n items: {\n ...rootType,\n },\n }\n : {\n ...rootType,\n };\n\n if (parsedType === \"\") {\n schema = undefined;\n }\n\n // remove the optional dash from the description.\n let description: string | undefined = tag.description.trim().replace(/^- /, \"\");\n\n if (description === \"\") {\n description = undefined;\n }\n\n return {\n name: tag.name,\n description,\n required: !tag.optional,\n schema,\n rawType,\n };\n}\n\n// @ts-expect-error\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction tagsToObjects(tags: Spec[], verbose?: boolean) {\n return tags.map((tag) => {\n const parsedResponse = parseDescription(tag);\n\n // Some ops only have a `description`, merge `name` and `description`\n // for these.\n let nameAndDescription = \"\";\n\n if (parsedResponse.name) {\n nameAndDescription += parsedResponse.name;\n }\n\n if (parsedResponse.description) {\n nameAndDescription += ` ${parsedResponse.description.trim()}`;\n }\n\n switch (tag.tag) {\n case \"operationId\":\n case \"summary\":\n case \"description\": {\n return { [tag.tag]: nameAndDescription };\n }\n\n case \"deprecated\": {\n return { deprecated: true };\n }\n\n case \"externalDocs\": {\n return {\n externalDocs: {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n };\n }\n\n case \"server\": {\n return {\n servers: [\n {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n ],\n };\n }\n\n case \"tag\": {\n return { tags: [nameAndDescription] };\n }\n\n case \"cookieParam\":\n case \"headerParam\":\n case \"queryParam\":\n case \"pathParam\": {\n return {\n parameters: [\n {\n name: parsedResponse.name,\n in: tag.tag.replace(/Param$/, \"\"),\n description: parsedResponse.description,\n required: parsedResponse.required,\n schema: parsedResponse.schema,\n },\n ],\n };\n }\n\n case \"bodyContent\": {\n return {\n requestBody: {\n content: {\n [parsedResponse.name.replace(\"*\\\\/*\", \"*/*\")]: {\n schema: parsedResponse.schema,\n },\n },\n },\n };\n }\n\n case \"bodyExample\": {\n const [contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n requestBody: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n };\n }\n\n case \"bodyDescription\": {\n return { requestBody: { description: nameAndDescription } };\n }\n\n case \"bodyRequired\": {\n return { requestBody: { required: true } };\n }\n\n case \"response\": {\n return {\n responses: {\n [parsedResponse.name]: {\n description: parsedResponse.description,\n },\n },\n };\n }\n\n case \"callback\": {\n return {\n callbacks: {\n [parsedResponse.name]: {\n $ref: `#/components/callbacks/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"responseContent\": {\n const [status, contentType] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeaderComponent\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n $ref: `#/components/headers/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeader\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n description: parsedResponse.description,\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseExample\": {\n const [status, contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n },\n };\n }\n\n case \"responseLink\": {\n const [status, link] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n links: {\n [link as string]: {\n $ref: `#/components/links/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"bodyComponent\": {\n return {\n requestBody: {\n $ref: `#/components/requestBodies/${parsedResponse.rawType}`,\n },\n };\n }\n\n case \"responseComponent\": {\n return {\n responses: {\n [parsedResponse.name]: {\n $ref: `#/components/responses/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"paramComponent\": {\n return {\n parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }],\n };\n }\n\n case \"security\": {\n const [security, scopeItem] = parsedResponse.name.split(\".\");\n\n let scope: string[] = [];\n\n if (scopeItem) {\n scope = [scopeItem];\n }\n\n return {\n security: { [security as string]: scope },\n };\n }\n\n default: {\n return {};\n }\n }\n });\n}\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const openAPIRegex = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \\/.*$/;\n\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments\n .filter((comment) => openAPIRegex.test(comment.description.trim()))\n .map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n fixSecurityObject(result);\n\n const [method, path]: string[] = comment.description.split(\" \");\n\n const pathsObject: PathsObject = {\n [(path as string).trim()]: {\n [(method as string).toLowerCase().trim()]: {\n ...result,\n },\n },\n };\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","const customizer = (objectValue: unknown, sourceValue: Array<unknown>): unknown[] | undefined => {\n if (Array.isArray(objectValue)) {\n return [...objectValue, ...sourceValue];\n }\n // eslint-disable-next-line unicorn/no-useless-undefined\n return undefined;\n};\n\nexport default customizer;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\nimport type { YAMLError } from \"yaml\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\nimport organizeSwaggerObject from \"./organize-swagger-object\";\nimport { getSwaggerVersionFromSpec, hasEmptyProperty } from \"./utils\";\n\nconst specificationTemplate = {\n v2: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\"],\n v3: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\"],\n v4: [\"components\", \"channels\"],\n};\n\ntype ExtendedYAMLError = YAMLError & { annotation?: string };\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst tagsToObjects = (specs: Spec[], verbose?: boolean) => specs.map((spec: Spec) => {\n if ((spec.tag === \"openapi\" || spec.tag === \"swagger\" || spec.tag === \"asyncapi\") && spec.description !== \"\") {\n const parsed = yaml.parseDocument(spec.description);\n\n if (parsed.errors.length > 0) {\n // eslint-disable-next-line sonarjs/no-ignored-return\n parsed.errors.map<ExtendedYAMLError>((error) => {\n const newError: ExtendedYAMLError = error;\n\n newError.annotation = spec.description;\n\n return newError;\n });\n\n let errorString = \"Error parsing YAML in @openapi spec:\";\n\n errorString += verbose\n ? (parsed.errors as ExtendedYAMLError[])\n .map((error) => `${error.toString()}\\nImbedded within:\\n\\`\\`\\`\\n ${error.annotation?.replace(/\\n/g, \"\\n \")}\\n\\`\\`\\``)\n .join(\"\\n\")\n : parsed.errors.map((error) => error.toString()).join(\"\\n\");\n\n throw new Error(errorString);\n }\n\n const parsedDocument = parsed.toJSON();\n const specification: Record<string, any> = {\n tags: [],\n };\n\n specificationTemplate[getSwaggerVersionFromSpec(spec)].forEach((property) => {\n specification[property] = specification[property] || {};\n });\n\n Object.keys(parsedDocument).forEach((property) => {\n organizeSwaggerObject(specification, parsedDocument, property);\n });\n\n return specification;\n }\n\n return {};\n});\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments.map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n [\"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\", \"tags\"].forEach((property) => {\n if (result[property] !== undefined && hasEmptyProperty(result[property])) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete result[property];\n }\n });\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify(result));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","import type { Spec } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\n/**\n * A recursive deep-merge that ignores null values when merging.\n * This returns the merged object and does not mutate.\n * @param {object} first the first object to get merged\n * @param {object} second the second object to get merged\n */\nexport const mergeDeep = (first?: object, second?: object): object => mergeWith({}, first, second, (a, b) => (b === null ? a : undefined));\n\n/**\n * Checks if there is any properties of the input object which are an empty object\n * @param {object} object - the object to check\n * @returns boolean\n */\nexport const hasEmptyProperty = (object: Record<string, any>): boolean => Object.keys(object)\n .map((key) => object[key])\n .every((keyObject) => typeof keyObject === \"object\" && Object.keys(keyObject).every((key) => !(key in keyObject)));\n\n/**\n * @param {object} tag\n * @param {array} tags\n * @returns boolean\n */\nexport const isTagPresentInTags = (tag: Spec, tags: Spec[]): boolean => tags.some((targetTag) => tag.name === targetTag.name);\n\nexport const getSwaggerVersionFromSpec = (tag: Spec): \"v2\" | \"v3\" | \"v4\" => {\n switch (tag.tag) {\n case \"openapi\": {\n return \"v3\";\n }\n case \"asyncapi\": {\n return \"v4\";\n }\n case \"swagger\": {\n return \"v2\";\n }\n default: {\n return \"v2\";\n }\n }\n};\n","import { isTagPresentInTags, mergeDeep } from \"./utils\";\n\n/**\n * @param {object} swaggerObject\n * @param {object} annotation\n * @param {string} property\n */\n// eslint-disable-next-line sonarjs/no-duplicate-string\nconst organizeSwaggerObject = (swaggerObject: Record<string, any>, annotation: Record<string, any>, property: string): void => {\n // Root property on purpose.\n // eslint-disable-next-line no-secrets/no-secrets\n // @see https://github.com/OAI/OpenAPI-Specification/blob/master/proposals/002_Webhooks.md#proposed-solution\n if (property === \"x-webhooks\") {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property] = annotation[property];\n }\n\n // Other extensions can be in varying places depending on different vendors and opinions.\n // The following return makes it so that they are not put in `paths` in the last case.\n // New specific extensions will need to be handled on case-by-case if to be included in `paths`.\n if (property.startsWith(\"x-\")) {\n return;\n }\n\n const commonProperties = [\n \"components\",\n \"consumes\",\n \"produces\",\n \"paths\",\n \"schemas\",\n \"securityDefinitions\",\n \"responses\",\n \"parameters\",\n \"definitions\",\n \"channels\",\n ];\n\n if (commonProperties.includes(property)) {\n Object.keys(annotation[property]).forEach((definition) => {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property][definition] = mergeDeep(swaggerObject[property][definition], annotation[property][definition]);\n });\n } else if (property === \"tags\") {\n const { tags } = annotation;\n\n if (Array.isArray(tags)) {\n tags.forEach((tag) => {\n if (!isTagPresentInTags(tag, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tag);\n }\n });\n } else if (!isTagPresentInTags(tags, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tags);\n }\n } else if (property === \"security\") {\n const { security } = annotation;\n\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"security\"] = security;\n } else if (property.startsWith(\"/\")) {\n // Paths which are not defined as \"paths\" property, starting with a slash \"/\"\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"paths\"][property] = mergeDeep(swaggerObject[\"paths\"][property], annotation[property]);\n }\n};\n\nexport default organizeSwaggerObject;\n","import type { ISpectralDiagnostic } from \"@stoplight/spectral-core\";\nimport { Spectral as OASValidator } from \"@stoplight/spectral-core\";\nimport type { IDocument, IParsedResult } from \"@stoplight/spectral-core/dist/document\";\nimport { asyncapi, oas } from \"@stoplight/spectral-rulesets\";\n\nconst validator = new OASValidator();\n\nvalidator.setRuleset({\n // @ts-expect-error: TS2322\n extends: [oas, asyncapi],\n});\n\nconst validate = async (spec: IDocument | IParsedResult | Record<string, unknown> | string): Promise<ISpectralDiagnostic[]> => {\n let title = \"\";\n\n if (typeof spec === \"object\") {\n title = (spec as { info: { title: string } }).info.title;\n } else if (typeof spec === \"string\") {\n title = spec;\n }\n\n return validator\n .run(spec)\n .then((results) => {\n results.forEach((result) => {\n // Ensure there are no errors about no format being matched\n if (result.code === \"unrecognized-format\") {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${result.message}`);\n }\n\n if (result.severity < 1) {\n throw new Error(`Invalid OpenAPI Specification '${title}'. [${result.path.join(\".\")}] ${result.message}`);\n }\n });\n\n return results;\n })\n .catch((error) => {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${error.message}`);\n });\n};\n\nexport default validate;\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/util/object-merge.ts","../src/spec-builder.ts","../src/util/yaml-loc.ts","../src/parse-file.ts","../src/jsdoc/comments-to-open-api.ts","../src/util/customizer.ts","../src/swagger-jsdoc/comments-to-open-api.ts","../src/swagger-jsdoc/utils.ts","../src/swagger-jsdoc/organize-swagger-object.ts","../src/validate.ts"],"names":["objectMerge","a","b","key","subKey","object_merge_default","SpecBuilder","baseDefinition","parsedFile","file","paths","components","rest","value","spec_builder_default","yamlLoc","string","line","yaml_loc_default","readFileSync","path","yaml","ALLOWED_KEYS","ParseError","parseFile","commentsToOpenApi","verbose","fileContent","extension","spec","invalidKeys","error","loc","parse_file_default","parseComments","mergeWith","customizer","objectValue","sourceValue","customizer_default","fixSecurityObject","thing","primitiveTypes","formatMap","parseDescription","tag","rawType","isArray","parsedType","isPrimitive","isFormat","defaultValue","rootType","schema","description","tagsToObjects","tags","parsedResponse","nameAndDescription","contentType","example","status","header","link","security","scopeItem","scope","fileContents","openAPIRegex","comment","result","method","pathsObject","comments_to_open_api_default","mergeDeep","first","second","hasEmptyProperty","object","keyObject","isTagPresentInTags","targetTag","getSwaggerVersionFromSpec","organizeSwaggerObject","swaggerObject","annotation","property","definition","organize_swagger_object_default","specificationTemplate","specs","parsed","newError","errorString","parsedDocument","specification","OASValidator","asyncapi","oas","validator","validate","title","results","validate_default"],"mappings":"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","sourcesContent":["const objectMerge = <T>(a: T, b: T): void => {\n Object.keys(b as object).forEach((key) => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (a[key as keyof typeof b] === undefined) {\n // eslint-disable-next-line no-param-reassign\n a[key as keyof typeof b] = {\n ...b[key as keyof typeof b],\n };\n } else {\n Object.keys(b[key as keyof typeof b] as object).forEach((subKey) => {\n // eslint-disable-next-line no-param-reassign\n (a[key as keyof typeof b] as { [key: string]: object })[subKey] = {\n ...(a[key as keyof typeof b] as { [key: string]: object })[subKey],\n ...(b[key as keyof typeof b] as { [key: string]: object })[subKey],\n };\n });\n }\n });\n};\n\nexport default objectMerge;\n","import type {\n BaseDefinition,\n ComponentsObject,\n ExternalDocumentationObject,\n InfoObject,\n OpenApiObject,\n PathsObject,\n SecurityRequirementObject,\n ServerObject,\n TagObject,\n} from \"./exported.d\";\nimport objectMerge from \"./util/object-merge\";\n\nclass SpecBuilder implements OpenApiObject {\n public openapi: string;\n\n public info: InfoObject;\n\n public servers?: ServerObject[];\n\n public paths: PathsObject;\n\n public components?: ComponentsObject;\n\n public security?: SecurityRequirementObject[];\n\n public tags?: TagObject[];\n\n public externalDocs?: ExternalDocumentationObject;\n\n public constructor(baseDefinition: BaseDefinition) {\n this.openapi = baseDefinition.openapi;\n this.info = baseDefinition.info;\n this.servers = baseDefinition.servers;\n this.paths = baseDefinition.paths ?? {};\n this.components = baseDefinition.components;\n this.security = baseDefinition.security;\n this.tags = baseDefinition.tags;\n this.externalDocs = baseDefinition.externalDocs;\n }\n\n public addData(parsedFile: OpenApiObject[]): void {\n parsedFile.forEach((file) => {\n const { paths, components, ...rest } = file;\n\n // only merge paths and components\n objectMerge(this, {\n paths: paths ?? {},\n components: components ?? {},\n } as OpenApiObject);\n\n // overwrite everything else:\n Object.entries(rest).forEach(([key, value]) => {\n // @ts-expect-error\n this[key as keyof OpenApiObject] = value;\n });\n });\n }\n}\n\nexport default SpecBuilder;\n","function yamlLoc(string: string): number {\n // Break string into lines.\n const split = string.split(/\\r\\n|\\r|\\n/);\n\n const filtered = split.filter((line) => {\n // Remove comments.\n if (/^\\s*(#\\s*.*)?$/.test(line)) {\n return false;\n }\n // Remove empty lines.\n return line.trim().length > 0;\n });\n\n return filtered.length;\n}\n\nexport default yamlLoc;\n","import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"./exported.d\";\nimport yamlLoc from \"./util/yaml-loc\";\n\nconst ALLOWED_KEYS = new Set([\"openapi\", \"info\", \"servers\", \"security\", \"tags\", \"externalDocs\", \"components\", \"paths\"]);\n\nclass ParseError extends Error {\n public filePath?: string;\n}\n\nconst parseFile = (\n file: string,\n commentsToOpenApi: (fileContent: string, verbose?: boolean) => { spec: OpenApiObject; loc: number }[],\n verbose?: boolean,\n): { spec: OpenApiObject; loc: number }[] => {\n const fileContent = readFileSync(file, { encoding: \"utf8\" });\n const extension = path.extname(file);\n\n if (extension === \".yaml\" || extension === \".yml\") {\n const spec = yaml.parse(fileContent);\n const invalidKeys = Object.keys(spec).filter((key) => !ALLOWED_KEYS.has(key));\n\n if (invalidKeys.length > 0) {\n const error = new ParseError(`Unexpected keys: ${invalidKeys.join(\", \")}`);\n\n error.filePath = file;\n\n throw error;\n }\n\n if (Object.keys(spec).some((key) => ALLOWED_KEYS.has(key))) {\n const loc = yamlLoc(fileContent);\n\n return [{ spec, loc }];\n }\n\n return [];\n }\n\n try {\n return commentsToOpenApi(fileContent, verbose);\n } catch (error: any) {\n error.filePath = file;\n\n throw error;\n }\n};\n\nexport default parseFile;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\nimport type { OpenApiObject, PathsObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\n\n// The security object has a bizare setup...\nfunction fixSecurityObject(thing: any) {\n if (thing.security) {\n // eslint-disable-next-line no-param-reassign\n thing.security = Object.keys(thing.security).map((s) => {\n return {\n [s]: thing.security[s],\n };\n });\n }\n}\n\nconst primitiveTypes = new Set([\"integer\", \"number\", \"string\", \"boolean\", \"object\", \"array\"]);\n\nconst formatMap: { [key: string]: string } = {\n int32: \"integer\",\n int64: \"integer\",\n float: \"number\",\n double: \"number\",\n date: \"string\",\n \"date-time\": \"string\",\n password: \"string\",\n byte: \"string\",\n binary: \"string\",\n};\n\nfunction parseDescription(tag: Spec): { name: string; description: string | undefined; required: boolean; schema: object | undefined; rawType: string } {\n const rawType = tag.type;\n const isArray = rawType.endsWith(\"[]\");\n const parsedType = rawType.replace(/\\[]$/, \"\");\n\n const isPrimitive = primitiveTypes.has(parsedType);\n const isFormat = Object.keys(formatMap).includes(parsedType);\n\n let defaultValue;\n\n if (tag.default) {\n switch (parsedType) {\n case \"integer\":\n case \"int32\":\n case \"int64\": {\n defaultValue = Number.parseInt(tag.default, 10);\n break;\n }\n case \"number\":\n case \"double\":\n case \"float\": {\n defaultValue = Number.parseFloat(tag.default);\n break;\n }\n default: {\n defaultValue = tag.default;\n break;\n }\n }\n }\n\n let rootType;\n\n if (isPrimitive) {\n rootType = { type: parsedType, default: defaultValue };\n } else if (isFormat) {\n rootType = {\n type: formatMap[parsedType],\n format: parsedType,\n default: defaultValue,\n };\n } else {\n rootType = { $ref: `#/components/schemas/${parsedType}` };\n }\n\n let schema: object | undefined = isArray\n ? {\n type: \"array\",\n items: {\n ...rootType,\n },\n }\n : {\n ...rootType,\n };\n\n if (parsedType === \"\") {\n schema = undefined;\n }\n\n // remove the optional dash from the description.\n let description: string | undefined = tag.description.trim().replace(/^- /, \"\");\n\n if (description === \"\") {\n description = undefined;\n }\n\n return {\n name: tag.name,\n description,\n required: !tag.optional,\n schema,\n rawType,\n };\n}\n\n// @ts-expect-error\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction tagsToObjects(tags: Spec[], verbose?: boolean) {\n return tags.map((tag) => {\n const parsedResponse = parseDescription(tag);\n\n // Some ops only have a `description`, merge `name` and `description`\n // for these.\n let nameAndDescription = \"\";\n\n if (parsedResponse.name) {\n nameAndDescription += parsedResponse.name;\n }\n\n if (parsedResponse.description) {\n nameAndDescription += ` ${parsedResponse.description.trim()}`;\n }\n\n switch (tag.tag) {\n case \"operationId\":\n case \"summary\":\n case \"description\": {\n return { [tag.tag]: nameAndDescription };\n }\n\n case \"deprecated\": {\n return { deprecated: true };\n }\n\n case \"externalDocs\": {\n return {\n externalDocs: {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n };\n }\n\n case \"server\": {\n return {\n servers: [\n {\n url: parsedResponse.name,\n description: parsedResponse.description,\n },\n ],\n };\n }\n\n case \"tag\": {\n return { tags: [nameAndDescription] };\n }\n\n case \"cookieParam\":\n case \"headerParam\":\n case \"queryParam\":\n case \"pathParam\": {\n return {\n parameters: [\n {\n name: parsedResponse.name,\n in: tag.tag.replace(/Param$/, \"\"),\n description: parsedResponse.description,\n required: parsedResponse.required,\n schema: parsedResponse.schema,\n },\n ],\n };\n }\n\n case \"bodyContent\": {\n return {\n requestBody: {\n content: {\n [parsedResponse.name.replace(\"*\\\\/*\", \"*/*\")]: {\n schema: parsedResponse.schema,\n },\n },\n },\n };\n }\n\n case \"bodyExample\": {\n const [contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n requestBody: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n };\n }\n\n case \"bodyDescription\": {\n return { requestBody: { description: nameAndDescription } };\n }\n\n case \"bodyRequired\": {\n return { requestBody: { required: true } };\n }\n\n case \"response\": {\n return {\n responses: {\n [parsedResponse.name]: {\n description: parsedResponse.description,\n },\n },\n };\n }\n\n case \"callback\": {\n return {\n callbacks: {\n [parsedResponse.name]: {\n $ref: `#/components/callbacks/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"responseContent\": {\n const [status, contentType] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeaderComponent\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n $ref: `#/components/headers/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"responseHeader\": {\n const [status, header] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n headers: {\n [header as string]: {\n description: parsedResponse.description,\n schema: parsedResponse.schema,\n },\n },\n },\n },\n };\n }\n\n case \"responseExample\": {\n const [status, contentType, example] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n content: {\n [contentType as string]: {\n examples: {\n [example as string]: {\n $ref: `#/components/examples/${parsedResponse.rawType}`,\n },\n },\n },\n },\n },\n },\n };\n }\n\n case \"responseLink\": {\n const [status, link] = parsedResponse.name.split(\".\");\n\n return {\n responses: {\n [status as string]: {\n links: {\n [link as string]: {\n $ref: `#/components/links/${parsedResponse.rawType}`,\n },\n },\n },\n },\n };\n }\n\n case \"bodyComponent\": {\n return {\n requestBody: {\n $ref: `#/components/requestBodies/${parsedResponse.rawType}`,\n },\n };\n }\n\n case \"responseComponent\": {\n return {\n responses: {\n [parsedResponse.name]: {\n $ref: `#/components/responses/${parsedResponse.rawType}`,\n },\n },\n };\n }\n\n case \"paramComponent\": {\n return {\n parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }],\n };\n }\n\n case \"security\": {\n const [security, scopeItem] = parsedResponse.name.split(\".\");\n\n let scope: string[] = [];\n\n if (scopeItem) {\n scope = [scopeItem];\n }\n\n return {\n security: { [security as string]: scope },\n };\n }\n\n default: {\n return {};\n }\n }\n });\n}\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const openAPIRegex = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \\/.*$/;\n\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments\n .filter((comment) => openAPIRegex.test(comment.description.trim()))\n .map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n fixSecurityObject(result);\n\n const [method, path]: string[] = comment.description.split(\" \");\n\n const pathsObject: PathsObject = {\n [(path as string).trim()]: {\n [(method as string).toLowerCase().trim()]: {\n ...result,\n },\n },\n };\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","const customizer = (objectValue: unknown, sourceValue: Array<unknown>): unknown[] | undefined => {\n if (Array.isArray(objectValue)) {\n return [...objectValue, ...sourceValue];\n }\n // eslint-disable-next-line unicorn/no-useless-undefined\n return undefined;\n};\n\nexport default customizer;\n","import type { Spec } from \"comment-parser\";\nimport { parse as parseComments } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\nimport type { YAMLError } from \"yaml\";\nimport yaml from \"yaml\";\n\nimport type { OpenApiObject } from \"../exported.d\";\nimport customizer from \"../util/customizer\";\nimport organizeSwaggerObject from \"./organize-swagger-object\";\nimport { getSwaggerVersionFromSpec, hasEmptyProperty } from \"./utils\";\n\nconst specificationTemplate = {\n v2: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\"],\n v3: [\"paths\", \"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\"],\n v4: [\"components\", \"channels\"],\n};\n\ntype ExtendedYAMLError = YAMLError & { annotation?: string };\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst tagsToObjects = (specs: Spec[], verbose?: boolean) => specs.map((spec: Spec) => {\n if ((spec.tag === \"openapi\" || spec.tag === \"swagger\" || spec.tag === \"asyncapi\") && spec.description !== \"\") {\n const parsed = yaml.parseDocument(spec.description);\n\n if (parsed.errors.length > 0) {\n // eslint-disable-next-line sonarjs/no-ignored-return\n parsed.errors.map<ExtendedYAMLError>((error) => {\n const newError: ExtendedYAMLError = error;\n\n newError.annotation = spec.description;\n\n return newError;\n });\n\n let errorString = \"Error parsing YAML in @openapi spec:\";\n\n errorString += verbose\n ? (parsed.errors as ExtendedYAMLError[])\n .map((error) => `${error.toString()}\\nImbedded within:\\n\\`\\`\\`\\n ${error.annotation?.replace(/\\n/g, \"\\n \")}\\n\\`\\`\\``)\n .join(\"\\n\")\n : parsed.errors.map((error) => error.toString()).join(\"\\n\");\n\n throw new Error(errorString);\n }\n\n const parsedDocument = parsed.toJSON();\n const specification: Record<string, any> = {\n tags: [],\n };\n\n specificationTemplate[getSwaggerVersionFromSpec(spec)].forEach((property) => {\n specification[property] = specification[property] || {};\n });\n\n Object.keys(parsedDocument).forEach((property) => {\n organizeSwaggerObject(specification, parsedDocument, property);\n });\n\n return specification;\n }\n\n return {};\n});\n\nconst commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {\n const jsDocumentComments = parseComments(fileContents, { spacing: \"preserve\" });\n\n return jsDocumentComments.map((comment) => {\n // Line count, number of tags + 1 for description.\n // - Don't count line-breaking due to long descriptions\n // - Don't count empty lines\n const loc = comment.tags.length + 1;\n const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);\n\n [\"definitions\", \"responses\", \"parameters\", \"securityDefinitions\", \"components\", \"tags\"].forEach((property) => {\n if (result[property] !== undefined && hasEmptyProperty(result[property])) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete result[property];\n }\n });\n\n // Purge all undefined objects/arrays.\n const spec = JSON.parse(JSON.stringify(result));\n\n return {\n spec,\n loc,\n };\n });\n};\n\nexport default commentsToOpenApi;\n","import type { Spec } from \"comment-parser\";\nimport mergeWith from \"lodash.mergewith\";\n\n/**\n * A recursive deep-merge that ignores null values when merging.\n * This returns the merged object and does not mutate.\n * @param {object} first the first object to get merged\n * @param {object} second the second object to get merged\n */\nexport const mergeDeep = (first?: object, second?: object): object => mergeWith({}, first, second, (a, b) => (b === null ? a : undefined));\n\n/**\n * Checks if there is any properties of the input object which are an empty object\n * @param {object} object - the object to check\n * @returns boolean\n */\nexport const hasEmptyProperty = (object: Record<string, any>): boolean => Object.keys(object)\n .map((key) => object[key])\n .every((keyObject) => typeof keyObject === \"object\" && Object.keys(keyObject).every((key) => !(key in keyObject)));\n\n/**\n * @param {object} tag\n * @param {array} tags\n * @returns boolean\n */\nexport const isTagPresentInTags = (tag: Spec, tags: Spec[]): boolean => tags.some((targetTag) => tag.name === targetTag.name);\n\nexport const getSwaggerVersionFromSpec = (tag: Spec): \"v2\" | \"v3\" | \"v4\" => {\n switch (tag.tag) {\n case \"openapi\": {\n return \"v3\";\n }\n case \"asyncapi\": {\n return \"v4\";\n }\n case \"swagger\": {\n return \"v2\";\n }\n default: {\n return \"v2\";\n }\n }\n};\n","import { isTagPresentInTags, mergeDeep } from \"./utils\";\n\n/**\n * @param {object} swaggerObject\n * @param {object} annotation\n * @param {string} property\n */\n// eslint-disable-next-line sonarjs/no-duplicate-string\nconst organizeSwaggerObject = (swaggerObject: Record<string, any>, annotation: Record<string, any>, property: string): void => {\n // Root property on purpose.\n // eslint-disable-next-line no-secrets/no-secrets\n // @see https://github.com/OAI/OpenAPI-Specification/blob/master/proposals/002_Webhooks.md#proposed-solution\n if (property === \"x-webhooks\") {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property] = annotation[property];\n }\n\n // Other extensions can be in varying places depending on different vendors and opinions.\n // The following return makes it so that they are not put in `paths` in the last case.\n // New specific extensions will need to be handled on case-by-case if to be included in `paths`.\n if (property.startsWith(\"x-\")) {\n return;\n }\n\n const commonProperties = [\n \"components\",\n \"consumes\",\n \"produces\",\n \"paths\",\n \"schemas\",\n \"securityDefinitions\",\n \"responses\",\n \"parameters\",\n \"definitions\",\n \"channels\",\n ];\n\n if (commonProperties.includes(property)) {\n Object.keys(annotation[property]).forEach((definition) => {\n // eslint-disable-next-line no-param-reassign\n swaggerObject[property][definition] = mergeDeep(swaggerObject[property][definition], annotation[property][definition]);\n });\n } else if (property === \"tags\") {\n const { tags } = annotation;\n\n if (Array.isArray(tags)) {\n tags.forEach((tag) => {\n if (!isTagPresentInTags(tag, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tag);\n }\n });\n } else if (!isTagPresentInTags(tags, swaggerObject[\"tags\"])) {\n swaggerObject[\"tags\"].push(tags);\n }\n } else if (property === \"security\") {\n const { security } = annotation;\n\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"security\"] = security;\n } else if (property.startsWith(\"/\")) {\n // Paths which are not defined as \"paths\" property, starting with a slash \"/\"\n // eslint-disable-next-line no-param-reassign\n swaggerObject[\"paths\"][property] = mergeDeep(swaggerObject[\"paths\"][property], annotation[property]);\n }\n};\n\nexport default organizeSwaggerObject;\n","import type { ISpectralDiagnostic } from \"@stoplight/spectral-core\";\nimport { Spectral as OASValidator } from \"@stoplight/spectral-core\";\nimport type { IDocument, IParsedResult } from \"@stoplight/spectral-core/dist/document\";\nimport { asyncapi, oas } from \"@stoplight/spectral-rulesets\";\n\nconst validator = new OASValidator();\n\nvalidator.setRuleset({\n // @ts-expect-error: TS2322\n extends: [oas, asyncapi],\n});\n\nconst validate = async (spec: IDocument | IParsedResult | Record<string, unknown> | string): Promise<ISpectralDiagnostic[]> => {\n let title = \"\";\n\n if (typeof spec === \"object\") {\n title = (spec as { info: { title: string } }).info.title;\n } else if (typeof spec === \"string\") {\n title = spec;\n }\n\n return validator\n .run(spec)\n .then((results) => {\n results.forEach((result) => {\n // Ensure there are no errors about no format being matched\n if (result.code === \"unrecognized-format\") {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${result.message}`);\n }\n\n if (result.severity < 1) {\n throw new Error(`Invalid OpenAPI Specification '${title}'. [${result.path.join(\".\")}] ${result.message}`);\n }\n });\n\n return results;\n })\n .catch((error) => {\n throw new Error(`Could not validate OpenAPI Specification '${title}'. ${error.message}`);\n });\n};\n\nexport default validate;\n"]}
|
|
File without changes
|
|
File without changes
|