@visulima/jsdoc-open-api 3.0.0-alpha.4 → 3.0.0-alpha.41

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +371 -0
  2. package/LICENSE.md +35 -1
  3. package/README.md +44 -33
  4. package/bin/index.js +12 -9
  5. package/dist/cli/commander/index.d.ts +996 -3
  6. package/dist/cli/commander/index.js +1 -33
  7. package/dist/cli/index.d.ts +5 -6
  8. package/dist/cli/index.js +1 -17
  9. package/dist/index.d.ts +200 -182
  10. package/dist/index.js +1 -106
  11. package/dist/packem_shared/DEFAULT_OPTIONS-C7o6qjwP.js +1 -0
  12. package/dist/packem_shared/SpecBuilder-Vbq42UbW.js +1 -0
  13. package/dist/packem_shared/SwaggerCompilerPlugin-PUOALp2i.js +1 -0
  14. package/dist/packem_shared/constants-CdEv9ZcD.js +1 -0
  15. package/dist/packem_shared/customizer-BXFVpImq.js +1 -0
  16. package/dist/packem_shared/generateCommand-C_XPsbS6.js +5 -0
  17. package/dist/packem_shared/generateCommand-ClL9Mnc3.js +1 -0
  18. package/dist/packem_shared/initCommand-Ca1hGdYS.js +35 -0
  19. package/dist/packem_shared/initCommand-TixxsVQU.js +1 -0
  20. package/dist/packem_shared/jsDocumentCommentsToOpenApi-TjPhUj5G.js +1 -0
  21. package/dist/packem_shared/loadDefinition-7r9qpfuE.js +1 -0
  22. package/dist/packem_shared/parseFile-RDlR4tEF.js +1 -0
  23. package/dist/packem_shared/swaggerJsDocumentCommentsToOpenApi-Bm9R1BnW.js +10 -0
  24. package/dist/packem_shared/validate-9Rwe2A3r.js +1 -0
  25. package/dist/packem_shared/yamlLoc-DPq-xUM4.js +1 -0
  26. package/package.json +38 -45
  27. package/dist/chunk-2T6HMUIL.mjs +0 -1215
  28. package/dist/chunk-2T6HMUIL.mjs.map +0 -1
  29. package/dist/chunk-PTFTJY7I.js +0 -1233
  30. package/dist/chunk-PTFTJY7I.js.map +0 -1
  31. package/dist/chunk-RGP6RTJO.mjs +0 -142
  32. package/dist/chunk-RGP6RTJO.mjs.map +0 -1
  33. package/dist/chunk-RVCK3H3U.js +0 -149
  34. package/dist/chunk-RVCK3H3U.js.map +0 -1
  35. package/dist/cli/commander/index.d.mts +0 -7
  36. package/dist/cli/commander/index.js.map +0 -1
  37. package/dist/cli/commander/index.mjs +0 -30
  38. package/dist/cli/commander/index.mjs.map +0 -1
  39. package/dist/cli/index.d.mts +0 -10
  40. package/dist/cli/index.js.map +0 -1
  41. package/dist/cli/index.mjs +0 -4
  42. package/dist/cli/index.mjs.map +0 -1
  43. package/dist/index.d.mts +0 -248
  44. package/dist/index.js.map +0 -1
  45. package/dist/index.mjs +0 -85
  46. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,5 @@
1
+ import{mkdir as D,writeFile as b,lstat as E,realpath as O}from"node:fs/promises";import{dirname as S,extname as _,normalize as F}from"node:path";import{stdout as U}from"node:process";import{pathToFileURL as x}from"node:url";import{collect as L}from"@visulima/fs";import{MultiBar as N,Presets as j}from"cli-progress";import R from"yaml";import{D as k}from"./constants-CdEv9ZcD.js";import C from"./jsDocumentCommentsToOpenApi-TjPhUj5G.js";import{parseFileMulti as g}from"./parseFile-RDlR4tEF.js";import M from"./SpecBuilder-Vbq42UbW.js";import V from"./swaggerJsDocumentCommentsToOpenApi-Bm9R1BnW.js";import P from"./loadDefinition-7r9qpfuE.js";import T from"./validate-9Rwe2A3r.js";const A=new Set([".yaml",".yml"]),u="-",p=[C,V],J=async t=>{try{let e=await import(x(F(t)).href);return e?.default&&(e=e.default),e}catch(e){if(e?.code==="ERR_MODULE_NOT_FOUND"||e?.code==="MODULE_NOT_FOUND"||e?.code==="ERR_LOAD_URL")throw new Error(`No config file found, on: ${t}
2
+ `,{cause:e});const o=e instanceof Error?e.message:String(e);throw new Error(`Failed to load config file "${t}": ${o}`,{cause:e})}},z=async(t,e,o)=>{const r=await J(o.config??t),i=o.definition??r.definition;let{swaggerDefinition:c}=r;i&&(c={...P(i),...c});const f=o.output===u?void 0:new N({clearOnComplete:!1,format:"{value}/{total} | {bar} | {filename}",hideCursor:!0},j.shades_grey),s=new M(c),w=new Set([...k,...r.exclude]);for(const m of e){const y=(await E(m)).isDirectory(),a=await O(m);if(!y){s.addData(g(a,p,o.verbose).map(l=>l.spec));continue}const n=await L(a,{extensions:r.extensions??[".js",".cjs",".mjs",".ts",".tsx",".jsx",".yaml",".yml"],followSymlinks:r.followSymlinks??!1,match:r.include,skip:[...w]});(o.verbose??o.veryVerbose)&&console.log(`
3
+ Found ${String(n.length)} files in ${a}`),o.veryVerbose&&console.log(n);const h=f?.create(n.length,0);n.forEach(l=>{o.verbose&&console.log(`Parsing file ${l}`),h?.increment(1,{filename:a}),s.addData(g(l,p,o.verbose).map(v=>v.spec))})}return o.verbose&&console.log("Validating swagger spec"),o.veryVerbose&&console.log(JSON.stringify(s,void 0,2)),await T(structuredClone(s)),f?.stop(),s},d=(t,e)=>A.has(_(e))?R.stringify(structuredClone(t)):JSON.stringify(t,void 0,2),te=async(t,e,o)=>{const r=await z(t,e,o),i=o.output??"swagger.json";if(i===u){U.write(`${d(r,"swagger.json")}
4
+ `);return}o.verbose&&console.log(`Written swagger spec to "${i}" file`),await D(S(i),{recursive:!0}),await b(i,d(r,i)),console.log(`
5
+ Swagger specification is ready, check the "${i}" file.`)};export{te as default};
@@ -0,0 +1 @@
1
+ import{watch as u}from"node:fs";import s,{exit as p}from"node:process";import f from"./generateCommand-C_XPsbS6.js";const c=o=>{console.error(o)},h=async(o,a,r)=>{const e=async()=>{await f(o,a,r)},t=a.map(i=>u(i,{recursive:!0},()=>{e().catch(c)})),n=()=>{t.forEach(i=>{i.close()}),p(0)};s.once("SIGINT",n),s.once("SIGTERM",n);try{await e()}catch(i){c(i)}console.log("Watching for changes... (press Ctrl+C to exit)")},d=(o,a="generate",r=".openapirc.js")=>{o.command(a).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("-d, --definition [definition.yaml]","Base OpenAPI definition file (YAML/JSON) to seed info/servers/components.").option("-o, --output [swaggerSpec.json]",'Output swagger specification. Use "-" to write to stdout, or a .yaml/.yml path for YAML output.').option("-w, --watch","Re-generate the specification whenever a watched path changes.").option("-v, --verbose","Verbose output.").option("--very-verbose","Very verbose output.").action(async(e,t)=>{if(t.watch){await h(r,e,t);return}try{await f(r,e,t)}catch(n){c(n),p(1)}})};export{d as default};
@@ -0,0 +1,35 @@
1
+ import{existsSync as t,realpathSync as c,writeFileSync as l}from"node:fs";import{findUpSync as i,readJsonSync as r}from"@visulima/fs";const j=(e,a=process.cwd())=>{if(t(e))throw new Error("Config file already exists");const o=i("package.json",{cwd:c(a)});let s="module.exports =";if(o){const n=r(o);console.info(`Found package.json at "${o}"`),n.type==="module"&&(console.info("Found package.json with type: module, using ES6 as export for the config file"),s="export default")}else console.info("No package.json found");l(e,`${s} {
2
+ exclude: [
3
+ 'coverage/**',
4
+ '.github/**',
5
+ 'packages/*/test{,s}/**',
6
+ '**/*.d.ts',
7
+ 'test{,s}/**',
8
+ 'test{,-*}.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}',
9
+ '**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}',
10
+ '**/__tests__/**',
11
+ '**/{ava,babel,nyc}.config.{js,cjs,mjs}',
12
+ '**/jest.config.{js,cjs,mjs,ts}',
13
+ '**/{karma,rollup,webpack}.config.js',
14
+ '**/.{eslint,mocha}rc.{js,cjs}',
15
+ '**/.{travis,yarnrc}.yml',
16
+ '**/{docker-compose,docker}.yml',
17
+ '**/.yamllint.{yaml,yml}',
18
+ '**/node_modules/**',
19
+ '**/pnpm-lock.yaml',
20
+ '**/pnpm-workspace.yaml',
21
+ '**/{package,package-lock}.json',
22
+ '**/yarn.lock',
23
+ '**/package.json5',
24
+ '**/.next/**',
25
+ ],
26
+ followSymlinks: false,
27
+ swaggerDefinition: {
28
+ openapi: '3.0.0',
29
+ info: {
30
+ title: 'API',
31
+ version: '1.0.0',
32
+ },
33
+ },
34
+ };
35
+ `),console.log(`Created "${e}"`)};export{j as default};
@@ -0,0 +1 @@
1
+ import{exit as c}from"node:process";import e from"./initCommand-Ca1hGdYS.js";const s=(o,i="init",r="Inits a pre-configured @visulima/jsdoc-open-api config file.",n=".openapirc.js")=>{o.command(i).description(r).action(()=>{try{e(n)}catch(t){console.error(t),c(1)}})};export{s as default};
@@ -0,0 +1 @@
1
+ import{parse as d}from"comment-parser";import{mergeWith as l}from"es-toolkit";import{u as y}from"./customizer-BXFVpImq.js";const f=/\[\]$/,b=/^- /u,$=/Param$/u,g=/^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \/.*$/,h=t=>{t.security&&(t.security=Object.keys(t.security).map(o=>({[o]:t.security[o]})))},T=new Set(["array","boolean","integer","number","object","string"]),m={binary:"string",byte:"string",date:"string","date-time":"string",double:"number",float:"number",int32:"integer",int64:"integer",password:"string"},w=t=>{const o=t.type,c=o.endsWith("[]"),e=o.replace(f,""),n=T.has(e),r=Object.keys(m).includes(e);let s;if(t.default)switch(e){case"double":case"float":case"number":{s=Number.parseFloat(t.default);break}case"int32":case"int64":case"integer":{s=Number.parseInt(t.default,10);break}default:{s=t.default;break}}let a;n?a={default:s,type:e}:r?a={default:s,format:e,type:m[e]}:a={$ref:`#/components/schemas/${e}`};let p=c?{items:{...a},type:"array"}:{...a};e===""&&(p=void 0);let i=t.description.trim().replace(b,"");return i===""&&(i=void 0),{description:i,name:t.name,rawType:o,required:!t.optional,schema:p}},k=(t,o)=>t.map(c=>{const e=w(c);let n="";switch(e.name&&(n+=e.name),e.description&&(n+=` ${e.description.trim()}`),c.tag){case"bodyComponent":return{requestBody:{$ref:`#/components/requestBodies/${e.rawType}`}};case"bodyContent":return{requestBody:{content:{[e.name.replaceAll(String.raw`*\/*`,"*/*")]:{schema:e.schema}}}};case"bodyDescription":return{requestBody:{description:n}};case"bodyExample":{const[r,s]=e.name.split(".");return{requestBody:{content:{[r]:{examples:{[s]:{$ref:`#/components/examples/${e.rawType}`}}}}}}}case"bodyRequired":return{requestBody:{required:!0}};case"callback":return{callbacks:{[e.name]:{$ref:`#/components/callbacks/${e.rawType}`}}};case"cookieParam":case"headerParam":case"pathParam":case"queryParam":return{parameters:[{description:e.description,in:c.tag.replace($,""),name:e.name,required:e.required,schema:e.schema}]};case"deprecated":return{deprecated:!0};case"description":case"operationId":case"summary":return{[c.tag]:n};case"externalDocs":return{externalDocs:{description:e.description,url:e.name}};case"paramComponent":return{parameters:[{$ref:`#/components/parameters/${e.rawType}`}]};case"response":return{responses:{[e.name]:{description:e.description}}};case"responseComponent":return{responses:{[e.name]:{$ref:`#/components/responses/${e.rawType}`}}};case"responseContent":{const[r,s]=e.name.split(".");return{responses:{[r]:{content:{[s]:{schema:e.schema}}}}}}case"responseExample":{const[r,s,a]=e.name.split(".");return{responses:{[r]:{content:{[s]:{examples:{[a]:{$ref:`#/components/examples/${e.rawType}`}}}}}}}}case"responseHeader":{const[r,s]=e.name.split(".");return{responses:{[r]:{headers:{[s]:{description:e.description,schema:e.schema}}}}}}case"responseHeaderComponent":{const[r,s]=e.name.split(".");return{responses:{[r]:{headers:{[s]:{$ref:`#/components/headers/${e.rawType}`}}}}}}case"responseLink":{const[r,s]=e.name.split(".");return{responses:{[r]:{links:{[s]:{$ref:`#/components/links/${e.rawType}`}}}}}}case"security":{const[r,s]=e.name.split(".");let a=[];return s&&(a=[s]),{security:{[r]:a}}}case"server":return{servers:[{description:e.description,url:e.name}]};case"tag":return{tags:[n]};default:return{}}}),C=(t,o,c)=>(c??d(t,{spacing:"preserve"})).filter(e=>g.test(e.description.trim())).map(e=>{const n=e.tags.length+1,r={};for(const u of k(e.tags))l(r,u,y);h(r);const[s,a]=e.description.split(" "),p={[a.trim()]:{[s.toLowerCase().trim()]:{...r}}},i=JSON.parse(JSON.stringify({paths:p}));return{loc:n,spec:i}});export{C as default};
@@ -0,0 +1 @@
1
+ import{readFileSync as n}from"node:fs";import t from"node:path";import m from"yaml";const s=o=>{const r=t.extname(o);if(r!==".yaml"&&r!==".yml"&&r!==".json")throw new Error("OpenAPI definition path must be YAML or JSON.");const e=n(o,{encoding:"utf8"});return r===".yaml"||r===".yml"?m.parse(e):JSON.parse(e)};export{s as default};
@@ -0,0 +1 @@
1
+ import{readFileSync as f}from"node:fs";import p from"node:path";import{parse as u}from"comment-parser";import y from"yaml";import d from"./yamlLoc-DPq-xUM4.js";const i=new Set(["components","externalDocs","info","openapi","paths","security","servers","tags"]);class g extends Error{filePath}const l=new Set([".yaml",".yml"]),h=(t,o)=>{const r=y.parse(o);if(r===null||typeof r!="object")return[];const n=Object.keys(r).filter(e=>!i.has(e));if(n.length>0){const e=new g(`Unexpected keys: ${n.join(", ")}`);throw e.filePath=t,e}return Object.keys(r).some(e=>i.has(e))?[{loc:d(o),spec:r}]:[]},k=(t,o,r)=>{const n=f(t,{encoding:"utf8"}),e=p.extname(t);if(l.has(e))return h(t,n);try{return o(n,r)}catch(s){throw s.filePath=t,s}},O=(t,o,r)=>{const n=f(t,{encoding:"utf8"}),e=p.extname(t);if(l.has(e))return h(t,n);const s=u(n,{spacing:"preserve"}),c=[];for(const m of o)try{c.push(...m(n,r,s))}catch(a){throw a.filePath=t,a}return c};export{k as default,O as parseFileMulti};
@@ -0,0 +1,10 @@
1
+ import{parse as f}from"comment-parser";import{mergeWith as m}from"es-toolkit";import y from"yaml";import{u as l}from"./customizer-BXFVpImq.js";const g=(s,t)=>{if(t===null)return s},h=(s,t)=>{const e=m({},s??{},g);return m(e,t??{},g)},d=s=>Object.keys(s).map(t=>s[t]).every(t=>typeof t=="object"&&Object.keys(t).every(e=>!(e in t))),u=(s,t)=>t.some(e=>s.name===e.name),v=s=>{switch(s.tag){case"asyncapi":return"v4";case"openapi":return"v3";case"swagger":return"v2";default:return"v2"}},w=(s,t,e)=>{if(e==="x-webhooks"&&(s[e]=t[e]),!e.startsWith("x-"))if(["components","consumes","produces","paths","schemas","securityDefinitions","responses","parameters","definitions","channels"].includes(e))Object.keys(t[e]).forEach(r=>{s[e][r]=h(s[e][r],t[e][r])});else if(e==="tags"){const{tags:r}=t;Array.isArray(r)?r.forEach(n=>{u(n,s.tags)||s.tags.push(n)}):u(r,s.tags)||s.tags.push(r)}else if(e==="security"){const{security:r}=t;s.security=r}else e.startsWith("/")&&(s.paths[e]=h(s.paths[e],t[e]))},E={v2:["paths","definitions","responses","parameters","securityDefinitions"],v3:["paths","definitions","responses","parameters","securityDefinitions","components"],v4:["components","channels"]},S=(s,t)=>s.map(e=>{const r=e.description!==""||e.name.startsWith("/")||e.name.endsWith(":");if((e.tag==="openapi"||e.tag==="swagger"||e.tag==="asyncapi")&&r){let n=e.description;(e.name.startsWith("/")||e.name.endsWith(":"))&&(n=n.trim()===""?e.name:`${e.name}
2
+ ${n}`);const a=y.parseDocument(n);if(a.errors.length>0){a.errors.forEach(p=>{p.annotation=n});let i="Error parsing YAML in @openapi spec:";throw i+=t?a.errors.map(p=>`${p.toString()}
3
+ Imbedded within:
4
+ \`\`\`
5
+ ${p.annotation?.replaceAll(`
6
+ `,`
7
+ `)}
8
+ \`\`\``).join(`
9
+ `):a.errors.map(p=>p.toString()).join(`
10
+ `),new Error(i)}const c=a.toJSON(),o={tags:[]};return E[v(e)].forEach(i=>{o[i]=o[i]??{}}),Object.keys(c).forEach(i=>{w(o,c,i)}),o}return{}}),O=new Set(["asyncapi","openapi","swagger"]),k=(s,t,e)=>(e??f(s,{spacing:"preserve"})).filter(r=>r.tags.some(n=>O.has(n.tag))).map(r=>{const n=r.tags.length+1,a={};for(const o of S(r.tags,t))m(a,o,l);["definitions","responses","parameters","securityDefinitions","components","tags"].forEach(o=>{a[o]!==void 0&&d(a[o])&&delete a[o]});const c=JSON.parse(JSON.stringify(a));return{loc:n,spec:c}});export{k as default};
@@ -0,0 +1 @@
1
+ import t from"@apidevtools/swagger-parser";const e=async a=>{await t.validate(a)};export{e as default};
@@ -0,0 +1 @@
1
+ const s=/\r\n|\r|\n/u,l=/^\s*(#\s*(?:\S.*)?)?$/u,n=e=>e.split(s).filter(t=>l.test(t)?!1:t.trim().length>0).length;export{n as default};
package/package.json CHANGED
@@ -1,23 +1,21 @@
1
1
  {
2
2
  "name": "@visulima/jsdoc-open-api",
3
- "version": "3.0.0-alpha.4",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Generates swagger doc based on JSDoc.",
5
5
  "keywords": [
6
- "visulima",
6
+ "api",
7
+ "cli",
8
+ "command",
9
+ "comment",
7
10
  "javascript",
11
+ "jsdoc",
8
12
  "openapi",
9
13
  "swagger",
10
- "jsdoc",
11
- "comment",
12
- "api",
13
- "webpack",
14
- "cli",
15
- "command"
14
+ "visulima",
15
+ "webpack"
16
16
  ],
17
- "homepage": "https://www.visulima.com/docs/package/jsdoc-open-api",
18
- "bugs": {
19
- "url": "https://github.com/visulima/visulima/issues"
20
- },
17
+ "homepage": "https://visulima.com/packages/jsdoc-open-api/",
18
+ "bugs": "https://github.com/visulima/visulima/issues",
21
19
  "repository": {
22
20
  "type": "git",
23
21
  "url": "https://github.com/visulima/visulima.git",
@@ -39,42 +37,37 @@
39
37
  "email": "d.bannert@anolilab.de"
40
38
  },
41
39
  "sideEffects": false,
40
+ "type": "module",
42
41
  "exports": {
43
42
  ".": {
44
- "require": {
45
- "types": "./dist/index.d.ts",
46
- "default": "./dist/index.js"
47
- },
48
- "import": {
49
- "types": "./dist/index.d.mts",
50
- "default": "./dist/index.mjs"
51
- }
43
+ "types": "./dist/index.d.ts",
44
+ "default": "./dist/index.js"
52
45
  },
53
46
  "./cli": {
54
- "require": {
55
- "types": "./dist/cli/index.d.ts",
56
- "default": "./dist/cli/index.js"
57
- },
58
- "import": {
59
- "types": "./dist/cli/index.d.mts",
60
- "default": "./dist/cli/index.mjs"
61
- }
47
+ "types": "./dist/cli/index.d.ts",
48
+ "default": "./dist/cli/index.js"
62
49
  },
63
50
  "./cli/commander": {
64
- "require": {
65
- "types": "./dist/cli/commander/index.d.ts",
66
- "default": "./dist/cli/commander/index.js"
67
- },
68
- "import": {
69
- "types": "./dist/cli/commander/index.d.mts",
70
- "default": "./dist/cli/commander/index.mjs"
71
- }
51
+ "types": "./dist/cli/commander/index.d.ts",
52
+ "default": "./dist/cli/commander/index.js"
72
53
  },
73
54
  "./package.json": "./package.json"
74
55
  },
75
- "main": "dist/index.js",
76
- "module": "dist/index.mjs",
56
+ "module": "dist/index.js",
77
57
  "types": "dist/index.d.ts",
58
+ "typesVersions": {
59
+ ">=5.0": {
60
+ ".": [
61
+ "./dist/index.d.ts"
62
+ ],
63
+ "cli": [
64
+ "./dist/cli/index.d.ts"
65
+ ],
66
+ "cli/commander": [
67
+ "./dist/cli/commander/index.d.ts"
68
+ ]
69
+ }
70
+ },
78
71
  "bin": {
79
72
  "jsdoc-open-api": "./bin/index.js"
80
73
  },
@@ -88,18 +81,18 @@
88
81
  ],
89
82
  "dependencies": {
90
83
  "@apidevtools/swagger-parser": "^12.1.0",
91
- "comment-parser": "^1.4.3",
92
- "lodash.mergewith": "^4.6.2",
93
- "read-pkg-up": "^7.0.1",
94
- "yaml": "^2.8.2"
84
+ "@visulima/fs": "5.0.0-alpha.33",
85
+ "comment-parser": "1.4.7",
86
+ "es-toolkit": "^1.47.1",
87
+ "yaml": "2.9.0"
95
88
  },
96
89
  "optionalDependencies": {
97
90
  "cli-progress": "^3.12.0",
98
- "commander": "^14.0.2",
99
- "webpack": "^5.104.1"
91
+ "commander": "^15.0.0",
92
+ "webpack": "^5.107.2"
100
93
  },
101
94
  "engines": {
102
- "node": ">=22.13 <=25.x"
95
+ "node": "^22.14.0 || >=24.10.0"
103
96
  },
104
97
  "os": [
105
98
  "darwin",