exisjs 0.7.12 → 0.7.14

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 (132) hide show
  1. package/README.md +195 -39
  2. package/dist/cli/commands/run.d.ts.map +1 -1
  3. package/dist/cli/commands/run.js +3 -1
  4. package/dist/cli/commands/run.js.map +1 -1
  5. package/dist/config/types.d.ts +2 -2
  6. package/dist/config/types.d.ts.map +1 -1
  7. package/dist/decorators/params.d.ts +21 -0
  8. package/dist/decorators/params.d.ts.map +1 -1
  9. package/dist/decorators/params.js +21 -1
  10. package/dist/decorators/params.js.map +1 -1
  11. package/dist/di/container.d.ts +15 -6
  12. package/dist/di/container.d.ts.map +1 -1
  13. package/dist/di/container.js +26 -3
  14. package/dist/di/container.js.map +1 -1
  15. package/dist/di/index.d.ts +1 -1
  16. package/dist/di/index.d.ts.map +1 -1
  17. package/dist/di/index.js.map +1 -1
  18. package/dist/di/inject.d.ts +2 -1
  19. package/dist/di/inject.d.ts.map +1 -1
  20. package/dist/di/inject.js +2 -1
  21. package/dist/di/inject.js.map +1 -1
  22. package/dist/docs/ARCHITECTURE.md +130 -78
  23. package/dist/docs/BENCHMARKS.md +4 -4
  24. package/dist/docs/content/README.md +43 -44
  25. package/dist/docs/content/boundaries.mdx +138 -61
  26. package/dist/docs/content/cli/commands.mdx +151 -128
  27. package/dist/docs/content/cli/overview.mdx +61 -47
  28. package/dist/docs/content/cli/usage.mdx +107 -30
  29. package/dist/docs/content/config.mdx +145 -158
  30. package/dist/docs/content/controllers.mdx +193 -464
  31. package/dist/docs/content/cron.mdx +183 -69
  32. package/dist/docs/content/decorators.mdx +449 -154
  33. package/dist/docs/content/errors.mdx +202 -305
  34. package/dist/docs/content/exisjs-mcp.mdx +59 -49
  35. package/dist/docs/content/installation.mdx +243 -157
  36. package/dist/docs/content/introduction.mdx +220 -48
  37. package/dist/docs/content/middleware.mdx +171 -497
  38. package/dist/docs/content/modules.mdx +141 -83
  39. package/dist/docs/content/providers.mdx +216 -180
  40. package/dist/docs/content/requests.mdx +168 -488
  41. package/dist/docs/content/responses.mdx +200 -533
  42. package/dist/docs/content/routing.mdx +235 -598
  43. package/dist/docs/content/security.mdx +233 -57
  44. package/dist/docs/content/structure.mdx +151 -240
  45. package/dist/docs/content/swagger.mdx +192 -91
  46. package/dist/docs/content/testing.mdx +205 -74
  47. package/dist/docs/content/validation.mdx +479 -341
  48. package/dist/docs/reference/README.md +34 -2
  49. package/dist/docs/reference/config.mdx +277 -75
  50. package/dist/docs/reference/context.mdx +197 -106
  51. package/dist/docs/reference/cron.mdx +266 -152
  52. package/dist/docs/reference/database.mdx +135 -53
  53. package/dist/docs/reference/decorators.mdx +234 -116
  54. package/dist/docs/reference/di.mdx +146 -112
  55. package/dist/docs/reference/error.mdx +155 -178
  56. package/dist/docs/reference/exis.mdx +141 -70
  57. package/dist/docs/reference/logger.mdx +110 -126
  58. package/dist/docs/reference/middleware.mdx +235 -158
  59. package/dist/docs/reference/plugin.mdx +136 -64
  60. package/dist/docs/reference/router.mdx +275 -293
  61. package/dist/docs/reference/sanitize.mdx +91 -87
  62. package/dist/docs/reference/swagger.mdx +280 -100
  63. package/dist/docs/reference/testing.mdx +223 -89
  64. package/dist/docs/reference/validator.mdx +194 -206
  65. package/dist/lib/start-server.js +22 -8
  66. package/dist/lib/start-server.js.map +1 -1
  67. package/dist/module/module.d.ts +6 -3
  68. package/dist/module/module.d.ts.map +1 -1
  69. package/dist/module/module.js +17 -3
  70. package/dist/module/module.js.map +1 -1
  71. package/dist/router/controller-registrar.d.ts.map +1 -1
  72. package/dist/router/controller-registrar.js +26 -4
  73. package/dist/router/controller-registrar.js.map +1 -1
  74. package/dist/router/scanner/fs-scanner.d.ts.map +1 -1
  75. package/dist/router/scanner/fs-scanner.js +22 -0
  76. package/dist/router/scanner/fs-scanner.js.map +1 -1
  77. package/dist/router/types.d.ts +6 -4
  78. package/dist/router/types.d.ts.map +1 -1
  79. package/dist/server/app.d.ts +3 -1
  80. package/dist/server/app.d.ts.map +1 -1
  81. package/dist/server/app.js +24 -8
  82. package/dist/server/app.js.map +1 -1
  83. package/dist/server/bootstrapper.d.ts.map +1 -1
  84. package/dist/server/bootstrapper.js +19 -0
  85. package/dist/server/bootstrapper.js.map +1 -1
  86. package/dist/server/request.d.ts +2 -0
  87. package/dist/server/request.d.ts.map +1 -1
  88. package/dist/server/request.js +11 -0
  89. package/dist/server/request.js.map +1 -1
  90. package/dist/server/response.d.ts +10 -5
  91. package/dist/server/response.d.ts.map +1 -1
  92. package/dist/server/response.js +65 -18
  93. package/dist/server/response.js.map +1 -1
  94. package/dist/swagger/generator.d.ts.map +1 -1
  95. package/dist/swagger/generator.js +130 -10
  96. package/dist/swagger/generator.js.map +1 -1
  97. package/dist/telemetry/index.d.ts +12 -0
  98. package/dist/telemetry/index.d.ts.map +1 -0
  99. package/dist/telemetry/index.js +121 -0
  100. package/dist/telemetry/index.js.map +1 -0
  101. package/dist/testing/client.d.ts +1 -0
  102. package/dist/testing/client.d.ts.map +1 -1
  103. package/dist/testing/client.js +4 -1
  104. package/dist/testing/client.js.map +1 -1
  105. package/dist/testing/index.d.ts.map +1 -1
  106. package/dist/testing/index.js +11 -4
  107. package/dist/testing/index.js.map +1 -1
  108. package/dist/validator/builder.d.ts +26 -1
  109. package/dist/validator/builder.d.ts.map +1 -1
  110. package/dist/validator/builder.js +31 -0
  111. package/dist/validator/builder.js.map +1 -1
  112. package/dist/validator/engine.d.ts +23 -0
  113. package/dist/validator/engine.d.ts.map +1 -1
  114. package/dist/validator/engine.js +228 -31
  115. package/dist/validator/engine.js.map +1 -1
  116. package/dist/validator/index.d.ts +8 -4
  117. package/dist/validator/index.d.ts.map +1 -1
  118. package/dist/validator/index.js +4 -1
  119. package/dist/validator/index.js.map +1 -1
  120. package/dist/validator/tex-types.d.ts +19 -4
  121. package/dist/validator/tex-types.d.ts.map +1 -1
  122. package/dist/validator/tex-types.js +102 -0
  123. package/dist/validator/tex-types.js.map +1 -1
  124. package/dist/validator/tex.d.ts +1 -1
  125. package/dist/validator/tex.d.ts.map +1 -1
  126. package/dist/validator/tex.js +3 -1
  127. package/dist/validator/tex.js.map +1 -1
  128. package/dist/validator/types.d.ts +1 -0
  129. package/dist/validator/types.d.ts.map +1 -1
  130. package/package.json +46 -14
  131. package/dist/docs/content/dataloader.mdx +0 -170
  132. package/dist/docs/reference/dataloader.mdx +0 -91
@@ -5,13 +5,36 @@ class TexType {
5
5
  constructor(_raw, defaultValue) {
6
6
  this._raw = _raw;
7
7
  this.sanitizers = [];
8
+ this.transformations = [];
8
9
  this.refinements = [];
9
10
  this.defaultValue = defaultValue;
10
11
  }
12
+ describe(description) {
13
+ this.description = description;
14
+ return this;
15
+ }
16
+ example(example) {
17
+ this.exampleValue = example;
18
+ return this;
19
+ }
20
+ setExample(example) {
21
+ this.exampleValue = example;
22
+ return this;
23
+ }
11
24
  sanitize(...fns) {
12
25
  this.sanitizers.push(...fns);
13
26
  return this;
14
27
  }
28
+ transform(fn) {
29
+ const clone = new TexType(this._raw, this.defaultValue);
30
+ clone.sanitizers = [...this.sanitizers];
31
+ clone.transformations = [...this.transformations, fn];
32
+ clone.refinements = [...this.refinements];
33
+ clone.description = this.description;
34
+ clone.exampleValue = this.exampleValue;
35
+ clone.__kind = 'TexTransformed';
36
+ return clone;
37
+ }
15
38
  refine(fn, message) {
16
39
  this.refinements.push({ async: false, fn, message });
17
40
  return this;
@@ -32,6 +55,85 @@ class TexType {
32
55
  this._raw += ' | nullish';
33
56
  return this;
34
57
  }
58
+ toOpenApi() {
59
+ const raw = this._raw.split('|')[0].trim();
60
+ const isNullable = this._raw.includes('nullable') || this._raw.includes('nullish');
61
+ const base = raw.replace('?', '');
62
+ let schema = { type: 'string' };
63
+ if (base.startsWith('number')) {
64
+ schema = { type: 'number' };
65
+ const minMatch = this._raw.match(/min:(-?\d+(\.\d+)?)/);
66
+ if (minMatch)
67
+ schema.minimum = parseFloat(minMatch[1]);
68
+ const maxMatch = this._raw.match(/max:(-?\d+(\.\d+)?)/);
69
+ if (maxMatch)
70
+ schema.maximum = parseFloat(maxMatch[1]);
71
+ }
72
+ else if (base.startsWith('boolean')) {
73
+ schema = { type: 'boolean' };
74
+ }
75
+ else if (base.startsWith('date')) {
76
+ schema = { type: 'string', format: 'date-time' };
77
+ }
78
+ else if (base.startsWith('email')) {
79
+ schema = { type: 'string', format: 'email' };
80
+ }
81
+ else if (base.startsWith('uuid')) {
82
+ schema = { type: 'string', format: 'uuid' };
83
+ }
84
+ else if (base.startsWith('cuid')) {
85
+ schema = { type: 'string' };
86
+ }
87
+ else if (base.startsWith('password')) {
88
+ schema = { type: 'string', format: 'password' };
89
+ }
90
+ else if (base.startsWith('literal:')) {
91
+ const val = base.replace('literal:', '');
92
+ if (val === 'true' || val === 'false') {
93
+ schema = { type: 'boolean', enum: [val === 'true'] };
94
+ }
95
+ else if (!isNaN(Number(val))) {
96
+ schema = { type: 'number', enum: [Number(val)] };
97
+ }
98
+ else {
99
+ schema = { type: 'string', enum: [val] };
100
+ }
101
+ }
102
+ else if (base.startsWith('enum:')) {
103
+ const vals = base.replace('enum:', '').split(',');
104
+ schema = { type: 'string', enum: vals };
105
+ }
106
+ else if (base.startsWith('array<')) {
107
+ const inner = this._item;
108
+ const itemSchema = inner && typeof inner.toOpenApi === 'function'
109
+ ? inner.toOpenApi()
110
+ : { type: 'string' };
111
+ schema = { type: 'array', items: itemSchema };
112
+ const minMatch = this._raw.match(/min:(\d+)/);
113
+ if (minMatch)
114
+ schema.minItems = parseInt(minMatch[1], 10);
115
+ const maxMatch = this._raw.match(/max:(\d+)/);
116
+ if (maxMatch)
117
+ schema.maxItems = parseInt(maxMatch[1], 10);
118
+ }
119
+ else if (base.startsWith('record<')) {
120
+ schema = { type: 'object', additionalProperties: true };
121
+ }
122
+ else if (base.startsWith('file')) {
123
+ schema = { type: 'string', format: 'binary' };
124
+ }
125
+ if (this.description)
126
+ schema.description = this.description;
127
+ if (this.exampleValue !== undefined)
128
+ schema.example = this.exampleValue;
129
+ if (this.defaultValue !== undefined &&
130
+ typeof this.defaultValue !== 'function') {
131
+ schema.default = this.defaultValue;
132
+ }
133
+ if (isNullable)
134
+ schema.nullable = true;
135
+ return schema;
136
+ }
35
137
  }
36
138
  exports.TexType = TexType;
37
139
  //# sourceMappingURL=tex-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tex-types.js","sourceRoot":"","sources":["../../src/validator/tex-types.ts"],"names":[],"mappings":";;;AAAA,MAAa,OAAO;IAUlB,YACS,IAAY,EACnB,YAAgC;QADzB,SAAI,GAAJ,IAAI,CAAQ;QATd,eAAU,GAA0B,EAAE,CAAA;QACtC,gBAAW,GAIZ,EAAE,CAAA;QAON,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;IAED,QAAQ,CAAC,GAAG,GAA0B;QACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CACJ,EAAyB,EACzB,OAAyC;QAEzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;QACpD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,WAAW,CACT,EAAkC,EAClC,OAAyC;QAEzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;QACnD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,IAAI,aAAa,CAAA;QAC1B,OAAO,IAAW,CAAA;IACpB,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,IAAI,aAAa,CAAA;QAC1B,OAAO,IAAW,CAAA;IACpB,CAAC;IAED,OAAO;QAIL,IAAI,CAAC,IAAI,IAAI,YAAY,CAAA;QACzB,OAAO,IAAW,CAAA;IACpB,CAAC;CACF;AAvDD,0BAuDC"}
1
+ {"version":3,"file":"tex-types.js","sourceRoot":"","sources":["../../src/validator/tex-types.ts"],"names":[],"mappings":";;;AAAA,MAAa,OAAO;IAalB,YACS,IAAY,EACnB,YAAgC;QADzB,SAAI,GAAJ,IAAI,CAAQ;QAZd,eAAU,GAA0B,EAAE,CAAA;QACtC,oBAAe,GAA0B,EAAE,CAAA;QAC3C,gBAAW,GAIZ,EAAE,CAAA;QASN,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;IAED,QAAQ,CAAC,WAAmB;QAC1B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CAAC,OAAY;QAClB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAA;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,UAAU,CAAC,OAAY;QACrB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAA;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ,CAAC,GAAG,GAA0B;QACpC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAA;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,SAAS,CAAM,EAAqB;QAClC,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAQ,CAAA;QAC9D,KAAK,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAA;QACvC,KAAK,CAAC,eAAe,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;QACrD,KAAK,CAAC,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAA;QACzC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QACpC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAA;QACtC,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAA;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,CACJ,EAAyB,EACzB,OAAyC;QAEzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;QACpD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,WAAW,CACT,EAAkC,EAClC,OAAyC;QAEzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;QACnD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,IAAI,aAAa,CAAA;QAC1B,OAAO,IAAW,CAAA;IACpB,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,IAAI,IAAI,aAAa,CAAA;QAC1B,OAAO,IAAW,CAAA;IACpB,CAAC;IAED,OAAO;QAIL,IAAI,CAAC,IAAI,IAAI,YAAY,CAAA;QACzB,OAAO,IAAW,CAAA;IACpB,CAAC;IAED,SAAS;QACP,MAAM,GAAG,GAAW,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAClD,MAAM,UAAU,GACd,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QACjE,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QAEjC,IAAI,MAAM,GAAwB,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAEpD,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;YAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAA;YACvD,IAAI,QAAQ;gBAAE,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;YACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAA;YACvD,IAAI,QAAQ;gBAAE,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QACxD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,MAAM,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;QAC9B,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;QAClD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;QAC9C,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAA;QAC7C,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;QAC7B,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACvC,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAA;QACjD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;YACxC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;gBACtC,MAAM,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,EAAE,CAAA;YACtD,CAAC;iBAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC/B,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAA;YAClD,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAA;YAC1C,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACjD,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QACzC,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrC,MAAM,KAAK,GAAI,IAAY,CAAC,KAAK,CAAA;YACjC,MAAM,UAAU,GACd,KAAK,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU;gBAC5C,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE;gBACnB,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;YACxB,MAAM,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;YAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAC7C,IAAI,QAAQ;gBAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;YAC7C,IAAI,QAAQ;gBAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAC3D,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACtC,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAA;QACzD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;QAC/C,CAAC;QAED,IAAI,IAAI,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QAC3D,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAA;QACvE,IACE,IAAI,CAAC,YAAY,KAAK,SAAS;YAC/B,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU,EACvC,CAAC;YACD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,CAAA;QACpC,CAAC;QACD,IAAI,UAAU;YAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAA;QAEtC,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAxJD,0BAwJC"}
@@ -1,7 +1,7 @@
1
1
  import { TexBuilder } from './builder';
2
2
  export { TexBuilder } from './builder';
3
3
  export declare const tex: TexBuilder;
4
- export { TexEngine } from './engine';
4
+ export { TexEngine, TexTransformedEngine, TexDiscriminatedUnionEngine, } from './engine';
5
5
  export { ValidatorError, getNestedValue, formatReceivedValue } from './error';
6
6
  export { paginate, getPaginationSkip } from './pagination';
7
7
  export type { TexDefaultValue, TexBaseOptions, TexStringOptions, TexNumberOptions, TexBooleanOptions, TexArrayOptions, TexEnumOptions, TexObjectOptions, TexFileOptions, TexPasswordOptions, TexDateOptions, ValidationErrorDescriptor, PaginationMeta, PaginatedResult, } from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"tex.d.ts","sourceRoot":"","sources":["../../src/validator/tex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,eAAO,MAAM,GAAG,YAAmB,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAC7E,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC1D,YAAY,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,cAAc,EACd,eAAe,GAChB,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"tex.d.ts","sourceRoot":"","sources":["../../src/validator/tex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,eAAO,MAAM,GAAG,YAAmB,CAAA;AACnC,OAAO,EACL,SAAS,EACT,oBAAoB,EACpB,2BAA2B,GAC5B,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAC7E,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC1D,YAAY,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,cAAc,EACd,eAAe,GAChB,MAAM,SAAS,CAAA"}
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPaginationSkip = exports.paginate = exports.formatReceivedValue = exports.getNestedValue = exports.ValidatorError = exports.TexEngine = exports.tex = exports.TexBuilder = void 0;
3
+ exports.getPaginationSkip = exports.paginate = exports.formatReceivedValue = exports.getNestedValue = exports.ValidatorError = exports.TexDiscriminatedUnionEngine = exports.TexTransformedEngine = exports.TexEngine = exports.tex = exports.TexBuilder = void 0;
4
4
  const builder_1 = require("./builder");
5
5
  var builder_2 = require("./builder");
6
6
  Object.defineProperty(exports, "TexBuilder", { enumerable: true, get: function () { return builder_2.TexBuilder; } });
7
7
  exports.tex = new builder_1.TexBuilder();
8
8
  var engine_1 = require("./engine");
9
9
  Object.defineProperty(exports, "TexEngine", { enumerable: true, get: function () { return engine_1.TexEngine; } });
10
+ Object.defineProperty(exports, "TexTransformedEngine", { enumerable: true, get: function () { return engine_1.TexTransformedEngine; } });
11
+ Object.defineProperty(exports, "TexDiscriminatedUnionEngine", { enumerable: true, get: function () { return engine_1.TexDiscriminatedUnionEngine; } });
10
12
  var error_1 = require("./error");
11
13
  Object.defineProperty(exports, "ValidatorError", { enumerable: true, get: function () { return error_1.ValidatorError; } });
12
14
  Object.defineProperty(exports, "getNestedValue", { enumerable: true, get: function () { return error_1.getNestedValue; } });
@@ -1 +1 @@
1
- {"version":3,"file":"tex.js","sourceRoot":"","sources":["../../src/validator/tex.ts"],"names":[],"mappings":";;;AAAA,uCAAsC;AAEtC,qCAAsC;AAA7B,qGAAA,UAAU,OAAA;AACN,QAAA,GAAG,GAAG,IAAI,oBAAU,EAAE,CAAA;AACnC,mCAAoC;AAA3B,mGAAA,SAAS,OAAA;AAClB,iCAA6E;AAApE,uGAAA,cAAc,OAAA;AAAE,uGAAA,cAAc,OAAA;AAAE,4GAAA,mBAAmB,OAAA;AAC5D,2CAA0D;AAAjD,sGAAA,QAAQ,OAAA;AAAE,+GAAA,iBAAiB,OAAA"}
1
+ {"version":3,"file":"tex.js","sourceRoot":"","sources":["../../src/validator/tex.ts"],"names":[],"mappings":";;;AAAA,uCAAsC;AAEtC,qCAAsC;AAA7B,qGAAA,UAAU,OAAA;AACN,QAAA,GAAG,GAAG,IAAI,oBAAU,EAAE,CAAA;AACnC,mCAIiB;AAHf,mGAAA,SAAS,OAAA;AACT,8GAAA,oBAAoB,OAAA;AACpB,qHAAA,2BAA2B,OAAA;AAE7B,iCAA6E;AAApE,uGAAA,cAAc,OAAA;AAAE,uGAAA,cAAc,OAAA;AAAE,4GAAA,mBAAmB,OAAA;AAC5D,2CAA0D;AAAjD,sGAAA,QAAQ,OAAA;AAAE,+GAAA,iBAAiB,OAAA"}
@@ -4,6 +4,7 @@ export interface TexBaseOptions {
4
4
  optional?: boolean;
5
5
  nullable?: boolean;
6
6
  nullish?: boolean;
7
+ coerce?: boolean;
7
8
  }
8
9
  export interface TexStringOptions extends TexBaseOptions {
9
10
  min?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/validator/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/validator/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exisjs",
3
- "version": "0.7.12",
3
+ "version": "0.7.14",
4
4
  "description": "efficient full-stack web framework for Node.js",
5
5
  "author": "V25 Group <support@v25group.com>",
6
6
  "keywords": [
@@ -88,6 +88,10 @@
88
88
  "./swagger": {
89
89
  "types": "./dist/swagger/index.d.ts",
90
90
  "default": "./dist/swagger/index.js"
91
+ },
92
+ "./telemetry": {
93
+ "types": "./dist/telemetry/index.d.ts",
94
+ "default": "./dist/telemetry/index.js"
91
95
  }
92
96
  },
93
97
  "files": [
@@ -97,7 +101,7 @@
97
101
  "build": "tsc",
98
102
  "postbuild": "node -e \"require('fs').cpSync('../../docs', './dist/docs', {recursive:true, force:true})\"",
99
103
  "dev": "tsc --watch",
100
- "test": "cross-env NODE_ENV=test tsx --test --test-reporter=./src/testing/reporter.mts tests/**/*.test.ts"
104
+ "test": "cross-env NODE_ENV=test tsx --tsconfig ../../tsconfig.base.json --test --test-reporter=./src/testing/reporter.mts tests/**/*.test.ts"
101
105
  },
102
106
  "bin": {
103
107
  "exis": "bin/exis.js",
@@ -110,7 +114,6 @@
110
114
  },
111
115
  "dependencies": {
112
116
  "@exisjs/rs": "*",
113
- "@exisjs/telemetry": "^0.7.0",
114
117
  "accepts": "^1.3.8",
115
118
  "busboy": "^1.6.0",
116
119
  "chokidar": "^5.0.0",
@@ -119,34 +122,63 @@
119
122
  "dotenv": "^17.4.2",
120
123
  "dotenv-expand": "^13.0.0",
121
124
  "esbuild": "^0.28.2",
122
- "execa": "^10.0.1",
123
- "fast-json-stringify": "^7.0.1",
124
125
  "fast-querystring": "^1.1.2",
125
126
  "fresh": "^0.5.2",
126
- "fs-extra": "^11.4.0",
127
127
  "mime-types": "^3.0.2",
128
- "ora": "^9.4.1",
129
128
  "pino": "^10.3.1",
130
129
  "pino-pretty": "^13.1.3",
131
- "tsc-alias": "^1.9.5",
132
- "tsx": "^4.23.12",
133
- "typescript": "^5.9.3",
130
+ "tsx": "^4.23.15",
131
+ "typescript": "^5.9.3"
132
+ },
133
+ "devDependencies": {
134
134
  "@types/accepts": "^1.3.7",
135
135
  "@types/busboy": "^1.5.4",
136
136
  "@types/content-disposition": "^0.5.9",
137
137
  "@types/fresh": "^0.5.3",
138
138
  "@types/mime-types": "^3.0.1",
139
- "@types/node": "^26.4.0"
140
- },
141
- "devDependencies": {
139
+ "@types/node": "^26.4.0",
142
140
  "@types/autocannon": "^7.12.7",
143
141
  "@types/better-sqlite3": "^9.6.0",
144
142
  "@types/bun": "^1.4.2",
145
143
  "@types/mocha": "^10.0.10",
144
+ "fast-json-stringify": "^7.0.1",
146
145
  "find-my-way": "^9.9.0",
146
+ "fs-extra": "^11.4.1",
147
147
  "mitata": "^1.0.34"
148
148
  },
149
+ "peerDependencies": {
150
+ "@opentelemetry/api": "^1.9.0",
151
+ "@opentelemetry/sdk-node": "^0.222.0",
152
+ "@opentelemetry/auto-instrumentations-node": "^0.80.0",
153
+ "@opentelemetry/exporter-trace-otlp-http": "^0.222.0",
154
+ "@opentelemetry/sdk-trace-node": "^2.11.0",
155
+ "@opentelemetry/resources": "^2.11.0",
156
+ "@opentelemetry/semantic-conventions": "^1.43.0"
157
+ },
158
+ "peerDependenciesMeta": {
159
+ "@opentelemetry/api": {
160
+ "optional": true
161
+ },
162
+ "@opentelemetry/sdk-node": {
163
+ "optional": true
164
+ },
165
+ "@opentelemetry/auto-instrumentations-node": {
166
+ "optional": true
167
+ },
168
+ "@opentelemetry/exporter-trace-otlp-http": {
169
+ "optional": true
170
+ },
171
+ "@opentelemetry/sdk-trace-node": {
172
+ "optional": true
173
+ },
174
+ "@opentelemetry/resources": {
175
+ "optional": true
176
+ },
177
+ "@opentelemetry/semantic-conventions": {
178
+ "optional": true
179
+ }
180
+ },
149
181
  "optionalDependencies": {
150
- "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.70.0"
182
+ "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.71.0"
151
183
  }
152
184
  }
@@ -1,170 +0,0 @@
1
- ---
2
- nextUrl: "/docs/security"
3
- nextTitle: "Security & Auth"
4
- ---
5
-
6
- # Dataloader (N+1 Queries)
7
-
8
- The **N+1 problem** is a common performance issue in backend development. It occurs when your code executes one query to fetch a list of items (e.g. 100 Posts), and then executes $N$ additional queries to fetch related data (e.g. 100 separate queries for each Post's Author).
9
-
10
- ExisJS ships with a native `Dataloader` implementation (inspired by GraphQL/Facebook's DataLoader) built directly into the core framework. It automatically **batches** and **caches** requests over a single tick of the Node.js event loop.
11
-
12
- ---
13
-
14
- ## 1. Defining Loaders
15
-
16
- The best practice in ExisJS is to define a central registry of Dataloaders that are **securely scoped to the current HTTP Request** (to prevent data leaking between different users).
17
-
18
- ExisJS provides `defineLoaders` to create this context-aware registry.
19
-
20
- ```typescript filename="src/loaders.ts"
21
- import { Dataloader, defineLoaders } from 'exisjs/dataloader'
22
- import { getRequest } from 'exisjs/router'
23
- import { db } from './db'
24
-
25
- export const { loaderMiddleware, getLoaders } = defineLoaders({
26
- // 1. Author Loader
27
- authorLoader: () => new Dataloader<number, any>(async (keys) => {
28
- // You can access the current HTTP Request anywhere using getRequest()
29
- const req = getRequest()
30
- const authToken = req.headers.authorization
31
-
32
- // This function will only be called ONCE per event-loop tick,
33
- // receiving an array of all requested Author IDs: e.g. [1, 2, 3]
34
- const authors = await db.authors.findMany({
35
- where: { id: { in: keys } }
36
- })
37
-
38
- // You MUST return an array of results in the EXACT same order as the keys
39
- return keys.map(key => authors.find(a => a.id === key) || new Error('Not found'))
40
- }),
41
-
42
- // 2. Comments Loader
43
- commentsLoader: () => new Dataloader<number, any[]>(async (keys) => {
44
- const comments = await db.comments.findMany({
45
- where: { postId: { in: keys } }
46
- })
47
-
48
- // Group comments by postId
49
- return keys.map(key => comments.filter(c => c.postId === key))
50
- })
51
- })
52
- ```
53
-
54
- ---
55
-
56
- ## 2. Registering the Middleware
57
-
58
- `defineLoaders` returns a `loaderMiddleware`. You must register this middleware so that ExisJS can securely inject a fresh, isolated instance of your Dataloaders into every incoming request.
59
-
60
- Because ExisJS uses lazy-initialization, there is **zero performance penalty** for routes that don't actually use the loaders.
61
-
62
- #### Functional Paradigm
63
-
64
- ```typescript filename="src/http/server.ts"
65
- import { exis } from 'exisjs'
66
- import { loaderMiddleware } from '../loaders'
67
-
68
- export default exis({
69
- async onStart(app) {
70
- // Register globally for all routes
71
- app.use(loaderMiddleware)
72
- }
73
- })
74
- ```
75
-
76
- #### Class-Based (OOP) Paradigm
77
-
78
- ```typescript filename="src/http/server.ts"
79
- import { Server } from 'exisjs/decorators'
80
- import { loaderMiddleware } from '../loaders'
81
- import type { App } from 'exisjs'
82
-
83
- @Server()
84
- export default class RootServer {
85
- async onStart(app: App) {
86
- // Register globally for all routes
87
- app.use(loaderMiddleware)
88
- }
89
- }
90
- ```
91
-
92
- ---
93
-
94
- ## 3. Using Dataloader in Routes
95
-
96
- Anywhere in your application (Routes, Controllers, Services), you can call `getLoaders()` to retrieve the securely isolated loaders for the *current* request.
97
-
98
- #### Functional Paradigm
99
-
100
- ```typescript filename="src/http/posts/route.ts"
101
- import { controller, route } from 'exisjs/router'
102
- import { getLoaders } from '../../loaders'
103
-
104
- export default controller({
105
- list: route.get('/', {
106
- async handle() {
107
- // 1. Fetch 100 posts (1 Query)
108
- const posts = await db.posts.findMany()
109
-
110
- const { authorLoader } = getLoaders()
111
-
112
- // 2. Loop through 100 posts and call .load()
113
- const postsWithAuthors = await Promise.all(
114
- posts.map(async (post) => {
115
- // Instead of firing 100 queries to the database,
116
- // Dataloader queues them up and fires exactly ONE batched query.
117
- const author = await authorLoader.load(post.authorId)
118
- return { ...post, author }
119
- })
120
- )
121
-
122
- return postsWithAuthors
123
- // Total Queries: 2 (Not 101)
124
- }
125
- })
126
- })
127
- ```
128
-
129
- #### Class-Based (OOP) Paradigm
130
-
131
- ```typescript filename="src/http/posts/route.ts"
132
- import { Controller, Get } from 'exisjs/decorators'
133
- import { getLoaders } from '../../loaders'
134
-
135
- @Controller()
136
- export default class PostsController {
137
- @Get('/')
138
- async list() {
139
- // 1. Fetch 100 posts (1 Query)
140
- const posts = await db.posts.findMany()
141
-
142
- const { authorLoader } = getLoaders()
143
-
144
- // 2. Loop through 100 posts and call .load()
145
- const postsWithAuthors = await Promise.all(
146
- posts.map(async (post) => {
147
- // Instead of firing 100 queries to the database,
148
- // Dataloader queues them up and fires exactly ONE batched query.
149
- const author = await authorLoader.load(post.authorId)
150
- return { ...post, author }
151
- })
152
- )
153
-
154
- return postsWithAuthors
155
- // Total Queries: 2 (Not 101)
156
- }
157
- }
158
- ```
159
-
160
- ---
161
-
162
- ## API Reference (`exisjs/dataloader`)
163
-
164
- The `Dataloader` class exposes the standard, battle-tested API:
165
-
166
- - **`load(key: K): Promise<V>`**: Queues a key to be fetched and returns a Promise.
167
- - **`loadMany(keys: K[]): Promise<V[]>`**: Equivalent to calling `Promise.all(keys.map(k => load(k)))`.
168
- - **`clear(key: K): this`**: Clears the cached result for a specific key.
169
- - **`clearAll(): this`**: Clears the entire cache for this dataloader instance.
170
- - **`prime(key: K, value: V): this`**: Primes the cache with a predefined value, preventing the batch function from being called for that key.
@@ -1,91 +0,0 @@
1
- ---
2
- title: "Data Loader"
3
- description: "Strict API Reference for the N+1 batching utility."
4
- ---
5
-
6
- # Data Loader (`exisjs/dataloader`)
7
-
8
- This document provides the strict API signatures and TypeScript interfaces exported by the `exisjs/dataloader` module. For high-level guides on solving N+1 query problems, see the [Data Loader Guide](/docs/dataloader).
9
-
10
- ---
11
-
12
- ## `Dataloader<K, V, C>` Class
13
-
14
- The `Dataloader` class batches and caches requests to a backend data source.
15
-
16
- ```typescript
17
- import { Dataloader } from 'exisjs/dataloader'
18
-
19
- class Dataloader<K, V, C = K> {
20
- constructor(batchFn: BatchLoadFn<K, V>, options?: DataloaderOptions<K, C>)
21
-
22
- // Enqueues a key to be batched, returning a Promise that resolves to the value
23
- load(key: K): Promise<V>
24
-
25
- // Loads multiple keys, returning an array of Promises
26
- loadMany(keys: readonly K[]): Promise<V[]>
27
-
28
- // Clears the value at `key` from the cache
29
- clear(key: K): this
30
-
31
- // Clears all values from the cache
32
- clearAll(): this
33
-
34
- // Primes the cache with a predefined value or Error for a specific key
35
- prime(key: K, value: V | Error): this
36
- }
37
- ```
38
-
39
- ### `BatchLoadFn<K, V>`
40
-
41
- The function responsible for loading the batched keys. **It must return an array of values (or Errors) that are precisely the same length and in the exact same order as the provided keys array.**
42
-
43
- ```typescript
44
- type BatchLoadFn<K, V> = (
45
- keys: readonly K[]
46
- ) => Promise<readonly (V | Error)[]>
47
- ```
48
-
49
- ### `DataloaderOptions<K, C>`
50
-
51
- ```typescript
52
- interface DataloaderOptions<K, C = K> {
53
- // Whether to cache resolved keys within this Dataloader instance. Default: true
54
- cache?: boolean
55
-
56
- // The maximum number of keys to include in a single batch. Default: 1000
57
- maxBatchSize?: number
58
-
59
- // A function to generate a unique cache key from the provided load key
60
- cacheKeyFn?: (key: K) => C
61
- }
62
- ```
63
-
64
- ---
65
-
66
- ## Context Registry (`defineLoaders`)
67
-
68
- Because `Dataloader` instances are inherently stateful (they cache data), they **must not** be shared across different HTTP requests, or else users might read each other's cached data.
69
-
70
- The `defineLoaders` function securely isolates Dataloader instances per-request by binding them to the ExisJS asynchronous context.
71
-
72
- ```typescript
73
- import { defineLoaders } from 'exisjs/dataloader'
74
-
75
- function defineLoaders<
76
- T extends Record<string, () => Dataloader<any, any>>
77
- >(factories: T): {
78
- // Middleware to register onto your router/app
79
- loaderMiddleware: (req, res, next) => void;
80
-
81
- // Hook to retrieve the isolated loaders anywhere in the request lifecycle
82
- getLoaders: () => { [K in keyof T]: ReturnType<T[K]> }
83
- }
84
- ```
85
-
86
- ### Usage Signature
87
- ```typescript
88
- const { loaderMiddleware, getLoaders } = defineLoaders({
89
- userLoader: () => new Dataloader(async (keys) => { /* ... */ })
90
- })
91
- ```