@avleon/core 0.0.46 → 0.0.48

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 (142) hide show
  1. package/License +21 -21
  2. package/README.md +666 -666
  3. package/dist/chunk-9hOWP6kD.cjs +64 -0
  4. package/dist/chunk-DORXReHP.js +37 -0
  5. package/dist/index-BxIMWhgy.d.ts +1284 -0
  6. package/dist/index-DPn7qtzq.d.cts +1283 -0
  7. package/dist/index.cjs +3194 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.js +3022 -79
  10. package/dist/index.js.map +1 -0
  11. package/dist/lib-Bk8hUm06.cjs +7847 -0
  12. package/dist/lib-Bk8hUm06.cjs.map +1 -0
  13. package/dist/lib-CvDxBMkR.js +7843 -0
  14. package/dist/lib-CvDxBMkR.js.map +1 -0
  15. package/package.json +41 -103
  16. package/dist/application.test.d.ts +0 -1
  17. package/dist/application.test.js +0 -15
  18. package/dist/authentication.d.ts +0 -13
  19. package/dist/authentication.js +0 -16
  20. package/dist/cache.d.ts +0 -12
  21. package/dist/cache.js +0 -78
  22. package/dist/cache.test.d.ts +0 -1
  23. package/dist/cache.test.js +0 -36
  24. package/dist/collection.d.ts +0 -43
  25. package/dist/collection.js +0 -231
  26. package/dist/collection.test.d.ts +0 -1
  27. package/dist/collection.test.js +0 -59
  28. package/dist/config.d.ts +0 -18
  29. package/dist/config.js +0 -58
  30. package/dist/config.test.d.ts +0 -1
  31. package/dist/config.test.js +0 -40
  32. package/dist/constants.d.ts +0 -1
  33. package/dist/constants.js +0 -4
  34. package/dist/container.d.ts +0 -30
  35. package/dist/container.js +0 -55
  36. package/dist/controller.d.ts +0 -50
  37. package/dist/controller.js +0 -71
  38. package/dist/controller.test.d.ts +0 -1
  39. package/dist/controller.test.js +0 -97
  40. package/dist/core/application.d.ts +0 -74
  41. package/dist/core/application.js +0 -424
  42. package/dist/core/router.d.ts +0 -44
  43. package/dist/core/router.js +0 -520
  44. package/dist/core/testing.d.ts +0 -21
  45. package/dist/core/testing.js +0 -104
  46. package/dist/core/types.d.ts +0 -67
  47. package/dist/core/types.js +0 -2
  48. package/dist/decorators.d.ts +0 -15
  49. package/dist/decorators.js +0 -41
  50. package/dist/environment-variables.d.ts +0 -49
  51. package/dist/environment-variables.js +0 -130
  52. package/dist/environment-variables.test.d.ts +0 -1
  53. package/dist/environment-variables.test.js +0 -70
  54. package/dist/event-dispatcher.d.ts +0 -22
  55. package/dist/event-dispatcher.js +0 -97
  56. package/dist/event-subscriber.d.ts +0 -14
  57. package/dist/event-subscriber.js +0 -87
  58. package/dist/exceptions/http-exceptions.d.ts +0 -50
  59. package/dist/exceptions/http-exceptions.js +0 -85
  60. package/dist/exceptions/index.d.ts +0 -1
  61. package/dist/exceptions/index.js +0 -17
  62. package/dist/exceptions/system-exception.d.ts +0 -22
  63. package/dist/exceptions/system-exception.js +0 -26
  64. package/dist/file-storage.d.ts +0 -69
  65. package/dist/file-storage.js +0 -323
  66. package/dist/file-storage.test.d.ts +0 -1
  67. package/dist/file-storage.test.js +0 -117
  68. package/dist/helpers.d.ts +0 -11
  69. package/dist/helpers.js +0 -27
  70. package/dist/helpers.test.d.ts +0 -1
  71. package/dist/helpers.test.js +0 -95
  72. package/dist/index.d.ts +0 -57
  73. package/dist/interfaces/avleon-application.d.ts +0 -75
  74. package/dist/interfaces/avleon-application.js +0 -2
  75. package/dist/kenx-provider.d.ts +0 -7
  76. package/dist/kenx-provider.js +0 -44
  77. package/dist/kenx-provider.test.d.ts +0 -1
  78. package/dist/kenx-provider.test.js +0 -36
  79. package/dist/logger.d.ts +0 -12
  80. package/dist/logger.js +0 -87
  81. package/dist/logger.test.d.ts +0 -1
  82. package/dist/logger.test.js +0 -42
  83. package/dist/map-types.d.ts +0 -17
  84. package/dist/map-types.js +0 -89
  85. package/dist/middleware.d.ts +0 -34
  86. package/dist/middleware.js +0 -73
  87. package/dist/middleware.test.d.ts +0 -1
  88. package/dist/middleware.test.js +0 -121
  89. package/dist/multipart.d.ts +0 -17
  90. package/dist/multipart.js +0 -70
  91. package/dist/multipart.test.d.ts +0 -1
  92. package/dist/multipart.test.js +0 -87
  93. package/dist/openapi.d.ts +0 -410
  94. package/dist/openapi.js +0 -59
  95. package/dist/openapi.test.d.ts +0 -1
  96. package/dist/openapi.test.js +0 -111
  97. package/dist/params.d.ts +0 -17
  98. package/dist/params.js +0 -64
  99. package/dist/params.test.d.ts +0 -1
  100. package/dist/params.test.js +0 -83
  101. package/dist/queue.d.ts +0 -29
  102. package/dist/queue.js +0 -84
  103. package/dist/response.d.ts +0 -16
  104. package/dist/response.js +0 -56
  105. package/dist/results.d.ts +0 -20
  106. package/dist/results.js +0 -32
  107. package/dist/route-methods.d.ts +0 -25
  108. package/dist/route-methods.js +0 -60
  109. package/dist/route-methods.test.d.ts +0 -1
  110. package/dist/route-methods.test.js +0 -129
  111. package/dist/swagger-schema.d.ts +0 -37
  112. package/dist/swagger-schema.js +0 -454
  113. package/dist/swagger-schema.test.d.ts +0 -1
  114. package/dist/swagger-schema.test.js +0 -125
  115. package/dist/types/app-builder.interface.d.ts +0 -15
  116. package/dist/types/app-builder.interface.js +0 -8
  117. package/dist/types/application.interface.d.ts +0 -8
  118. package/dist/types/application.interface.js +0 -2
  119. package/dist/utils/common-utils.d.ts +0 -17
  120. package/dist/utils/common-utils.js +0 -108
  121. package/dist/utils/di-utils.d.ts +0 -1
  122. package/dist/utils/di-utils.js +0 -22
  123. package/dist/utils/hash.d.ts +0 -2
  124. package/dist/utils/hash.js +0 -11
  125. package/dist/utils/index.d.ts +0 -2
  126. package/dist/utils/index.js +0 -18
  127. package/dist/utils/object-utils.d.ts +0 -11
  128. package/dist/utils/object-utils.js +0 -198
  129. package/dist/utils/optional-require.d.ts +0 -8
  130. package/dist/utils/optional-require.js +0 -70
  131. package/dist/utils/validation-utils.d.ts +0 -13
  132. package/dist/utils/validation-utils.js +0 -119
  133. package/dist/validation.d.ts +0 -39
  134. package/dist/validation.js +0 -108
  135. package/dist/validation.test.d.ts +0 -1
  136. package/dist/validation.test.js +0 -61
  137. package/dist/validator-extend.d.ts +0 -7
  138. package/dist/validator-extend.js +0 -28
  139. package/dist/websocket.d.ts +0 -10
  140. package/dist/websocket.js +0 -21
  141. package/dist/websocket.test.d.ts +0 -1
  142. package/dist/websocket.test.js +0 -27
@@ -1,454 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OpenApiProperty = OpenApiProperty;
4
- exports.CreateSwaggerObjectSchema = CreateSwaggerObjectSchema;
5
- exports.generateClassSchema = generateClassSchema;
6
- exports.generateSwaggerSchema = generateSwaggerSchema;
7
- exports.OpenApiResponse = OpenApiResponse;
8
- /**
9
- * @copyright 2024
10
- * @author Tareq Hossain
11
- * @email xtrinsic96@gmail.com
12
- * @url https://github.com/xtareq
13
- */
14
- const class_validator_1 = require("class-validator");
15
- const container_1 = require("./container");
16
- // Decorator to add OpenAPI metadata to properties
17
- function OpenApiProperty(options) {
18
- return function (target, propertyKey) {
19
- var _a;
20
- let meta = options ? { ...options } : {};
21
- if (meta.format === "binary") {
22
- if (meta.isArray) {
23
- meta = {
24
- ...meta,
25
- type: "array",
26
- items: (_a = meta.items) !== null && _a !== void 0 ? _a : { type: "string", format: "binary" },
27
- description: meta.description || "Array of files",
28
- };
29
- }
30
- else {
31
- meta = {
32
- ...meta,
33
- type: "string",
34
- format: "binary",
35
- description: meta.description || "File upload",
36
- };
37
- }
38
- }
39
- Reflect.defineMetadata("property:openapi", meta, target, propertyKey);
40
- };
41
- }
42
- function extractOpenApiFields(meta) {
43
- const result = {};
44
- // ✅ Complete list — was missing required, title, readOnly, writeOnly, nullable
45
- const jsonSchemaFields = [
46
- "description",
47
- "deprecated",
48
- "example",
49
- "enum",
50
- "format",
51
- "default",
52
- "minimum",
53
- "maximum",
54
- "minLength",
55
- "maxLength",
56
- "pattern",
57
- "oneOf",
58
- "allOf",
59
- "anyOf",
60
- "title",
61
- "readOnly",
62
- "writeOnly",
63
- "nullable"
64
- ];
65
- // Valid JSON Schema formats
66
- const validFormats = [
67
- "date-time", "date", "time", "duration",
68
- "email", "idn-email", "hostname", "idn-hostname",
69
- "ipv4", "ipv6", "uri", "uri-reference",
70
- "iri", "iri-reference", "uuid", "uri-template",
71
- "json-pointer", "relative-json-pointer", "regex",
72
- "int32", "int64", "float", "double",
73
- "byte", "binary", "password",
74
- ];
75
- jsonSchemaFields.forEach((field) => {
76
- if (meta[field] !== undefined) {
77
- if (field === "format") {
78
- const formatValue = meta[field];
79
- if (validFormats.includes(formatValue)) {
80
- result[field] = formatValue;
81
- }
82
- }
83
- else {
84
- result[field] = meta[field];
85
- }
86
- }
87
- });
88
- return result;
89
- }
90
- function CreateSwaggerObjectSchema(classType) {
91
- const metadataStorage = (0, class_validator_1.getMetadataStorage)();
92
- const validationMetadata = metadataStorage.getTargetValidationMetadatas(classType, "", true, false);
93
- const schema = { type: "object", properties: {}, required: [] };
94
- const prototype = classType.prototype;
95
- const propertyKeys = new Set();
96
- Object.getOwnPropertyNames(prototype).forEach((k) => propertyKeys.add(k));
97
- Object.keys(prototype).forEach((k) => propertyKeys.add(k));
98
- validationMetadata.forEach((m) => propertyKeys.add(m.propertyName));
99
- // ✅ Discover instance-level properties (class fields with !)
100
- try {
101
- const instance = new classType();
102
- Reflect.ownKeys(instance).forEach((k) => {
103
- if (typeof k === "string")
104
- propertyKeys.add(k);
105
- });
106
- }
107
- catch (_) { }
108
- propertyKeys.forEach((propertyName) => {
109
- var _a;
110
- if (!propertyName || propertyName === "constructor")
111
- return;
112
- const openApiMeta = Reflect.getMetadata("property:openapi", prototype, propertyName);
113
- if (openApiMeta === null || openApiMeta === void 0 ? void 0 : openApiMeta.exclude)
114
- return;
115
- const propertyType = Reflect.getMetadata("design:type", prototype, propertyName);
116
- let swaggerProperty = {};
117
- switch (propertyType) {
118
- case String:
119
- swaggerProperty.type = "string";
120
- break;
121
- case Number:
122
- swaggerProperty.type = "number";
123
- break;
124
- case Boolean:
125
- swaggerProperty.type = "boolean";
126
- break;
127
- case Date:
128
- swaggerProperty.type = "string";
129
- swaggerProperty.format = "date-time";
130
- break;
131
- case Array:
132
- swaggerProperty.type = "array";
133
- swaggerProperty.items = { type: "string" };
134
- break;
135
- case Object:
136
- swaggerProperty = CreateSwaggerObjectSchema(propertyType);
137
- break;
138
- default:
139
- if (propertyType && typeof propertyType === "function") {
140
- swaggerProperty.$ref = `#/components/schemas/${propertyType.name}`;
141
- }
142
- else {
143
- swaggerProperty.type = ((_a = propertyType === null || propertyType === void 0 ? void 0 : propertyType.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || "string";
144
- }
145
- }
146
- if (openApiMeta) {
147
- swaggerProperty = {
148
- ...swaggerProperty,
149
- ...openApiMeta,
150
- ...extractOpenApiFields(openApiMeta),
151
- };
152
- if (openApiMeta.format === "binary") {
153
- if (openApiMeta.isArray || propertyType === Array) {
154
- swaggerProperty = {
155
- type: "array",
156
- items: { type: "string", format: "binary" },
157
- description: openApiMeta.description || "Array of files",
158
- };
159
- }
160
- else {
161
- swaggerProperty = {
162
- type: "string",
163
- format: "binary",
164
- description: openApiMeta.description || "File upload",
165
- };
166
- }
167
- }
168
- }
169
- schema.properties[propertyName] = swaggerProperty;
170
- });
171
- validationMetadata.forEach((meta) => {
172
- const propertyName = meta.propertyName;
173
- const property = schema.properties[propertyName];
174
- if (!property)
175
- return;
176
- switch (meta.name) {
177
- case "isNotEmpty":
178
- case "isDefined":
179
- if (!schema.required.includes(propertyName))
180
- schema.required.push(propertyName);
181
- break;
182
- case "isOptional":
183
- schema.required = schema.required.filter((item) => item !== propertyName);
184
- break;
185
- case "minLength":
186
- property.minLength = meta.constraints[0];
187
- break;
188
- case "maxLength":
189
- property.maxLength = meta.constraints[0];
190
- break;
191
- case "min":
192
- property.minimum = meta.constraints[0];
193
- break;
194
- case "max":
195
- property.maximum = meta.constraints[0];
196
- break;
197
- case "isEmail":
198
- property.format = "email";
199
- break;
200
- case "isDate":
201
- property.format = "date-time";
202
- break;
203
- case "isIn":
204
- property.enum = meta.constraints[0];
205
- break;
206
- case "isNumber":
207
- property.type = "number";
208
- break;
209
- case "isInt":
210
- property.type = "integer";
211
- break;
212
- case "isBoolean":
213
- property.type = "boolean";
214
- break;
215
- case "isString":
216
- property.type = "string";
217
- break;
218
- }
219
- });
220
- if (schema.required.length === 0)
221
- delete schema.required;
222
- return schema;
223
- }
224
- function generateClassSchema(classType) {
225
- const schema = { type: "object", properties: {}, required: [] };
226
- // ✅ Guard against null/undefined
227
- if (!classType || !classType.prototype)
228
- return schema;
229
- const metadataStorage = (0, class_validator_1.getMetadataStorage)();
230
- const validationMetadata = metadataStorage.getTargetValidationMetadatas(classType, "", true, false);
231
- const prototype = classType.prototype;
232
- const propertyKeys = new Set([
233
- ...Object.getOwnPropertyNames(prototype),
234
- ...validationMetadata.map((m) => m.propertyName),
235
- ]);
236
- // ✅ Discover instance-level class fields (e.g. `search!: string`)
237
- // These don't appear on prototype — only on instantiated objects
238
- try {
239
- const instance = new classType();
240
- Reflect.ownKeys(instance).forEach((k) => {
241
- if (typeof k === "string")
242
- propertyKeys.add(k);
243
- });
244
- }
245
- catch (_) { }
246
- propertyKeys.forEach((propertyName) => {
247
- var _a;
248
- if (!propertyName || propertyName === "constructor")
249
- return;
250
- const openApiMeta = Reflect.getMetadata("property:openapi", prototype, propertyName);
251
- if (openApiMeta === null || openApiMeta === void 0 ? void 0 : openApiMeta.exclude)
252
- return;
253
- const propertyType = Reflect.getMetadata("design:type", prototype, propertyName);
254
- let swaggerProperty = {};
255
- switch (propertyType) {
256
- case String:
257
- swaggerProperty.type = "string";
258
- break;
259
- case Number:
260
- swaggerProperty.type = "number";
261
- break;
262
- case Boolean:
263
- swaggerProperty.type = "boolean";
264
- break;
265
- case Date:
266
- swaggerProperty.type = "string";
267
- swaggerProperty.format = "date-time";
268
- break;
269
- case Array:
270
- swaggerProperty.type = "array";
271
- swaggerProperty.items = { type: "string" };
272
- break;
273
- case Object:
274
- swaggerProperty = generateClassSchema(propertyType);
275
- break;
276
- default:
277
- if (propertyType && typeof propertyType === "function") {
278
- swaggerProperty.$ref = `#/components/schemas/${propertyType.name}`;
279
- }
280
- else {
281
- swaggerProperty.type = ((_a = propertyType === null || propertyType === void 0 ? void 0 : propertyType.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || "string";
282
- }
283
- }
284
- // ✅ Apply OpenApi metadata — extractOpenApiFields now includes all fields
285
- if (openApiMeta) {
286
- const { required: _required, exclude: _exclude, isArray: _isArray, ...safeOpenApiMeta } = openApiMeta;
287
- swaggerProperty = {
288
- ...swaggerProperty,
289
- ...extractOpenApiFields(safeOpenApiMeta),
290
- };
291
- }
292
- schema.properties[propertyName] = swaggerProperty;
293
- });
294
- validationMetadata.forEach((meta) => {
295
- const propertyName = meta.propertyName;
296
- // Guard: property might not be in schema if it had no type info
297
- if (!schema.properties[propertyName]) {
298
- schema.properties[propertyName] = { type: "string" }; // ✅ safe fallback
299
- }
300
- switch (meta.name) {
301
- case "isNotEmpty":
302
- case "isDefined":
303
- if (!schema.required.includes(propertyName))
304
- schema.required.push(propertyName);
305
- break;
306
- case "isOptional":
307
- schema.required = schema.required.filter((item) => item !== propertyName);
308
- break;
309
- case "minLength":
310
- schema.properties[propertyName].minLength = meta.constraints[0];
311
- break;
312
- case "maxLength":
313
- schema.properties[propertyName].maxLength = meta.constraints[0];
314
- break;
315
- case "min":
316
- schema.properties[propertyName].minimum = meta.constraints[0];
317
- break;
318
- case "max":
319
- schema.properties[propertyName].maximum = meta.constraints[0];
320
- break;
321
- case "isEmail":
322
- schema.properties[propertyName].format = "email";
323
- break;
324
- case "isDate":
325
- schema.properties[propertyName].format = "date-time";
326
- break;
327
- case "isIn":
328
- schema.properties[propertyName].enum = meta.constraints[0];
329
- break;
330
- case "isNumber":
331
- schema.properties[propertyName].type = "number";
332
- break;
333
- case "isInt":
334
- schema.properties[propertyName].type = "integer";
335
- break;
336
- case "isBoolean":
337
- schema.properties[propertyName].type = "boolean";
338
- break;
339
- case "isString":
340
- schema.properties[propertyName].type = "string";
341
- break;
342
- }
343
- });
344
- if (schema.required.length === 0)
345
- delete schema.required;
346
- return schema;
347
- }
348
- // Build OpenAPI components.schemas from an array of controller/DTO classes
349
- function generateSwaggerSchema(controllers) {
350
- if (!Array.isArray(controllers)) {
351
- return generateClassSchema(controllers);
352
- }
353
- const components = {};
354
- for (const controller of controllers) {
355
- if (!controller || typeof controller !== "function")
356
- continue;
357
- if (!controller.prototype)
358
- continue;
359
- // Skip @ApiController classes
360
- const isController = Reflect.getMetadata(container_1.CONTROLLER_META_KEY, controller);
361
- if (isController)
362
- continue;
363
- // Only include classes explicitly marked with @ApiSchema
364
- const isSchema = Reflect.getMetadata("openapi:schema", controller);
365
- if (!isSchema)
366
- continue;
367
- components[controller.name] = generateClassSchema(controller);
368
- }
369
- return {
370
- components: Object.keys(components).length > 0
371
- ? { schemas: components }
372
- : undefined,
373
- };
374
- }
375
- function OpenApiResponse(code = 200, model, description = "Successful response") {
376
- let dataSchema;
377
- if (typeof model === "function") {
378
- dataSchema = generateClassSchema(model);
379
- }
380
- else if (model && typeof model === "object") {
381
- dataSchema = inferSchemaFromExample(model);
382
- }
383
- else {
384
- dataSchema = { type: "string" };
385
- }
386
- let message = "OK";
387
- switch (code) {
388
- case 400:
389
- message = "Error";
390
- description = "Error: Bad Request";
391
- break;
392
- case 401:
393
- message = "Error";
394
- description = "Error: Unauthorized";
395
- break;
396
- case 403:
397
- message = "Error";
398
- description = "Error: Forbidden";
399
- break;
400
- case 201:
401
- message = "Created";
402
- description = "Success: Created";
403
- break;
404
- case 500:
405
- message = "Error";
406
- description = "Error: InternalError";
407
- break;
408
- }
409
- return {
410
- description,
411
- content: {
412
- "application/json": {
413
- schema: {
414
- type: "object",
415
- properties: {
416
- code: { type: "number", example: code },
417
- status: { type: "string", example: message },
418
- data: dataSchema,
419
- },
420
- },
421
- },
422
- },
423
- };
424
- }
425
- function inferSchemaFromExample(obj) {
426
- var _a;
427
- if (Array.isArray(obj)) {
428
- return { type: "array", items: inferSchemaFromExample((_a = obj[0]) !== null && _a !== void 0 ? _a : {}) };
429
- }
430
- if (obj && typeof obj === "object") {
431
- const properties = {};
432
- for (const [key, value] of Object.entries(obj)) {
433
- properties[key] = inferType(value);
434
- }
435
- return { type: "object", properties };
436
- }
437
- return inferType(obj);
438
- }
439
- function inferType(value) {
440
- const type = typeof value;
441
- switch (type) {
442
- case "string": return { type: "string", example: value };
443
- case "number": return { type: "number", example: value };
444
- case "boolean": return { type: "boolean", example: value };
445
- case "object":
446
- if (Array.isArray(value))
447
- return inferSchemaFromExample(value);
448
- if (value === null)
449
- return { type: "null" };
450
- return inferSchemaFromExample(value);
451
- default:
452
- return { type: "string" };
453
- }
454
- }
@@ -1 +0,0 @@
1
- import "reflect-metadata";
@@ -1,125 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- require("reflect-metadata");
4
- const swagger_schema_1 = require("./swagger-schema"); // ✅ single-class function
5
- // Mocks for class-validator metadata
6
- const mockValidationMetadatas = [
7
- { propertyName: "name", name: "isNotEmpty", constraints: [] },
8
- { propertyName: "age", name: "isInt", constraints: [] },
9
- { propertyName: "email", name: "isEmail", constraints: [] },
10
- { propertyName: "tags", name: "isOptional", constraints: [] },
11
- { propertyName: "desc", name: "minLength", constraints: [5] },
12
- { propertyName: "desc", name: "maxLength", constraints: [100] },
13
- ];
14
- jest.mock("class-validator", () => {
15
- const mockGetMetadataStorage = jest.fn(() => ({
16
- getTargetValidationMetadatas: jest.fn(() => [
17
- { propertyName: "name", name: "isNotEmpty", constraints: [] },
18
- { propertyName: "age", name: "isInt", constraints: [] },
19
- { propertyName: "email", name: "isEmail", constraints: [] },
20
- { propertyName: "tags", name: "isOptional", constraints: [] },
21
- { propertyName: "desc", name: "minLength", constraints: [5] },
22
- { propertyName: "desc", name: "maxLength", constraints: [100] },
23
- ]),
24
- }));
25
- return {
26
- getMetadataStorage: mockGetMetadataStorage,
27
- };
28
- });
29
- // Helper to set Reflect metadata for property types and openapi
30
- function setPropertyMetadata(target, property, type, openApi) {
31
- Reflect.defineMetadata("design:type", type, target, property);
32
- if (openApi) {
33
- Reflect.defineMetadata("property:openapi", openApi, target, property);
34
- }
35
- }
36
- // Test class
37
- class TestDto {
38
- }
39
- setPropertyMetadata(TestDto.prototype, "name", String);
40
- setPropertyMetadata(TestDto.prototype, "age", Number);
41
- setPropertyMetadata(TestDto.prototype, "email", String);
42
- setPropertyMetadata(TestDto.prototype, "tags", Array);
43
- setPropertyMetadata(TestDto.prototype, "desc", String, { description: "Description", example: "A desc" });
44
- setPropertyMetadata(TestDto.prototype, "ignored", String, { exclude: true });
45
- describe("generateClassSchema", () => {
46
- it("should generate correct schema for class properties and validation", () => {
47
- const schema = (0, swagger_schema_1.generateClassSchema)(TestDto); // ✅
48
- expect(schema).toEqual({
49
- type: "object",
50
- properties: {
51
- name: { type: "string" },
52
- age: { type: "integer" },
53
- email: { type: "string", format: "email" },
54
- tags: { type: "array", items: { type: "string" } },
55
- desc: {
56
- type: "string",
57
- description: "Description",
58
- example: "A desc",
59
- minLength: 5,
60
- maxLength: 100,
61
- },
62
- },
63
- required: ["name", "age", "email", "desc"],
64
- });
65
- expect(schema.properties.ignored).toBeUndefined();
66
- });
67
- it("should handle openapi metadata fields", () => {
68
- setPropertyMetadata(TestDto.prototype, "desc", String, {
69
- description: "desc field",
70
- example: "example",
71
- deprecated: true,
72
- enum: ["a", "b"],
73
- format: "custom-format",
74
- default: "default",
75
- minimum: 1,
76
- maximum: 10,
77
- minLength: 2,
78
- maxLength: 20,
79
- pattern: ".*",
80
- oneOf: [{ type: "string" }],
81
- allOf: [{ type: "string" }],
82
- anyOf: [{ type: "string" }],
83
- });
84
- const schema = (0, swagger_schema_1.generateClassSchema)(TestDto); // ✅
85
- expect(schema.properties.desc).toMatchObject({
86
- description: "desc field",
87
- example: "example",
88
- deprecated: true,
89
- enum: ["a", "b"],
90
- format: "custom-format",
91
- default: "default",
92
- minimum: 1,
93
- maximum: 10,
94
- minLength: 2,
95
- maxLength: 20,
96
- pattern: ".*",
97
- oneOf: [{ type: "string" }],
98
- allOf: [{ type: "string" }],
99
- anyOf: [{ type: "string" }],
100
- type: "string",
101
- });
102
- });
103
- it("should not include excluded properties", () => {
104
- setPropertyMetadata(TestDto.prototype, "ignored", String, { exclude: true });
105
- const schema = (0, swagger_schema_1.generateClassSchema)(TestDto); // ✅
106
- expect(schema.properties.ignored).toBeUndefined();
107
- });
108
- it("should fallback to string type if type is unknown", () => {
109
- setPropertyMetadata(TestDto.prototype, "unknown", undefined);
110
- mockValidationMetadatas.push({ propertyName: "unknown", name: "isNotEmpty", constraints: [] });
111
- const schema = (0, swagger_schema_1.generateClassSchema)(TestDto); // ✅
112
- expect(schema.properties.unknown.type).toBe("string");
113
- });
114
- it("should return empty schema for null or undefined input", () => {
115
- const schema = (0, swagger_schema_1.generateClassSchema)(null);
116
- expect(schema).toEqual({ type: "object", properties: {}, required: [] });
117
- });
118
- it("should handle array controllers input gracefully", () => {
119
- // generateSwaggerSchema (array version) should skip non-DTO classes
120
- // generateClassSchema should never receive an array
121
- const schema = (0, swagger_schema_1.generateClassSchema)(TestDto);
122
- expect(schema.type).toBe("object");
123
- expect(schema.properties).toBeDefined();
124
- });
125
- });
@@ -1,15 +0,0 @@
1
- /**
2
- * @copyright 2024
3
- * @author Tareq Hossain
4
- * @email xtrinsic96@gmail.com
5
- * @url https://github.com/xtareq
6
- */
7
- import { IApplication } from "./application.interface";
8
- export interface IAppBuilder {
9
- createBuilder(): IAppBuilder;
10
- /**
11
- * @description will create a application instace
12
- * @returns IApplication
13
- */
14
- builder: () => IApplication;
15
- }
@@ -1,8 +0,0 @@
1
- "use strict";
2
- /**
3
- * @copyright 2024
4
- * @author Tareq Hossain
5
- * @email xtrinsic96@gmail.com
6
- * @url https://github.com/xtareq
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,8 +0,0 @@
1
- /**
2
- * @copyright 2024
3
- * @author Tareq Hossain
4
- * @email xtrinsic96@gmail.com
5
- * @url https://github.com/xtareq
6
- */
7
- export interface IApplication {
8
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,17 +0,0 @@
1
- export declare const uuid: `${string}-${string}-${string}-${string}-${string}`;
2
- export type Constructor<T = any> = new (...args: any[]) => T;
3
- export declare function isConstructor(func: any): boolean;
4
- export declare function formatUrl(path: string): string;
5
- export declare function parsedPath(ipath: string): string;
6
- export interface MatchLocation {
7
- line: number;
8
- column: number;
9
- }
10
- export declare const getLineNumber: (filePath: string, rpath: string | RegExp) => MatchLocation[] | null;
11
- export declare function normalizePath(base?: string, subPath?: string): string;
12
- export declare function extrctParamFromUrl(url: string): {
13
- key: string;
14
- required: boolean;
15
- }[];
16
- export declare function findDuplicates(arr: string[]): string[];
17
- export declare function sleep(ms: number): Promise<unknown>;