@abejarano/ts-express-server 1.5.1
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 +61 -0
- package/dist/BootstrapServer.d.ts +26 -0
- package/dist/BootstrapServer.js +172 -0
- package/dist/BootstrapStandardServer.d.ts +20 -0
- package/dist/BootstrapStandardServer.js +75 -0
- package/dist/abstract/ServerModule.d.ts +7 -0
- package/dist/abstract/ServerModule.js +12 -0
- package/dist/abstract/ServerService.d.ts +6 -0
- package/dist/abstract/ServerService.js +9 -0
- package/dist/abstract/index.d.ts +2 -0
- package/dist/abstract/index.js +18 -0
- package/dist/controllers/ReportFinanceController.d.ts +0 -0
- package/dist/controllers/ReportFinanceController.js +1 -0
- package/dist/decorators/Controller.d.ts +2 -0
- package/dist/decorators/Controller.js +10 -0
- package/dist/decorators/Handlers.d.ts +18 -0
- package/dist/decorators/Handlers.js +31 -0
- package/dist/decorators/MetadataKeys.d.ts +6 -0
- package/dist/decorators/MetadataKeys.js +10 -0
- package/dist/decorators/Parameters.d.ts +24 -0
- package/dist/decorators/Parameters.js +41 -0
- package/dist/decorators/Use.d.ts +3 -0
- package/dist/decorators/Use.js +22 -0
- package/dist/decorators/index.d.ts +5 -0
- package/dist/decorators/index.js +21 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +26 -0
- package/dist/modules/ControllersModule.d.ts +11 -0
- package/dist/modules/ControllersModule.js +132 -0
- package/dist/modules/CorsModule.d.ts +11 -0
- package/dist/modules/CorsModule.js +27 -0
- package/dist/modules/FileUploadModule.d.ts +11 -0
- package/dist/modules/FileUploadModule.js +27 -0
- package/dist/modules/RateLimitModule.d.ts +11 -0
- package/dist/modules/RateLimitModule.js +29 -0
- package/dist/modules/RequestContextModule.d.ts +25 -0
- package/dist/modules/RequestContextModule.js +45 -0
- package/dist/modules/RoutesModule.d.ts +17 -0
- package/dist/modules/RoutesModule.js +34 -0
- package/dist/modules/SecurityModule.d.ts +11 -0
- package/dist/modules/SecurityModule.js +44 -0
- package/dist/modules/index.d.ts +7 -0
- package/dist/modules/index.js +23 -0
- package/dist/testing/createDecoratedTestApp.d.ts +20 -0
- package/dist/testing/createDecoratedTestApp.js +46 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +17 -0
- package/package.json +74 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.BootstrapStandardServer = exports.BootstrapServer = void 0;
|
|
18
|
+
require("reflect-metadata");
|
|
19
|
+
var BootstrapServer_1 = require("./BootstrapServer");
|
|
20
|
+
Object.defineProperty(exports, "BootstrapServer", { enumerable: true, get: function () { return BootstrapServer_1.BootstrapServer; } });
|
|
21
|
+
var BootstrapStandardServer_1 = require("./BootstrapStandardServer");
|
|
22
|
+
Object.defineProperty(exports, "BootstrapStandardServer", { enumerable: true, get: function () { return BootstrapStandardServer_1.BootstrapStandardServer; } });
|
|
23
|
+
__exportStar(require("./modules"), exports);
|
|
24
|
+
__exportStar(require("./abstract"), exports);
|
|
25
|
+
__exportStar(require("./decorators"), exports);
|
|
26
|
+
__exportStar(require("./testing"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import { BaseServerModule } from "../abstract";
|
|
3
|
+
import "reflect-metadata";
|
|
4
|
+
export declare class ControllersModule extends BaseServerModule {
|
|
5
|
+
private controllers;
|
|
6
|
+
name: string;
|
|
7
|
+
priority: number;
|
|
8
|
+
constructor(controllers: Function[]);
|
|
9
|
+
getModuleName(): string;
|
|
10
|
+
init(app: Express): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ControllersModule = void 0;
|
|
4
|
+
const express_1 = require("express");
|
|
5
|
+
const abstract_1 = require("../abstract");
|
|
6
|
+
const MetadataKeys_1 = require("../decorators/MetadataKeys");
|
|
7
|
+
const Parameters_1 = require("../decorators/Parameters");
|
|
8
|
+
require("reflect-metadata");
|
|
9
|
+
class ControllersModule extends abstract_1.BaseServerModule {
|
|
10
|
+
constructor(controllers) {
|
|
11
|
+
super();
|
|
12
|
+
this.controllers = controllers;
|
|
13
|
+
this.name = "Controllers";
|
|
14
|
+
this.priority = 10;
|
|
15
|
+
}
|
|
16
|
+
getModuleName() {
|
|
17
|
+
return this.name;
|
|
18
|
+
}
|
|
19
|
+
init(app) {
|
|
20
|
+
this.controllers.forEach((ControllerClass) => {
|
|
21
|
+
const basePath = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.BASE_PATH, ControllerClass);
|
|
22
|
+
const classMiddlewares = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.MIDDLEWARE, ControllerClass) || [];
|
|
23
|
+
const routers = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.ROUTERS, ControllerClass.prototype) ||
|
|
24
|
+
[];
|
|
25
|
+
if (!basePath) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const router = (0, express_1.Router)();
|
|
29
|
+
// Create a single controller instance per controller class (singleton pattern)
|
|
30
|
+
const controllerInstance = new ControllerClass();
|
|
31
|
+
// Apply class-level middlewares
|
|
32
|
+
if (classMiddlewares.length > 0) {
|
|
33
|
+
router.use(classMiddlewares);
|
|
34
|
+
}
|
|
35
|
+
routers.forEach(({ method, path, handlerName }) => {
|
|
36
|
+
const routeHandler = ControllerClass.prototype[handlerName];
|
|
37
|
+
const routeMiddlewares = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.MIDDLEWARE, ControllerClass.prototype, handlerName) || [];
|
|
38
|
+
const parameterMetadata = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.PARAMETERS, ControllerClass.prototype, handlerName) || [];
|
|
39
|
+
router[method](path, ...routeMiddlewares, async (req, res, next) => {
|
|
40
|
+
if (parameterMetadata.length === 0) {
|
|
41
|
+
try {
|
|
42
|
+
const result = routeHandler.call(controllerInstance, req, res, next);
|
|
43
|
+
if (result instanceof Promise) {
|
|
44
|
+
await result;
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return next(error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const maxIndex = Math.max(routeHandler.length - 1, ...parameterMetadata.map((param) => param.index));
|
|
53
|
+
const args = new Array(Math.max(0, maxIndex + 1));
|
|
54
|
+
parameterMetadata.forEach((param) => {
|
|
55
|
+
switch (param.type) {
|
|
56
|
+
case Parameters_1.ParameterType.BODY:
|
|
57
|
+
args[param.index] =
|
|
58
|
+
param.data && req.body ? req.body[param.data] : req.body;
|
|
59
|
+
break;
|
|
60
|
+
case Parameters_1.ParameterType.PARAM:
|
|
61
|
+
args[param.index] = param.data
|
|
62
|
+
? req.params?.[param.data]
|
|
63
|
+
: req.params;
|
|
64
|
+
break;
|
|
65
|
+
case Parameters_1.ParameterType.QUERY:
|
|
66
|
+
args[param.index] =
|
|
67
|
+
param.data && req.query ? req.query[param.data] : req.query;
|
|
68
|
+
break;
|
|
69
|
+
case Parameters_1.ParameterType.HEADERS:
|
|
70
|
+
if (param.data) {
|
|
71
|
+
const headerKey = param.data.toLowerCase();
|
|
72
|
+
args[param.index] = req.headers?.[headerKey];
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
args[param.index] = req.headers;
|
|
76
|
+
}
|
|
77
|
+
break;
|
|
78
|
+
case Parameters_1.ParameterType.FILE: {
|
|
79
|
+
const files = req.files;
|
|
80
|
+
if (!files) {
|
|
81
|
+
args[param.index] = undefined;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
if (param.data) {
|
|
85
|
+
args[param.index] = files[param.data];
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
args[param.index] = files;
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case Parameters_1.ParameterType.REQUEST:
|
|
93
|
+
args[param.index] = req;
|
|
94
|
+
break;
|
|
95
|
+
case Parameters_1.ParameterType.RESPONSE:
|
|
96
|
+
args[param.index] = res;
|
|
97
|
+
break;
|
|
98
|
+
case Parameters_1.ParameterType.NEXT:
|
|
99
|
+
args[param.index] = next;
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
args[param.index] = undefined;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
// Fallbacks for common Express arguments when not explicitly decorated
|
|
107
|
+
if (args[0] === undefined) {
|
|
108
|
+
args[0] = req;
|
|
109
|
+
}
|
|
110
|
+
if (args[1] === undefined) {
|
|
111
|
+
args[1] = res;
|
|
112
|
+
}
|
|
113
|
+
if (args[2] === undefined) {
|
|
114
|
+
args[2] = next;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const result = routeHandler.apply(controllerInstance, args);
|
|
118
|
+
if (result instanceof Promise) {
|
|
119
|
+
await result;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
return next(error);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
app.use(basePath, router);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
exports.ControllersModule = ControllersModule;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import { BaseServerModule } from "../abstract";
|
|
3
|
+
import cors from "cors";
|
|
4
|
+
export declare class CorsModule extends BaseServerModule {
|
|
5
|
+
name: string;
|
|
6
|
+
priority: number;
|
|
7
|
+
private corsOptions;
|
|
8
|
+
constructor(corsOptions?: cors.CorsOptions);
|
|
9
|
+
getModuleName(): string;
|
|
10
|
+
init(app: Express): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CorsModule = void 0;
|
|
7
|
+
const abstract_1 = require("../abstract");
|
|
8
|
+
const cors_1 = __importDefault(require("cors"));
|
|
9
|
+
class CorsModule extends abstract_1.BaseServerModule {
|
|
10
|
+
constructor(corsOptions) {
|
|
11
|
+
super();
|
|
12
|
+
this.name = "Cors";
|
|
13
|
+
this.priority = -90;
|
|
14
|
+
this.corsOptions = corsOptions || {
|
|
15
|
+
origin: "*",
|
|
16
|
+
preflightContinue: false,
|
|
17
|
+
optionsSuccessStatus: 204,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
getModuleName() {
|
|
21
|
+
return this.name;
|
|
22
|
+
}
|
|
23
|
+
init(app) {
|
|
24
|
+
app.use((0, cors_1.default)(this.corsOptions));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.CorsModule = CorsModule;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import fileUpload from "express-fileupload";
|
|
3
|
+
import { BaseServerModule } from "../abstract";
|
|
4
|
+
export declare class FileUploadModule extends BaseServerModule {
|
|
5
|
+
name: string;
|
|
6
|
+
priority: number;
|
|
7
|
+
private fileUploadOptions;
|
|
8
|
+
constructor(fileUploadOptions?: fileUpload.Options);
|
|
9
|
+
getModuleName(): string;
|
|
10
|
+
init(app: Express): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FileUploadModule = void 0;
|
|
7
|
+
const express_fileupload_1 = __importDefault(require("express-fileupload"));
|
|
8
|
+
const abstract_1 = require("../abstract");
|
|
9
|
+
class FileUploadModule extends abstract_1.BaseServerModule {
|
|
10
|
+
constructor(fileUploadOptions) {
|
|
11
|
+
super();
|
|
12
|
+
this.name = "FileUpload";
|
|
13
|
+
this.priority = -60;
|
|
14
|
+
this.fileUploadOptions = fileUploadOptions || {
|
|
15
|
+
limits: { fileSize: 50 * 1024 * 1024 },
|
|
16
|
+
useTempFiles: true,
|
|
17
|
+
tempFileDir: "/tmp/",
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
getModuleName() {
|
|
21
|
+
return this.name;
|
|
22
|
+
}
|
|
23
|
+
init(app) {
|
|
24
|
+
app.use((0, express_fileupload_1.default)(this.fileUploadOptions));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.FileUploadModule = FileUploadModule;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import { BaseServerModule } from "../abstract";
|
|
3
|
+
import rateLimit from "express-rate-limit";
|
|
4
|
+
export declare class RateLimitModule extends BaseServerModule {
|
|
5
|
+
name: string;
|
|
6
|
+
priority: number;
|
|
7
|
+
private limiterOptions;
|
|
8
|
+
constructor(limiterOptions?: Parameters<typeof rateLimit>[0]);
|
|
9
|
+
getModuleName(): string;
|
|
10
|
+
init(app: Express): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RateLimitModule = void 0;
|
|
7
|
+
const abstract_1 = require("../abstract");
|
|
8
|
+
const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
|
|
9
|
+
class RateLimitModule extends abstract_1.BaseServerModule {
|
|
10
|
+
constructor(limiterOptions) {
|
|
11
|
+
super();
|
|
12
|
+
this.name = "RateLimit";
|
|
13
|
+
this.priority = -70;
|
|
14
|
+
this.limiterOptions = limiterOptions || {
|
|
15
|
+
windowMs: 8 * 60 * 1000, // 8 minutes
|
|
16
|
+
limit: 100,
|
|
17
|
+
standardHeaders: true,
|
|
18
|
+
legacyHeaders: false,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
getModuleName() {
|
|
22
|
+
return this.name;
|
|
23
|
+
}
|
|
24
|
+
init(app) {
|
|
25
|
+
const limiter = (0, express_rate_limit_1.default)(this.limiterOptions);
|
|
26
|
+
app.use(limiter);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.RateLimitModule = RateLimitModule;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import { BaseServerModule } from "../abstract";
|
|
3
|
+
declare global {
|
|
4
|
+
namespace Express {
|
|
5
|
+
interface Request {
|
|
6
|
+
requestId?: string;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export declare class RequestContextModule extends BaseServerModule {
|
|
11
|
+
name: string;
|
|
12
|
+
priority: number;
|
|
13
|
+
init(app: Express): void;
|
|
14
|
+
getModuleName(): string;
|
|
15
|
+
}
|
|
16
|
+
interface Context {
|
|
17
|
+
requestId: string;
|
|
18
|
+
}
|
|
19
|
+
declare class RequestContext {
|
|
20
|
+
private static storage;
|
|
21
|
+
static get currentContext(): Context | undefined;
|
|
22
|
+
static get requestId(): string | undefined;
|
|
23
|
+
static run(context: Context, callback: () => void): void;
|
|
24
|
+
}
|
|
25
|
+
export { RequestContext };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RequestContext = exports.RequestContextModule = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const abstract_1 = require("../abstract");
|
|
6
|
+
const async_hooks_1 = require("async_hooks");
|
|
7
|
+
class RequestContextModule extends abstract_1.BaseServerModule {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.name = "RequestContext";
|
|
11
|
+
this.priority = -50;
|
|
12
|
+
}
|
|
13
|
+
init(app) {
|
|
14
|
+
const requestContextMiddleware = (req, res, next) => {
|
|
15
|
+
const incomingRequestId = req.headers["x-request-id"];
|
|
16
|
+
const requestId = (Array.isArray(incomingRequestId)
|
|
17
|
+
? incomingRequestId[0]
|
|
18
|
+
: incomingRequestId) || (0, uuid_1.v4)();
|
|
19
|
+
RequestContext.run({ requestId }, () => {
|
|
20
|
+
next();
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
app.use(requestContextMiddleware);
|
|
24
|
+
}
|
|
25
|
+
getModuleName() {
|
|
26
|
+
return this.name;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.RequestContextModule = RequestContextModule;
|
|
30
|
+
class RequestContext {
|
|
31
|
+
// Obtiene el contexto actual
|
|
32
|
+
static get currentContext() {
|
|
33
|
+
return this.storage.getStore();
|
|
34
|
+
}
|
|
35
|
+
// Obtiene el requestId actual del contexto
|
|
36
|
+
static get requestId() {
|
|
37
|
+
return this.currentContext?.requestId;
|
|
38
|
+
}
|
|
39
|
+
// Inicializa el contexto
|
|
40
|
+
static run(context, callback) {
|
|
41
|
+
this.storage.run(context, callback);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.RequestContext = RequestContext;
|
|
45
|
+
RequestContext.storage = new async_hooks_1.AsyncLocalStorage();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Express, RequestHandler, Router } from "express";
|
|
2
|
+
import { BaseServerModule } from "../abstract";
|
|
3
|
+
export interface RouteConfig {
|
|
4
|
+
path: string;
|
|
5
|
+
router: Router;
|
|
6
|
+
middleware?: RequestHandler[] | RequestHandler;
|
|
7
|
+
}
|
|
8
|
+
export declare class RoutesModule extends BaseServerModule {
|
|
9
|
+
name: string;
|
|
10
|
+
priority: number;
|
|
11
|
+
private routes;
|
|
12
|
+
constructor(routes?: RouteConfig[]);
|
|
13
|
+
getModuleName(): string;
|
|
14
|
+
addRoute(route: RouteConfig): void;
|
|
15
|
+
addRoutes(routes: RouteConfig[]): void;
|
|
16
|
+
init(app: Express): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RoutesModule = void 0;
|
|
4
|
+
const abstract_1 = require("../abstract");
|
|
5
|
+
class RoutesModule extends abstract_1.BaseServerModule {
|
|
6
|
+
constructor(routes = []) {
|
|
7
|
+
super();
|
|
8
|
+
this.name = "Routes";
|
|
9
|
+
this.priority = 10; // Executed after basic middlewares
|
|
10
|
+
this.routes = routes;
|
|
11
|
+
}
|
|
12
|
+
getModuleName() {
|
|
13
|
+
return this.name;
|
|
14
|
+
}
|
|
15
|
+
addRoute(route) {
|
|
16
|
+
this.routes.push({
|
|
17
|
+
...route,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
addRoutes(routes) {
|
|
21
|
+
this.routes.push(...routes);
|
|
22
|
+
}
|
|
23
|
+
init(app) {
|
|
24
|
+
this.routes.forEach(({ path, router, middleware }) => {
|
|
25
|
+
if (middleware && middleware.length > 0) {
|
|
26
|
+
app.use(path, middleware, router);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
app.use(path, router);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.RoutesModule = RoutesModule;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import helmet from "helmet";
|
|
3
|
+
import { BaseServerModule } from "../abstract";
|
|
4
|
+
export declare class SecurityModule extends BaseServerModule {
|
|
5
|
+
name: string;
|
|
6
|
+
priority: number;
|
|
7
|
+
private readonly helmetOptions;
|
|
8
|
+
constructor(helmetOptions?: Parameters<typeof helmet>[0]);
|
|
9
|
+
getModuleName(): string;
|
|
10
|
+
init(app: Express): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SecurityModule = void 0;
|
|
7
|
+
const helmet_1 = __importDefault(require("helmet"));
|
|
8
|
+
const abstract_1 = require("../abstract");
|
|
9
|
+
class SecurityModule extends abstract_1.BaseServerModule {
|
|
10
|
+
constructor(helmetOptions) {
|
|
11
|
+
super();
|
|
12
|
+
this.name = "Security";
|
|
13
|
+
this.priority = -80;
|
|
14
|
+
this.helmetOptions = helmetOptions || {
|
|
15
|
+
contentSecurityPolicy: {
|
|
16
|
+
directives: {
|
|
17
|
+
defaultSrc: ["'self'"],
|
|
18
|
+
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
19
|
+
scriptSrc: ["'self'"],
|
|
20
|
+
imgSrc: ["'self'", "data:", "https:"],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
crossOriginEmbedderPolicy: true,
|
|
24
|
+
crossOriginOpenerPolicy: true,
|
|
25
|
+
crossOriginResourcePolicy: { policy: "cross-origin" },
|
|
26
|
+
dnsPrefetchControl: true,
|
|
27
|
+
frameguard: { action: "deny" },
|
|
28
|
+
hidePoweredBy: true,
|
|
29
|
+
ieNoOpen: true,
|
|
30
|
+
noSniff: true,
|
|
31
|
+
originAgentCluster: true,
|
|
32
|
+
permittedCrossDomainPolicies: false,
|
|
33
|
+
referrerPolicy: { policy: "no-referrer" },
|
|
34
|
+
xssFilter: true,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
getModuleName() {
|
|
38
|
+
return this.name;
|
|
39
|
+
}
|
|
40
|
+
init(app) {
|
|
41
|
+
app.use((0, helmet_1.default)(this.helmetOptions));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.SecurityModule = SecurityModule;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./CorsModule"), exports);
|
|
18
|
+
__exportStar(require("./ControllersModule"), exports);
|
|
19
|
+
__exportStar(require("./FileUploadModule"), exports);
|
|
20
|
+
__exportStar(require("./RateLimitModule"), exports);
|
|
21
|
+
__exportStar(require("./RequestContextModule"), exports);
|
|
22
|
+
__exportStar(require("./RoutesModule"), exports);
|
|
23
|
+
__exportStar(require("./SecurityModule"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import type { BootstrapServer } from "../BootstrapServer";
|
|
3
|
+
import { ControllersModule } from "../modules";
|
|
4
|
+
import { BaseServerService } from "../abstract";
|
|
5
|
+
import { BootstrapStandardServerOptions } from "../BootstrapStandardServer";
|
|
6
|
+
type ControllerClass<T = any> = new (...args: any[]) => T;
|
|
7
|
+
export interface DecoratedTestAppOptions {
|
|
8
|
+
controllers?: ControllerClass[];
|
|
9
|
+
controllersModule?: ControllersModule;
|
|
10
|
+
port?: number;
|
|
11
|
+
services?: BaseServerService[];
|
|
12
|
+
standardOptions?: BootstrapStandardServerOptions;
|
|
13
|
+
}
|
|
14
|
+
export interface DecoratedTestAppResult {
|
|
15
|
+
app: Express;
|
|
16
|
+
server: BootstrapServer;
|
|
17
|
+
stop: () => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createDecoratedTestApp(options: DecoratedTestAppOptions): Promise<DecoratedTestAppResult>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDecoratedTestApp = createDecoratedTestApp;
|
|
4
|
+
const BootstrapStandardServer_1 = require("../BootstrapStandardServer");
|
|
5
|
+
const modules_1 = require("../modules");
|
|
6
|
+
const mergeOptions = (base, override) => {
|
|
7
|
+
if (!override) {
|
|
8
|
+
return base;
|
|
9
|
+
}
|
|
10
|
+
const mergedServices = [
|
|
11
|
+
...(base.services ?? []),
|
|
12
|
+
...(override.services ?? []),
|
|
13
|
+
];
|
|
14
|
+
return {
|
|
15
|
+
services: mergedServices.length ? mergedServices : undefined,
|
|
16
|
+
modules: {
|
|
17
|
+
...(base.modules ?? {}),
|
|
18
|
+
...(override.modules ?? {}),
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
async function createDecoratedTestApp(options) {
|
|
23
|
+
const { controllers = [], controllersModule, port = 0, services, standardOptions, } = options;
|
|
24
|
+
const moduleInstance = controllersModule ?? new modules_1.ControllersModule(controllers);
|
|
25
|
+
const baseOptions = {
|
|
26
|
+
services,
|
|
27
|
+
modules: {
|
|
28
|
+
cors: false,
|
|
29
|
+
security: false,
|
|
30
|
+
rateLimit: false,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const mergedOptions = mergeOptions(baseOptions, standardOptions);
|
|
34
|
+
const server = (0, BootstrapStandardServer_1.BootstrapStandardServer)(port, moduleInstance, mergedOptions);
|
|
35
|
+
await server.initialize();
|
|
36
|
+
return {
|
|
37
|
+
app: server.getApp(),
|
|
38
|
+
server,
|
|
39
|
+
stop: async () => {
|
|
40
|
+
const httpServer = server.getHttpServer();
|
|
41
|
+
if (httpServer) {
|
|
42
|
+
await new Promise((resolve) => httpServer.close(() => resolve()));
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./createDecoratedTestApp";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./createDecoratedTestApp"), exports);
|