tspace-spear 1.2.5 → 1.2.6
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/README.md +300 -26
- package/dist/cli/app.d.ts +1 -0
- package/dist/cli/app.js +24 -0
- package/dist/cli/app.js.map +1 -0
- package/dist/cli/controller.d.ts +1 -0
- package/dist/cli/controller.js +158 -0
- package/dist/cli/controller.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +138 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/lib/core/client/index.d.ts +82 -0
- package/dist/lib/core/client/index.js +142 -0
- package/dist/lib/core/client/index.js.map +1 -0
- package/dist/lib/core/compiler/generator.d.ts +18 -0
- package/dist/lib/core/compiler/generator.js +347 -0
- package/dist/lib/core/compiler/generator.js.map +1 -0
- package/dist/lib/core/compiler/index.d.ts +14 -0
- package/dist/lib/core/compiler/index.js +12 -0
- package/dist/lib/core/compiler/index.js.map +1 -0
- package/dist/lib/core/compiler/pre-routes.d.ts +165 -0
- package/dist/lib/core/compiler/pre-routes.js +48 -0
- package/dist/lib/core/compiler/pre-routes.js.map +1 -0
- package/dist/lib/core/compiler/types.d.ts +14 -0
- package/dist/lib/core/compiler/types.js +3 -0
- package/dist/lib/core/compiler/types.js.map +1 -0
- package/dist/lib/core/decorators/context.d.ts +50 -1
- package/dist/lib/core/decorators/context.js +87 -3
- package/dist/lib/core/decorators/context.js.map +1 -1
- package/dist/lib/core/decorators/swagger.d.ts +1 -1
- package/dist/lib/core/decorators/swagger.js +1 -1
- package/dist/lib/core/decorators/swagger.js.map +1 -1
- package/dist/lib/core/server/fast-router.js +11 -2
- package/dist/lib/core/server/fast-router.js.map +1 -1
- package/dist/lib/core/server/index.d.ts +16 -0
- package/dist/lib/core/server/index.js +118 -38
- package/dist/lib/core/server/index.js.map +1 -1
- package/dist/lib/core/server/parser-factory.d.ts +2 -2
- package/dist/lib/core/server/parser-factory.js +236 -4
- package/dist/lib/core/server/parser-factory.js.map +1 -1
- package/dist/lib/core/types/index.d.ts +13 -9
- package/dist/tests/e2e..test.d.ts +1 -0
- package/dist/tests/e2e..test.js +16 -0
- package/dist/tests/e2e..test.js.map +1 -0
- package/package.json +32 -4
|
@@ -20,7 +20,7 @@ export declare function createContextDecorator(hook: (ctx: T.Context, next: T.Ne
|
|
|
20
20
|
* }
|
|
21
21
|
* ```
|
|
22
22
|
*
|
|
23
|
-
* @param {...string}
|
|
23
|
+
* @param {...string} keys - Body field names to extract.
|
|
24
24
|
* @returns {MethodDecorator}
|
|
25
25
|
*/
|
|
26
26
|
export declare const Body: (...keys: string[]) => MethodDecorator;
|
|
@@ -96,3 +96,52 @@ export declare const Query: (...keys: string[]) => MethodDecorator;
|
|
|
96
96
|
* @returns {MethodDecorator}
|
|
97
97
|
*/
|
|
98
98
|
export declare const Cookies: (...keys: string[]) => MethodDecorator;
|
|
99
|
+
/**
|
|
100
|
+
* Validates required fields from a request target.
|
|
101
|
+
*
|
|
102
|
+
* @param keys - List of required field names.
|
|
103
|
+
* @param options - Validation options.
|
|
104
|
+
* @param options.target - Request source to validate.
|
|
105
|
+
* Defaults to `"body"`.
|
|
106
|
+
*
|
|
107
|
+
* @param options.required - Enables required-value validation.
|
|
108
|
+
*
|
|
109
|
+
* - `true`
|
|
110
|
+
* - Rejects `null`
|
|
111
|
+
* - Rejects empty strings (`""`)
|
|
112
|
+
*
|
|
113
|
+
* - `object`
|
|
114
|
+
* - Allows customizing required rules.
|
|
115
|
+
*
|
|
116
|
+
* @param options.required.allowNull - Allow `null` values.
|
|
117
|
+
* Default: `false`
|
|
118
|
+
*
|
|
119
|
+
* @param options.required.allowEmptyString - Allow empty string values.
|
|
120
|
+
* Default: `false`
|
|
121
|
+
* @returns {MethodDecorator}
|
|
122
|
+
*
|
|
123
|
+
* @throws {Object} Throws a validation error object when
|
|
124
|
+
* one or more required fields are missing.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* \@Validate(["email", "password"], {
|
|
129
|
+
* required: {
|
|
130
|
+
* allowEmptyString : true,
|
|
131
|
+
* allowNull : false
|
|
132
|
+
* }
|
|
133
|
+
* });
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* \@Validate(["id"], { target: "query" });
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare const Validate: (keys: string[], { target, required }?: {
|
|
142
|
+
target?: "params" | "query" | "body" | "files";
|
|
143
|
+
required?: boolean | {
|
|
144
|
+
allowNull?: boolean;
|
|
145
|
+
allowEmptyString?: boolean;
|
|
146
|
+
};
|
|
147
|
+
}) => MethodDecorator;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Cookies = exports.Query = exports.Params = exports.Files = exports.Body = void 0;
|
|
3
|
+
exports.Validate = exports.Cookies = exports.Query = exports.Params = exports.Files = exports.Body = void 0;
|
|
4
4
|
exports.createDtoDecorator = createDtoDecorator;
|
|
5
5
|
exports.createContextDecorator = createContextDecorator;
|
|
6
6
|
function createDtoDecorator(validator, onError) {
|
|
@@ -16,7 +16,7 @@ function createDtoDecorator(validator, onError) {
|
|
|
16
16
|
return onError(ctx, err);
|
|
17
17
|
}
|
|
18
18
|
let message = err?.message ?? "Bad Request";
|
|
19
|
-
let issues = err.issues ?? [];
|
|
19
|
+
let issues = err.issues ?? err.errors ?? [];
|
|
20
20
|
let status = 400;
|
|
21
21
|
if (err.name === "ZodError") {
|
|
22
22
|
const zodIssues = err.issues
|
|
@@ -67,7 +67,7 @@ function createContextDecorator(hook) {
|
|
|
67
67
|
* }
|
|
68
68
|
* ```
|
|
69
69
|
*
|
|
70
|
-
* @param {...string}
|
|
70
|
+
* @param {...string} keys - Body field names to extract.
|
|
71
71
|
* @returns {MethodDecorator}
|
|
72
72
|
*/
|
|
73
73
|
const Body = (...keys) => {
|
|
@@ -178,4 +178,88 @@ const Cookies = (...keys) => {
|
|
|
178
178
|
});
|
|
179
179
|
};
|
|
180
180
|
exports.Cookies = Cookies;
|
|
181
|
+
/**
|
|
182
|
+
* Validates required fields from a request target.
|
|
183
|
+
*
|
|
184
|
+
* @param keys - List of required field names.
|
|
185
|
+
* @param options - Validation options.
|
|
186
|
+
* @param options.target - Request source to validate.
|
|
187
|
+
* Defaults to `"body"`.
|
|
188
|
+
*
|
|
189
|
+
* @param options.required - Enables required-value validation.
|
|
190
|
+
*
|
|
191
|
+
* - `true`
|
|
192
|
+
* - Rejects `null`
|
|
193
|
+
* - Rejects empty strings (`""`)
|
|
194
|
+
*
|
|
195
|
+
* - `object`
|
|
196
|
+
* - Allows customizing required rules.
|
|
197
|
+
*
|
|
198
|
+
* @param options.required.allowNull - Allow `null` values.
|
|
199
|
+
* Default: `false`
|
|
200
|
+
*
|
|
201
|
+
* @param options.required.allowEmptyString - Allow empty string values.
|
|
202
|
+
* Default: `false`
|
|
203
|
+
* @returns {MethodDecorator}
|
|
204
|
+
*
|
|
205
|
+
* @throws {Object} Throws a validation error object when
|
|
206
|
+
* one or more required fields are missing.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* \@Validate(["email", "password"], {
|
|
211
|
+
* required: {
|
|
212
|
+
* allowEmptyString : true,
|
|
213
|
+
* allowNull : false
|
|
214
|
+
* }
|
|
215
|
+
* });
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* \@Validate(["id"], { target: "query" });
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
const Validate = (keys, { target, required } = {}) => {
|
|
224
|
+
return createDtoDecorator((ctx) => {
|
|
225
|
+
const payload = ctx[target ?? 'body'] ?? {};
|
|
226
|
+
const issues = [];
|
|
227
|
+
const requiredOpts = typeof required === "object"
|
|
228
|
+
? required
|
|
229
|
+
: {};
|
|
230
|
+
const allowNull = requiredOpts.allowNull ?? false;
|
|
231
|
+
const allowEmptyString = requiredOpts.allowEmptyString ?? false;
|
|
232
|
+
for (let i = 0; i < keys.length; i++) {
|
|
233
|
+
const key = keys[i];
|
|
234
|
+
const value = payload[key];
|
|
235
|
+
if (value === undefined) {
|
|
236
|
+
issues.push({
|
|
237
|
+
path: key,
|
|
238
|
+
message: "Missing field",
|
|
239
|
+
});
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (required) {
|
|
243
|
+
const isNull = value === null && !allowNull;
|
|
244
|
+
const isEmptyString = typeof value === "string" &&
|
|
245
|
+
value.trim() === "" &&
|
|
246
|
+
!allowEmptyString;
|
|
247
|
+
if (isNull || isEmptyString) {
|
|
248
|
+
issues.push({
|
|
249
|
+
path: key,
|
|
250
|
+
message: "Field is required",
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (issues.length) {
|
|
256
|
+
throw {
|
|
257
|
+
message: "Validation failed",
|
|
258
|
+
issues
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return;
|
|
262
|
+
});
|
|
263
|
+
};
|
|
264
|
+
exports.Validate = Validate;
|
|
181
265
|
//# sourceMappingURL=context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/lib/core/decorators/context.ts"],"names":[],"mappings":";;;AAEA,gDA4CC;AACD,wDA0BC;AAvED,SAAgB,kBAAkB,CAC9B,SAAmD,EACnD,OAA6C;IAE7C,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,UAA8B,EAAE,EAAE;QACrD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;QAElC,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAc,EAAE,IAAoB;YACnE,IAAI,CAAC;gBACD,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;gBAErB,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAEhD,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAEhB,IAAI,OAAO,EAAE,CAAC;oBACV,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC7B,CAAC;gBAED,IAAI,OAAO,GAAG,GAAG,EAAE,OAAO,IAAI,aAAa,CAAC;gBAC5C,IAAI,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/lib/core/decorators/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,4 +33,4 @@ import { type T } from "../types";
|
|
|
33
33
|
* @param {T.Swagger.Spec} data - Swagger/OpenAPI specification for the route.
|
|
34
34
|
* @returns {MethodDecorator}
|
|
35
35
|
*/
|
|
36
|
-
export declare const Swagger: (data
|
|
36
|
+
export declare const Swagger: (data?: T.Swagger.Spec) => MethodDecorator;
|
|
@@ -35,7 +35,7 @@ exports.Swagger = void 0;
|
|
|
35
35
|
* @param {T.Swagger.Spec} data - Swagger/OpenAPI specification for the route.
|
|
36
36
|
* @returns {MethodDecorator}
|
|
37
37
|
*/
|
|
38
|
-
const Swagger = (data) => {
|
|
38
|
+
const Swagger = (data = {}) => {
|
|
39
39
|
return (target, propertyKey) => {
|
|
40
40
|
const controller = target.constructor;
|
|
41
41
|
const swaggers = Reflect.hasMetadata("swaggers", controller)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swagger.js","sourceRoot":"","sources":["../../../../src/lib/core/decorators/swagger.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACI,MAAM,OAAO,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"swagger.js","sourceRoot":"","sources":["../../../../src/lib/core/decorators/swagger.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACI,MAAM,OAAO,GAAG,CAAC,OAAuB,EAAE,EAAmB,EAAE;IACpE,OAAO,CAAC,MAAW,EAAE,WAAgB,EAAE,EAAE;QACvC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;QAEtC,MAAM,QAAQ,GAAU,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC;YACjE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC;YAC7C,CAAC,CAAC,EAAE,CAAC;QAEP,QAAQ,CAAC,IAAI,CAAC;YACZ,OAAO,EAAE,WAAW;YACpB,GAAG,IAAI;SACR,CAAC,CAAC;QAEH,OAAO,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC3D,CAAC,CAAC;AACJ,CAAC,CAAC;AAfW,QAAA,OAAO,WAelB"}
|
|
@@ -162,8 +162,10 @@ class FastRouter {
|
|
|
162
162
|
const method = req.method;
|
|
163
163
|
let node = this.trees[method];
|
|
164
164
|
if (!node) {
|
|
165
|
+
if (res.writableEnded) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
165
168
|
res.statusCode = 405;
|
|
166
|
-
console.log({ method });
|
|
167
169
|
return res.end("Method Not Allowed");
|
|
168
170
|
}
|
|
169
171
|
let url = req.url || "/";
|
|
@@ -200,6 +202,9 @@ class FastRouter {
|
|
|
200
202
|
if (rootWildcard?.handler) {
|
|
201
203
|
return rootWildcard.handler(req, res, params);
|
|
202
204
|
}
|
|
205
|
+
if (res.writableEnded) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
203
208
|
res.statusCode = 404;
|
|
204
209
|
res.end("Not Found");
|
|
205
210
|
return;
|
|
@@ -209,8 +214,12 @@ class FastRouter {
|
|
|
209
214
|
if (rootWildcard?.handler) {
|
|
210
215
|
return rootWildcard.handler(req, res, params);
|
|
211
216
|
}
|
|
217
|
+
if (res.writableEnded) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
212
220
|
res.statusCode = 404;
|
|
213
|
-
|
|
221
|
+
res.end("Not Found");
|
|
222
|
+
return;
|
|
214
223
|
}
|
|
215
224
|
return node.handler(req, res, params);
|
|
216
225
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fast-router.js","sourceRoot":"","sources":["../../../../src/lib/core/server/fast-router.ts"],"names":[],"mappings":";;;AAiBA,MAAM,OAAO,GAAG;IACd,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;IAC7B,QAAQ,EAAE,SAAS,EAAE,MAAM;CACnB,CAAA;AAGV,MAAa,UAAU;IACb,KAAK,GAAyB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,GAAc,EAAE,CAAA;IAE/B;QACE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;OAWG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAY,EAAE,OAAgB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,IAAY,EAAE,OAAgB;QACzC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,IAAY,EAAE,OAAgB;QAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,OAAO,CAAC,IAAY,EAAE,OAAgB;QAC3C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAY,EAAE,OAAgB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,KAAI,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,MAAM,CAAC,GAAoB,EAAE,GAAmB;QACrD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAO,CAAC;QAE3B,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"fast-router.js","sourceRoot":"","sources":["../../../../src/lib/core/server/fast-router.ts"],"names":[],"mappings":";;;AAiBA,MAAM,OAAO,GAAG;IACd,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;IAC7B,QAAQ,EAAE,SAAS,EAAE,MAAM;CACnB,CAAA;AAGV,MAAa,UAAU;IACb,KAAK,GAAyB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,GAAc,EAAE,CAAA;IAE/B;QACE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;OAWG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAY,EAAE,OAAgB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,IAAY,EAAE,OAAgB;QACzC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,IAAY,EAAE,OAAgB;QAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,OAAO,CAAC,IAAY,EAAE,OAAgB;QAC3C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACI,IAAI,CAAC,IAAY,EAAE,OAAgB;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,GAAG,CAAC,IAAY,EAAE,OAAgB;QACvC,KAAI,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,MAAM,CAAC,GAAoB,EAAE,GAAmB;QACrD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAO,CAAC;QAE3B,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;gBACtB,OAAM;YACR,CAAC;YACD,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,OAAO,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACvC,CAAC;QAED,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEpC,MAAM,MAAM,GAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE3D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC;QAEnC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;gBACvC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;gBAEhC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;gBACV,CAAC;gBAED,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAE7B,IAAI,IAAI,EAAE,CAAC;oBACT,IAAI,GAAG,IAAI,CAAA;oBACX,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;gBACV,CAAC;gBAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAU,CAAC,GAAG,IAAI,CAAA;oBACpC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;oBACjB,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAQ;gBACV,CAAC;gBAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC/B,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;oBACrB,MAAK;gBACP,CAAC;gBAED,IAAI,YAAY,EAAE,OAAO,EAAE,CAAC;oBAC1B,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;gBAC/C,CAAC;gBAED,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;oBACtB,OAAM;gBACR,CAAC;gBAED,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;gBACrB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QAEA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAEnB,IAAI,YAAY,EAAE,OAAO,EAAE,CAAC;gBAC1B,OAAO,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAChD,CAAC;YAED,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC;IAEO,WAAW;QACjB,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAA;IACxC,CAAC;IAEO,IAAI,CAAC,MAAc,EAAE,IAAY,EAAE,OAAgB;QACzD,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE9B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAElC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,KAAK,GAAG,CAAC,GAAG,CAAC,CAAA;oBACb,SAAS;gBACX,CAAC;gBAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBAEpB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;wBAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;wBAChC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBACvC,CAAC;oBAED,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;gBACpB,CAAC;qBAEI,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;oBAEtB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;wBACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrC,CAAC;oBACD,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;oBAErB,MAAK;gBACP,CAAC;qBAEI,CAAC;oBAEJ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;wBACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;oBACzC,CAAC;oBAED,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC;gBAED,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QAEvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QAEH,OAAO;IACT,CAAC;IAEO,cAAc,CAAC,IAAY;QACjC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;gBACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAElC,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7B,CAAC;gBAED,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA1UD,gCA0UC"}
|
|
@@ -3,6 +3,7 @@ import WebSocket from 'ws';
|
|
|
3
3
|
import { FastRouter } from './fast-router';
|
|
4
4
|
import { Router } from './router';
|
|
5
5
|
import type { T } from '../types';
|
|
6
|
+
import { AppRoutes } from '../compiler/pre-routes';
|
|
6
7
|
/**
|
|
7
8
|
*
|
|
8
9
|
* The 'Spear' class is used to create a server and handle HTTP requests.
|
|
@@ -36,6 +37,7 @@ declare class Spear {
|
|
|
36
37
|
private _formatResponse;
|
|
37
38
|
private _onListeners;
|
|
38
39
|
private _fileUploadOptions;
|
|
40
|
+
private _generatePreRouteTypes;
|
|
39
41
|
constructor({ controllers, middlewares, globalPrefix, logger, cluster, adapter }?: T.Application);
|
|
40
42
|
/**
|
|
41
43
|
* The get 'instance' method is used to get the instance of Spear.
|
|
@@ -49,6 +51,19 @@ declare class Spear {
|
|
|
49
51
|
* @returns {FastRouter}
|
|
50
52
|
*/
|
|
51
53
|
get routers(): FastRouter;
|
|
54
|
+
get contract(): AppRoutes;
|
|
55
|
+
/**
|
|
56
|
+
* The 'usePreRouteTypes' method is used to create pre routes for e2e and swagger
|
|
57
|
+
*
|
|
58
|
+
* @param {{object}} options options
|
|
59
|
+
* @property {string} options.folder
|
|
60
|
+
* @property {RegExp} options.name
|
|
61
|
+
* @returns {this}
|
|
62
|
+
*/
|
|
63
|
+
usePreRouteTypes(options: {
|
|
64
|
+
folder: string;
|
|
65
|
+
name: RegExp;
|
|
66
|
+
}): this;
|
|
52
67
|
/**
|
|
53
68
|
* The 'ws' method is used to creates the WebSocket server.
|
|
54
69
|
*
|
|
@@ -282,6 +297,7 @@ declare class Spear {
|
|
|
282
297
|
*/
|
|
283
298
|
all(path: string, ...handlers: T.ContextHandler[]): this;
|
|
284
299
|
private _import;
|
|
300
|
+
private _scan;
|
|
285
301
|
private _registerControllers;
|
|
286
302
|
private _registerMiddlewares;
|
|
287
303
|
private _wrapHandlers;
|
|
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) ||
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
35
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
27
|
};
|
|
@@ -50,6 +40,7 @@ const net_1 = __importDefault(require("net"));
|
|
|
50
40
|
const parser_factory_1 = require("./parser-factory");
|
|
51
41
|
const fast_router_1 = require("./fast-router");
|
|
52
42
|
const response_1 = require("./response");
|
|
43
|
+
const compiler_1 = require("../compiler");
|
|
53
44
|
const uWS_1 = require("./uWS");
|
|
54
45
|
const net_2 = require("./net");
|
|
55
46
|
/**
|
|
@@ -110,6 +101,7 @@ class Spear {
|
|
|
110
101
|
ms: 1000 * 60 * 10
|
|
111
102
|
}
|
|
112
103
|
};
|
|
104
|
+
_generatePreRouteTypes;
|
|
113
105
|
constructor({ controllers, middlewares, globalPrefix, logger, cluster, adapter } = {}) {
|
|
114
106
|
this._controllers = controllers;
|
|
115
107
|
this._middlewares = middlewares;
|
|
@@ -121,6 +113,24 @@ class Spear {
|
|
|
121
113
|
this.useAdater(adapter);
|
|
122
114
|
if (globalPrefix)
|
|
123
115
|
this.useGlobalPrefix(globalPrefix);
|
|
116
|
+
// Ensure controllers is NOT an array and has the required shape
|
|
117
|
+
// before enabling automatic route generation (used for E2E typing).
|
|
118
|
+
const isValidControllerObject = controllers &&
|
|
119
|
+
!Array.isArray(controllers) &&
|
|
120
|
+
typeof controllers === "object" &&
|
|
121
|
+
"folder" in controllers &&
|
|
122
|
+
"name" in controllers &&
|
|
123
|
+
"preRouteTypes" in controllers &&
|
|
124
|
+
controllers.folder &&
|
|
125
|
+
controllers.name &&
|
|
126
|
+
controllers.preRouteTypes;
|
|
127
|
+
if (isValidControllerObject) {
|
|
128
|
+
// Auto-generate route metadata for type-safe E2E usage;
|
|
129
|
+
this._generatePreRouteTypes = {
|
|
130
|
+
folder: controllers.folder,
|
|
131
|
+
name: controllers.name,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
124
134
|
}
|
|
125
135
|
/**
|
|
126
136
|
* The get 'instance' method is used to get the instance of Spear.
|
|
@@ -138,6 +148,21 @@ class Spear {
|
|
|
138
148
|
get routers() {
|
|
139
149
|
return this._router;
|
|
140
150
|
}
|
|
151
|
+
get contract() {
|
|
152
|
+
return {};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The 'usePreRouteTypes' method is used to create pre routes for e2e and swagger
|
|
156
|
+
*
|
|
157
|
+
* @param {{object}} options options
|
|
158
|
+
* @property {string} options.folder
|
|
159
|
+
* @property {RegExp} options.name
|
|
160
|
+
* @returns {this}
|
|
161
|
+
*/
|
|
162
|
+
usePreRouteTypes(options) {
|
|
163
|
+
this._generatePreRouteTypes = options;
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
141
166
|
/**
|
|
142
167
|
* The 'ws' method is used to creates the WebSocket server.
|
|
143
168
|
*
|
|
@@ -391,6 +416,9 @@ class Spear {
|
|
|
391
416
|
callback = hostname;
|
|
392
417
|
}
|
|
393
418
|
const server = await this._createServer();
|
|
419
|
+
if (this._generatePreRouteTypes) {
|
|
420
|
+
await new compiler_1.Compiler().generateRoutes(this._generatePreRouteTypes);
|
|
421
|
+
}
|
|
394
422
|
if (this._cluster != null &&
|
|
395
423
|
this._cluster || typeof this._cluster === 'number') {
|
|
396
424
|
this._clusterMode({
|
|
@@ -402,10 +430,10 @@ class Spear {
|
|
|
402
430
|
return server;
|
|
403
431
|
}
|
|
404
432
|
if (this._adapter.kind === 'uWS') {
|
|
405
|
-
const handler = () => {
|
|
433
|
+
const handler = async () => {
|
|
406
434
|
this._onListeners.forEach(listener => listener());
|
|
407
435
|
if (this._swagger.use) {
|
|
408
|
-
this._swaggerHandler();
|
|
436
|
+
await this._swaggerHandler();
|
|
409
437
|
}
|
|
410
438
|
callback?.({ server, port });
|
|
411
439
|
};
|
|
@@ -421,10 +449,10 @@ class Spear {
|
|
|
421
449
|
? [port, hostname, () => callback?.({ server, port: port })]
|
|
422
450
|
: [port, () => callback?.({ server, port: port })];
|
|
423
451
|
server.listen(...args);
|
|
424
|
-
server.on('listening', () => {
|
|
452
|
+
server.on('listening', async () => {
|
|
425
453
|
this._onListeners.forEach(listener => listener());
|
|
426
454
|
if (this._swagger.use) {
|
|
427
|
-
this._swaggerHandler();
|
|
455
|
+
await this._swaggerHandler();
|
|
428
456
|
}
|
|
429
457
|
});
|
|
430
458
|
return server;
|
|
@@ -624,25 +652,55 @@ class Spear {
|
|
|
624
652
|
return this;
|
|
625
653
|
}
|
|
626
654
|
async _import(dir, pattern) {
|
|
627
|
-
const
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
655
|
+
const recursive = dir.endsWith("*");
|
|
656
|
+
const root = recursive
|
|
657
|
+
? dir.slice(0, -1)
|
|
658
|
+
: dir;
|
|
659
|
+
return this._scan(root, pattern, recursive);
|
|
660
|
+
}
|
|
661
|
+
async _scan(dir, pattern, recursive = false) {
|
|
662
|
+
const entries = await fs_1.default.promises.readdir(dir, {
|
|
663
|
+
withFileTypes: true,
|
|
664
|
+
});
|
|
665
|
+
const result = [];
|
|
666
|
+
for (const entry of entries) {
|
|
667
|
+
const fullPath = path_1.default.resolve(dir, entry.name);
|
|
668
|
+
if (entry.isDirectory()) {
|
|
669
|
+
if (recursive) {
|
|
670
|
+
result.push(...(await this._scan(fullPath, pattern, true)));
|
|
671
|
+
}
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
if (!pattern ||
|
|
675
|
+
pattern.test(entry.name)) {
|
|
676
|
+
result.push(fullPath);
|
|
632
677
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
: pattern.test(directory.name)
|
|
636
|
-
? newDir
|
|
637
|
-
: null;
|
|
638
|
-
}))).filter(d => d != null);
|
|
639
|
-
return [].concat(...files);
|
|
678
|
+
}
|
|
679
|
+
return result;
|
|
640
680
|
}
|
|
641
681
|
async _registerControllers() {
|
|
642
682
|
if (this._controllers == null)
|
|
643
683
|
return;
|
|
644
684
|
if (!Array.isArray(this._controllers)) {
|
|
645
|
-
|
|
685
|
+
let failDir = false;
|
|
686
|
+
const controllers = await this._import(this._controllers.folder, this._controllers.name).catch(err => {
|
|
687
|
+
console.log(`\x1b[31m[ControllerLoader ERROR]\x1b[0m Failed to read directory:\n` +
|
|
688
|
+
`Error: ${err.message}\n`);
|
|
689
|
+
failDir = true;
|
|
690
|
+
return [];
|
|
691
|
+
});
|
|
692
|
+
if (!controllers.length && !failDir) {
|
|
693
|
+
console.log(`\x1b[33m[ControllerLoader Warning]\x1b[0m No controllers found in:\n` +
|
|
694
|
+
`\x1b[36m${this._controllers.folder}\x1b[0m\n\n` +
|
|
695
|
+
`Using pattern:\n` +
|
|
696
|
+
`\x1b[36m${this._controllers.name}\x1b[0m`);
|
|
697
|
+
console.log(`\nMake sure that:\n` +
|
|
698
|
+
`- the folder path exists\n` +
|
|
699
|
+
`- controller files match the pattern\n` +
|
|
700
|
+
`- recursive scanning is enabled for nested folders\n\n` +
|
|
701
|
+
`Example:\n` +
|
|
702
|
+
`\x1b[36m${this._controllers.folder}/*\x1b[0m\n`);
|
|
703
|
+
}
|
|
646
704
|
for (const file of controllers) {
|
|
647
705
|
const imported = await Promise.resolve(`${file}`).then(s => __importStar(require(s)));
|
|
648
706
|
let maybeController = imported?.default;
|
|
@@ -709,7 +767,26 @@ class Spear {
|
|
|
709
767
|
if (this._middlewares == null)
|
|
710
768
|
return;
|
|
711
769
|
if (!Array.isArray(this._middlewares)) {
|
|
712
|
-
|
|
770
|
+
let failDir = false;
|
|
771
|
+
const middlewares = await this._import(this._middlewares.folder, this._middlewares.name)
|
|
772
|
+
.catch(err => {
|
|
773
|
+
console.log(`\x1b[31m[MiddlewareLoader ERROR]\x1b[0m Failed to read directory:\n` +
|
|
774
|
+
`Error: ${err.message}\n`);
|
|
775
|
+
failDir = true;
|
|
776
|
+
return [];
|
|
777
|
+
});
|
|
778
|
+
if (!middlewares.length && !failDir) {
|
|
779
|
+
console.log(`\x1b[33m[MiddlewareLoader Warning]\x1b[0m No middlewares found in:\n` +
|
|
780
|
+
`\x1b[36m${this._middlewares.folder}\x1b[0m\n\n` +
|
|
781
|
+
`Using pattern:\n` +
|
|
782
|
+
`\x1b[36m${this._middlewares.name}\x1b[0m`);
|
|
783
|
+
console.log(`\nMake sure that:\n` +
|
|
784
|
+
`- the folder path exists\n` +
|
|
785
|
+
`- middleware files match the pattern\n` +
|
|
786
|
+
`- recursive scanning is enabled for nested folders\n\n` +
|
|
787
|
+
`Example:\n` +
|
|
788
|
+
`\x1b[36m${this._middlewares.folder}/*\x1b[0m\n`);
|
|
789
|
+
}
|
|
713
790
|
for (const file of middlewares) {
|
|
714
791
|
const imported = await Promise.resolve(`${file}`).then(s => __importStar(require(s)));
|
|
715
792
|
let maybeMiddleware = imported?.default;
|
|
@@ -788,6 +865,8 @@ class Spear {
|
|
|
788
865
|
_nextError(ctx) {
|
|
789
866
|
const NEXT_MESSAGE = "The 'next' function does not have any subsequent function.";
|
|
790
867
|
return (err) => {
|
|
868
|
+
if (ctx.res.writableEnded)
|
|
869
|
+
return;
|
|
791
870
|
const errorMessage = err?.message || NEXT_MESSAGE;
|
|
792
871
|
if (this._errorHandler != null) {
|
|
793
872
|
return this._errorHandler(err, ctx);
|
|
@@ -998,7 +1077,7 @@ class Spear {
|
|
|
998
1077
|
? normalizedPath.replace(/\/api\/api\//, "/api/")
|
|
999
1078
|
: normalizedPath;
|
|
1000
1079
|
}
|
|
1001
|
-
_swaggerHandler() {
|
|
1080
|
+
async _swaggerHandler() {
|
|
1002
1081
|
const routes = this.routers
|
|
1003
1082
|
.routes
|
|
1004
1083
|
.filter(r => {
|
|
@@ -1009,10 +1088,11 @@ class Spear {
|
|
|
1009
1088
|
"HEAD", "OPTIONS"
|
|
1010
1089
|
].includes(r.method);
|
|
1011
1090
|
});
|
|
1012
|
-
const { path, html, staticSwaggerHandler, staticUrl } = this._parser.swagger({
|
|
1091
|
+
const { path, html, staticSwaggerHandler, staticUrl } = await this._parser.swagger({
|
|
1013
1092
|
...this._swagger,
|
|
1014
1093
|
specs: this._swaggerSpecs,
|
|
1015
|
-
routes
|
|
1094
|
+
routes,
|
|
1095
|
+
globalPrefix: this._globalPrefix
|
|
1016
1096
|
});
|
|
1017
1097
|
this._router.get(staticUrl, staticSwaggerHandler);
|
|
1018
1098
|
this._router.get(path, (req, res) => {
|