tspace-spear 1.2.7 → 1.2.9-beta.1

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 (99) hide show
  1. package/README.md +347 -155
  2. package/dist/cli/generators/app/index.d.ts +1 -0
  3. package/dist/cli/generators/app/index.js +124 -0
  4. package/dist/cli/generators/app/index.js.map +1 -0
  5. package/dist/cli/generators/app/template.d.ts +1 -0
  6. package/dist/cli/generators/app/template.js +42 -0
  7. package/dist/cli/generators/app/template.js.map +1 -0
  8. package/dist/cli/generators/client/template.d.ts +1 -0
  9. package/dist/cli/generators/client/template.js +30 -0
  10. package/dist/cli/generators/client/template.js.map +1 -0
  11. package/dist/cli/generators/controller/index.d.ts +1 -0
  12. package/dist/cli/generators/controller/index.js +78 -0
  13. package/dist/cli/generators/controller/index.js.map +1 -0
  14. package/dist/cli/generators/controller/template.d.ts +1 -0
  15. package/dist/cli/generators/controller/template.js +108 -0
  16. package/dist/cli/generators/controller/template.js.map +1 -0
  17. package/dist/cli/generators/dto/index.d.ts +1 -0
  18. package/dist/cli/generators/dto/index.js +57 -0
  19. package/dist/cli/generators/dto/index.js.map +1 -0
  20. package/dist/cli/generators/dto/template.d.ts +1 -0
  21. package/dist/cli/generators/dto/template.js +32 -0
  22. package/dist/cli/generators/dto/template.js.map +1 -0
  23. package/dist/cli/generators/middleware/index.d.ts +1 -0
  24. package/dist/cli/generators/middleware/index.js +38 -0
  25. package/dist/cli/generators/middleware/index.js.map +1 -0
  26. package/dist/cli/generators/middleware/template.d.ts +1 -0
  27. package/dist/cli/generators/middleware/template.js +16 -0
  28. package/dist/cli/generators/middleware/template.js.map +1 -0
  29. package/dist/cli/generators/module/index.d.ts +1 -0
  30. package/dist/cli/generators/module/index.js +173 -0
  31. package/dist/cli/generators/module/index.js.map +1 -0
  32. package/dist/cli/generators/service/index.d.ts +1 -0
  33. package/dist/cli/generators/service/index.js +53 -0
  34. package/dist/cli/generators/service/index.js.map +1 -0
  35. package/dist/cli/generators/service/template.d.ts +1 -0
  36. package/dist/cli/generators/service/template.js +74 -0
  37. package/dist/cli/generators/service/template.js.map +1 -0
  38. package/dist/cli/generators/shared/index.d.ts +3 -0
  39. package/dist/cli/generators/shared/index.js +22 -0
  40. package/dist/cli/generators/shared/index.js.map +1 -0
  41. package/dist/cli/index.js +55 -96
  42. package/dist/cli/index.js.map +1 -1
  43. package/dist/lib/core/client/index.d.ts +13 -43
  44. package/dist/lib/core/client/index.js +70 -33
  45. package/dist/lib/core/client/index.js.map +1 -1
  46. package/dist/lib/core/client/types.d.ts +43 -0
  47. package/dist/lib/core/client/types.js +3 -0
  48. package/dist/lib/core/client/types.js.map +1 -0
  49. package/dist/lib/core/compiler/generator.d.ts +4 -6
  50. package/dist/lib/core/compiler/generator.js +190 -39
  51. package/dist/lib/core/compiler/generator.js.map +1 -1
  52. package/dist/lib/core/compiler/index.d.ts +2 -2
  53. package/dist/lib/core/compiler/index.js +2 -2
  54. package/dist/lib/core/compiler/index.js.map +1 -1
  55. package/dist/lib/core/compiler/pre-routes.d.ts +12 -130
  56. package/dist/lib/core/compiler/pre-routes.js +13 -35
  57. package/dist/lib/core/compiler/pre-routes.js.map +1 -1
  58. package/dist/lib/core/compiler/types.d.ts +25 -0
  59. package/dist/lib/core/decorators/context.d.ts +78 -8
  60. package/dist/lib/core/decorators/context.js +84 -9
  61. package/dist/lib/core/decorators/context.js.map +1 -1
  62. package/dist/lib/core/decorators/controller.js +2 -1
  63. package/dist/lib/core/decorators/controller.js.map +1 -1
  64. package/dist/lib/core/decorators/index.d.ts +1 -0
  65. package/dist/lib/core/decorators/index.js +1 -0
  66. package/dist/lib/core/decorators/index.js.map +1 -1
  67. package/dist/lib/core/decorators/methods.js +4 -3
  68. package/dist/lib/core/decorators/methods.js.map +1 -1
  69. package/dist/lib/core/decorators/middleware.d.ts +40 -2
  70. package/dist/lib/core/decorators/middleware.js +54 -9
  71. package/dist/lib/core/decorators/middleware.js.map +1 -1
  72. package/dist/lib/core/decorators/service.d.ts +28 -0
  73. package/dist/lib/core/decorators/service.js +36 -0
  74. package/dist/lib/core/decorators/service.js.map +1 -0
  75. package/dist/lib/core/decorators/statusCode.js +3 -1
  76. package/dist/lib/core/decorators/statusCode.js.map +1 -1
  77. package/dist/lib/core/decorators/swagger.js +4 -3
  78. package/dist/lib/core/decorators/swagger.js.map +1 -1
  79. package/dist/lib/core/exception/index.d.ts +68 -0
  80. package/dist/lib/core/exception/index.js +123 -0
  81. package/dist/lib/core/exception/index.js.map +1 -0
  82. package/dist/lib/core/metadata/index.d.ts +6 -0
  83. package/dist/lib/core/metadata/index.js +13 -0
  84. package/dist/lib/core/metadata/index.js.map +1 -0
  85. package/dist/lib/core/package/index.d.ts +11 -0
  86. package/dist/lib/core/package/index.js +42 -0
  87. package/dist/lib/core/package/index.js.map +1 -0
  88. package/dist/lib/core/server/fast-router.d.ts +2 -2
  89. package/dist/lib/core/server/fast-router.js +17 -3
  90. package/dist/lib/core/server/fast-router.js.map +1 -1
  91. package/dist/lib/core/server/index.d.ts +32 -5
  92. package/dist/lib/core/server/index.js +188 -45
  93. package/dist/lib/core/server/index.js.map +1 -1
  94. package/dist/lib/core/server/parser-factory.js +59 -10
  95. package/dist/lib/core/server/parser-factory.js.map +1 -1
  96. package/dist/lib/core/server/response.js +21 -1
  97. package/dist/lib/core/server/response.js.map +1 -1
  98. package/dist/lib/core/types/index.d.ts +42 -29
  99. package/package.json +15 -6
@@ -5,6 +5,20 @@ const METHODS = [
5
5
  "GET", "POST", "PUT", "PATCH",
6
6
  "DELETE", "OPTIONS", "HEAD"
7
7
  ];
8
+ const parseValue = (value) => {
9
+ if (/^-?\d+(\.\d+)?$/.test(value)) {
10
+ const num = Number(value);
11
+ if (Number.isFinite(num) &&
12
+ Number.isSafeInteger(num)) {
13
+ return num;
14
+ }
15
+ if (Number.isFinite(num) &&
16
+ !Number.isInteger(num)) {
17
+ return num;
18
+ }
19
+ }
20
+ return value;
21
+ };
8
22
  class FastRouter {
9
23
  trees = Object.create(null);
10
24
  _routes = [];
@@ -146,8 +160,8 @@ class FastRouter {
146
160
  * It supports parameterized routes, static routes, and (optionally)
147
161
  * wildcard matching depending on router implementation.
148
162
  *
149
- * @param req Incoming HTTP request object
150
- * @param res Server response object used to send output
163
+ * @param {IncomingMessage} req Incoming HTTP request object
164
+ * @param {ServerResponse} res Server response object used to send output
151
165
  *
152
166
  * @returns void
153
167
  *
@@ -189,7 +203,7 @@ class FastRouter {
189
203
  continue;
190
204
  }
191
205
  if (node.param) {
192
- params[node.param.paramName] = part;
206
+ params[node.param.paramName] = parseValue(part);
193
207
  node = node.param;
194
208
  start = i + 1;
195
209
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"fast-router.js","sourceRoot":"","sources":["../../../../src/lib/core/server/fast-router.ts"],"names":[],"mappings":";;;AAiBA,MAAM,OAAO,GAAG;IACd,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;IAC7B,QAAQ,EAAE,SAAS,EAAE,MAAM;CACnB,CAAA;AAGV,MAAa,UAAU;IACb,KAAK,GAAyB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,GAAc,EAAE,CAAA;IAE/B;QACE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;OAWG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAY,EAAE,OAAgB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,IAAY,EAAE,OAAgB;QACzC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,IAAY,EAAE,OAAgB;QAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,OAAO,CAAC,IAAY,EAAE,OAAgB;QAC3C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAY,EAAE,OAAgB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,KAAI,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,MAAM,CAAC,GAAoB,EAAE,GAAmB;QACrD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAO,CAAC;QAE3B,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;gBACtB,OAAM;YACR,CAAC;YACD,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,OAAO,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpC,MAAM,MAAM,GAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE3D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC;QAEnC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;gBACvC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;gBAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;gBACV,CAAC;gBAED,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAE7B,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,GAAG,IAAI,CAAA;oBACX,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;gBACV,CAAC;gBAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAU,CAAC,GAAG,IAAI,CAAA;oBACpC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;oBACjB,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;gBACV,CAAC;gBAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC/B,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;oBACrB,MAAK;gBACP,CAAC;gBAED,IAAI,YAAY,EAAE,OAAO,EAAE,CAAC;oBAC1B,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;gBAC/C,CAAC;gBAED,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;oBACtB,OAAM;gBACR,CAAC;gBAED,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;gBACrB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QAEA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAEnB,IAAI,YAAY,EAAE,OAAO,EAAE,CAAC;gBAC1B,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAChD,CAAC;YAED,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC;IAEO,WAAW;QACjB,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAA;IACxC,CAAC;IAEO,IAAI,CAAC,MAAc,EAAE,IAAY,EAAE,OAAgB;QACzD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAElC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAS;gBACX,CAAC;gBAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBAEpB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;wBAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;wBAChC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACvC,CAAC;oBAED,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;gBACpB,CAAC;qBAEI,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;oBAEtB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrC,CAAC;oBACD,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;oBAErB,MAAK;gBACP,CAAC;qBAEI,CAAC;oBAEJ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;wBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;oBACzC,CAAC;oBAED,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC;gBAED,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QAEH,OAAO;IACT,CAAC;IAEO,cAAc,CAAC,IAAY;QACjC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAElC,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7B,CAAC;gBAED,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA1UD,gCA0UC"}
1
+ {"version":3,"file":"fast-router.js","sourceRoot":"","sources":["../../../../src/lib/core/server/fast-router.ts"],"names":[],"mappings":"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"}
@@ -84,13 +84,38 @@ declare class Spear {
84
84
  /**
85
85
  * The 'useGlobalPrefix' method is used to sets a global prefix for all routes in the router.
86
86
  *
87
- * If `globalPrefix` is `null` or `undefined`, it will default to an empty string,
88
- * meaning no prefix will be applied.
87
+ * This prefix will be prepended to every route path in the application.
88
+ * If `path` is `null`, `undefined`, or an empty string, no global prefix
89
+ * will be applied.
89
90
  *
90
- * @param {string | null} globalPrefix - The base path prefix to apply to all routes.
91
- * @returns {this} Returns the current instance for method chaining.
91
+ * @param {string} path - The global route prefix.
92
+ *
93
+ * @param {Object} [options] - Additional configuration options.
94
+ * @param {Array<{ path: string; method?: TMethod | TMethod[] }>} [options.exclude]
95
+ * Routes to exclude from the global prefix.
96
+ *
97
+ * @returns {this} Returns the current router instance for chaining.
98
+ *
99
+ * @example
100
+ * import Spear from "tspace-spear";
101
+ * const app = new Spear()
102
+ *
103
+ * app.useGlobalPrefix('/api');
104
+ *
105
+ * @example
106
+ * app.useGlobalPrefix('/api', {
107
+ * exclude: [
108
+ * { path: '/health' },
109
+ * { path: '/auth/login', method: 'POST' }
110
+ * ]
111
+ * });
92
112
  */
93
- useGlobalPrefix(globalPrefix: string | null): this;
113
+ useGlobalPrefix(path: string | null, options?: {
114
+ exclude?: {
115
+ path: string;
116
+ methods?: T.MethodInput[] | '*';
117
+ }[];
118
+ }): this;
94
119
  /**
95
120
  * The 'useAdater' method is used to switch between different server implementations,
96
121
  * such as the native Node.js HTTP server or uWebSockets.js (uWS).
@@ -299,6 +324,7 @@ declare class Spear {
299
324
  private _import;
300
325
  private _scan;
301
326
  private _registerControllers;
327
+ private _createController;
302
328
  private _registerMiddlewares;
303
329
  private _wrapHandlers;
304
330
  private _wrapResponse;
@@ -308,6 +334,7 @@ declare class Spear {
308
334
  private _createContext;
309
335
  private _normalizePath;
310
336
  private _swaggerHandler;
337
+ private _resolveGlobalPrefix;
311
338
  }
312
339
  export declare class Application extends Spear {
313
340
  }
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
37
  };
@@ -43,6 +53,7 @@ const response_1 = require("./response");
43
53
  const compiler_1 = require("../compiler");
44
54
  const uWS_1 = require("./uWS");
45
55
  const net_2 = require("./net");
56
+ const metadata_1 = require("../metadata");
46
57
  /**
47
58
  *
48
59
  * The 'Spear' class is used to create a server and handle HTTP requests.
@@ -64,7 +75,12 @@ class Spear {
64
75
  _middlewares;
65
76
  _router = new fast_router_1.FastRouter();
66
77
  _parser = new parser_factory_1.ParserFactory();
67
- _globalPrefix = '';
78
+ _globalPrefix = {
79
+ path: '',
80
+ options: {
81
+ exclude: []
82
+ }
83
+ };
68
84
  _adapter = { kind: 'http', server: http_1.default };
69
85
  _cluster;
70
86
  _cors;
@@ -190,14 +206,45 @@ class Spear {
190
206
  /**
191
207
  * The 'useGlobalPrefix' method is used to sets a global prefix for all routes in the router.
192
208
  *
193
- * If `globalPrefix` is `null` or `undefined`, it will default to an empty string,
194
- * meaning no prefix will be applied.
209
+ * This prefix will be prepended to every route path in the application.
210
+ * If `path` is `null`, `undefined`, or an empty string, no global prefix
211
+ * will be applied.
212
+ *
213
+ * @param {string} path - The global route prefix.
214
+ *
215
+ * @param {Object} [options] - Additional configuration options.
216
+ * @param {Array<{ path: string; method?: TMethod | TMethod[] }>} [options.exclude]
217
+ * Routes to exclude from the global prefix.
195
218
  *
196
- * @param {string | null} globalPrefix - The base path prefix to apply to all routes.
197
- * @returns {this} Returns the current instance for method chaining.
219
+ * @returns {this} Returns the current router instance for chaining.
220
+ *
221
+ * @example
222
+ * import Spear from "tspace-spear";
223
+ * const app = new Spear()
224
+ *
225
+ * app.useGlobalPrefix('/api');
226
+ *
227
+ * @example
228
+ * app.useGlobalPrefix('/api', {
229
+ * exclude: [
230
+ * { path: '/health' },
231
+ * { path: '/auth/login', method: 'POST' }
232
+ * ]
233
+ * });
198
234
  */
199
- useGlobalPrefix(globalPrefix) {
200
- this._globalPrefix = globalPrefix == null ? '' : globalPrefix;
235
+ useGlobalPrefix(path, options) {
236
+ this._globalPrefix.path = path == null
237
+ ? ''
238
+ : path.replace(/^\/+|\/+$/g, '');
239
+ this._globalPrefix.options.exclude = (options?.exclude ?? []).map(route => {
240
+ const method = route.methods == null || route.methods === '*'
241
+ ? '*'
242
+ : route.methods.map(m => m.toUpperCase());
243
+ return {
244
+ path: route.path.replace(/^\/+|\/+$/g, ''),
245
+ method
246
+ };
247
+ });
201
248
  return this;
202
249
  }
203
250
  /**
@@ -382,7 +429,7 @@ class Spear {
382
429
  useRouter(router) {
383
430
  const routes = router.routes;
384
431
  for (const { path, method, handlers } of routes) {
385
- this[method](this._normalizePath(this._globalPrefix, path), ...handlers);
432
+ this[method](this._normalizePath(this._resolveGlobalPrefix({ path, method }), path), ...handlers);
386
433
  }
387
434
  return this;
388
435
  }
@@ -417,7 +464,7 @@ class Spear {
417
464
  }
418
465
  const server = await this._createServer();
419
466
  if (this._generatePreRouteTypes) {
420
- await new compiler_1.Compiler().generateRoutes(this._generatePreRouteTypes);
467
+ await new compiler_1.Compiler().generateRoutes(this._globalPrefix.path, this._generatePreRouteTypes);
421
468
  }
422
469
  if (this._cluster != null &&
423
470
  this._cluster || typeof this._cluster === 'number') {
@@ -542,7 +589,7 @@ class Spear {
542
589
  */
543
590
  get(path, ...handlers) {
544
591
  this._onListeners.push(() => {
545
- return this._router.get(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
592
+ return this._router.get(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'get' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
546
593
  });
547
594
  return this;
548
595
  }
@@ -557,7 +604,7 @@ class Spear {
557
604
  */
558
605
  post(path, ...handlers) {
559
606
  this._onListeners.push(() => {
560
- return this._router.post(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
607
+ return this._router.post(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'post' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
561
608
  });
562
609
  return this;
563
610
  }
@@ -572,7 +619,7 @@ class Spear {
572
619
  */
573
620
  put(path, ...handlers) {
574
621
  this._onListeners.push(() => {
575
- return this._router.put(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
622
+ return this._router.put(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'put' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
576
623
  });
577
624
  return this;
578
625
  }
@@ -587,7 +634,7 @@ class Spear {
587
634
  */
588
635
  patch(path, ...handlers) {
589
636
  this._onListeners.push(() => {
590
- return this._router.patch(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
637
+ return this._router.patch(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'patch' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
591
638
  });
592
639
  return this;
593
640
  }
@@ -602,7 +649,7 @@ class Spear {
602
649
  */
603
650
  delete(path, ...handlers) {
604
651
  this._onListeners.push(() => {
605
- return this._router.delete(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
652
+ return this._router.delete(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'delete' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
606
653
  });
607
654
  return this;
608
655
  }
@@ -617,7 +664,7 @@ class Spear {
617
664
  */
618
665
  head(path, ...handlers) {
619
666
  this._onListeners.push(() => {
620
- return this._router.head(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
667
+ return this._router.head(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'head' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
621
668
  });
622
669
  return this;
623
670
  }
@@ -632,7 +679,7 @@ class Spear {
632
679
  */
633
680
  options(path, ...handlers) {
634
681
  this._onListeners.push(() => {
635
- return this._router.options(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
682
+ return this._router.options(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'options' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
636
683
  });
637
684
  return this;
638
685
  }
@@ -647,7 +694,7 @@ class Spear {
647
694
  */
648
695
  all(path, ...handlers) {
649
696
  this._onListeners.push(() => {
650
- return this._router.all(this._normalizePath(this._globalPrefix, path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
697
+ return this._router.all(this._normalizePath(this._resolveGlobalPrefix({ path, method: 'all' }), path), this._wrapHandlers(...this._globalMiddlewares, ...handlers));
651
698
  });
652
699
  return this;
653
700
  }
@@ -717,52 +764,100 @@ class Spear {
717
764
  console.log(`\x1b[31m[ControllerLoader ERROR]\x1b[0m \x1b[36m${file}\x1b[0m must export a controller class`);
718
765
  continue;
719
766
  }
720
- const controllerInstance = new controller();
721
- const prefixPath = Reflect.getMetadata("controllers", controller) ?? '';
722
- const routers = Reflect.getMetadata("routers", controller) ?? [];
723
- const swaggers = Reflect.getMetadata("swaggers", controller) ?? [];
724
- if (prefixPath == null)
725
- continue;
767
+ const controllerInstance = this._createController(controller);
768
+ const prefixPath = Reflect.getMetadata(metadata_1.CONTROLLER_METADATA, controller) ?? '';
769
+ const routers = Reflect.getMetadata(metadata_1.ROUTE_METADATA, controller) ?? [];
770
+ const swaggers = Reflect.getMetadata(metadata_1.SWAGGER_METADATA, controller) ?? [];
726
771
  for (const { method, path, handler } of Array.from(routers)) {
727
772
  const find = Array.from(swaggers).find(s => s.handler === handler);
728
773
  if (find != null) {
774
+ const globalPrefix = this._resolveGlobalPrefix({
775
+ path: this._normalizePath(prefixPath, path),
776
+ method
777
+ });
729
778
  this._swaggerSpecs = [
730
779
  ...this._swaggerSpecs,
731
780
  {
732
781
  ...find,
733
- path: this._normalizePath(this._globalPrefix, prefixPath, path),
782
+ path: this._normalizePath(globalPrefix, prefixPath, path),
734
783
  method
735
784
  }
736
785
  ];
737
786
  }
738
- this[method](this._normalizePath(this._globalPrefix, prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
787
+ this[method](this._normalizePath(prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
739
788
  }
740
789
  }
741
790
  return;
742
791
  }
743
792
  for (const controller of this._controllers) {
744
- const controllerInstance = new controller();
745
- const prefixPath = Reflect.getMetadata("controllers", controller) ?? '';
746
- const routers = Reflect.getMetadata("routers", controller) ?? [];
747
- const swaggers = Reflect.getMetadata("swaggers", controller) ?? [];
748
- if (prefixPath == null)
749
- continue;
793
+ const controllerInstance = this._createController(controller);
794
+ const prefixPath = Reflect.getMetadata(metadata_1.CONTROLLER_METADATA, controller) ?? '';
795
+ const routers = Reflect.getMetadata(metadata_1.ROUTE_METADATA, controller) ?? [];
796
+ const swaggers = Reflect.getMetadata(metadata_1.SWAGGER_METADATA, controller) ?? [];
750
797
  for (const { method, path, handler } of Array.from(routers)) {
751
798
  const find = Array.from(swaggers).find(s => s.handler === handler);
752
799
  if (find != null) {
800
+ const globalPrefix = this._resolveGlobalPrefix({
801
+ path: this._normalizePath(prefixPath, path),
802
+ method
803
+ });
753
804
  this._swaggerSpecs = [
754
805
  ...this._swaggerSpecs,
755
806
  {
756
807
  ...find,
757
- path: this._normalizePath(this._globalPrefix, prefixPath, path),
808
+ path: this._normalizePath(globalPrefix, prefixPath, path),
758
809
  method
759
810
  }
760
811
  ];
761
812
  }
762
- this[method](this._normalizePath(this._globalPrefix, prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
813
+ this[method](this._normalizePath(prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
763
814
  }
764
815
  }
765
816
  }
817
+ _createController(ControllerClass) {
818
+ const services = Reflect.getMetadata(metadata_1.SERVICE_METADATA, ControllerClass) ?? [];
819
+ const constructorTypes = Reflect.getMetadata(metadata_1.PARAMTYPES_METADATA, ControllerClass) ?? [];
820
+ if (!constructorTypes.length) {
821
+ return new ControllerClass();
822
+ }
823
+ if (!services.length) {
824
+ throw new Error(`\x1b[31m[ServiceLoader ERROR]\x1b[0m \x1b[36m${ControllerClass.name}\x1b[0m requires dependencies but no @Service() decorator was found`);
825
+ }
826
+ const serviceMap = new Map();
827
+ for (const ServiceClass of services) {
828
+ if (typeof ServiceClass !== 'function') {
829
+ throw new Error(`\x1b[31m[ServiceLoader ERROR]\x1b[0m Invalid service in @Service() of ${ControllerClass.name}`);
830
+ }
831
+ serviceMap.set(ServiceClass, new ServiceClass());
832
+ }
833
+ const injections = [];
834
+ const available = services.length
835
+ ? services
836
+ .map((s) => s.name)
837
+ : 'None';
838
+ for (const DependencyClass of constructorTypes) {
839
+ const service = serviceMap.get(DependencyClass);
840
+ if (!service) {
841
+ throw new Error([
842
+ '\x1b[31m[ServiceLoader ERROR]\x1b[0m',
843
+ '',
844
+ `\x1b[36mController\x1b[0m : ${ControllerClass.name}`,
845
+ `\x1b[36mDependency\x1b[0m : ${DependencyClass.name}`,
846
+ `\x1b[36mAvailable \x1b[0m : ${available.join(', ')}`,
847
+ '',
848
+ '\x1b[33mHint\x1b[0m',
849
+ '@Service([',
850
+ ` ${available.join(',\n ')},`,
851
+ ` ${DependencyClass.name}`,
852
+ '])',
853
+ '',
854
+ `Register '${DependencyClass.name}' in @Service()`
855
+ ].join('\n'));
856
+ }
857
+ injections.push(service);
858
+ }
859
+ return new ControllerClass(...injections);
860
+ }
766
861
  async _registerMiddlewares() {
767
862
  if (this._middlewares == null)
768
863
  return;
@@ -865,6 +960,10 @@ class Spear {
865
960
  _nextError(ctx) {
866
961
  const NEXT_MESSAGE = "The 'next' function does not have any subsequent function.";
867
962
  return (err) => {
963
+ const status = typeof err?.statusCode === 'number' &&
964
+ Number.isFinite(err.statusCode)
965
+ ? err.statusCode
966
+ : 500;
868
967
  if (ctx.res.writableEnded)
869
968
  return;
870
969
  const errorMessage = err?.message || NEXT_MESSAGE;
@@ -872,7 +971,7 @@ class Spear {
872
971
  return this._errorHandler(err, ctx);
873
972
  }
874
973
  if (!ctx.res.headersSent) {
875
- ctx.res.writeHead(500, const_1.HEADER_CONTENT_TYPES['json']);
974
+ ctx.res.writeHead(status, const_1.HEADER_CONTENT_TYPES['json']);
876
975
  }
877
976
  if (this._formatResponse != null) {
878
977
  ctx.res.end(JSON.stringify(this._formatResponse({
@@ -1069,13 +1168,25 @@ class Spear {
1069
1168
  }
1070
1169
  _normalizePath(...paths) {
1071
1170
  const path = paths
1171
+ .filter(Boolean)
1072
1172
  .join('/')
1073
1173
  .replace(/\/+/g, '/')
1074
1174
  .replace(/\/+$/, '');
1075
- const normalizedPath = path.startsWith('/') ? path : `/${path}`;
1076
- return /\/api\/api/.test(normalizedPath)
1077
- ? normalizedPath.replace(/\/api\/api\//, "/api/")
1078
- : normalizedPath;
1175
+ let normalizedPath = path.startsWith('/')
1176
+ ? path
1177
+ : `/${path}`;
1178
+ const globalPrefix = this._globalPrefix.path
1179
+ .replace(/^\/+|\/+$/g, '');
1180
+ if (globalPrefix) {
1181
+ const duplicatedPrefix = `/${globalPrefix}/${globalPrefix}/`;
1182
+ normalizedPath =
1183
+ normalizedPath.replace(duplicatedPrefix, `/${globalPrefix}/`);
1184
+ if (normalizedPath ===
1185
+ `/${globalPrefix}/${globalPrefix}`) {
1186
+ normalizedPath = `/${globalPrefix}`;
1187
+ }
1188
+ }
1189
+ return normalizedPath || '/';
1079
1190
  }
1080
1191
  async _swaggerHandler() {
1081
1192
  const routes = this.routers
@@ -1102,6 +1213,38 @@ class Spear {
1102
1213
  });
1103
1214
  return;
1104
1215
  }
1216
+ _resolveGlobalPrefix({ path, method }) {
1217
+ const globalPrefix = this._globalPrefix.path;
1218
+ if (!globalPrefix) {
1219
+ return '';
1220
+ }
1221
+ if (path === '*') {
1222
+ return `/${globalPrefix}`;
1223
+ }
1224
+ const cleanPath = path.replace(/^\/+|\/+$/g, '');
1225
+ const upperMethod = method.toUpperCase();
1226
+ const exclude = this._globalPrefix.options.exclude;
1227
+ const isExcluded = exclude.some(route => {
1228
+ const methods = route.method ?? '*';
1229
+ if (methods !== '*' &&
1230
+ !methods.includes(upperMethod)) {
1231
+ return false;
1232
+ }
1233
+ const routePath = route.path.replace(/^\/+|\/+$/g, '');
1234
+ if (routePath === cleanPath) {
1235
+ return true;
1236
+ }
1237
+ if (routePath.endsWith('/*')) {
1238
+ const basePath = routePath.slice(0, -2);
1239
+ return (cleanPath === basePath ||
1240
+ cleanPath.startsWith(basePath + '/'));
1241
+ }
1242
+ return false;
1243
+ });
1244
+ return isExcluded
1245
+ ? ''
1246
+ : `/${globalPrefix}`;
1247
+ }
1105
1248
  }
1106
1249
  exports.Spear = Spear;
1107
1250
  class Application extends Spear {