speedly 2.0.32 → 2.0.34

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.
@@ -8,6 +8,7 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const swagger_ui_express_1 = __importDefault(require("swagger-ui-express"));
10
10
  const swagger_themes_1 = require("swagger-themes");
11
+ const parser_1 = require("./parser");
11
12
  const METHODS_WITH_BODY = ["post", "put", "patch"];
12
13
  /* ===================== HELPERS ======================= */
13
14
  function extractPath(layer) {
@@ -101,11 +102,8 @@ function scanRouter(router, base = "") {
101
102
  function routeAnalyzer(route, routerName) {
102
103
  const routerDetails = {};
103
104
  const scanned = scanRouter(route);
104
- const paramsRegex = /:[^/]+/g;
105
105
  scanned.forEach((route) => {
106
- const fullPath = `/${routerName}${route.path
107
- .replace(/^\/$/, "")
108
- .replaceAll(paramsRegex, (r) => `{${r.slice(1)}}`)}`;
106
+ const fullPath = `/${routerName}${(0, parser_1.expressToSwagger)(route.path)}`;
109
107
  routerDetails[fullPath] = {};
110
108
  Object.entries(route.methods).forEach(([method, detail]) => {
111
109
  const doc = {
@@ -113,6 +111,16 @@ function routeAnalyzer(route, routerName) {
113
111
  description: "Public route",
114
112
  };
115
113
  const validation = detail.middlewares.find((mw) => mw.handle?.__validationSchema)?.handle.__validationSchema;
114
+ const pathParams = [...fullPath.matchAll(/{([^}]+)}/g)].map((m) => m[1]);
115
+ if (pathParams.length) {
116
+ doc.parameters = pathParams.map((name) => ({
117
+ name,
118
+ in: "path",
119
+ required: validation?.params?.fields?.[name]?.required ||
120
+ !new RegExp(`\\{[^\\}]*${name}[^\\}]*\\}`).test(route.path),
121
+ schema: { type: "string" },
122
+ }));
123
+ }
116
124
  // If body exists
117
125
  if (METHODS_WITH_BODY.includes(method)) {
118
126
  if (validation?.body) {
@@ -0,0 +1 @@
1
+ export declare function expressToSwagger(path: string): string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expressToSwagger = expressToSwagger;
4
+ function expressToSwagger(path) {
5
+ // مرحله 1: optional group ها رو unwrap کن
6
+ // {/:newName} -> /:newName
7
+ let normalized = path.replace(/\{([^}]+)\}/g, "$1");
8
+ // مرحله 2: :param رو تبدیل کن به {param}
9
+ normalized = normalized.replace(/:([A-Za-z0-9_]+)/g, "{$1}");
10
+ return normalized;
11
+ }
@@ -8,6 +8,7 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const swagger_ui_express_1 = __importDefault(require("swagger-ui-express"));
10
10
  const swagger_themes_1 = require("swagger-themes");
11
+ const parser_1 = require("./parser");
11
12
  const METHODS_WITH_BODY = ["post", "put", "patch"];
12
13
  /* ===================== HELPERS ======================= */
13
14
  function extractPath(layer) {
@@ -101,11 +102,8 @@ function scanRouter(router, base = "") {
101
102
  function routeAnalyzer(route, routerName) {
102
103
  const routerDetails = {};
103
104
  const scanned = scanRouter(route);
104
- const paramsRegex = /:[^/]+/g;
105
105
  scanned.forEach((route) => {
106
- const fullPath = `/${routerName}${route.path
107
- .replace(/^\/$/, "")
108
- .replaceAll(paramsRegex, (r) => `{${r.slice(1)}}`)}`;
106
+ const fullPath = `/${routerName}${(0, parser_1.expressToSwagger)(route.path)}`;
109
107
  routerDetails[fullPath] = {};
110
108
  Object.entries(route.methods).forEach(([method, detail]) => {
111
109
  const doc = {
@@ -113,6 +111,16 @@ function routeAnalyzer(route, routerName) {
113
111
  description: "Public route",
114
112
  };
115
113
  const validation = detail.middlewares.find((mw) => mw.handle?.__validationSchema)?.handle.__validationSchema;
114
+ const pathParams = [...fullPath.matchAll(/{([^}]+)}/g)].map((m) => m[1]);
115
+ if (pathParams.length) {
116
+ doc.parameters = pathParams.map((name) => ({
117
+ name,
118
+ in: "path",
119
+ required: validation?.params?.fields?.[name]?.required ||
120
+ !new RegExp(`\\{[^\\}]*${name}[^\\}]*\\}`).test(route.path),
121
+ schema: { type: "string" },
122
+ }));
123
+ }
116
124
  // If body exists
117
125
  if (METHODS_WITH_BODY.includes(method)) {
118
126
  if (validation?.body) {
@@ -0,0 +1 @@
1
+ export declare function expressToSwagger(path: string): string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.expressToSwagger = expressToSwagger;
4
+ function expressToSwagger(path) {
5
+ // مرحله 1: optional group ها رو unwrap کن
6
+ // {/:newName} -> /:newName
7
+ let normalized = path.replace(/\{([^}]+)\}/g, "$1");
8
+ // مرحله 2: :param رو تبدیل کن به {param}
9
+ normalized = normalized.replace(/:([A-Za-z0-9_]+)/g, "{$1}");
10
+ return normalized;
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speedly",
3
- "version": "2.0.32",
3
+ "version": "2.0.34",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/esm/index.d.ts",