deco-express 0.1.5 → 0.2.0
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/dist/index.d.mts +17 -8
- package/dist/index.d.ts +17 -8
- package/dist/index.js +7 -24
- package/dist/index.mjs +7 -14
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RequestHandler, Express } from 'express';
|
|
2
2
|
import Joi from 'joi';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -34,19 +34,24 @@ declare function Route(method: keyof Express, path?: string, ...middleware: Requ
|
|
|
34
34
|
* and is prepended to every route path registered by {@link Route} decorators
|
|
35
35
|
* on the class's methods.
|
|
36
36
|
*
|
|
37
|
+
* Controller-level middleware is stored under the `"controllerMiddleware"` key
|
|
38
|
+
* and is prepended to every route handler in the controller.
|
|
39
|
+
*
|
|
37
40
|
* @param baseRoute - The base path prefix for all routes in the controller
|
|
38
41
|
* (e.g. `"/users"`). Defaults to `""` (no prefix).
|
|
42
|
+
* @param middleware - Zero or more Express middleware functions that are
|
|
43
|
+
* executed **before** every route handler in the controller.
|
|
39
44
|
*
|
|
40
45
|
* @example
|
|
41
46
|
* ```ts
|
|
42
|
-
* \@Controller('/users')
|
|
47
|
+
* \@Controller('/users', authMiddleware)
|
|
43
48
|
* class UserController {
|
|
44
49
|
* \@Route('get', '/:id')
|
|
45
50
|
* getUser(req: Request, res: Response) { ... }
|
|
46
51
|
* }
|
|
47
52
|
* ```
|
|
48
53
|
*/
|
|
49
|
-
declare function Controller(baseRoute?: string): (target: object) => void;
|
|
54
|
+
declare function Controller(baseRoute?: string, ...middleware: RequestHandler[]): (target: object) => void;
|
|
50
55
|
|
|
51
56
|
/**
|
|
52
57
|
* Method decorator that validates `req.body` against a Joi schema before the
|
|
@@ -91,8 +96,10 @@ type Constructor<T = object> = new (...args: unknown[]) => T;
|
|
|
91
96
|
* For each controller the function:
|
|
92
97
|
* 1. Instantiates the class with `new`.
|
|
93
98
|
* 2. Reads the `"baseRoute"` metadata set by {@link Controller}.
|
|
94
|
-
* 3. Reads the `"
|
|
95
|
-
* 4.
|
|
99
|
+
* 3. Reads the `"controllerMiddleware"` metadata set by {@link Controller}.
|
|
100
|
+
* 4. Reads the `"routeHandlers"` metadata set by {@link Route}.
|
|
101
|
+
* 5. Mounts each handler at the resolved full path on the Express app,
|
|
102
|
+
* with controller-level middleware prepended to each route's handlers.
|
|
96
103
|
*
|
|
97
104
|
* The full path is built as:
|
|
98
105
|
* ```
|
|
@@ -105,6 +112,8 @@ type Constructor<T = object> = new (...args: unknown[]) => T;
|
|
|
105
112
|
* @param version - API version number. When `addApi` is `true` and `version`
|
|
106
113
|
* is non-zero, a `/v{version}` segment is inserted after `/api`.
|
|
107
114
|
* Defaults to `1`.
|
|
115
|
+
* @param log - When `true`, prints each registered route to the console.
|
|
116
|
+
* Defaults to `false`.
|
|
108
117
|
*
|
|
109
118
|
* @example
|
|
110
119
|
* ```ts
|
|
@@ -113,11 +122,11 @@ type Constructor<T = object> = new (...args: unknown[]) => T;
|
|
|
113
122
|
* import { UserController } from './controllers/user';
|
|
114
123
|
*
|
|
115
124
|
* const app = express();
|
|
116
|
-
* defineRoutes([UserController], app);
|
|
117
|
-
* //
|
|
125
|
+
* defineRoutes([UserController], app, true, 1, true);
|
|
126
|
+
* // [deco-express] GET /api/v1/users/:id
|
|
118
127
|
* ```
|
|
119
128
|
*/
|
|
120
|
-
declare function defineRoutes(controllers: Constructor[], application: Express, addApi?: boolean, version?: number): void;
|
|
129
|
+
declare function defineRoutes(controllers: Constructor[], application: Express, addApi?: boolean, version?: number, log?: boolean): void;
|
|
121
130
|
|
|
122
131
|
/**
|
|
123
132
|
* A nested map that stores route handlers organised by HTTP method and path.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RequestHandler, Express } from 'express';
|
|
2
2
|
import Joi from 'joi';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -34,19 +34,24 @@ declare function Route(method: keyof Express, path?: string, ...middleware: Requ
|
|
|
34
34
|
* and is prepended to every route path registered by {@link Route} decorators
|
|
35
35
|
* on the class's methods.
|
|
36
36
|
*
|
|
37
|
+
* Controller-level middleware is stored under the `"controllerMiddleware"` key
|
|
38
|
+
* and is prepended to every route handler in the controller.
|
|
39
|
+
*
|
|
37
40
|
* @param baseRoute - The base path prefix for all routes in the controller
|
|
38
41
|
* (e.g. `"/users"`). Defaults to `""` (no prefix).
|
|
42
|
+
* @param middleware - Zero or more Express middleware functions that are
|
|
43
|
+
* executed **before** every route handler in the controller.
|
|
39
44
|
*
|
|
40
45
|
* @example
|
|
41
46
|
* ```ts
|
|
42
|
-
* \@Controller('/users')
|
|
47
|
+
* \@Controller('/users', authMiddleware)
|
|
43
48
|
* class UserController {
|
|
44
49
|
* \@Route('get', '/:id')
|
|
45
50
|
* getUser(req: Request, res: Response) { ... }
|
|
46
51
|
* }
|
|
47
52
|
* ```
|
|
48
53
|
*/
|
|
49
|
-
declare function Controller(baseRoute?: string): (target: object) => void;
|
|
54
|
+
declare function Controller(baseRoute?: string, ...middleware: RequestHandler[]): (target: object) => void;
|
|
50
55
|
|
|
51
56
|
/**
|
|
52
57
|
* Method decorator that validates `req.body` against a Joi schema before the
|
|
@@ -91,8 +96,10 @@ type Constructor<T = object> = new (...args: unknown[]) => T;
|
|
|
91
96
|
* For each controller the function:
|
|
92
97
|
* 1. Instantiates the class with `new`.
|
|
93
98
|
* 2. Reads the `"baseRoute"` metadata set by {@link Controller}.
|
|
94
|
-
* 3. Reads the `"
|
|
95
|
-
* 4.
|
|
99
|
+
* 3. Reads the `"controllerMiddleware"` metadata set by {@link Controller}.
|
|
100
|
+
* 4. Reads the `"routeHandlers"` metadata set by {@link Route}.
|
|
101
|
+
* 5. Mounts each handler at the resolved full path on the Express app,
|
|
102
|
+
* with controller-level middleware prepended to each route's handlers.
|
|
96
103
|
*
|
|
97
104
|
* The full path is built as:
|
|
98
105
|
* ```
|
|
@@ -105,6 +112,8 @@ type Constructor<T = object> = new (...args: unknown[]) => T;
|
|
|
105
112
|
* @param version - API version number. When `addApi` is `true` and `version`
|
|
106
113
|
* is non-zero, a `/v{version}` segment is inserted after `/api`.
|
|
107
114
|
* Defaults to `1`.
|
|
115
|
+
* @param log - When `true`, prints each registered route to the console.
|
|
116
|
+
* Defaults to `false`.
|
|
108
117
|
*
|
|
109
118
|
* @example
|
|
110
119
|
* ```ts
|
|
@@ -113,11 +122,11 @@ type Constructor<T = object> = new (...args: unknown[]) => T;
|
|
|
113
122
|
* import { UserController } from './controllers/user';
|
|
114
123
|
*
|
|
115
124
|
* const app = express();
|
|
116
|
-
* defineRoutes([UserController], app);
|
|
117
|
-
* //
|
|
125
|
+
* defineRoutes([UserController], app, true, 1, true);
|
|
126
|
+
* // [deco-express] GET /api/v1/users/:id
|
|
118
127
|
* ```
|
|
119
128
|
*/
|
|
120
|
-
declare function defineRoutes(controllers: Constructor[], application: Express, addApi?: boolean, version?: number): void;
|
|
129
|
+
declare function defineRoutes(controllers: Constructor[], application: Express, addApi?: boolean, version?: number, log?: boolean): void;
|
|
121
130
|
|
|
122
131
|
/**
|
|
123
132
|
* A nested map that stores route handlers organised by HTTP method and path.
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
7
|
var __export = (target, all) => {
|
|
@@ -18,14 +16,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
16
|
}
|
|
19
17
|
return to;
|
|
20
18
|
};
|
|
21
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
-
mod
|
|
28
|
-
));
|
|
29
19
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
20
|
|
|
31
21
|
// src/index.ts
|
|
@@ -51,15 +41,15 @@ function Route(method, path = "", ...middleware) {
|
|
|
51
41
|
};
|
|
52
42
|
}
|
|
53
43
|
__name(Route, "Route");
|
|
54
|
-
function Controller(baseRoute = "") {
|
|
44
|
+
function Controller(baseRoute = "", ...middleware) {
|
|
55
45
|
return (target) => {
|
|
56
46
|
Reflect.defineMetadata("baseRoute", baseRoute, target);
|
|
47
|
+
Reflect.defineMetadata("controllerMiddleware", middleware, target);
|
|
57
48
|
};
|
|
58
49
|
}
|
|
59
50
|
__name(Controller, "Controller");
|
|
60
51
|
|
|
61
52
|
// src/decorators/validation.ts
|
|
62
|
-
var import_joi = __toESM(require("joi"));
|
|
63
53
|
function Validate(schema) {
|
|
64
54
|
return function(_target, _propertyKey, descriptor) {
|
|
65
55
|
const originalMethod = descriptor.value;
|
|
@@ -67,16 +57,7 @@ function Validate(schema) {
|
|
|
67
57
|
try {
|
|
68
58
|
await schema.validateAsync(req.body);
|
|
69
59
|
} catch (error) {
|
|
70
|
-
|
|
71
|
-
return res.status(422).json({
|
|
72
|
-
message: "Validation failed",
|
|
73
|
-
details: error.details.map((d) => ({
|
|
74
|
-
field: d.path.join("."),
|
|
75
|
-
message: d.message
|
|
76
|
-
}))
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
return next(error);
|
|
60
|
+
return res.status(422).json(error);
|
|
80
61
|
}
|
|
81
62
|
return originalMethod.call(this, req, res, next);
|
|
82
63
|
};
|
|
@@ -86,7 +67,7 @@ function Validate(schema) {
|
|
|
86
67
|
__name(Validate, "Validate");
|
|
87
68
|
|
|
88
69
|
// src/functions/routes.ts
|
|
89
|
-
function defineRoutes(controllers, application, addApi = true, version = 1) {
|
|
70
|
+
function defineRoutes(controllers, application, addApi = true, version = 1, log = false) {
|
|
90
71
|
for (const ControllerClass of controllers) {
|
|
91
72
|
const controller = new ControllerClass();
|
|
92
73
|
const routeHandlers = Reflect.getMetadata(
|
|
@@ -94,12 +75,14 @@ function defineRoutes(controllers, application, addApi = true, version = 1) {
|
|
|
94
75
|
controller
|
|
95
76
|
);
|
|
96
77
|
const controllerPath = Reflect.getMetadata("baseRoute", controller.constructor) ?? "";
|
|
78
|
+
const controllerMiddleware = Reflect.getMetadata("controllerMiddleware", controller.constructor) ?? [];
|
|
97
79
|
if (!routeHandlers) continue;
|
|
98
80
|
for (const [method, routes] of routeHandlers) {
|
|
99
81
|
for (const [routePath, handlers] of routes) {
|
|
100
82
|
const versionSegment = addApi && version ? `/v${version}` : "";
|
|
101
83
|
const fullPath = `${addApi ? "/api" : ""}${versionSegment}${controllerPath}${routePath}`;
|
|
102
|
-
application[method](fullPath, handlers);
|
|
84
|
+
application[method](fullPath, [...controllerMiddleware, ...handlers]);
|
|
85
|
+
if (log) console.log(`[deco-express] ${method.toUpperCase()} ${fullPath}`);
|
|
103
86
|
}
|
|
104
87
|
}
|
|
105
88
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -16,15 +16,15 @@ function Route(method, path = "", ...middleware) {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
__name(Route, "Route");
|
|
19
|
-
function Controller(baseRoute = "") {
|
|
19
|
+
function Controller(baseRoute = "", ...middleware) {
|
|
20
20
|
return (target) => {
|
|
21
21
|
Reflect.defineMetadata("baseRoute", baseRoute, target);
|
|
22
|
+
Reflect.defineMetadata("controllerMiddleware", middleware, target);
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
__name(Controller, "Controller");
|
|
25
26
|
|
|
26
27
|
// src/decorators/validation.ts
|
|
27
|
-
import Joi from "joi";
|
|
28
28
|
function Validate(schema) {
|
|
29
29
|
return function(_target, _propertyKey, descriptor) {
|
|
30
30
|
const originalMethod = descriptor.value;
|
|
@@ -32,16 +32,7 @@ function Validate(schema) {
|
|
|
32
32
|
try {
|
|
33
33
|
await schema.validateAsync(req.body);
|
|
34
34
|
} catch (error) {
|
|
35
|
-
|
|
36
|
-
return res.status(422).json({
|
|
37
|
-
message: "Validation failed",
|
|
38
|
-
details: error.details.map((d) => ({
|
|
39
|
-
field: d.path.join("."),
|
|
40
|
-
message: d.message
|
|
41
|
-
}))
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
return next(error);
|
|
35
|
+
return res.status(422).json(error);
|
|
45
36
|
}
|
|
46
37
|
return originalMethod.call(this, req, res, next);
|
|
47
38
|
};
|
|
@@ -51,7 +42,7 @@ function Validate(schema) {
|
|
|
51
42
|
__name(Validate, "Validate");
|
|
52
43
|
|
|
53
44
|
// src/functions/routes.ts
|
|
54
|
-
function defineRoutes(controllers, application, addApi = true, version = 1) {
|
|
45
|
+
function defineRoutes(controllers, application, addApi = true, version = 1, log = false) {
|
|
55
46
|
for (const ControllerClass of controllers) {
|
|
56
47
|
const controller = new ControllerClass();
|
|
57
48
|
const routeHandlers = Reflect.getMetadata(
|
|
@@ -59,12 +50,14 @@ function defineRoutes(controllers, application, addApi = true, version = 1) {
|
|
|
59
50
|
controller
|
|
60
51
|
);
|
|
61
52
|
const controllerPath = Reflect.getMetadata("baseRoute", controller.constructor) ?? "";
|
|
53
|
+
const controllerMiddleware = Reflect.getMetadata("controllerMiddleware", controller.constructor) ?? [];
|
|
62
54
|
if (!routeHandlers) continue;
|
|
63
55
|
for (const [method, routes] of routeHandlers) {
|
|
64
56
|
for (const [routePath, handlers] of routes) {
|
|
65
57
|
const versionSegment = addApi && version ? `/v${version}` : "";
|
|
66
58
|
const fullPath = `${addApi ? "/api" : ""}${versionSegment}${controllerPath}${routePath}`;
|
|
67
|
-
application[method](fullPath, handlers);
|
|
59
|
+
application[method](fullPath, [...controllerMiddleware, ...handlers]);
|
|
60
|
+
if (log) console.log(`[deco-express] ${method.toUpperCase()} ${fullPath}`);
|
|
68
61
|
}
|
|
69
62
|
}
|
|
70
63
|
}
|