@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/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# TypeScript Express Server Framework
|
|
2
|
+
|
|
3
|
+
A modular and extensible TypeScript framework for building Express.js servers with a clean architecture pattern that separates concerns between server modules and services.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🏗️ **Modular Architecture**: Build your server using reusable modules
|
|
8
|
+
- 🚀 **Service Management**: Integrate background services that start with your server
|
|
9
|
+
- 📦 **Built-in Modules**: Pre-configured modules for common functionality
|
|
10
|
+
- 🔄 **Graceful Shutdown**: Proper cleanup and shutdown handling
|
|
11
|
+
- ⚡ **Priority System**: Control module initialization order
|
|
12
|
+
- 🛡️ **Type Safety**: Full TypeScript support with strong typing
|
|
13
|
+
- 🔧 **Configurable**: Highly customizable modules and services
|
|
14
|
+
- 🎨 **Decorators**: Clean and declarative controller definition
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @abejarano/ts-express-server
|
|
20
|
+
# or
|
|
21
|
+
yarn add @abejarano/ts-express-server
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Documentation
|
|
25
|
+
|
|
26
|
+
- [Getting Started](docs/getting-started.md)
|
|
27
|
+
- [Core Concepts](docs/core-concepts.md)
|
|
28
|
+
- [Modules](docs/modules.md)
|
|
29
|
+
- [Using Decorators](docs/decorators.md)
|
|
30
|
+
- [Services](docs/services.md)
|
|
31
|
+
- [Testing Helpers](docs/testing.md)
|
|
32
|
+
- [API Reference](docs/api-reference.md)
|
|
33
|
+
- [Examples](docs/examples.md)
|
|
34
|
+
|
|
35
|
+
## Contributing
|
|
36
|
+
|
|
37
|
+
1. Fork the repository
|
|
38
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
39
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
40
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
41
|
+
5. Open a Pull Request
|
|
42
|
+
|
|
43
|
+
## Conventional Commits
|
|
44
|
+
|
|
45
|
+
We use Conventional Commits to automatically generate releases:
|
|
46
|
+
|
|
47
|
+
- `feat:` - New feature
|
|
48
|
+
- `fix:` - Bug fix
|
|
49
|
+
- `docs:` - Documentation
|
|
50
|
+
- `style:` - Format, spaces, etc.
|
|
51
|
+
- `refactor:` - Code refactoring
|
|
52
|
+
- `test:` - Add tests
|
|
53
|
+
- `chore:` - Maintenance tasks
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
58
|
+
|
|
59
|
+
## Author
|
|
60
|
+
|
|
61
|
+
Angel Bejarano - angel.bejarano@jaspesoft.com
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Express } from "express";
|
|
2
|
+
import { Server as HttpServer } from "http";
|
|
3
|
+
import { BaseServerModule, BaseServerService } from "./abstract";
|
|
4
|
+
export declare class BootstrapServer {
|
|
5
|
+
private readonly app;
|
|
6
|
+
private readonly port;
|
|
7
|
+
private httpServer?;
|
|
8
|
+
private modules;
|
|
9
|
+
private services;
|
|
10
|
+
constructor(port: number);
|
|
11
|
+
removeModule(moduleName: string): BootstrapServer;
|
|
12
|
+
addModule(module: BaseServerModule): BootstrapServer;
|
|
13
|
+
addModules(modules: BaseServerModule[]): BootstrapServer;
|
|
14
|
+
addService(service: BaseServerService): BootstrapServer;
|
|
15
|
+
addServices(services: BaseServerService[]): BootstrapServer;
|
|
16
|
+
getApp(): Express;
|
|
17
|
+
getHttpServer(): HttpServer | undefined;
|
|
18
|
+
initialize(): Promise<void>;
|
|
19
|
+
start(): Promise<void>;
|
|
20
|
+
gracefulShutdown(): Promise<void>;
|
|
21
|
+
getModule<T extends BaseServerModule>(moduleClass: new (...args: any[]) => T): T | undefined;
|
|
22
|
+
hasModule(moduleClass: new (...args: any[]) => any): boolean;
|
|
23
|
+
private initializeServices;
|
|
24
|
+
private initializeServerModules;
|
|
25
|
+
private setupGracefulShutdown;
|
|
26
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
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.BootstrapServer = void 0;
|
|
7
|
+
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const body_parser_1 = __importDefault(require("body-parser"));
|
|
9
|
+
const cookie_parser_1 = __importDefault(require("cookie-parser"));
|
|
10
|
+
class BootstrapServer {
|
|
11
|
+
constructor(port) {
|
|
12
|
+
this.modules = [];
|
|
13
|
+
this.services = [];
|
|
14
|
+
this.port = port;
|
|
15
|
+
this.app = (0, express_1.default)();
|
|
16
|
+
this.app.use(express_1.default.json());
|
|
17
|
+
this.app.use(body_parser_1.default.urlencoded({ extended: true }));
|
|
18
|
+
this.app.use((0, cookie_parser_1.default)());
|
|
19
|
+
this.app.set("port", port);
|
|
20
|
+
}
|
|
21
|
+
removeModule(moduleName) {
|
|
22
|
+
this.modules = this.modules.filter((m) => m.getModuleName() !== moduleName);
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
addModule(module) {
|
|
26
|
+
const existingModuleIndex = this.modules.findIndex((m) => m.getModuleName() === module.getModuleName());
|
|
27
|
+
if (existingModuleIndex !== -1) {
|
|
28
|
+
// Replace existing module
|
|
29
|
+
this.modules[existingModuleIndex] = module;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Add new module
|
|
33
|
+
this.modules.push(module);
|
|
34
|
+
}
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
addModules(modules) {
|
|
38
|
+
for (const module of modules) {
|
|
39
|
+
const existingModuleIndex = this.modules.findIndex((m) => m.getModuleName() === module.getModuleName());
|
|
40
|
+
if (existingModuleIndex !== -1) {
|
|
41
|
+
// Replace existing module
|
|
42
|
+
this.modules[existingModuleIndex] = module;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Add new module
|
|
46
|
+
this.modules.push(module);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
addService(service) {
|
|
52
|
+
this.services.push(service);
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
addServices(services) {
|
|
56
|
+
this.services.push(...services);
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
getApp() {
|
|
60
|
+
return this.app;
|
|
61
|
+
}
|
|
62
|
+
getHttpServer() {
|
|
63
|
+
return this.httpServer;
|
|
64
|
+
}
|
|
65
|
+
async initialize() {
|
|
66
|
+
await this.initializeServerModules();
|
|
67
|
+
}
|
|
68
|
+
async start() {
|
|
69
|
+
await this.initializeServerModules();
|
|
70
|
+
return new Promise((resolve) => {
|
|
71
|
+
this.httpServer = this.app.listen(this.port, () => {
|
|
72
|
+
console.log(`Server running on port ${this.port}`);
|
|
73
|
+
this.setupGracefulShutdown();
|
|
74
|
+
resolve();
|
|
75
|
+
});
|
|
76
|
+
this.initializeServices(this.httpServer);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async gracefulShutdown() {
|
|
80
|
+
try {
|
|
81
|
+
console.log("Starting graceful shutdown...");
|
|
82
|
+
// Execute module shutdown in reverse order
|
|
83
|
+
const reversedModules = [...this.modules].reverse();
|
|
84
|
+
for (const module of reversedModules) {
|
|
85
|
+
if (module.shutdown) {
|
|
86
|
+
try {
|
|
87
|
+
console.log(`Shutting down module: ${module.getModuleName()}`);
|
|
88
|
+
await module.shutdown();
|
|
89
|
+
console.log(`Module shutdown completed: ${module.getModuleName()}`);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.error(`Error shutting down module ${module.getModuleName()}:`, error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Stop services in reverse order
|
|
97
|
+
const reversedServices = [...this.services].reverse();
|
|
98
|
+
for (const service of reversedServices) {
|
|
99
|
+
if (service.stop) {
|
|
100
|
+
try {
|
|
101
|
+
console.log(`Stopping service: ${service.name}`);
|
|
102
|
+
await service.stop();
|
|
103
|
+
console.log(`Service stopped: ${service.name}`);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error(`Error stopping service ${service.name}:`, error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Close HTTP server
|
|
111
|
+
if (this.httpServer) {
|
|
112
|
+
console.log("Closing HTTP server...");
|
|
113
|
+
await new Promise((resolve) => {
|
|
114
|
+
this.httpServer.close(() => resolve());
|
|
115
|
+
});
|
|
116
|
+
console.log("HTTP server closed");
|
|
117
|
+
}
|
|
118
|
+
console.log("Graceful shutdown completed. Exiting...");
|
|
119
|
+
process.exit(0);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error("Error during graceful shutdown:", error);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Convenience methods to access specific modules
|
|
127
|
+
getModule(moduleClass) {
|
|
128
|
+
return this.modules.find((m) => m instanceof moduleClass);
|
|
129
|
+
}
|
|
130
|
+
hasModule(moduleClass) {
|
|
131
|
+
return this.modules.some((m) => m instanceof moduleClass);
|
|
132
|
+
}
|
|
133
|
+
async initializeServices(http) {
|
|
134
|
+
console.log("Starting services...");
|
|
135
|
+
for (const service of this.services) {
|
|
136
|
+
try {
|
|
137
|
+
await service.start(http);
|
|
138
|
+
console.log(`Service started: ${service.name}`);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
console.error(`Failed to start service ${service.name}:`, error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
console.log("All services started successfully");
|
|
146
|
+
}
|
|
147
|
+
async initializeServerModules() {
|
|
148
|
+
// Sort modules by priority (lower number = higher priority)
|
|
149
|
+
this.modules.sort((a, b) => (a.priority || 0) - (b.priority || 0));
|
|
150
|
+
console.log("Initializing server modules in priority order:");
|
|
151
|
+
for (const module of this.modules) {
|
|
152
|
+
try {
|
|
153
|
+
await module.init(this.app);
|
|
154
|
+
console.log(`Module initialized: ${module.getModuleName()}`);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
console.error(`Failed to initialize module ${module.getModuleName()}:`, error);
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
console.log("All modules initialized successfully");
|
|
162
|
+
}
|
|
163
|
+
setupGracefulShutdown() {
|
|
164
|
+
const shutdown = async (signal) => {
|
|
165
|
+
console.log(`${signal} signal received. Shutting down application...`);
|
|
166
|
+
await this.gracefulShutdown();
|
|
167
|
+
};
|
|
168
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
169
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.BootstrapServer = BootstrapServer;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BootstrapServer } from "./BootstrapServer";
|
|
2
|
+
import { ControllersModule, RoutesModule } from "./modules";
|
|
3
|
+
import { BaseServerModule, BaseServerService } from "./abstract";
|
|
4
|
+
export interface BootstrapStandardServerOptions {
|
|
5
|
+
modules?: {
|
|
6
|
+
cors?: BaseServerModule | false;
|
|
7
|
+
security?: BaseServerModule | false;
|
|
8
|
+
rateLimit?: BaseServerModule | false;
|
|
9
|
+
fileUpload?: BaseServerModule | false;
|
|
10
|
+
requestContext?: BaseServerModule | false;
|
|
11
|
+
extra?: BaseServerModule[];
|
|
12
|
+
};
|
|
13
|
+
services?: BaseServerService[];
|
|
14
|
+
}
|
|
15
|
+
export declare function BootstrapStandardServer(port: number, module: RoutesModule | ControllersModule, services?: BaseServerService[]): BootstrapServer;
|
|
16
|
+
export declare function BootstrapStandardServer(port: number, module: RoutesModule | ControllersModule, services: BaseServerService[], options: BootstrapStandardServerOptions): BootstrapServer;
|
|
17
|
+
export declare function BootstrapStandardServer(port: number, module: RoutesModule | ControllersModule, options: BootstrapStandardServerOptions): BootstrapServer;
|
|
18
|
+
export declare function BootstrapStandardServer(port: number, routes: RoutesModule, controllersModule: ControllersModule, services?: BaseServerService[]): BootstrapServer;
|
|
19
|
+
export declare function BootstrapStandardServer(port: number, routes: RoutesModule, controllersModule: ControllersModule, services: BaseServerService[], options: BootstrapStandardServerOptions): BootstrapServer;
|
|
20
|
+
export declare function BootstrapStandardServer(port: number, routes: RoutesModule, controllersModule: ControllersModule, options: BootstrapStandardServerOptions): BootstrapServer;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BootstrapStandardServer = BootstrapStandardServer;
|
|
4
|
+
const BootstrapServer_1 = require("./BootstrapServer");
|
|
5
|
+
const modules_1 = require("./modules");
|
|
6
|
+
function BootstrapStandardServer(port, arg2, arg3, arg4, arg5) {
|
|
7
|
+
let routesModule;
|
|
8
|
+
let controllersModule;
|
|
9
|
+
let services;
|
|
10
|
+
let options;
|
|
11
|
+
const setControllersModule = (module) => {
|
|
12
|
+
if (controllersModule && controllersModule !== module) {
|
|
13
|
+
throw new Error("ControllersModule provided multiple times. Pass a single instance only.");
|
|
14
|
+
}
|
|
15
|
+
controllersModule = module;
|
|
16
|
+
};
|
|
17
|
+
if (arg2 instanceof modules_1.RoutesModule) {
|
|
18
|
+
routesModule = arg2;
|
|
19
|
+
}
|
|
20
|
+
else if (arg2 instanceof modules_1.ControllersModule) {
|
|
21
|
+
setControllersModule(arg2);
|
|
22
|
+
routesModule = new modules_1.RoutesModule();
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
throw new Error("Invalid second argument. Must be RoutesModule or ControllersModule");
|
|
26
|
+
}
|
|
27
|
+
const addServices = (value) => {
|
|
28
|
+
if (!value?.length) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
services = [...(services ?? []), ...value];
|
|
32
|
+
};
|
|
33
|
+
const processOptionalArg = (value) => {
|
|
34
|
+
if (!value) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (value instanceof modules_1.ControllersModule) {
|
|
38
|
+
setControllersModule(value);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
addServices(value);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
options = value;
|
|
46
|
+
};
|
|
47
|
+
processOptionalArg(arg3);
|
|
48
|
+
processOptionalArg(arg4);
|
|
49
|
+
processOptionalArg(arg5);
|
|
50
|
+
addServices(options?.services);
|
|
51
|
+
const modulesToRegister = [routesModule];
|
|
52
|
+
const preset = options?.modules;
|
|
53
|
+
const registerModule = (factory, override) => {
|
|
54
|
+
if (override === false) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
modulesToRegister.push(override ?? factory());
|
|
58
|
+
};
|
|
59
|
+
registerModule(() => new modules_1.CorsModule(), preset?.cors);
|
|
60
|
+
registerModule(() => new modules_1.SecurityModule(), preset?.security);
|
|
61
|
+
registerModule(() => new modules_1.RateLimitModule(), preset?.rateLimit);
|
|
62
|
+
registerModule(() => new modules_1.FileUploadModule(), preset?.fileUpload);
|
|
63
|
+
registerModule(() => new modules_1.RequestContextModule(), preset?.requestContext);
|
|
64
|
+
if (preset?.extra?.length) {
|
|
65
|
+
modulesToRegister.push(...preset.extra);
|
|
66
|
+
}
|
|
67
|
+
const expressServer = new BootstrapServer_1.BootstrapServer(port).addModules(modulesToRegister);
|
|
68
|
+
if (controllersModule) {
|
|
69
|
+
expressServer.addModule(controllersModule);
|
|
70
|
+
}
|
|
71
|
+
if (services) {
|
|
72
|
+
expressServer.addServices(services);
|
|
73
|
+
}
|
|
74
|
+
return expressServer;
|
|
75
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseServerModule = void 0;
|
|
4
|
+
class BaseServerModule {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.priority = 0;
|
|
7
|
+
}
|
|
8
|
+
async shutdown() {
|
|
9
|
+
// Default empty shutdown
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.BaseServerModule = BaseServerModule;
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./ServerService"), exports);
|
|
18
|
+
__exportStar(require("./ServerModule"), exports);
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Controller = Controller;
|
|
4
|
+
const MetadataKeys_1 = require("./MetadataKeys");
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
function Controller(basePath) {
|
|
7
|
+
return function (target) {
|
|
8
|
+
Reflect.defineMetadata(MetadataKeys_1.MetadataKeys.BASE_PATH, basePath, target);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
export declare enum Methods {
|
|
3
|
+
GET = "get",
|
|
4
|
+
POST = "post",
|
|
5
|
+
PUT = "put",
|
|
6
|
+
DELETE = "delete",
|
|
7
|
+
PATCH = "patch"
|
|
8
|
+
}
|
|
9
|
+
export interface IRouter {
|
|
10
|
+
method: Methods;
|
|
11
|
+
path: string;
|
|
12
|
+
handlerName: string | symbol;
|
|
13
|
+
}
|
|
14
|
+
export declare const Get: (path: string) => (target: any, key: string, descriptor: PropertyDescriptor) => void;
|
|
15
|
+
export declare const Post: (path: string) => (target: any, key: string, descriptor: PropertyDescriptor) => void;
|
|
16
|
+
export declare const Put: (path: string) => (target: any, key: string, descriptor: PropertyDescriptor) => void;
|
|
17
|
+
export declare const Delete: (path: string) => (target: any, key: string, descriptor: PropertyDescriptor) => void;
|
|
18
|
+
export declare const Patch: (path: string) => (target: any, key: string, descriptor: PropertyDescriptor) => void;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Patch = exports.Delete = exports.Put = exports.Post = exports.Get = exports.Methods = void 0;
|
|
4
|
+
const MetadataKeys_1 = require("./MetadataKeys");
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
var Methods;
|
|
7
|
+
(function (Methods) {
|
|
8
|
+
Methods["GET"] = "get";
|
|
9
|
+
Methods["POST"] = "post";
|
|
10
|
+
Methods["PUT"] = "put";
|
|
11
|
+
Methods["DELETE"] = "delete";
|
|
12
|
+
Methods["PATCH"] = "patch";
|
|
13
|
+
})(Methods || (exports.Methods = Methods = {}));
|
|
14
|
+
function methodDecorator(method) {
|
|
15
|
+
return function (path) {
|
|
16
|
+
return function (target, key, descriptor) {
|
|
17
|
+
const routers = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.ROUTERS, target) || [];
|
|
18
|
+
routers.push({
|
|
19
|
+
method,
|
|
20
|
+
path,
|
|
21
|
+
handlerName: key,
|
|
22
|
+
});
|
|
23
|
+
Reflect.defineMetadata(MetadataKeys_1.MetadataKeys.ROUTERS, routers, target);
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
exports.Get = methodDecorator(Methods.GET);
|
|
28
|
+
exports.Post = methodDecorator(Methods.POST);
|
|
29
|
+
exports.Put = methodDecorator(Methods.PUT);
|
|
30
|
+
exports.Delete = methodDecorator(Methods.DELETE);
|
|
31
|
+
exports.Patch = methodDecorator(Methods.PATCH);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MetadataKeys = void 0;
|
|
4
|
+
var MetadataKeys;
|
|
5
|
+
(function (MetadataKeys) {
|
|
6
|
+
MetadataKeys["BASE_PATH"] = "base_path";
|
|
7
|
+
MetadataKeys["ROUTERS"] = "routers";
|
|
8
|
+
MetadataKeys["MIDDLEWARE"] = "middleware";
|
|
9
|
+
MetadataKeys["PARAMETERS"] = "parameters";
|
|
10
|
+
})(MetadataKeys || (exports.MetadataKeys = MetadataKeys = {}));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
export declare enum ParameterType {
|
|
3
|
+
BODY = "body",
|
|
4
|
+
QUERY = "query",
|
|
5
|
+
PARAM = "param",
|
|
6
|
+
HEADERS = "headers",
|
|
7
|
+
REQUEST = "request",
|
|
8
|
+
RESPONSE = "response",
|
|
9
|
+
NEXT = "next",
|
|
10
|
+
FILE = "file"
|
|
11
|
+
}
|
|
12
|
+
export interface ParameterMetadata {
|
|
13
|
+
index: number;
|
|
14
|
+
type: ParameterType;
|
|
15
|
+
data?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const Body: (data?: string) => ParameterDecorator;
|
|
18
|
+
export declare const Query: (data?: string) => ParameterDecorator;
|
|
19
|
+
export declare const Param: (data?: string) => ParameterDecorator;
|
|
20
|
+
export declare const Headers: (data?: string) => ParameterDecorator;
|
|
21
|
+
export declare const Req: (data?: string) => ParameterDecorator;
|
|
22
|
+
export declare const Res: (data?: string) => ParameterDecorator;
|
|
23
|
+
export declare const Next: (data?: string) => ParameterDecorator;
|
|
24
|
+
export declare const UploadedFile: (data?: string) => ParameterDecorator;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UploadedFile = exports.Next = exports.Res = exports.Req = exports.Headers = exports.Param = exports.Query = exports.Body = exports.ParameterType = void 0;
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const MetadataKeys_1 = require("./MetadataKeys");
|
|
6
|
+
var ParameterType;
|
|
7
|
+
(function (ParameterType) {
|
|
8
|
+
ParameterType["BODY"] = "body";
|
|
9
|
+
ParameterType["QUERY"] = "query";
|
|
10
|
+
ParameterType["PARAM"] = "param";
|
|
11
|
+
ParameterType["HEADERS"] = "headers";
|
|
12
|
+
ParameterType["REQUEST"] = "request";
|
|
13
|
+
ParameterType["RESPONSE"] = "response";
|
|
14
|
+
ParameterType["NEXT"] = "next";
|
|
15
|
+
ParameterType["FILE"] = "file";
|
|
16
|
+
})(ParameterType || (exports.ParameterType = ParameterType = {}));
|
|
17
|
+
// Helper to register parameter metadata for a method
|
|
18
|
+
function addParameterMetadata(target, propertyKey, metadata) {
|
|
19
|
+
const existingParameters = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.PARAMETERS, target, propertyKey) || [];
|
|
20
|
+
Reflect.defineMetadata(MetadataKeys_1.MetadataKeys.PARAMETERS, [...existingParameters, metadata].sort((a, b) => a.index - b.index), target, propertyKey);
|
|
21
|
+
}
|
|
22
|
+
function createParameterDecorator(type) {
|
|
23
|
+
return (data) => (target, propertyKey, parameterIndex) => {
|
|
24
|
+
if (propertyKey === undefined) {
|
|
25
|
+
throw new Error("Parameter decorators can only be used on methods");
|
|
26
|
+
}
|
|
27
|
+
addParameterMetadata(target, propertyKey, {
|
|
28
|
+
index: parameterIndex,
|
|
29
|
+
type,
|
|
30
|
+
data,
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
exports.Body = createParameterDecorator(ParameterType.BODY);
|
|
35
|
+
exports.Query = createParameterDecorator(ParameterType.QUERY);
|
|
36
|
+
exports.Param = createParameterDecorator(ParameterType.PARAM);
|
|
37
|
+
exports.Headers = createParameterDecorator(ParameterType.HEADERS);
|
|
38
|
+
exports.Req = createParameterDecorator(ParameterType.REQUEST);
|
|
39
|
+
exports.Res = createParameterDecorator(ParameterType.RESPONSE);
|
|
40
|
+
exports.Next = createParameterDecorator(ParameterType.NEXT);
|
|
41
|
+
exports.UploadedFile = createParameterDecorator(ParameterType.FILE);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Use = Use;
|
|
4
|
+
const MetadataKeys_1 = require("./MetadataKeys");
|
|
5
|
+
require("reflect-metadata");
|
|
6
|
+
function Use(middleware) {
|
|
7
|
+
return function (target, key, descriptor) {
|
|
8
|
+
const newMiddlewares = Array.isArray(middleware)
|
|
9
|
+
? middleware
|
|
10
|
+
: [middleware];
|
|
11
|
+
if (key) {
|
|
12
|
+
// Method decorator
|
|
13
|
+
const middlewares = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.MIDDLEWARE, target, key) || [];
|
|
14
|
+
Reflect.defineMetadata(MetadataKeys_1.MetadataKeys.MIDDLEWARE, [...middlewares, ...newMiddlewares], target, key);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// Class decorator
|
|
18
|
+
const middlewares = Reflect.getMetadata(MetadataKeys_1.MetadataKeys.MIDDLEWARE, target) || [];
|
|
19
|
+
Reflect.defineMetadata(MetadataKeys_1.MetadataKeys.MIDDLEWARE, [...middlewares, ...newMiddlewares], target);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
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("./Controller"), exports);
|
|
18
|
+
__exportStar(require("./Handlers"), exports);
|
|
19
|
+
__exportStar(require("./MetadataKeys"), exports);
|
|
20
|
+
__exportStar(require("./Use"), exports);
|
|
21
|
+
__exportStar(require("./Parameters"), exports);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
export { BootstrapServer } from "./BootstrapServer";
|
|
3
|
+
export { BootstrapStandardServer } from "./BootstrapStandardServer";
|
|
4
|
+
export type { BootstrapStandardServerOptions } from "./BootstrapStandardServer";
|
|
5
|
+
export * from "./modules";
|
|
6
|
+
export * from "./abstract";
|
|
7
|
+
export * from "./decorators";
|
|
8
|
+
export * from "./testing";
|