xypriss-swagger 1.0.11 → 1.0.13
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/README.md +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/openapi.js +1 -1
- package/dist/cjs/openapi.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/openapi.js +1 -1
- package/dist/esm/openapi.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/package.json +4 -2
- package/src/index.ts +2 -3
- package/src/openapi.ts +25 -9
package/README.md
CHANGED
|
@@ -27,6 +27,9 @@ This module is designed to be loaded natively by the XyPriss plugin manager. Ens
|
|
|
27
27
|
}
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
> [!NOTE]
|
|
31
|
+
> For a deep dive into how XyPriss manages plugin isolation and filesystem access, see the [Workspace System Guide](../core/WORKSPACE_SYSTEM.md).
|
|
32
|
+
|
|
30
33
|
## Security & Permissions
|
|
31
34
|
|
|
32
35
|
In order to properly analyze your project's codebase and generate accurate Swagger documentation, this plugin requires the `CWD://` (Current Working Directory) context permission.
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/index.ts"],"sourcesContent":["import { logger, Logger } from \"./configs/Logger\";\nimport { meta, toPascalCase } from \"./configs/meta\";\nimport { SwaggerServer } from \"./server\";\nimport { SwaggerConfig } from \"./types\";\nimport { Plugin } from \"xypriss\";\n\n// console.log(\"[swagger] internal plugin sys\", __sys__.__root__);\n\nconst pluginName = toPascalCase(meta.name);\nexport function SwaggerPlugin(config: SwaggerConfig)
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/index.ts"],"sourcesContent":["import { logger, Logger } from \"./configs/Logger\";\nimport { meta, toPascalCase } from \"./configs/meta\";\nimport { SwaggerServer } from \"./server\";\nimport { SwaggerConfig } from \"./types\";\nimport { Plugin } from \"xypriss\";\n\n// console.log(\"[swagger] internal plugin sys\", __sys__.__root__);\n\nconst pluginName = toPascalCase(meta.name);\nexport function SwaggerPlugin(config: SwaggerConfig) {\n return Plugin.create(\n {\n name: meta.name,\n version: meta.version,\n description: meta.description,\n onRegister(_error) {\n const log = Logger.for(\"Bootstrap\");\n log.info(\"Starting swagger plugin...\");\n if (_error) {\n log.error(pluginName + \" plugin failed to start:\", _error);\n }\n },\n onServerStart(server) {\n logger.success(pluginName + \" plugin has started\");\n\n server.app.get(\"/swagger\", (_req: any, res: any) => {\n res.redirect(`http://localhost:${config.port}`);\n });\n },\n onAuxiliaryServerDeploy(ops, server) {\n SwaggerServer(config, ops, server);\n },\n }, \n __sys__.__root__,\n );\n}\n\n"],"names":["pluginName","toPascalCase","meta","name","config","Plugin","create","version","description","onRegister","_error","log","Logger","for","info","error","onServerStart","server","logger","success","app","get","_req","res","redirect","port","onAuxiliaryServerDeploy","ops","SwaggerServer","__sys__","__root__"],"mappings":"+HAQA,MAAMA,EAAaC,EAAAA,aAAaC,EAAAA,KAAKC,4BAC/B,SAAwBC,GAC1B,OAAOC,EAAAA,OAAOC,OACV,CACIH,KAAMD,EAAAA,KAAKC,KACXI,QAASL,EAAAA,KAAKK,QACdC,YAAaN,EAAAA,KAAKM,YAClB,UAAAC,CAAWC,GACP,MAAMC,EAAMC,EAAAA,OAAOC,IAAI,aACvBF,EAAIG,KAAK,8BACLJ,GACAC,EAAII,MAAMf,EAAa,2BAA4BU,EAE3D,EACA,aAAAM,CAAcC,GACVC,SAAOC,QAAQnB,EAAa,uBAE5BiB,EAAOG,IAAIC,IAAI,WAAY,CAACC,EAAWC,KACnCA,EAAIC,SAAS,oBAAoBpB,EAAOqB,SAEhD,EACA,uBAAAC,CAAwBC,EAAKV,GACzBW,EAAAA,cAAcxB,EAAQuB,EAC1B,GAEJE,QAAQC,SAEhB"}
|
package/dist/cjs/openapi.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("./configs/meta.js");exports.generateOpenAPI=function(t,s){const a={openapi:e.meta.version,info:{title:__sys__.vars.__name__||s.title||"XyPriss API Documentation",version:s.version||"1.0.0",description:s.description||e.meta.description},paths:{},components:{securitySchemes:{BearerAuth:{type:"http",scheme:"bearer"}}}};for(const e of t){if(!e.path||!e.method)continue;const t=e.path.replace(/:([a-zA-Z0-9_]+)(
|
|
1
|
+
"use strict";var e=require("./configs/meta.js");exports.generateOpenAPI=function(t,s){const a={openapi:e.meta.version,info:{title:__sys__.vars.__name__||s.title||"XyPriss API Documentation",version:s.version||"1.0.0",description:s.description||e.meta.description},paths:{},components:{securitySchemes:{BearerAuth:{type:"http",scheme:"bearer"}}}};for(const e of t){if(!e.path||!e.method)continue;const t=e.path.replace(/:([a-zA-Z0-9_]+)(?:<[^>]+>)?(?:\([^)]+\))?/g,"{$1}");a.paths[t]||(a.paths[t]={});const s=(Array.isArray(e.method)?e.method[0]:e.method).toLowerCase(),r={summary:e.meta?.summary||`${e.method} ${e.path}`,description:e.meta?.description||"",tags:e.meta?.tags||["Default"],parameters:[],responses:e.responses||{200:{description:"Successful response"}}};if(e.hasGuards&&(r.security=[{BearerAuth:[]}]),e.paramNames&&e.paramNames.length>0)for(const t of e.paramNames){const s=e.paramConstraints?.[t];let a,n="string";s&&("number"===s.type||"integer"===s.type?n="number":"boolean"===s.type?n="boolean":"regex"===s.type&&"string"==typeof s.options?a=s.options:"uuid"===s.type&&(a="^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")),r.parameters.push({name:t,in:"path",required:!0,schema:{type:n,pattern:a}})}e.meta?.openapi&&Object.assign(r,e.meta.openapi),a.paths[t][s]=r}return a};
|
|
2
2
|
//# sourceMappingURL=openapi.js.map
|
package/dist/cjs/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sources":["../../../../src/openapi.ts"],"sourcesContent":["import { meta } from \"./configs/meta\";\n\nexport interface OpenAPIConfig {\n openapi: string;\n info: {\n title: string;\n version: string;\n description?: string;\n };\n paths: Record<string, any>;\n components: {\n securitySchemes?: Record<string, any>;\n };\n}\n\nexport function generateOpenAPI(registry: any[], config: any): OpenAPIConfig {\n const doc: OpenAPIConfig = {\n openapi: meta.version,\n info: {\n title:\n __sys__.vars.__name__ ||\n config.title ||\n \"XyPriss API Documentation\",\n version: config.version || \"1.0.0\",\n description: config.description || meta.description,\n },\n paths: {},\n components: {\n securitySchemes: {\n BearerAuth: {\n type: \"http\",\n scheme: \"bearer\",\n },\n },\n },\n };\n\n for (const route of registry) {\n if (!route.path || !route.method) continue;\n\n // Convert Express-like path /users/:id to Swagger-like path /users/{id}\n const openApiPath = route.path.replace(\n /:([a-zA-Z0-9_]+)(
|
|
1
|
+
{"version":3,"file":"openapi.js","sources":["../../../../src/openapi.ts"],"sourcesContent":["import { meta } from \"./configs/meta\";\n\nexport interface OpenAPIConfig {\n openapi: string;\n info: {\n title: string;\n version: string;\n description?: string;\n };\n paths: Record<string, any>;\n components: {\n securitySchemes?: Record<string, any>;\n };\n}\n\nexport function generateOpenAPI(registry: any[], config: any): OpenAPIConfig {\n const doc: OpenAPIConfig = {\n openapi: meta.version,\n info: {\n title:\n __sys__.vars.__name__ ||\n config.title ||\n \"XyPriss API Documentation\",\n version: config.version || \"1.0.0\",\n description: config.description || meta.description,\n },\n paths: {},\n components: {\n securitySchemes: {\n BearerAuth: {\n type: \"http\",\n scheme: \"bearer\",\n },\n },\n },\n };\n\n for (const route of registry) {\n if (!route.path || !route.method) continue;\n\n // Convert Express-like path /users/:id to Swagger-like path /users/{id}\n // Handles: :id, :id<number>, :id(\\d+)\n const openApiPath = route.path.replace(\n /:([a-zA-Z0-9_]+)(?:<[^>]+>)?(?:\\([^)]+\\))?/g,\n \"{$1}\",\n );\n\n if (!doc.paths[openApiPath]) {\n doc.paths[openApiPath] = {};\n }\n\n const methodStr = (\n Array.isArray(route.method) ? route.method[0] : route.method\n ).toLowerCase();\n\n // Base operation object\n const operation: any = {\n summary: route.meta?.summary || `${route.method} ${route.path}`,\n description: route.meta?.description || \"\",\n tags: route.meta?.tags || [\"Default\"],\n parameters: [],\n responses: route.responses || {\n \"200\": {\n description: \"Successful response\",\n },\n },\n };\n\n // If guards are detected, optionally assume it requires Auth\n if (route.hasGuards) {\n operation.security = [{ BearerAuth: [] }];\n }\n\n // Add Path Parameters\n if (route.paramNames && route.paramNames.length > 0) {\n for (const param of route.paramNames) {\n const constraint = route.paramConstraints?.[param];\n let type = \"string\";\n let pattern: string | undefined = undefined;\n\n if (constraint) {\n if (\n constraint.type === \"number\" ||\n constraint.type === \"integer\"\n ) {\n type = \"number\";\n } else if (constraint.type === \"boolean\") {\n type = \"boolean\";\n } else if (\n constraint.type === \"regex\" &&\n typeof constraint.options === \"string\"\n ) {\n pattern = constraint.options;\n } else if (constraint.type === \"uuid\") {\n pattern =\n \"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$\";\n }\n }\n\n operation.parameters.push({\n name: param,\n in: \"path\",\n required: true,\n schema: {\n type,\n pattern,\n },\n });\n }\n }\n\n // Add additional meta (like requestBody, query params) if defined by user within meta.openapi\n if (route.meta?.openapi) {\n Object.assign(operation, route.meta.openapi);\n }\n\n doc.paths[openApiPath][methodStr] = operation;\n }\n\n return doc;\n}\n\n"],"names":["registry","config","doc","openapi","meta","version","info","title","__sys__","vars","__name__","description","paths","components","securitySchemes","BearerAuth","type","scheme","route","path","method","openApiPath","replace","methodStr","Array","isArray","toLowerCase","operation","summary","tags","parameters","responses","hasGuards","security","paramNames","length","param","constraint","paramConstraints","pattern","options","push","name","in","required","schema","Object","assign"],"mappings":"wEAeM,SAA0BA,EAAiBC,GAC7C,MAAMC,EAAqB,CACvBC,QAASC,EAAAA,KAAKC,QACdC,KAAM,CACFC,MACIC,QAAQC,KAAKC,UACbT,EAAOM,OACP,4BACJF,QAASJ,EAAOI,SAAW,QAC3BM,YAAaV,EAAOU,aAAeP,EAAAA,KAAKO,aAE5CC,MAAO,CAAA,EACPC,WAAY,CACRC,gBAAiB,CACbC,WAAY,CACRC,KAAM,OACNC,OAAQ,aAMxB,IAAK,MAAMC,KAASlB,EAAU,CAC1B,IAAKkB,EAAMC,OAASD,EAAME,OAAQ,SAIlC,MAAMC,EAAcH,EAAMC,KAAKG,QAC3B,8CACA,QAGCpB,EAAIU,MAAMS,KACXnB,EAAIU,MAAMS,GAAe,CAAA,GAG7B,MAAME,GACFC,MAAMC,QAAQP,EAAME,QAAUF,EAAME,OAAO,GAAKF,EAAME,QACxDM,cAGIC,EAAiB,CACnBC,QAASV,EAAMd,MAAMwB,SAAW,GAAGV,EAAME,UAAUF,EAAMC,OACzDR,YAAaO,EAAMd,MAAMO,aAAe,GACxCkB,KAAMX,EAAMd,MAAMyB,MAAQ,CAAC,WAC3BC,WAAY,GACZC,UAAWb,EAAMa,WAAa,CAC1B,IAAO,CACHpB,YAAa,yBAWzB,GALIO,EAAMc,YACNL,EAAUM,SAAW,CAAC,CAAElB,WAAY,MAIpCG,EAAMgB,YAAchB,EAAMgB,WAAWC,OAAS,EAC9C,IAAK,MAAMC,KAASlB,EAAMgB,WAAY,CAClC,MAAMG,EAAanB,EAAMoB,mBAAmBF,GAC5C,IACIG,EADAvB,EAAO,SAGPqB,IAEwB,WAApBA,EAAWrB,MACS,YAApBqB,EAAWrB,KAEXA,EAAO,SACoB,YAApBqB,EAAWrB,KAClBA,EAAO,UAEa,UAApBqB,EAAWrB,MACmB,iBAAvBqB,EAAWG,QAElBD,EAAUF,EAAWG,QACM,SAApBH,EAAWrB,OAClBuB,EACI,mEAIZZ,EAAUG,WAAWW,KAAK,CACtBC,KAAMN,EACNO,GAAI,OACJC,UAAU,EACVC,OAAQ,CACJ7B,OACAuB,YAGZ,CAIArB,EAAMd,MAAMD,SACZ2C,OAAOC,OAAOpB,EAAWT,EAAMd,KAAKD,SAGxCD,EAAIU,MAAMS,GAAaE,GAAaI,CACxC,CAEA,OAAOzB,CACX"}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/index.ts"],"sourcesContent":["import { logger, Logger } from \"./configs/Logger\";\nimport { meta, toPascalCase } from \"./configs/meta\";\nimport { SwaggerServer } from \"./server\";\nimport { SwaggerConfig } from \"./types\";\nimport { Plugin } from \"xypriss\";\n\n// console.log(\"[swagger] internal plugin sys\", __sys__.__root__);\n\nconst pluginName = toPascalCase(meta.name);\nexport function SwaggerPlugin(config: SwaggerConfig)
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/index.ts"],"sourcesContent":["import { logger, Logger } from \"./configs/Logger\";\nimport { meta, toPascalCase } from \"./configs/meta\";\nimport { SwaggerServer } from \"./server\";\nimport { SwaggerConfig } from \"./types\";\nimport { Plugin } from \"xypriss\";\n\n// console.log(\"[swagger] internal plugin sys\", __sys__.__root__);\n\nconst pluginName = toPascalCase(meta.name);\nexport function SwaggerPlugin(config: SwaggerConfig) {\n return Plugin.create(\n {\n name: meta.name,\n version: meta.version,\n description: meta.description,\n onRegister(_error) {\n const log = Logger.for(\"Bootstrap\");\n log.info(\"Starting swagger plugin...\");\n if (_error) {\n log.error(pluginName + \" plugin failed to start:\", _error);\n }\n },\n onServerStart(server) {\n logger.success(pluginName + \" plugin has started\");\n\n server.app.get(\"/swagger\", (_req: any, res: any) => {\n res.redirect(`http://localhost:${config.port}`);\n });\n },\n onAuxiliaryServerDeploy(ops, server) {\n SwaggerServer(config, ops, server);\n },\n }, \n __sys__.__root__,\n );\n}\n\n"],"names":["pluginName","toPascalCase","meta","name","SwaggerPlugin","config","Plugin","create","version","description","onRegister","_error","log","Logger","for","info","error","onServerStart","server","logger","success","app","get","_req","res","redirect","port","onAuxiliaryServerDeploy","ops","SwaggerServer","__sys__","__root__"],"mappings":"iMAQA,MAAMA,EAAaC,EAAaC,EAAKC,MAC/B,SAAUC,EAAcC,GAC1B,OAAOC,EAAOC,OACV,CACIJ,KAAMD,EAAKC,KACXK,QAASN,EAAKM,QACdC,YAAaP,EAAKO,YAClB,UAAAC,CAAWC,GACP,MAAMC,EAAMC,EAAOC,IAAI,aACvBF,EAAIG,KAAK,8BACLJ,GACAC,EAAII,MAAMhB,EAAa,2BAA4BW,EAE3D,EACA,aAAAM,CAAcC,GACVC,EAAOC,QAAQpB,EAAa,uBAE5BkB,EAAOG,IAAIC,IAAI,WAAY,CAACC,EAAWC,KACnCA,EAAIC,SAAS,oBAAoBpB,EAAOqB,SAEhD,EACA,uBAAAC,CAAwBC,EAAKV,GACzBW,EAAcxB,EAAQuB,EAC1B,GAEJE,QAAQC,SAEhB"}
|
package/dist/esm/openapi.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{meta as e}from"./configs/meta.js";function t(t,s){const a={openapi:e.version,info:{title:__sys__.vars.__name__||s.title||"XyPriss API Documentation",version:s.version||"1.0.0",description:s.description||e.description},paths:{},components:{securitySchemes:{BearerAuth:{type:"http",scheme:"bearer"}}}};for(const e of t){if(!e.path||!e.method)continue;const t=e.path.replace(/:([a-zA-Z0-9_]+)(
|
|
1
|
+
import{meta as e}from"./configs/meta.js";function t(t,s){const a={openapi:e.version,info:{title:__sys__.vars.__name__||s.title||"XyPriss API Documentation",version:s.version||"1.0.0",description:s.description||e.description},paths:{},components:{securitySchemes:{BearerAuth:{type:"http",scheme:"bearer"}}}};for(const e of t){if(!e.path||!e.method)continue;const t=e.path.replace(/:([a-zA-Z0-9_]+)(?:<[^>]+>)?(?:\([^)]+\))?/g,"{$1}");a.paths[t]||(a.paths[t]={});const s=(Array.isArray(e.method)?e.method[0]:e.method).toLowerCase(),r={summary:e.meta?.summary||`${e.method} ${e.path}`,description:e.meta?.description||"",tags:e.meta?.tags||["Default"],parameters:[],responses:e.responses||{200:{description:"Successful response"}}};if(e.hasGuards&&(r.security=[{BearerAuth:[]}]),e.paramNames&&e.paramNames.length>0)for(const t of e.paramNames){const s=e.paramConstraints?.[t];let a,o="string";s&&("number"===s.type||"integer"===s.type?o="number":"boolean"===s.type?o="boolean":"regex"===s.type&&"string"==typeof s.options?a=s.options:"uuid"===s.type&&(a="^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$")),r.parameters.push({name:t,in:"path",required:!0,schema:{type:o,pattern:a}})}e.meta?.openapi&&Object.assign(r,e.meta.openapi),a.paths[t][s]=r}return a}export{t as generateOpenAPI};
|
|
2
2
|
//# sourceMappingURL=openapi.js.map
|
package/dist/esm/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sources":["../../../../src/openapi.ts"],"sourcesContent":["import { meta } from \"./configs/meta\";\n\nexport interface OpenAPIConfig {\n openapi: string;\n info: {\n title: string;\n version: string;\n description?: string;\n };\n paths: Record<string, any>;\n components: {\n securitySchemes?: Record<string, any>;\n };\n}\n\nexport function generateOpenAPI(registry: any[], config: any): OpenAPIConfig {\n const doc: OpenAPIConfig = {\n openapi: meta.version,\n info: {\n title:\n __sys__.vars.__name__ ||\n config.title ||\n \"XyPriss API Documentation\",\n version: config.version || \"1.0.0\",\n description: config.description || meta.description,\n },\n paths: {},\n components: {\n securitySchemes: {\n BearerAuth: {\n type: \"http\",\n scheme: \"bearer\",\n },\n },\n },\n };\n\n for (const route of registry) {\n if (!route.path || !route.method) continue;\n\n // Convert Express-like path /users/:id to Swagger-like path /users/{id}\n const openApiPath = route.path.replace(\n /:([a-zA-Z0-9_]+)(
|
|
1
|
+
{"version":3,"file":"openapi.js","sources":["../../../../src/openapi.ts"],"sourcesContent":["import { meta } from \"./configs/meta\";\n\nexport interface OpenAPIConfig {\n openapi: string;\n info: {\n title: string;\n version: string;\n description?: string;\n };\n paths: Record<string, any>;\n components: {\n securitySchemes?: Record<string, any>;\n };\n}\n\nexport function generateOpenAPI(registry: any[], config: any): OpenAPIConfig {\n const doc: OpenAPIConfig = {\n openapi: meta.version,\n info: {\n title:\n __sys__.vars.__name__ ||\n config.title ||\n \"XyPriss API Documentation\",\n version: config.version || \"1.0.0\",\n description: config.description || meta.description,\n },\n paths: {},\n components: {\n securitySchemes: {\n BearerAuth: {\n type: \"http\",\n scheme: \"bearer\",\n },\n },\n },\n };\n\n for (const route of registry) {\n if (!route.path || !route.method) continue;\n\n // Convert Express-like path /users/:id to Swagger-like path /users/{id}\n // Handles: :id, :id<number>, :id(\\d+)\n const openApiPath = route.path.replace(\n /:([a-zA-Z0-9_]+)(?:<[^>]+>)?(?:\\([^)]+\\))?/g,\n \"{$1}\",\n );\n\n if (!doc.paths[openApiPath]) {\n doc.paths[openApiPath] = {};\n }\n\n const methodStr = (\n Array.isArray(route.method) ? route.method[0] : route.method\n ).toLowerCase();\n\n // Base operation object\n const operation: any = {\n summary: route.meta?.summary || `${route.method} ${route.path}`,\n description: route.meta?.description || \"\",\n tags: route.meta?.tags || [\"Default\"],\n parameters: [],\n responses: route.responses || {\n \"200\": {\n description: \"Successful response\",\n },\n },\n };\n\n // If guards are detected, optionally assume it requires Auth\n if (route.hasGuards) {\n operation.security = [{ BearerAuth: [] }];\n }\n\n // Add Path Parameters\n if (route.paramNames && route.paramNames.length > 0) {\n for (const param of route.paramNames) {\n const constraint = route.paramConstraints?.[param];\n let type = \"string\";\n let pattern: string | undefined = undefined;\n\n if (constraint) {\n if (\n constraint.type === \"number\" ||\n constraint.type === \"integer\"\n ) {\n type = \"number\";\n } else if (constraint.type === \"boolean\") {\n type = \"boolean\";\n } else if (\n constraint.type === \"regex\" &&\n typeof constraint.options === \"string\"\n ) {\n pattern = constraint.options;\n } else if (constraint.type === \"uuid\") {\n pattern =\n \"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$\";\n }\n }\n\n operation.parameters.push({\n name: param,\n in: \"path\",\n required: true,\n schema: {\n type,\n pattern,\n },\n });\n }\n }\n\n // Add additional meta (like requestBody, query params) if defined by user within meta.openapi\n if (route.meta?.openapi) {\n Object.assign(operation, route.meta.openapi);\n }\n\n doc.paths[openApiPath][methodStr] = operation;\n }\n\n return doc;\n}\n\n"],"names":["generateOpenAPI","registry","config","doc","openapi","meta","version","info","title","__sys__","vars","__name__","description","paths","components","securitySchemes","BearerAuth","type","scheme","route","path","method","openApiPath","replace","methodStr","Array","isArray","toLowerCase","operation","summary","tags","parameters","responses","hasGuards","security","paramNames","length","param","constraint","paramConstraints","pattern","options","push","name","in","required","schema","Object","assign"],"mappings":"yCAeM,SAAUA,EAAgBC,EAAiBC,GAC7C,MAAMC,EAAqB,CACvBC,QAASC,EAAKC,QACdC,KAAM,CACFC,MACIC,QAAQC,KAAKC,UACbT,EAAOM,OACP,4BACJF,QAASJ,EAAOI,SAAW,QAC3BM,YAAaV,EAAOU,aAAeP,EAAKO,aAE5CC,MAAO,CAAA,EACPC,WAAY,CACRC,gBAAiB,CACbC,WAAY,CACRC,KAAM,OACNC,OAAQ,aAMxB,IAAK,MAAMC,KAASlB,EAAU,CAC1B,IAAKkB,EAAMC,OAASD,EAAME,OAAQ,SAIlC,MAAMC,EAAcH,EAAMC,KAAKG,QAC3B,8CACA,QAGCpB,EAAIU,MAAMS,KACXnB,EAAIU,MAAMS,GAAe,CAAA,GAG7B,MAAME,GACFC,MAAMC,QAAQP,EAAME,QAAUF,EAAME,OAAO,GAAKF,EAAME,QACxDM,cAGIC,EAAiB,CACnBC,QAASV,EAAMd,MAAMwB,SAAW,GAAGV,EAAME,UAAUF,EAAMC,OACzDR,YAAaO,EAAMd,MAAMO,aAAe,GACxCkB,KAAMX,EAAMd,MAAMyB,MAAQ,CAAC,WAC3BC,WAAY,GACZC,UAAWb,EAAMa,WAAa,CAC1B,IAAO,CACHpB,YAAa,yBAWzB,GALIO,EAAMc,YACNL,EAAUM,SAAW,CAAC,CAAElB,WAAY,MAIpCG,EAAMgB,YAAchB,EAAMgB,WAAWC,OAAS,EAC9C,IAAK,MAAMC,KAASlB,EAAMgB,WAAY,CAClC,MAAMG,EAAanB,EAAMoB,mBAAmBF,GAC5C,IACIG,EADAvB,EAAO,SAGPqB,IAEwB,WAApBA,EAAWrB,MACS,YAApBqB,EAAWrB,KAEXA,EAAO,SACoB,YAApBqB,EAAWrB,KAClBA,EAAO,UAEa,UAApBqB,EAAWrB,MACmB,iBAAvBqB,EAAWG,QAElBD,EAAUF,EAAWG,QACM,SAApBH,EAAWrB,OAClBuB,EACI,mEAIZZ,EAAUG,WAAWW,KAAK,CACtBC,KAAMN,EACNO,GAAI,OACJC,UAAU,EACVC,OAAQ,CACJ7B,OACAuB,YAGZ,CAIArB,EAAMd,MAAMD,SACZ2C,OAAOC,OAAOpB,EAAWT,EAAMd,KAAKD,SAGxCD,EAAIU,MAAMS,GAAaE,GAAaI,CACxC,CAEA,OAAOzB,CACX"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as xypriss from 'xypriss';
|
|
2
|
+
|
|
1
3
|
interface SwaggerConfig {
|
|
2
4
|
/**
|
|
3
5
|
* The path where the UI will be served.
|
|
@@ -14,6 +16,6 @@ interface SwaggerConfig {
|
|
|
14
16
|
port?: number;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
declare function SwaggerPlugin(config: SwaggerConfig):
|
|
19
|
+
declare function SwaggerPlugin(config: SwaggerConfig): xypriss.XyPrissPlugin;
|
|
18
20
|
|
|
19
21
|
export { SwaggerPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xypriss-swagger",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Auto-documentation plugin for XyPriss Router V2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"nehoid": "^2.1.4",
|
|
23
|
-
"xypriss": "9.6.48-xnb14",
|
|
24
23
|
"xypriss-security": "^2.1.13"
|
|
25
24
|
},
|
|
26
25
|
"devDependencies": {
|
|
@@ -34,5 +33,8 @@
|
|
|
34
33
|
"rollup-plugin-dts": "^6.4.1",
|
|
35
34
|
"tslib": "^2.8.1",
|
|
36
35
|
"typescript": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"xypriss": ">=9.6.69"
|
|
37
39
|
}
|
|
38
40
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,13 +7,12 @@ import { Plugin } from "xypriss";
|
|
|
7
7
|
// console.log("[swagger] internal plugin sys", __sys__.__root__);
|
|
8
8
|
|
|
9
9
|
const pluginName = toPascalCase(meta.name);
|
|
10
|
-
export function SwaggerPlugin(config: SwaggerConfig)
|
|
10
|
+
export function SwaggerPlugin(config: SwaggerConfig) {
|
|
11
11
|
return Plugin.create(
|
|
12
12
|
{
|
|
13
13
|
name: meta.name,
|
|
14
14
|
version: meta.version,
|
|
15
15
|
description: meta.description,
|
|
16
|
-
|
|
17
16
|
onRegister(_error) {
|
|
18
17
|
const log = Logger.for("Bootstrap");
|
|
19
18
|
log.info("Starting swagger plugin...");
|
|
@@ -31,7 +30,7 @@ export function SwaggerPlugin(config: SwaggerConfig): any {
|
|
|
31
30
|
onAuxiliaryServerDeploy(ops, server) {
|
|
32
31
|
SwaggerServer(config, ops, server);
|
|
33
32
|
},
|
|
34
|
-
},
|
|
33
|
+
},
|
|
35
34
|
__sys__.__root__,
|
|
36
35
|
);
|
|
37
36
|
}
|
package/src/openapi.ts
CHANGED
|
@@ -39,8 +39,9 @@ export function generateOpenAPI(registry: any[], config: any): OpenAPIConfig {
|
|
|
39
39
|
if (!route.path || !route.method) continue;
|
|
40
40
|
|
|
41
41
|
// Convert Express-like path /users/:id to Swagger-like path /users/{id}
|
|
42
|
+
// Handles: :id, :id<number>, :id(\d+)
|
|
42
43
|
const openApiPath = route.path.replace(
|
|
43
|
-
/:([a-zA-Z0-9_]+)(
|
|
44
|
+
/:([a-zA-Z0-9_]+)(?:<[^>]+>)?(?:\([^)]+\))?/g,
|
|
44
45
|
"{$1}",
|
|
45
46
|
);
|
|
46
47
|
|
|
@@ -73,20 +74,35 @@ export function generateOpenAPI(registry: any[], config: any): OpenAPIConfig {
|
|
|
73
74
|
// Add Path Parameters
|
|
74
75
|
if (route.paramNames && route.paramNames.length > 0) {
|
|
75
76
|
for (const param of route.paramNames) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
const constraint = route.paramConstraints?.[param];
|
|
78
|
+
let type = "string";
|
|
79
|
+
let pattern: string | undefined = undefined;
|
|
80
|
+
|
|
81
|
+
if (constraint) {
|
|
82
|
+
if (
|
|
83
|
+
constraint.type === "number" ||
|
|
84
|
+
constraint.type === "integer"
|
|
85
|
+
) {
|
|
86
|
+
type = "number";
|
|
87
|
+
} else if (constraint.type === "boolean") {
|
|
88
|
+
type = "boolean";
|
|
89
|
+
} else if (
|
|
90
|
+
constraint.type === "regex" &&
|
|
91
|
+
typeof constraint.options === "string"
|
|
92
|
+
) {
|
|
93
|
+
pattern = constraint.options;
|
|
94
|
+
} else if (constraint.type === "uuid") {
|
|
95
|
+
pattern =
|
|
96
|
+
"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
83
99
|
|
|
84
100
|
operation.parameters.push({
|
|
85
101
|
name: param,
|
|
86
102
|
in: "path",
|
|
87
103
|
required: true,
|
|
88
104
|
schema: {
|
|
89
|
-
type
|
|
105
|
+
type,
|
|
90
106
|
pattern,
|
|
91
107
|
},
|
|
92
108
|
});
|