@avleon/core 0.0.46 → 0.0.49
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.
- package/License +21 -21
- package/README.md +666 -666
- package/dist/chunk-9hOWP6kD.cjs +64 -0
- package/dist/chunk-DORXReHP.js +37 -0
- package/dist/index-CWUcfHYp.d.ts +1283 -0
- package/dist/index-CzAzauXZ.d.cts +1282 -0
- package/dist/index.cjs +3194 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +3022 -79
- package/dist/index.js.map +1 -0
- package/dist/lib-Bk8hUm06.cjs +7847 -0
- package/dist/lib-Bk8hUm06.cjs.map +1 -0
- package/dist/lib-CvDxBMkR.js +7843 -0
- package/dist/lib-CvDxBMkR.js.map +1 -0
- package/package.json +41 -103
- package/dist/application.test.d.ts +0 -1
- package/dist/application.test.js +0 -15
- package/dist/authentication.d.ts +0 -13
- package/dist/authentication.js +0 -16
- package/dist/cache.d.ts +0 -12
- package/dist/cache.js +0 -78
- package/dist/cache.test.d.ts +0 -1
- package/dist/cache.test.js +0 -36
- package/dist/collection.d.ts +0 -43
- package/dist/collection.js +0 -231
- package/dist/collection.test.d.ts +0 -1
- package/dist/collection.test.js +0 -59
- package/dist/config.d.ts +0 -18
- package/dist/config.js +0 -58
- package/dist/config.test.d.ts +0 -1
- package/dist/config.test.js +0 -40
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +0 -4
- package/dist/container.d.ts +0 -30
- package/dist/container.js +0 -55
- package/dist/controller.d.ts +0 -50
- package/dist/controller.js +0 -71
- package/dist/controller.test.d.ts +0 -1
- package/dist/controller.test.js +0 -97
- package/dist/core/application.d.ts +0 -74
- package/dist/core/application.js +0 -424
- package/dist/core/router.d.ts +0 -44
- package/dist/core/router.js +0 -520
- package/dist/core/testing.d.ts +0 -21
- package/dist/core/testing.js +0 -104
- package/dist/core/types.d.ts +0 -67
- package/dist/core/types.js +0 -2
- package/dist/decorators.d.ts +0 -15
- package/dist/decorators.js +0 -41
- package/dist/environment-variables.d.ts +0 -49
- package/dist/environment-variables.js +0 -130
- package/dist/environment-variables.test.d.ts +0 -1
- package/dist/environment-variables.test.js +0 -70
- package/dist/event-dispatcher.d.ts +0 -22
- package/dist/event-dispatcher.js +0 -97
- package/dist/event-subscriber.d.ts +0 -14
- package/dist/event-subscriber.js +0 -87
- package/dist/exceptions/http-exceptions.d.ts +0 -50
- package/dist/exceptions/http-exceptions.js +0 -85
- package/dist/exceptions/index.d.ts +0 -1
- package/dist/exceptions/index.js +0 -17
- package/dist/exceptions/system-exception.d.ts +0 -22
- package/dist/exceptions/system-exception.js +0 -26
- package/dist/file-storage.d.ts +0 -69
- package/dist/file-storage.js +0 -323
- package/dist/file-storage.test.d.ts +0 -1
- package/dist/file-storage.test.js +0 -117
- package/dist/helpers.d.ts +0 -11
- package/dist/helpers.js +0 -27
- package/dist/helpers.test.d.ts +0 -1
- package/dist/helpers.test.js +0 -95
- package/dist/index.d.ts +0 -57
- package/dist/interfaces/avleon-application.d.ts +0 -75
- package/dist/interfaces/avleon-application.js +0 -2
- package/dist/kenx-provider.d.ts +0 -7
- package/dist/kenx-provider.js +0 -44
- package/dist/kenx-provider.test.d.ts +0 -1
- package/dist/kenx-provider.test.js +0 -36
- package/dist/logger.d.ts +0 -12
- package/dist/logger.js +0 -87
- package/dist/logger.test.d.ts +0 -1
- package/dist/logger.test.js +0 -42
- package/dist/map-types.d.ts +0 -17
- package/dist/map-types.js +0 -89
- package/dist/middleware.d.ts +0 -34
- package/dist/middleware.js +0 -73
- package/dist/middleware.test.d.ts +0 -1
- package/dist/middleware.test.js +0 -121
- package/dist/multipart.d.ts +0 -17
- package/dist/multipart.js +0 -70
- package/dist/multipart.test.d.ts +0 -1
- package/dist/multipart.test.js +0 -87
- package/dist/openapi.d.ts +0 -410
- package/dist/openapi.js +0 -59
- package/dist/openapi.test.d.ts +0 -1
- package/dist/openapi.test.js +0 -111
- package/dist/params.d.ts +0 -17
- package/dist/params.js +0 -64
- package/dist/params.test.d.ts +0 -1
- package/dist/params.test.js +0 -83
- package/dist/queue.d.ts +0 -29
- package/dist/queue.js +0 -84
- package/dist/response.d.ts +0 -16
- package/dist/response.js +0 -56
- package/dist/results.d.ts +0 -20
- package/dist/results.js +0 -32
- package/dist/route-methods.d.ts +0 -25
- package/dist/route-methods.js +0 -60
- package/dist/route-methods.test.d.ts +0 -1
- package/dist/route-methods.test.js +0 -129
- package/dist/swagger-schema.d.ts +0 -37
- package/dist/swagger-schema.js +0 -454
- package/dist/swagger-schema.test.d.ts +0 -1
- package/dist/swagger-schema.test.js +0 -125
- package/dist/types/app-builder.interface.d.ts +0 -15
- package/dist/types/app-builder.interface.js +0 -8
- package/dist/types/application.interface.d.ts +0 -8
- package/dist/types/application.interface.js +0 -2
- package/dist/utils/common-utils.d.ts +0 -17
- package/dist/utils/common-utils.js +0 -108
- package/dist/utils/di-utils.d.ts +0 -1
- package/dist/utils/di-utils.js +0 -22
- package/dist/utils/hash.d.ts +0 -2
- package/dist/utils/hash.js +0 -11
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -18
- package/dist/utils/object-utils.d.ts +0 -11
- package/dist/utils/object-utils.js +0 -198
- package/dist/utils/optional-require.d.ts +0 -8
- package/dist/utils/optional-require.js +0 -70
- package/dist/utils/validation-utils.d.ts +0 -13
- package/dist/utils/validation-utils.js +0 -119
- package/dist/validation.d.ts +0 -39
- package/dist/validation.js +0 -108
- package/dist/validation.test.d.ts +0 -1
- package/dist/validation.test.js +0 -61
- package/dist/validator-extend.d.ts +0 -7
- package/dist/validator-extend.js +0 -28
- package/dist/websocket.d.ts +0 -10
- package/dist/websocket.js +0 -21
- package/dist/websocket.test.d.ts +0 -1
- package/dist/websocket.test.js +0 -27
package/dist/swagger-schema.js
DELETED
|
@@ -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,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>;
|