@abejarano/ts-express-server 1.7.6 → 2.0.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/README.md +13 -10
- package/dist/BootstrapServer.d.ts +1 -3
- package/dist/BootstrapServer.js +1 -8
- package/dist/BootstrapStandardServer.d.ts +2 -2
- package/dist/BootstrapStandardServer.js +1 -1
- package/dist/abstract/ServerTypes.d.ts +1 -3
- package/dist/abstract/ServerTypes.js +0 -1
- package/dist/adapters/BunAdapter.js +8 -10
- package/dist/adapters/index.d.ts +0 -1
- package/dist/adapters/index.js +0 -1
- package/dist/createRouter.d.ts +2 -2
- package/dist/createRouter.js +2 -6
- package/dist/modules/ControllersModule.js +2 -2
- package/dist/modules/CorsModule.d.ts +2 -2
- package/dist/modules/CorsModule.js +0 -10
- package/dist/modules/FileUploadModule.d.ts +12 -2
- package/dist/modules/FileUploadModule.js +3 -12
- package/dist/modules/RateLimitModule.d.ts +8 -1
- package/dist/modules/RateLimitModule.js +0 -9
- package/dist/modules/RoutesModule.js +0 -4
- package/dist/modules/SecurityModule.js +0 -8
- package/dist/testing/createDecoratedTestApp.d.ts +1 -2
- package/dist/testing/createDecoratedTestApp.js +1 -2
- package/package.json +2 -13
- package/dist/adapters/ExpressAdapter.d.ts +0 -8
- package/dist/adapters/ExpressAdapter.js +0 -65
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# TypeScript Server Framework (
|
|
1
|
+
# TypeScript Server Framework (Bun)
|
|
2
2
|
|
|
3
|
-
A modular and extensible TypeScript framework for building
|
|
3
|
+
A modular and extensible TypeScript framework for building Bun servers with a clean architecture pattern that separates concerns between server modules and services.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -12,7 +12,6 @@ A modular and extensible TypeScript framework for building Express or Bun server
|
|
|
12
12
|
- 🛡️ **Type Safety**: Full TypeScript support with strong typing
|
|
13
13
|
- 🔧 **Configurable**: Highly customizable modules and services
|
|
14
14
|
- 🎨 **Decorators**: Clean and declarative controller definition
|
|
15
|
-
- ⚙️ **Runtime Choice**: Run on Express (Node) or Bun via `ServerRuntime`
|
|
16
15
|
|
|
17
16
|
## Installation
|
|
18
17
|
|
|
@@ -33,17 +32,21 @@ yarn add @abejarano/ts-express-server
|
|
|
33
32
|
- [API Reference](docs/api-reference.md)
|
|
34
33
|
- [Examples](docs/examples.md)
|
|
35
34
|
|
|
36
|
-
##
|
|
35
|
+
## File uploads
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
import { BootstrapServer } from "@abejarano/ts-express-server";
|
|
37
|
+
Uploads are disabled unless `FileUploadModule` is registered. Configure limits and MIME allowlists through the module:
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
server
|
|
39
|
+
```typescript
|
|
40
|
+
import { FileUploadModule } from "@abejarano/ts-express-server";
|
|
41
|
+
|
|
42
|
+
const fileUpload = new FileUploadModule({
|
|
43
|
+
maxBodyBytes: 10 * 1024 * 1024,
|
|
44
|
+
maxFileBytes: 10 * 1024 * 1024,
|
|
45
|
+
maxFiles: 10,
|
|
46
|
+
allowedMimeTypes: ["image/*", "application/pdf"],
|
|
47
|
+
});
|
|
43
48
|
```
|
|
44
49
|
|
|
45
|
-
You can also use `ServerRuntime.Bun` and `ServerRuntime.Express` if you prefer the enum.
|
|
46
|
-
|
|
47
50
|
## Contributing
|
|
48
51
|
|
|
49
52
|
1. Fork the repository
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { BaseServerModule, BaseServerService } from "./abstract";
|
|
2
|
-
import { ServerAdapter, ServerApp, ServerInstance
|
|
2
|
+
import { ServerAdapter, ServerApp, ServerInstance } from "./abstract";
|
|
3
3
|
export interface BootstrapServerOptions {
|
|
4
|
-
runtime?: ServerRuntime;
|
|
5
4
|
adapter?: ServerAdapter;
|
|
6
5
|
}
|
|
7
6
|
export declare class BootstrapServer {
|
|
@@ -29,5 +28,4 @@ export declare class BootstrapServer {
|
|
|
29
28
|
private initializeServices;
|
|
30
29
|
private initializeServerModules;
|
|
31
30
|
private setupGracefulShutdown;
|
|
32
|
-
private createAdapter;
|
|
33
31
|
}
|
package/dist/BootstrapServer.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BootstrapServer = void 0;
|
|
4
|
-
const abstract_1 = require("./abstract");
|
|
5
4
|
const adapters_1 = require("./adapters");
|
|
6
5
|
class BootstrapServer {
|
|
7
6
|
constructor(port, options) {
|
|
8
7
|
this.modules = [];
|
|
9
8
|
this.services = [];
|
|
10
9
|
this.port = port;
|
|
11
|
-
this.adapter = options?.adapter ??
|
|
10
|
+
this.adapter = options?.adapter ?? new adapters_1.BunAdapter();
|
|
12
11
|
this.runtime = this.adapter.runtime;
|
|
13
12
|
this.app = this.adapter.createApp();
|
|
14
13
|
this.adapter.configure(this.app, port);
|
|
@@ -170,11 +169,5 @@ class BootstrapServer {
|
|
|
170
169
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
171
170
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
172
171
|
}
|
|
173
|
-
createAdapter(runtime) {
|
|
174
|
-
if (runtime === abstract_1.ServerRuntime.Bun) {
|
|
175
|
-
return new adapters_1.BunAdapter();
|
|
176
|
-
}
|
|
177
|
-
return new adapters_1.ExpressAdapter();
|
|
178
|
-
}
|
|
179
172
|
}
|
|
180
173
|
exports.BootstrapServer = BootstrapServer;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BootstrapServer } from "./BootstrapServer";
|
|
2
2
|
import { ControllersModule, RoutesModule } from "./modules";
|
|
3
|
-
import { BaseServerModule, BaseServerService,
|
|
3
|
+
import { BaseServerModule, BaseServerService, ServerAdapter } from "./abstract";
|
|
4
4
|
export interface BootstrapStandardServerOptions {
|
|
5
|
-
|
|
5
|
+
adapter?: ServerAdapter;
|
|
6
6
|
modules?: {
|
|
7
7
|
cors?: BaseServerModule | false;
|
|
8
8
|
security?: BaseServerModule | false;
|
|
@@ -65,7 +65,7 @@ function BootstrapStandardServer(port, arg2, arg3, arg4, arg5) {
|
|
|
65
65
|
modulesToRegister.push(...preset.extra);
|
|
66
66
|
}
|
|
67
67
|
const server = new BootstrapServer_1.BootstrapServer(port, {
|
|
68
|
-
|
|
68
|
+
adapter: options?.adapter,
|
|
69
69
|
}).addModules(modulesToRegister);
|
|
70
70
|
if (controllersModule) {
|
|
71
71
|
server.addModule(controllersModule);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type fileUpload from "express-fileupload";
|
|
2
1
|
export declare enum ServerRuntime {
|
|
3
|
-
Express = "express",
|
|
4
2
|
Bun = "bun"
|
|
5
3
|
}
|
|
6
4
|
export type NextFunction = (err?: unknown) => void;
|
|
@@ -48,7 +46,7 @@ export type BunMultipartFile = {
|
|
|
48
46
|
arrayBuffer(): Promise<ArrayBuffer>;
|
|
49
47
|
lastModified?: number;
|
|
50
48
|
};
|
|
51
|
-
export type ServerFile = BunMultipartFile
|
|
49
|
+
export type ServerFile = BunMultipartFile;
|
|
52
50
|
export type ServerFiles = Record<string, ServerFile | ServerFile[]>;
|
|
53
51
|
export type ServerHandlerInput = ServerHandler | ServerHandler[] | ServerRouter;
|
|
54
52
|
export interface ServerRouter {
|
|
@@ -3,6 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ServerRuntime = void 0;
|
|
4
4
|
var ServerRuntime;
|
|
5
5
|
(function (ServerRuntime) {
|
|
6
|
-
ServerRuntime["Express"] = "express";
|
|
7
6
|
ServerRuntime["Bun"] = "bun";
|
|
8
7
|
})(ServerRuntime || (exports.ServerRuntime = ServerRuntime = {}));
|
|
@@ -512,6 +512,12 @@ const createMultipartBodyParser = (app) => {
|
|
|
512
512
|
if (!contentType.includes("multipart/form-data")) {
|
|
513
513
|
return next();
|
|
514
514
|
}
|
|
515
|
+
if (app.get("fileUploadEnabled") !== true) {
|
|
516
|
+
res
|
|
517
|
+
.status(415)
|
|
518
|
+
.json({ message: "File uploads are disabled. Enable FileUploadModule." });
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
515
521
|
const options = normalizeMultipartOptions(app.get("multipart"));
|
|
516
522
|
const lengthHeader = req.headers["content-length"];
|
|
517
523
|
const contentLength = parseContentLength(lengthHeader);
|
|
@@ -986,16 +992,8 @@ function resolveCookieDefaults(input) {
|
|
|
986
992
|
}
|
|
987
993
|
function resolveTrustProxySetting(app) {
|
|
988
994
|
const input = app.get("trustProxy");
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
if (input === true) {
|
|
992
|
-
if (!allowInsecure) {
|
|
993
|
-
throw new Error("Invalid trustProxy=true. Use CIDR allowlist or set allowInsecureTrustProxy=true explicitly.");
|
|
994
|
-
}
|
|
995
|
-
return true;
|
|
996
|
-
}
|
|
997
|
-
if (input === false) {
|
|
998
|
-
return false;
|
|
995
|
+
if (typeof input === "boolean") {
|
|
996
|
+
throw new Error("Invalid trustProxy boolean. Use a CIDR allowlist or a custom trust function instead.");
|
|
999
997
|
}
|
|
1000
998
|
if (Array.isArray(input) && input.every((entry) => typeof entry === "string")) {
|
|
1001
999
|
return input;
|
package/dist/adapters/index.d.ts
CHANGED
package/dist/adapters/index.js
CHANGED
package/dist/createRouter.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const createRouter: (
|
|
1
|
+
import { ServerRouter } from "./abstract";
|
|
2
|
+
export declare const createRouter: () => ServerRouter;
|
package/dist/createRouter.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createRouter = void 0;
|
|
4
|
-
const abstract_1 = require("./abstract");
|
|
5
4
|
const adapters_1 = require("./adapters");
|
|
6
|
-
const createRouter = (
|
|
7
|
-
|
|
8
|
-
return new adapters_1.BunAdapter().createRouter();
|
|
9
|
-
}
|
|
10
|
-
return new adapters_1.ExpressAdapter().createRouter();
|
|
5
|
+
const createRouter = () => {
|
|
6
|
+
return new adapters_1.BunAdapter().createRouter();
|
|
11
7
|
};
|
|
12
8
|
exports.createRouter = createRouter;
|
|
@@ -24,7 +24,7 @@ class ControllersModule extends abstract_1.BaseServerModule {
|
|
|
24
24
|
if (!basePath) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
const adapter = context?.adapter ?? new adapters_1.
|
|
27
|
+
const adapter = context?.adapter ?? new adapters_1.BunAdapter();
|
|
28
28
|
const router = adapter.createRouter();
|
|
29
29
|
// Create a single controller instance per controller class (singleton pattern)
|
|
30
30
|
const controllerInstance = new ControllerClass();
|
|
@@ -109,7 +109,7 @@ class ControllersModule extends abstract_1.BaseServerModule {
|
|
|
109
109
|
break;
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
|
-
// Fallbacks for common
|
|
112
|
+
// Fallbacks for common handler arguments when not explicitly decorated
|
|
113
113
|
if (args[0] === undefined) {
|
|
114
114
|
args[0] = req;
|
|
115
115
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { BaseServerModule } from "../abstract";
|
|
2
2
|
import { ServerApp, ServerContext } from "../abstract";
|
|
3
|
-
import
|
|
3
|
+
import type { CorsOptions } from "cors";
|
|
4
4
|
export declare class CorsModule extends BaseServerModule {
|
|
5
5
|
name: string;
|
|
6
6
|
priority: number;
|
|
7
7
|
private corsOptions;
|
|
8
|
-
constructor(corsOptions?:
|
|
8
|
+
constructor(corsOptions?: CorsOptions);
|
|
9
9
|
getModuleName(): string;
|
|
10
10
|
init(app: ServerApp, context?: ServerContext): void;
|
|
11
11
|
}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.CorsModule = void 0;
|
|
7
4
|
const abstract_1 = require("../abstract");
|
|
8
|
-
const abstract_2 = require("../abstract");
|
|
9
|
-
const cors_1 = __importDefault(require("cors"));
|
|
10
5
|
class CorsModule extends abstract_1.BaseServerModule {
|
|
11
6
|
constructor(corsOptions) {
|
|
12
7
|
super();
|
|
@@ -24,11 +19,6 @@ class CorsModule extends abstract_1.BaseServerModule {
|
|
|
24
19
|
return this.name;
|
|
25
20
|
}
|
|
26
21
|
init(app, context) {
|
|
27
|
-
const runtime = context?.runtime ?? abstract_2.ServerRuntime.Express;
|
|
28
|
-
if (runtime === abstract_2.ServerRuntime.Express) {
|
|
29
|
-
app.use((0, cors_1.default)(this.corsOptions));
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
22
|
app.use(createCorsMiddleware(this.corsOptions));
|
|
33
23
|
}
|
|
34
24
|
}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { BaseServerModule } from "../abstract";
|
|
2
|
-
import { ServerApp, ServerContext } from "../abstract";
|
|
3
|
-
|
|
2
|
+
import { BunMultipartFile, ServerApp, ServerContext } from "../abstract";
|
|
3
|
+
export type FileUploadOptions = {
|
|
4
|
+
maxBodyBytes?: number;
|
|
5
|
+
maxFileBytes?: number;
|
|
6
|
+
maxFiles?: number;
|
|
7
|
+
maxFields?: number;
|
|
8
|
+
maxFieldBytes?: number;
|
|
9
|
+
maxFieldsBytes?: number;
|
|
10
|
+
allowedMimeTypes?: string[];
|
|
11
|
+
allowedFileSignatures?: Array<"png" | "jpg" | "jpeg" | "pdf">;
|
|
12
|
+
validateFile?: (file: BunMultipartFile) => boolean | Promise<boolean>;
|
|
13
|
+
};
|
|
4
14
|
export declare class FileUploadModule extends BaseServerModule {
|
|
5
15
|
name: string;
|
|
6
16
|
priority: number;
|
|
@@ -2,28 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FileUploadModule = void 0;
|
|
4
4
|
const abstract_1 = require("../abstract");
|
|
5
|
-
const abstract_2 = require("../abstract");
|
|
6
5
|
class FileUploadModule extends abstract_1.BaseServerModule {
|
|
7
6
|
constructor(fileUploadOptions) {
|
|
8
7
|
super();
|
|
9
8
|
this.name = "FileUpload";
|
|
10
9
|
this.priority = -60;
|
|
11
|
-
this.fileUploadOptions = fileUploadOptions
|
|
12
|
-
limits: { fileSize: 50 * 1024 * 1024 },
|
|
13
|
-
useTempFiles: true,
|
|
14
|
-
tempFileDir: "/tmp/",
|
|
15
|
-
};
|
|
10
|
+
this.fileUploadOptions = fileUploadOptions ?? {};
|
|
16
11
|
}
|
|
17
12
|
getModuleName() {
|
|
18
13
|
return this.name;
|
|
19
14
|
}
|
|
20
15
|
init(app, context) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const fileUpload = require("express-fileupload");
|
|
24
|
-
app.use(fileUpload(this.fileUploadOptions));
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
16
|
+
app.set?.("fileUploadEnabled", true);
|
|
17
|
+
app.set?.("multipart", this.fileUploadOptions);
|
|
27
18
|
}
|
|
28
19
|
}
|
|
29
20
|
exports.FileUploadModule = FileUploadModule;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { BaseServerModule } from "../abstract";
|
|
2
2
|
import { ServerApp, ServerContext } from "../abstract";
|
|
3
|
-
|
|
3
|
+
export type RateLimitOptions = {
|
|
4
|
+
windowMs?: number;
|
|
5
|
+
limit?: number;
|
|
6
|
+
max?: number;
|
|
7
|
+
standardHeaders?: boolean;
|
|
8
|
+
legacyHeaders?: boolean;
|
|
9
|
+
message?: string | Record<string, unknown>;
|
|
10
|
+
};
|
|
4
11
|
export declare class RateLimitModule extends BaseServerModule {
|
|
5
12
|
name: string;
|
|
6
13
|
priority: number;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RateLimitModule = void 0;
|
|
4
4
|
const abstract_1 = require("../abstract");
|
|
5
|
-
const abstract_2 = require("../abstract");
|
|
6
5
|
class RateLimitModule extends abstract_1.BaseServerModule {
|
|
7
6
|
constructor(limiterOptions) {
|
|
8
7
|
super();
|
|
@@ -19,14 +18,6 @@ class RateLimitModule extends abstract_1.BaseServerModule {
|
|
|
19
18
|
return this.name;
|
|
20
19
|
}
|
|
21
20
|
init(app, context) {
|
|
22
|
-
const runtime = context?.runtime ?? abstract_2.ServerRuntime.Express;
|
|
23
|
-
if (runtime === abstract_2.ServerRuntime.Express) {
|
|
24
|
-
const rateLimitModule = require("express-rate-limit");
|
|
25
|
-
const rateLimit = rateLimitModule.default ?? rateLimitModule;
|
|
26
|
-
const limiter = rateLimit(this.limiterOptions);
|
|
27
|
-
app.use(limiter);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
21
|
app.use(createRateLimitMiddleware(this.limiterOptions));
|
|
31
22
|
}
|
|
32
23
|
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RoutesModule = void 0;
|
|
4
4
|
const abstract_1 = require("../abstract");
|
|
5
|
-
const abstract_2 = require("../abstract");
|
|
6
5
|
class RoutesModule extends abstract_1.BaseServerModule {
|
|
7
6
|
constructor(routes = []) {
|
|
8
7
|
super();
|
|
@@ -22,9 +21,6 @@ class RoutesModule extends abstract_1.BaseServerModule {
|
|
|
22
21
|
this.routes.push(...routes);
|
|
23
22
|
}
|
|
24
23
|
init(app, context) {
|
|
25
|
-
if (context?.runtime === abstract_2.ServerRuntime.Bun) {
|
|
26
|
-
console.warn("[RoutesModule] Express routers are not supported on Bun. Migrate to decorated controllers for Bun runtime.");
|
|
27
|
-
}
|
|
28
24
|
this.routes.forEach(({ path, router, middleware }) => {
|
|
29
25
|
const middlewareList = Array.isArray(middleware)
|
|
30
26
|
? middleware
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SecurityModule = void 0;
|
|
4
4
|
const abstract_1 = require("../abstract");
|
|
5
|
-
const abstract_2 = require("../abstract");
|
|
6
5
|
class SecurityModule extends abstract_1.BaseServerModule {
|
|
7
6
|
constructor(helmetOptions) {
|
|
8
7
|
super();
|
|
@@ -27,13 +26,6 @@ class SecurityModule extends abstract_1.BaseServerModule {
|
|
|
27
26
|
return this.name;
|
|
28
27
|
}
|
|
29
28
|
init(app, context) {
|
|
30
|
-
const runtime = context?.runtime ?? abstract_2.ServerRuntime.Express;
|
|
31
|
-
if (runtime === abstract_2.ServerRuntime.Express) {
|
|
32
|
-
const helmetModule = require("helmet");
|
|
33
|
-
const helmet = helmetModule.default ?? helmetModule;
|
|
34
|
-
app.use(helmet(this.helmetOptions));
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
29
|
app.use(createSecurityMiddleware(this.helmetOptions));
|
|
38
30
|
}
|
|
39
31
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BootstrapServer } from "../BootstrapServer";
|
|
2
2
|
import { ControllersModule } from "../modules";
|
|
3
|
-
import { BaseServerService, ServerApp
|
|
3
|
+
import { BaseServerService, ServerApp } from "../abstract";
|
|
4
4
|
import { BootstrapStandardServerOptions } from "../BootstrapStandardServer";
|
|
5
5
|
type ControllerClass<T = any> = new (...args: any[]) => T;
|
|
6
6
|
export interface DecoratedTestAppOptions {
|
|
@@ -9,7 +9,6 @@ export interface DecoratedTestAppOptions {
|
|
|
9
9
|
port?: number;
|
|
10
10
|
services?: BaseServerService[];
|
|
11
11
|
standardOptions?: BootstrapStandardServerOptions;
|
|
12
|
-
runtime?: ServerRuntime;
|
|
13
12
|
}
|
|
14
13
|
export interface DecoratedTestAppResult {
|
|
15
14
|
app: ServerApp;
|
|
@@ -12,7 +12,7 @@ const mergeOptions = (base, override) => {
|
|
|
12
12
|
...(override.services ?? []),
|
|
13
13
|
];
|
|
14
14
|
return {
|
|
15
|
-
|
|
15
|
+
adapter: override.adapter ?? base.adapter,
|
|
16
16
|
services: mergedServices.length ? mergedServices : undefined,
|
|
17
17
|
modules: {
|
|
18
18
|
...(base.modules ?? {}),
|
|
@@ -34,7 +34,6 @@ async function createDecoratedTestApp(options) {
|
|
|
34
34
|
const mergedOptions = mergeOptions(baseOptions, standardOptions);
|
|
35
35
|
const server = (0, BootstrapStandardServer_1.BootstrapStandardServer)(port, moduleInstance, {
|
|
36
36
|
...mergedOptions,
|
|
37
|
-
runtime: options.runtime ?? mergedOptions.runtime,
|
|
38
37
|
});
|
|
39
38
|
await server.initialize();
|
|
40
39
|
return {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abejarano/ts-express-server",
|
|
3
3
|
"author": "angel bejarano / angel.bejarano@jaspesoft.com",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -26,16 +26,11 @@
|
|
|
26
26
|
"keywords": [
|
|
27
27
|
"server",
|
|
28
28
|
"modular",
|
|
29
|
-
"
|
|
29
|
+
"bun"
|
|
30
30
|
],
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"body-parser": "^2.2.1",
|
|
34
|
-
"cookie-parser": "^1.4.7",
|
|
35
33
|
"cors": "^2.8.5",
|
|
36
|
-
"express": "^5.2.1",
|
|
37
|
-
"express-fileupload": "^1.5.2",
|
|
38
|
-
"express-rate-limit": "^8.2.1",
|
|
39
34
|
"helmet": "^8.1.0",
|
|
40
35
|
"reflect-metadata": "^0.2.2",
|
|
41
36
|
"uuid": "^13.0.0"
|
|
@@ -43,19 +38,13 @@
|
|
|
43
38
|
"devDependencies": {
|
|
44
39
|
"@semantic-release/changelog": "^6.0.3",
|
|
45
40
|
"@semantic-release/git": "^10.0.1",
|
|
46
|
-
"@types/body-parser": "^1.19.6",
|
|
47
|
-
"@types/cookie-parser": "^1.4.9",
|
|
48
41
|
"@types/cors": "^2.8.19",
|
|
49
|
-
"@types/express": "^5.0.6",
|
|
50
|
-
"@types/express-fileupload": "^1.5.1",
|
|
51
42
|
"@types/jest": "^30.0.0",
|
|
52
43
|
"@types/node": "^25.0.3",
|
|
53
|
-
"@types/supertest": "^6.0.3",
|
|
54
44
|
"jest": "^30.2.0",
|
|
55
45
|
"prettier": "^3.6.2",
|
|
56
46
|
"rimraf": "^6.0.1",
|
|
57
47
|
"semantic-release": "^25.0.2",
|
|
58
|
-
"supertest": "^7.1.4",
|
|
59
48
|
"ts-jest": "^29.4.5",
|
|
60
49
|
"typescript": "^5.9.3"
|
|
61
50
|
},
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { ServerAdapter, ServerApp, ServerInstance, ServerRouter, ServerRuntime } from "../abstract/ServerTypes";
|
|
2
|
-
export declare class ExpressAdapter implements ServerAdapter {
|
|
3
|
-
runtime: ServerRuntime;
|
|
4
|
-
createApp(): ServerApp;
|
|
5
|
-
createRouter(): ServerRouter;
|
|
6
|
-
configure(app: ServerApp, port: number): void;
|
|
7
|
-
listen(app: ServerApp, port: number, onListen: () => void): ServerInstance;
|
|
8
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ExpressAdapter = void 0;
|
|
4
|
-
const ServerTypes_1 = require("../abstract/ServerTypes");
|
|
5
|
-
let expressModule = null;
|
|
6
|
-
const getExpressModule = () => {
|
|
7
|
-
if (!expressModule) {
|
|
8
|
-
expressModule = require("express");
|
|
9
|
-
}
|
|
10
|
-
return expressModule;
|
|
11
|
-
};
|
|
12
|
-
class ExpressAdapter {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.runtime = ServerTypes_1.ServerRuntime.Express;
|
|
15
|
-
}
|
|
16
|
-
createApp() {
|
|
17
|
-
const express = getExpressModule();
|
|
18
|
-
return express();
|
|
19
|
-
}
|
|
20
|
-
createRouter() {
|
|
21
|
-
const express = getExpressModule();
|
|
22
|
-
return express.Router();
|
|
23
|
-
}
|
|
24
|
-
configure(app, port) {
|
|
25
|
-
const expressApp = app;
|
|
26
|
-
const express = getExpressModule();
|
|
27
|
-
const bodyParser = require("body-parser");
|
|
28
|
-
const cookieParser = require("cookie-parser");
|
|
29
|
-
const jsonParser = express.json();
|
|
30
|
-
expressApp.use((req, res, next) => {
|
|
31
|
-
if (!shouldParseJson(req)) {
|
|
32
|
-
return next();
|
|
33
|
-
}
|
|
34
|
-
return jsonParser(req, res, next);
|
|
35
|
-
});
|
|
36
|
-
expressApp.use(bodyParser.urlencoded({ extended: true }));
|
|
37
|
-
expressApp.use(cookieParser());
|
|
38
|
-
expressApp.set("port", port);
|
|
39
|
-
expressApp.set("trust proxy", 1);
|
|
40
|
-
}
|
|
41
|
-
listen(app, port, onListen) {
|
|
42
|
-
const expressApp = app;
|
|
43
|
-
return expressApp.listen(port, onListen);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
exports.ExpressAdapter = ExpressAdapter;
|
|
47
|
-
const shouldParseJson = (req) => {
|
|
48
|
-
const method = String(req.method || "").toUpperCase();
|
|
49
|
-
if (method === "GET" || method === "HEAD") {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
const lengthHeader = req.headers?.["content-length"];
|
|
53
|
-
if (lengthHeader === undefined) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
const value = Array.isArray(lengthHeader) ? lengthHeader[0] : lengthHeader;
|
|
57
|
-
if (!value) {
|
|
58
|
-
return true;
|
|
59
|
-
}
|
|
60
|
-
const parsed = Number.parseInt(value, 10);
|
|
61
|
-
if (Number.isNaN(parsed)) {
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
return parsed > 0;
|
|
65
|
-
};
|