tspace-spear 1.2.2 → 1.2.4

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 (57) hide show
  1. package/README.md +304 -23
  2. package/dist/lib/core/const/index.d.ts +153 -0
  3. package/dist/lib/core/const/index.js +105 -0
  4. package/dist/lib/core/const/index.js.map +1 -0
  5. package/dist/lib/core/decorators/context.d.ts +16 -9
  6. package/dist/lib/core/decorators/context.js +85 -59
  7. package/dist/lib/core/decorators/context.js.map +1 -1
  8. package/dist/lib/core/decorators/headers.d.ts +2 -2
  9. package/dist/lib/core/decorators/headers.js +1 -1
  10. package/dist/lib/core/decorators/headers.js.map +1 -1
  11. package/dist/lib/core/decorators/methods.d.ts +7 -7
  12. package/dist/lib/core/decorators/methods.js.map +1 -1
  13. package/dist/lib/core/decorators/middleware.d.ts +3 -3
  14. package/dist/lib/core/decorators/middleware.js +2 -2
  15. package/dist/lib/core/decorators/middleware.js.map +1 -1
  16. package/dist/lib/core/decorators/statusCode.d.ts +1 -1
  17. package/dist/lib/core/decorators/statusCode.js.map +1 -1
  18. package/dist/lib/core/decorators/swagger.d.ts +1 -1
  19. package/dist/lib/core/decorators/swagger.js.map +1 -1
  20. package/dist/lib/core/server/express.d.ts +295 -0
  21. package/dist/lib/core/server/express.js +1356 -0
  22. package/dist/lib/core/server/express.js.map +1 -0
  23. package/dist/lib/core/server/fast-router.d.ts +133 -0
  24. package/dist/lib/core/server/fast-router.js +277 -0
  25. package/dist/lib/core/server/fast-router.js.map +1 -0
  26. package/dist/lib/core/server/index.d.ts +43 -36
  27. package/dist/lib/core/server/index.js +300 -426
  28. package/dist/lib/core/server/index.js.map +1 -1
  29. package/dist/lib/core/server/net/index.d.ts +20 -0
  30. package/dist/lib/core/server/net/index.js +393 -0
  31. package/dist/lib/core/server/net/index.js.map +1 -0
  32. package/dist/lib/core/server/parser-factory.d.ts +20 -12
  33. package/dist/lib/core/server/parser-factory.js +283 -196
  34. package/dist/lib/core/server/parser-factory.js.map +1 -1
  35. package/dist/lib/core/server/request.d.ts +2 -0
  36. package/dist/lib/core/server/request.js +7 -0
  37. package/dist/lib/core/server/request.js.map +1 -0
  38. package/dist/lib/core/server/response.d.ts +6 -0
  39. package/dist/lib/core/server/response.js +168 -0
  40. package/dist/lib/core/server/response.js.map +1 -0
  41. package/dist/lib/core/server/router.d.ts +2 -2
  42. package/dist/lib/core/server/router.js +2 -1
  43. package/dist/lib/core/server/router.js.map +1 -1
  44. package/dist/lib/core/server/uWS/index.d.ts +30 -0
  45. package/dist/lib/core/server/uWS/index.js +357 -0
  46. package/dist/lib/core/server/uWS/index.js.map +1 -0
  47. package/dist/lib/core/types/index.d.ts +159 -38
  48. package/dist/lib/core/utils/index.d.ts +12 -0
  49. package/dist/lib/core/utils/index.js +137 -0
  50. package/dist/lib/core/utils/index.js.map +1 -0
  51. package/dist/lib/index.d.ts +3 -3
  52. package/dist/lib/index.js +3 -2
  53. package/dist/lib/index.js.map +1 -1
  54. package/package.json +27 -11
  55. package/dist/tests/benchmark.test.d.ts +0 -1
  56. package/dist/tests/benchmark.test.js +0 -145
  57. package/dist/tests/benchmark.test.js.map +0 -1
@@ -4,16 +4,42 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ParserFactory = void 0;
7
+ const busboy_1 = __importDefault(require("busboy"));
7
8
  const fs_1 = __importDefault(require("fs"));
8
9
  const path_1 = __importDefault(require("path"));
9
10
  const mime_types_1 = __importDefault(require("mime-types"));
10
11
  const crypto_1 = __importDefault(require("crypto"));
11
12
  const swagger_ui_dist_1 = __importDefault(require("swagger-ui-dist"));
12
- const querystring_1 = __importDefault(require("querystring"));
13
13
  const string_decoder_1 = require("string_decoder");
14
- const busboy_1 = __importDefault(require("busboy"));
14
+ const fast_querystring_1 = __importDefault(require("fast-querystring"));
15
+ const utils_1 = require("../utils");
16
+ const uWS_1 = require("./uWS");
17
+ const net_1 = require("./net");
15
18
  class ParserFactory {
16
- files(req, options) {
19
+ uWebStockets = false;
20
+ net = false;
21
+ useAdater(adapter) {
22
+ if (adapter.kind === 'uWS') {
23
+ this.uWebStockets = true;
24
+ }
25
+ if (adapter.kind === 'net') {
26
+ this.net = true;
27
+ }
28
+ return this;
29
+ }
30
+ queryString(url) {
31
+ const i = url.indexOf("?");
32
+ if (i === -1)
33
+ return {};
34
+ return fast_querystring_1.default.parse(url.slice(i + 1));
35
+ }
36
+ async files({ req, res, options, }) {
37
+ if (this.uWebStockets) {
38
+ return (0, uWS_1.uWSfiles)({ req, res, options });
39
+ }
40
+ if (this.net) {
41
+ return (0, net_1.netFiles)(req, options);
42
+ }
17
43
  const temp = options.tempFileDir;
18
44
  if (!fs_1.default.existsSync(temp)) {
19
45
  try {
@@ -25,7 +51,7 @@ class ParserFactory {
25
51
  const body = {};
26
52
  const files = {};
27
53
  const fileWritePromises = [];
28
- const bb = (0, busboy_1.default)({ headers: req.headers, defParamCharset: 'utf8' });
54
+ const bb = (0, busboy_1.default)({ headers: req.headers, defParamCharset: "utf8" });
29
55
  const removeTemp = (fileTemp, ms) => {
30
56
  const remove = () => {
31
57
  try {
@@ -35,13 +61,16 @@ class ParserFactory {
35
61
  };
36
62
  setTimeout(remove, ms);
37
63
  };
38
- bb.on('file', (fieldName, fileData, info) => {
64
+ bb.on("file", (fieldName, fileData, info) => {
39
65
  const { filename, mimeType } = info;
40
- const tempFilename = crypto_1.default.randomBytes(16).toString('hex');
66
+ const extension = mime_types_1.default.extension(mimeType) ||
67
+ path_1.default.extname(filename).replace(".", "") ||
68
+ "bin";
69
+ const tempFilename = crypto_1.default.randomBytes(16).toString("hex");
41
70
  const filePath = path_1.default.join(path_1.default.resolve(), `${temp}/${tempFilename}`);
42
71
  const writeStream = fs_1.default.createWriteStream(filePath);
43
72
  let fileSize = 0;
44
- fileData.on('data', (data) => {
73
+ fileData.on("data", (data) => {
45
74
  fileSize += data.length;
46
75
  if (fileSize > options.limit) {
47
76
  fileData.unpipe(writeStream);
@@ -51,38 +80,39 @@ class ParserFactory {
51
80
  });
52
81
  const fileWritePromise = new Promise((resolve, reject) => {
53
82
  fileData.pipe(writeStream);
54
- writeStream.on('finish', () => {
83
+ writeStream.on("finish", () => {
55
84
  const file = {
56
85
  name: filename,
57
86
  tempFilePath: filePath,
58
87
  tempFileName: tempFilename,
59
88
  mimetype: mimeType,
60
- extension: String(mime_types_1.default.extension(String(mimeType))),
89
+ extension: extension,
61
90
  size: fileSize,
62
91
  sizes: {
63
92
  bytes: fileSize,
64
93
  kb: fileSize / 1024,
65
94
  mb: fileSize / 1024 / 1024,
66
- gb: fileSize / 1024 / 1024 / 1024
95
+ gb: fileSize / 1024 / 1024 / 1024,
67
96
  },
68
97
  write: (to) => {
69
98
  return new Promise((resolve, reject) => {
70
- fs_1.default.createReadStream(filePath)
99
+ fs_1.default
100
+ .createReadStream(filePath)
71
101
  .pipe(fs_1.default.createWriteStream(to))
72
- .on('finish', () => {
102
+ .on("finish", () => {
73
103
  return resolve(null);
74
104
  })
75
- .on('error', (err) => {
105
+ .on("error", (err) => {
76
106
  return reject(err);
77
107
  });
78
108
  });
79
109
  },
80
110
  remove: () => {
81
- return new Promise(resolve => setTimeout(() => {
111
+ return new Promise((resolve) => setTimeout(() => {
82
112
  fs_1.default.unlinkSync(filePath);
83
113
  return resolve(null);
84
114
  }, 100));
85
- }
115
+ },
86
116
  };
87
117
  if (files[fieldName] == null) {
88
118
  files[fieldName] = [];
@@ -93,52 +123,56 @@ class ParserFactory {
93
123
  }
94
124
  return resolve(null);
95
125
  });
96
- writeStream.on('error', reject);
126
+ writeStream.on("error", reject);
97
127
  });
98
128
  fileWritePromises.push(fileWritePromise);
99
129
  });
100
- bb.on('field', (name, value) => {
130
+ bb.on("field", (name, value) => {
101
131
  body[name] = value;
102
132
  });
103
- bb.on('finish', () => {
133
+ bb.on("finish", () => {
104
134
  Promise.all(fileWritePromises)
105
135
  .then(() => {
106
136
  return resolve({
107
137
  files,
108
- body
138
+ body,
109
139
  });
110
140
  })
111
141
  .catch((err) => {
112
142
  return reject(err);
113
143
  });
114
144
  });
115
- bb.on('error', (err) => {
145
+ bb.on("error", (err) => {
116
146
  return reject(err);
117
147
  });
118
148
  req.pipe(bb);
119
149
  });
120
150
  }
121
- body(req) {
151
+ async body(req, res) {
152
+ if (this.uWebStockets) {
153
+ return (await (0, uWS_1.uWSBody)(req, res));
154
+ }
155
+ if (this.net) {
156
+ return (await (0, net_1.netBody)(req));
157
+ }
122
158
  return new Promise((resolve, reject) => {
123
- const decoder = new string_decoder_1.StringDecoder('utf-8');
124
- let payload = '';
125
- req.on('data', (data) => {
159
+ const decoder = new string_decoder_1.StringDecoder("utf-8");
160
+ let payload = "";
161
+ req.on("data", (data) => {
126
162
  payload += decoder.write(data);
127
163
  });
128
- req.on('end', () => {
164
+ req.on("end", async () => {
165
+ payload += decoder.end();
166
+ const contentType = req.headers["content-type"]?.toLowerCase() || null;
129
167
  try {
130
- const isUrlEncoded = req.headers['content-type']?.includes('x-www-form-urlencoded');
131
- if (isUrlEncoded) {
132
- return resolve(querystring_1.default.parse(payload));
133
- }
134
- payload += decoder.end();
135
- return resolve(JSON.parse(payload));
168
+ const body = await (0, utils_1.normalizeRequestBody)({ contentType, payload });
169
+ return resolve(body);
136
170
  }
137
- catch (e) {
138
- return resolve({});
171
+ catch (err) {
172
+ return reject(err);
139
173
  }
140
174
  });
141
- req.on('error', (err) => {
175
+ req.on("error", (err) => {
142
176
  return reject(err);
143
177
  });
144
178
  });
@@ -148,15 +182,15 @@ class ParserFactory {
148
182
  const cookieString = req.headers?.cookie;
149
183
  if (cookieString == null)
150
184
  return null;
151
- for (const cookie of cookieString.split(';')) {
152
- const [name, value] = cookie.split('=').map((v) => v.trim());
185
+ for (const cookie of cookieString.split(";")) {
186
+ const [name, value] = cookie.split("=").map((v) => v.trim());
153
187
  cookies[name] = decodeURIComponent(value);
154
188
  }
155
189
  for (const name of Object.keys(cookies)) {
156
190
  const cookie = cookies[name];
157
- if (!cookie.startsWith('Expires='))
191
+ if (!cookie.startsWith("Expires="))
158
192
  continue;
159
- const expiresString = cookie.replace('Expires=', '');
193
+ const expiresString = cookie.replace("Expires=", "");
160
194
  const expiresDate = new Date(expiresString);
161
195
  if (isNaN(expiresDate.getTime()) || expiresDate < new Date()) {
162
196
  delete cookies[name];
@@ -168,9 +202,9 @@ class ParserFactory {
168
202
  const spec = {
169
203
  openapi: "3.1.0",
170
204
  info: doc.info ?? {
171
- title: 'API Documentation',
205
+ title: "API Documentation",
172
206
  description: "Documentation",
173
- version: '1.0.0'
207
+ version: "1.0.0",
174
208
  },
175
209
  components: {
176
210
  securitySchemes: {
@@ -178,14 +212,14 @@ class ParserFactory {
178
212
  type: "http",
179
213
  scheme: "bearer",
180
214
  name: "Authorization",
181
- description: "Enter your token in the format : 'Bearer {TOKEN}'"
215
+ description: "Enter your token in the format : 'Bearer {TOKEN}'",
182
216
  },
183
217
  cookies: {
184
218
  type: "apiKey",
185
219
  in: "header",
186
220
  name: "Cookie",
187
- description: "Enter your cookies in the headers"
188
- }
221
+ description: "Enter your cookies in the headers",
222
+ },
189
223
  },
190
224
  },
191
225
  servers: doc.servers,
@@ -194,14 +228,30 @@ class ParserFactory {
194
228
  };
195
229
  const specPaths = (routes) => {
196
230
  let paths = {};
231
+ const defaultSpecResponse = {
232
+ "200": {
233
+ description: "OK",
234
+ content: {
235
+ "application/json": {
236
+ schema: {
237
+ type: "object",
238
+ properties: {
239
+ message: {
240
+ example: "success",
241
+ },
242
+ },
243
+ },
244
+ },
245
+ },
246
+ },
247
+ };
197
248
  for (const r of routes) {
198
- if (r.path === '*')
249
+ if (r.path === "*")
199
250
  continue;
200
251
  const path = r.path.replace(/:(\w+)/g, "{$1}");
201
- const method = r.method.toLocaleLowerCase();
202
- const swagger = (doc.specs ?? []).find(s => {
203
- return s.path === r.path &&
204
- s.method.toLocaleLowerCase() === method;
252
+ const method = r.method.toLowerCase();
253
+ const swagger = (doc.specs ?? []).find((s) => {
254
+ return s.path === r.path && s.method.toLowerCase() === method;
205
255
  });
206
256
  const decoratedOnly = doc.options?.decoratedOnly ?? false;
207
257
  if ((swagger == null && decoratedOnly) || swagger?.disabled) {
@@ -209,15 +259,15 @@ class ParserFactory {
209
259
  }
210
260
  if (paths[path] == null) {
211
261
  paths[path] = {
212
- [method]: {}
262
+ [method]: {},
213
263
  };
214
264
  }
215
265
  const spec = {};
216
266
  const tags = /\/api\/v\d+/.test(r.path)
217
- ? r.path.split('/')[3]
267
+ ? r.path.split("/")[3]
218
268
  : /\/api/.test(r.path)
219
- ? r.path.split('/')[2]
220
- : r.path.split('/')[1];
269
+ ? r.path.split("/")[2]
270
+ : r.path.split("/")[1];
221
271
  spec.parameters = [];
222
272
  spec.responses = {};
223
273
  spec.tags = [];
@@ -231,152 +281,192 @@ class ParserFactory {
231
281
  content: {
232
282
  "application/json": {
233
283
  schema: {
234
- type: 'object',
284
+ type: "object",
235
285
  properties: response.example == null
236
286
  ? {}
237
- : Object.keys(response.example)
238
- .reduce((prev, key) => {
239
- prev[key] = { example: (response?.example ?? {})[key] ?? {} };
287
+ : Object.keys(response.example).reduce((prev, key) => {
288
+ prev[key] = {
289
+ example: (response?.example ?? {})[key] ?? {},
290
+ };
240
291
  return prev;
241
- }, {})
242
- }
243
- }
244
- }
292
+ }, {}),
293
+ },
294
+ },
295
+ },
245
296
  };
246
297
  }
247
298
  spec.responses = {
248
- ...responses
299
+ ...responses,
249
300
  };
250
301
  }
251
- if (swagger != null) {
302
+ if (swagger == null) {
252
303
  spec.tags = [
253
- swagger.tags == null
254
- ? tags == null || tags === '' || /^:[^:]*$/.test(tags) ? 'default' : tags
255
- : swagger.tags
304
+ tags == null || tags === "" || /^:[^:]*$/.test(tags)
305
+ ? "default"
306
+ : tags,
256
307
  ];
257
- if (swagger.bearerToken) {
258
- spec.security = [{ "BearerToken": [] }];
259
- }
260
- if (swagger.summary != null) {
261
- spec.summary = swagger.summary;
262
- }
263
- if (swagger.description != null) {
264
- spec.description = swagger.description;
265
- }
266
308
  if (Array.isArray(r.params) && Array.from(r.params).length) {
267
- spec.parameters = Array.from(r?.params).map(p => {
309
+ spec.parameters = Array.from(r.params).map((p) => {
268
310
  return {
269
311
  name: p,
270
312
  in: "path",
271
313
  required: true,
272
314
  schema: {
273
- type: "string"
274
- }
315
+ type: "string",
316
+ },
275
317
  };
276
318
  });
277
319
  }
278
- if (swagger.query != null) {
279
- spec.parameters = [
280
- ...spec.parameters,
281
- ...Object.entries(swagger.query).map(([k, v]) => {
282
- return {
283
- name: k,
284
- in: "query",
285
- required: v.required == null ? false : true,
286
- schema: {
287
- type: v.type
288
- }
289
- };
290
- })
291
- ];
292
- }
293
- if (swagger.cookies != null) {
294
- spec.parameters = [
295
- ...spec.parameters,
296
- ...[{
297
- name: "Cookie",
298
- in: "header",
299
- required: swagger.cookies.required == null ? false : true,
300
- schema: {
301
- type: "string"
302
- },
303
- example: swagger.cookies.names.map((v, i) => `${v}={value${i + 1}}`).join(' ; '),
304
- description: swagger.cookies?.description
305
- }]
306
- ];
307
- }
308
- if (swagger.body != null) {
309
- spec.requestBody = {
310
- description: swagger.body?.description == null ? "description" : swagger.body.description,
311
- required: swagger.body?.required == null ? false : true,
312
- content: {
313
- "application/json": {
314
- schema: {
315
- type: "object",
316
- properties: swagger.body.properties
317
- }
318
- }
319
- }
320
- };
321
- }
322
- if (swagger.files != null) {
323
- spec.requestBody = {
324
- description: swagger.files?.description == null ? "description" : swagger.files.description,
325
- required: swagger.files?.required == null ? false : true,
326
- content: {
327
- "multipart/form-data": {
328
- schema: {
329
- type: "object",
330
- properties: swagger.files.properties
331
- }
332
- }
333
- }
334
- };
335
- }
336
- if (swagger.responses != null) {
337
- const responses = {};
338
- for (const response of swagger.responses) {
339
- if (response == null || !Object.keys(response).length)
340
- continue;
341
- responses[`${response.status}`] = {
342
- description: response.description,
343
- content: {
344
- "application/json": {
345
- schema: {
346
- type: 'object',
347
- properties: response.example == null
348
- ? {}
349
- : Object.keys(response.example)
350
- .reduce((prev, key) => {
351
- prev[key] = { example: (response?.example ?? {})[key] ?? {} };
352
- return prev;
353
- }, {})
354
- }
355
- }
356
- }
357
- };
358
- }
359
- spec.responses = {
360
- ...responses
361
- };
320
+ if (!Object.keys(spec.responses).length) {
321
+ spec.responses = defaultSpecResponse;
362
322
  }
363
323
  paths[path][method] = spec;
364
324
  continue;
365
325
  }
366
326
  spec.tags = [
367
- tags == null || tags === '' || /^:[^:]*$/.test(tags) ? 'default' : tags
327
+ swagger.tags == null
328
+ ? tags == null || tags === "" || /^:[^:]*$/.test(tags)
329
+ ? "default"
330
+ : tags
331
+ : swagger.tags,
368
332
  ];
369
- if (Array.isArray(r.params) && Array.from(r.params).length) {
370
- spec.parameters = Array.from(r.params).map(p => {
333
+ if (swagger.bearerToken) {
334
+ spec.security = [{ BearerToken: [] }];
335
+ }
336
+ if (swagger.summary != null) {
337
+ spec.summary = swagger.summary;
338
+ }
339
+ if (swagger.description != null) {
340
+ spec.description = swagger.description;
341
+ }
342
+ if (swagger.params != null) {
343
+ const params = Object.entries(swagger.params).map(([k, v]) => {
344
+ return {
345
+ name: k,
346
+ in: "path",
347
+ required: v?.required === true,
348
+ description: v?.description,
349
+ example: v?.example || v?.enum,
350
+ schema: {
351
+ type: v?.type ?? "string",
352
+ }
353
+ };
354
+ });
355
+ spec.parameters = [
356
+ ...(spec.parameters ?? []),
357
+ ...params,
358
+ ];
359
+ }
360
+ else if (Array.isArray(r.params) && Array.from(r.params).length) {
361
+ spec.parameters = Array.from(r?.params).map((p) => {
371
362
  return {
372
363
  name: p,
373
364
  in: "path",
374
365
  required: true,
375
366
  schema: {
376
- type: "string"
367
+ type: "string",
368
+ },
369
+ };
370
+ });
371
+ }
372
+ if (swagger.query != null) {
373
+ const queryParams = Object.entries(swagger.query).map(([k, v]) => {
374
+ return {
375
+ name: k,
376
+ in: "query",
377
+ required: v?.required === true,
378
+ description: v?.description,
379
+ example: v?.example || v?.enum,
380
+ schema: {
381
+ type: v?.type ?? "string",
377
382
  }
378
383
  };
379
384
  });
385
+ spec.parameters = [
386
+ ...(spec.parameters ?? []),
387
+ ...queryParams,
388
+ ];
389
+ }
390
+ if (swagger.cookies != null) {
391
+ spec.parameters = [
392
+ ...spec.parameters,
393
+ ...[
394
+ {
395
+ name: "Cookie",
396
+ in: "header",
397
+ required: swagger.cookies.required === true,
398
+ schema: {
399
+ type: "string",
400
+ },
401
+ example: swagger.cookies.names
402
+ .map((v, i) => `${v}={value${i + 1}}`)
403
+ .join(" ; "),
404
+ description: swagger.cookies?.description,
405
+ },
406
+ ],
407
+ ];
408
+ }
409
+ if (swagger.body != null) {
410
+ spec.requestBody = {
411
+ description: swagger.body.description,
412
+ required: swagger.body?.required === true,
413
+ content: {
414
+ "application/json": {
415
+ schema: {
416
+ type: "object",
417
+ properties: swagger.body.properties,
418
+ required: Object.entries(swagger.body.properties)
419
+ .filter(([_, v]) => v.required)
420
+ .map(([key]) => key)
421
+ },
422
+ },
423
+ },
424
+ };
425
+ }
426
+ if (swagger.files != null) {
427
+ spec.requestBody = {
428
+ description: swagger.files.description,
429
+ required: swagger.files?.required === true,
430
+ content: {
431
+ "multipart/form-data": {
432
+ schema: {
433
+ type: "object",
434
+ properties: swagger.files.properties,
435
+ },
436
+ },
437
+ },
438
+ };
439
+ }
440
+ if (swagger.responses != null) {
441
+ const responses = {};
442
+ for (const response of swagger.responses) {
443
+ if (response == null || !Object.keys(response).length)
444
+ continue;
445
+ responses[`${response.status}`] = {
446
+ description: response.description,
447
+ content: {
448
+ "application/json": {
449
+ schema: {
450
+ type: "object",
451
+ properties: response.example == null
452
+ ? {}
453
+ : Object.keys(response.example).reduce((prev, key) => {
454
+ prev[key] = {
455
+ example: (response?.example ?? {})[key] ?? {},
456
+ };
457
+ return prev;
458
+ }, {}),
459
+ },
460
+ },
461
+ },
462
+ };
463
+ }
464
+ spec.responses = {
465
+ ...responses,
466
+ };
467
+ }
468
+ if (!Object.keys(spec.responses).length) {
469
+ spec.responses = defaultSpecResponse;
380
470
  }
381
471
  paths[path][method] = spec;
382
472
  }
@@ -384,20 +474,17 @@ class ParserFactory {
384
474
  };
385
475
  spec.paths = specPaths(doc.routes ?? []);
386
476
  const normalizePath = (...paths) => {
387
- const path = paths
388
- .join('/')
389
- .replace(/\/+/g, '/')
390
- .replace(/\/+$/, '');
391
- const normalizedPath = path.startsWith('/') ? path : `/${path}`;
477
+ const path = paths.join("/").replace(/\/+/g, "/").replace(/\/+$/, "");
478
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
392
479
  return /\/api\/api/.test(normalizedPath)
393
480
  ? normalizedPath.replace(/\/api\/api\//, "/api/")
394
481
  : normalizedPath;
395
482
  };
396
- const STATIC_URL = '/swagger-ui';
397
- const iconURL = normalizePath(doc.staticUrl ?? '', `${STATIC_URL}/favicon-32x32.png`).replace(/^\/(http[s]?:\/{0,2})/, '$1');
398
- const cssURL = normalizePath(doc.staticUrl ?? '', `${STATIC_URL}/swagger-ui.css`).replace(/^\/(http[s]?:\/{0,2})/, '$1');
399
- const scriptBundle = normalizePath(doc.staticUrl ?? '', `${STATIC_URL}/swagger-ui-bundle.js`).replace(/^\/(http[s]?:\/{0,2})/, '$1');
400
- const scriptStandalonePreset = normalizePath(doc.staticUrl ?? '', `${STATIC_URL}/swagger-ui-standalone-preset.js`).replace(/^\/(http[s]?:\/{0,2})/, '$1');
483
+ const STATIC_URL = "/swagger-ui";
484
+ const iconURL = normalizePath(doc.staticUrl ?? "", `${STATIC_URL}/favicon-32x32.png`).replace(/^\/(http[s]?:\/{0,2})/, "$1");
485
+ const cssURL = normalizePath(doc.staticUrl ?? "", `${STATIC_URL}/swagger-ui.css`).replace(/^\/(http[s]?:\/{0,2})/, "$1");
486
+ const scriptBundle = normalizePath(doc.staticUrl ?? "", `${STATIC_URL}/swagger-ui-bundle.js`).replace(/^\/(http[s]?:\/{0,2})/, "$1");
487
+ const scriptStandalonePreset = normalizePath(doc.staticUrl ?? "", `${STATIC_URL}/swagger-ui-standalone-preset.js`).replace(/^\/(http[s]?:\/{0,2})/, "$1");
401
488
  const html = `
402
489
  <!DOCTYPE html>
403
490
  <html lang="en">
@@ -425,7 +512,7 @@ class ParserFactory {
425
512
  presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
426
513
  spec : ${JSON.stringify(spec)},
427
514
  withCredentials: ${doc.options?.withCredentials ?? "true"},
428
- layout: "${doc.options?.layout ?? 'StandaloneLayout'}",
515
+ layout: "${doc.options?.layout ?? "StandaloneLayout"}",
429
516
  filter: "${doc.options?.filter ?? "false"}",
430
517
  docExpansion: "${doc.options?.docExpansion ?? "list"}",
431
518
  deepLinking: "${doc.options?.deepLinking ?? "true"}",
@@ -437,36 +524,36 @@ class ParserFactory {
437
524
  </html>
438
525
  `;
439
526
  const staticSwaggerHandler = (req, res, params) => {
440
- const swaggerUiPath = swagger_ui_dist_1.default.getAbsoluteFSPath();
441
- const mimeTypes = {
442
- '.html': 'text/html',
443
- '.css': 'text/css',
444
- '.js': 'application/javascript',
445
- '.png': 'image/png',
446
- '.jpg': 'image/jpeg',
447
- '.gif': 'image/gif',
448
- '.svg': 'image/svg+xml',
449
- '.json': 'application/json'
450
- };
451
- const requestedFilePath = params['*'];
452
- const filePath = path_1.default.join(swaggerUiPath, requestedFilePath);
453
- const extname = path_1.default.extname(filePath);
454
- const contentType = mimeTypes[extname] || 'text/html';
455
527
  try {
528
+ const swaggerUiPath = swagger_ui_dist_1.default.getAbsoluteFSPath();
529
+ const mimeTypes = {
530
+ ".html": "text/html",
531
+ ".css": "text/css",
532
+ ".js": "application/javascript",
533
+ ".png": "image/png",
534
+ ".jpg": "image/jpeg",
535
+ ".gif": "image/gif",
536
+ ".svg": "image/svg+xml",
537
+ ".json": "application/json",
538
+ };
539
+ const requestedFilePath = params["*"];
540
+ const filePath = path_1.default.join(swaggerUiPath, requestedFilePath);
541
+ const extname = path_1.default.extname(filePath);
542
+ const contentType = mimeTypes[extname] || "text/html";
456
543
  const content = fs_1.default.readFileSync(filePath);
457
- res.writeHead(200, { 'Content-Type': contentType });
458
- return res.end(content, 'utf-8');
544
+ res.writeHead(200, { "Content-Type": contentType });
545
+ return res.end(content, "utf-8");
459
546
  }
460
547
  catch (err) {
461
- res.writeHead(404, { 'Content-Type': contentType });
462
- return res.end(`The file '${requestedFilePath}' is not exists`);
548
+ res.writeHead(404, { "Content-Type": "text/plain" });
549
+ return res.end("Not found");
463
550
  }
464
551
  };
465
552
  return {
466
553
  path: doc.path,
467
554
  staticUrl: `${STATIC_URL}/*`,
468
555
  staticSwaggerHandler,
469
- html
556
+ html,
470
557
  };
471
558
  }
472
559
  }