@dooboostore/simple-boot-http-server 1.0.20 → 1.0.22
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 +24 -248
- package/dist/cjs/SimpleBootHttpServer.js +2 -2
- package/dist/cjs/SimpleBootHttpServer.js.map +2 -2
- package/dist/cjs/filters/ResourceFilter.js +59 -19
- package/dist/cjs/filters/ResourceFilter.js.map +2 -2
- package/dist/cjs/models/RequestResponse.js +23 -1
- package/dist/cjs/models/RequestResponse.js.map +2 -2
- package/dist/cjs/package.json +5 -0
- package/dist/esm/SimpleBootHttpServer.js +2 -2
- package/dist/esm/SimpleBootHttpServer.js.map +2 -2
- package/dist/esm/filters/ResourceFilter.js +56 -18
- package/dist/esm/filters/ResourceFilter.js.map +2 -2
- package/dist/esm/models/RequestResponse.js +23 -1
- package/dist/esm/models/RequestResponse.js.map +2 -2
- package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +166 -149
- package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +4 -4
- package/dist/types/SimpleBootHttpServer.d.ts +1 -2
- package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
- package/dist/types/filters/ResourceFilter.d.ts +16 -6
- package/dist/types/filters/ResourceFilter.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -38
- package/dist/types/models/RequestResponse.d.ts +2 -1
- package/dist/types/models/RequestResponse.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +173 -156
- package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +4 -4
- package/package.json +16 -15
- package/src/SimpleBootHttpServer.ts +2 -3
- package/src/filters/ResourceFilter.ts +67 -20
- package/src/models/RequestResponse.ts +26 -2
package/README.MD
CHANGED
|
@@ -1,262 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
===
|
|
1
|
+
# @dooboostore/simple-boot-http-server
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
](https://www.npmjs.com/package/@dooboostore/simple-boot-http-server)
|
|
4
|
+
[](https://github.com/dooboostore-develop/packages/actions/workflows/main.yaml)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **HTTP Method Mapping**: Decorators for all standard HTTP methods (`@GET`, `@POST`, `@PUT`, `@DELETE`, etc.).
|
|
9
|
-
- **Request/Response Handling**: A unified `RequestResponse` object to manage the HTTP transaction.
|
|
10
|
-
- **Middleware/Filters**: Intercept requests and responses for cross-cutting concerns like logging, authentication, or CORS.
|
|
11
|
-
- **Endpoints**: Define logic to be executed at different stages of the request lifecycle (e.g., on request start, close, or error).
|
|
12
|
-
- **Global Exception Handling**: Centralized error handling using `@Sim` advice classes.
|
|
13
|
-
- **Session Management**: Built-in session management with customizable storage providers.
|
|
14
|
-
- **HTTPS and HTTP/2 Support**: Configure the server to run over HTTPS.
|
|
7
|
+
**Full Documentation:** [https://dooboostore-develop.github.io/packages/simple-boot-http-server](https://dooboostore-develop.github.io/packages/simple-boot-http-server)
|
|
15
8
|
|
|
16
|
-
|
|
9
|
+
A lightweight and powerful HTTP web server framework for Node.js, built on `@dooboostore/simple-boot`.
|
|
17
10
|
|
|
18
|
-
|
|
11
|
+
---
|
|
19
12
|
|
|
20
|
-
##
|
|
13
|
+
## Features
|
|
21
14
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# 😃 Examples
|
|
29
|
-
|
|
30
|
-
- [More examples](./examples)
|
|
31
|
-
|
|
32
|
-
## URL & Method Mapping
|
|
33
|
-
|
|
34
|
-
Simple Boot provides decorators for all standard HTTP methods to map incoming requests to your class methods. These are combined with `@Route` from `@dooboostore/simple-boot` to define endpoints.
|
|
35
|
-
|
|
36
|
-
### Available Method Decorators
|
|
37
|
-
|
|
38
|
-
- `@GET`
|
|
39
|
-
- `@POST`
|
|
40
|
-
- `@PUT`
|
|
41
|
-
- `@DELETE`
|
|
42
|
-
- `@PATCH`
|
|
43
|
-
- `@OPTIONS`
|
|
44
|
-
- `@HEAD`
|
|
45
|
-
- `@TRACE`
|
|
46
|
-
- `@CONNECT`
|
|
47
|
-
- `@UrlMapping`: A generic decorator where you can specify the method as a string.
|
|
48
|
-
|
|
49
|
-
### Example Usage
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
import { Sim, Router, Route, RouterModule } from '@dooboostore/simple-boot';
|
|
53
|
-
import {
|
|
54
|
-
GET, POST, PUT, DELETE,
|
|
55
|
-
Mimes,
|
|
56
|
-
RequestResponse,
|
|
57
|
-
ReqJsonBody
|
|
58
|
-
} from '@dooboostore/simple-boot-http-server';
|
|
59
|
-
|
|
60
|
-
@Sim
|
|
61
|
-
@Router({ path: '/api/items' })
|
|
62
|
-
export class ItemApi {
|
|
63
|
-
|
|
64
|
-
@Route({ path: '' })
|
|
65
|
-
@GET({ res: { contentType: Mimes.ApplicationJson } })
|
|
66
|
-
getAllItems() {
|
|
67
|
-
// Logic to get all items
|
|
68
|
-
return [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@Route({ path: '/{id}' })
|
|
72
|
-
@GET({ res: { contentType: Mimes.ApplicationJson } })
|
|
73
|
-
getItemById(routerModule: RouterModule) {
|
|
74
|
-
const itemId = routerModule.pathData?.id;
|
|
75
|
-
// Logic to get item by ID
|
|
76
|
-
return { id: itemId, name: `Item ${itemId}` };
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
@Route({ path: '' })
|
|
80
|
-
@POST({
|
|
81
|
-
req: { contentType: [Mimes.ApplicationJson] },
|
|
82
|
-
res: { status: 201, contentType: Mimes.ApplicationJson }
|
|
83
|
-
})
|
|
84
|
-
createItem(body: ReqJsonBody) {
|
|
85
|
-
console.log('Creating new item:', body);
|
|
86
|
-
// Logic to create a new item
|
|
87
|
-
return { success: true, id: 3, ...body };
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
@Route({ path: '/{id}' })
|
|
91
|
-
@PUT({ req: { contentType: [Mimes.ApplicationJson] } })
|
|
92
|
-
updateItem(routerModule: RouterModule, body: ReqJsonBody) {
|
|
93
|
-
const itemId = routerModule.pathData?.id;
|
|
94
|
-
console.log(`Updating item ${itemId}:`, body);
|
|
95
|
-
// Logic to update an item
|
|
96
|
-
return { success: true, id: itemId, ...body };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
@Route({ path: '/{id}' })
|
|
100
|
-
@DELETE({ res: { status: 204 } })
|
|
101
|
-
deleteItem(routerModule: RouterModule) {
|
|
102
|
-
const itemId = routerModule.pathData?.id;
|
|
103
|
-
console.log(`Deleting item ${itemId}`);
|
|
104
|
-
// Logic to delete an item
|
|
105
|
-
// No content returned for 204
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### Decorator Options
|
|
111
|
-
|
|
112
|
-
The method decorators accept a `MappingConfig` object to control request and response properties.
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
export type MappingConfig = {
|
|
116
|
-
method: HttpMethod | string;
|
|
117
|
-
description?: { name?: string; detail?: string; };
|
|
118
|
-
req?: {
|
|
119
|
-
contentType?: (Mimes | string)[];
|
|
120
|
-
accept?: (Mimes | string)[];
|
|
121
|
-
};
|
|
122
|
-
res?: {
|
|
123
|
-
status?: number;
|
|
124
|
-
header?: { [key: string]: string };
|
|
125
|
-
contentType?: Mimes | string;
|
|
126
|
-
}
|
|
127
|
-
resolver?: Resolver | ConstructorType<Resolver>;
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Filters
|
|
132
|
-
|
|
133
|
-
Filters allow you to intercept the request-response cycle. The `before` method runs before the route handler, and `after` runs after. Returning `false` from `before` will stop the chain.
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
import { Filter, RequestResponse, SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server';
|
|
15
|
+
- **Declarative Routing**: Use decorators like `@Router`, `@Route`, `@GET`, `@POST`, etc., to map URL paths and HTTP methods directly to your controller methods.
|
|
16
|
+
- **Middleware via Filters**: Intercept the request-response cycle with `Filter` classes to implement cross-cutting concerns like logging, authentication, and CORS.
|
|
17
|
+
- **Lifecycle Endpoints**: Hook into the request lifecycle with `EndPoint` classes that run on request start, close, or error.
|
|
18
|
+
- **Integrated Exception Handling**: Leverage `@simple-boot`'s AOP capabilities to create robust global error handlers.
|
|
19
|
+
- **Built-in Session Management**: Easily manage user sessions with a built-in session manager and customizable storage.
|
|
20
|
+
- **HTTPS and HTTP/2 Support**: Secure your server with HTTPS and HTTP/2 configuration.
|
|
137
21
|
|
|
138
|
-
|
|
139
|
-
async before(rr: RequestResponse, app: SimpleBootHttpServer): Promise<boolean> {
|
|
140
|
-
console.log(`[${new Date().toISOString()}] Received ${rr.reqMethod()} request for ${rr.reqUrl}`);
|
|
141
|
-
return true; // Continue the chain
|
|
142
|
-
}
|
|
22
|
+
## Quick Start
|
|
143
23
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// In HttpServerOption
|
|
151
|
-
const option = new HttpServerOption({
|
|
152
|
-
filters: [LoggingFilter]
|
|
153
|
-
});
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## Global Advice & Exception Handling
|
|
157
|
-
|
|
158
|
-
Define global exception handlers in an `Advice` class. This class is managed by `@Sim` and can catch errors thrown from anywhere in the application.
|
|
159
|
-
|
|
160
|
-
### Preventing `ERR_HTTP_HEADERS_SENT`
|
|
161
|
-
|
|
162
|
-
A common issue in asynchronous frameworks is the `ERR_HTTP_HEADERS_SENT` error. This occurs when an error is thrown *after* a response has already been sent by another part of the application (like a filter). The global exception handler then tries to send a *second* response, causing a crash.
|
|
163
|
-
|
|
164
|
-
To prevent this, **always check if a response has already been sent** before sending a new one from your exception handler. The `RequestResponse` object provides the `resIsDone()` method for this purpose.
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
import { Sim, ExceptionHandler, Inject, ExceptionHandlerSituationType } from '@dooboostore/simple-boot';
|
|
168
|
-
import { RequestResponse, NotFoundError, HttpError, InternalServerError, Mimes, HttpStatus } from '@dooboostore/simple-boot-http-server';
|
|
169
|
-
|
|
170
|
-
@Sim
|
|
171
|
-
export class GlobalErrorHandler {
|
|
172
|
-
|
|
173
|
-
@ExceptionHandler({ type: NotFoundError })
|
|
174
|
-
handleNotFound(rr: RequestResponse, e: NotFoundError) {
|
|
175
|
-
// Critical check
|
|
176
|
-
if (rr.resIsDone()) {
|
|
177
|
-
console.error(`Not found error for URL: ${rr.reqUrl}, but response already sent.`, e);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
rr.resStatusCode(404).resSetHeader('X-Error-Message', 'Resource not found');
|
|
181
|
-
console.error(`Not found error for URL: ${rr.reqUrl}`, e);
|
|
182
|
-
rr.resEnd(JSON.stringify({ error: 'Resource not found' }));
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
@ExceptionHandler()
|
|
186
|
-
async catch(@Inject({situationType: ExceptionHandlerSituationType.ERROR_OBJECT}) e: any, rr: RequestResponse) {
|
|
187
|
-
console.error(`GlobalAdvice.catch ${rr.reqUrl}`, e);
|
|
188
|
-
|
|
189
|
-
// Critical check to prevent writing to an already-sent response
|
|
190
|
-
if (rr.resIsDone()) {
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
rr.resStatusCode(HttpStatus.InternalServerError);
|
|
195
|
-
rr.resSetHeader('Content-Type', Mimes.ApplicationJson);
|
|
196
|
-
|
|
197
|
-
let data = '';
|
|
198
|
-
if (e instanceof HttpError) {
|
|
199
|
-
rr.resStatusCode(e.status);
|
|
200
|
-
data = JSON.stringify(e);
|
|
201
|
-
} else if (e instanceof Error){
|
|
202
|
-
const error = new InternalServerError();
|
|
203
|
-
error.data = {message: e.message, stack: e.stack}; // Be careful with stack in production
|
|
204
|
-
data = JSON.stringify(error);
|
|
205
|
-
} else {
|
|
206
|
-
const error = new InternalServerError();
|
|
207
|
-
error.data = e;
|
|
208
|
-
data = JSON.stringify(error);
|
|
209
|
-
}
|
|
210
|
-
await rr.resEnd(data);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// In HttpServerOption
|
|
215
|
-
const option = new HttpServerOption({
|
|
216
|
-
globalAdvice: GlobalErrorHandler,
|
|
217
|
-
noSuchRouteEndPointMappingThrow: (rr) => new NotFoundError({ message: `No route for ${rr.reqUrl}` }),
|
|
218
|
-
});
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
## Endpoints
|
|
222
|
-
|
|
223
|
-
Endpoints are hooks that run at specific points in the request lifecycle.
|
|
224
|
-
|
|
225
|
-
- **`requestEndPoints`**: Run as soon as a request is received.
|
|
226
|
-
- **`closeEndPoints`**: Run when the client connection is closed.
|
|
227
|
-
- **`errorEndPoints`**: Run if an error occurs on the response stream.
|
|
228
|
-
|
|
229
|
-
```typescript
|
|
230
|
-
import { EndPoint, RequestResponse, SimpleBootHttpServer } from '@dooboostore/simple-boot-http-server';
|
|
231
|
-
|
|
232
|
-
@Sim
|
|
233
|
-
class ConnectionLogger implements EndPoint {
|
|
234
|
-
async endPoint(rr: RequestResponse, app: SimpleBootHttpServer) {
|
|
235
|
-
console.log(`Connection closed for ${rr.reqRemoteAddress}`);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// In HttpServerOption
|
|
240
|
-
const option = new HttpServerOption({
|
|
241
|
-
closeEndPoints: [ConnectionLogger]
|
|
242
|
-
});
|
|
24
|
+
```bash
|
|
25
|
+
npx @dooboostore/create-simple-boot-http-server my-server
|
|
26
|
+
cd my-server
|
|
27
|
+
npm start
|
|
243
28
|
```
|
|
244
29
|
|
|
245
|
-
##
|
|
246
|
-
|
|
247
|
-
The server has built-in session management. It automatically creates a session ID cookie and provides a `SessionManager` to store and retrieve session data.
|
|
30
|
+
## Learn More
|
|
248
31
|
|
|
249
|
-
|
|
250
|
-
import { RequestResponse } from '@dooboostore/simple-boot-http-server';
|
|
32
|
+
The detailed API documentation, including all decorators and usage examples, is available on our documentation website.
|
|
251
33
|
|
|
252
|
-
|
|
253
|
-
async function handleSession(rr: RequestResponse) {
|
|
254
|
-
const session = await rr.reqSession();
|
|
34
|
+
**[Explore the full @dooboostore/simple-boot-http-server documentation »](https://dooboostore-develop.github.io/packages/simple-boot-http-server)**
|
|
255
35
|
|
|
256
|
-
|
|
257
|
-
visitCount++;
|
|
258
|
-
session.visitCount = visitCount;
|
|
36
|
+
## License
|
|
259
37
|
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
```
|
|
38
|
+
This package is licensed under the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -52,12 +52,12 @@ class SimpleBootHttpServer extends import_SimpleApplication.SimpleApplication {
|
|
|
52
52
|
this.sessionManager = new import_SessionManager.SessionManager(this.option);
|
|
53
53
|
}
|
|
54
54
|
run(otherInstanceSim) {
|
|
55
|
-
|
|
55
|
+
super.run(otherInstanceSim);
|
|
56
56
|
const targets = [...this.option.closeEndPoints ?? [], ...this.option.errorEndPoints ?? [], ...this.option.requestEndPoints ?? [], ...this.option.filters ?? []];
|
|
57
57
|
Promise.all(targets.map((it) => typeof it === "function" ? this.simstanceManager.getOrNewSim({ target: it }) : it).map((it) => it.onInit(this))).then((it) => {
|
|
58
58
|
this.startServer();
|
|
59
59
|
});
|
|
60
|
-
return
|
|
60
|
+
return this;
|
|
61
61
|
}
|
|
62
62
|
startServer() {
|
|
63
63
|
if (this.option.serverOption && "key" in this.option.serverOption && "cert" in this.option.serverOption) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/SimpleBootHttpServer.ts"],
|
|
4
|
-
"sourcesContent": ["import { SimpleApplication } from '@dooboostore/simple-boot/SimpleApplication';\nimport { HttpServerOption } from './option/HttpServerOption';\nimport { ConstructorType } from '@dooboostore/core/types';\nimport { IncomingMessage, Server as HttpServer, ServerResponse } from 'http'\nimport { Server as HttpsServer } from 'https'; // Add HTTPS support\nimport { RequestResponse } from './models/RequestResponse';\nimport { getUrlMapping, getUrlMappings, SaveMappingConfig, UrlMappingSituationType } from './decorators/MethodMapping';\nimport { HttpStatus } from './codes/HttpStatus';\nimport { HttpHeaders } from './codes/HttpHeaders';\nimport { Mimes } from './codes/Mimes';\nimport { Filter } from './filters/Filter';\nimport { SimstanceManager } from '@dooboostore/simple-boot/simstance/SimstanceManager';\nimport { ExceptionHandlerSituationType, targetExceptionHandler } from '@dooboostore/simple-boot/decorators/exception/ExceptionDecorator';\nimport { getInject, SituationTypeContainer, SituationTypeContainers } from '@dooboostore/simple-boot/decorators/inject/Inject';\nimport { EndPoint } from './endpoints/EndPoint';\nimport { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';\nimport { ReqFormUrlBody } from './models/datas/body/ReqFormUrlBody';\nimport { ReqJsonBody } from './models/datas/body/ReqJsonBody';\nimport { ReqHeader } from './models/datas/ReqHeader';\nimport { RouterModule } from '@dooboostore/simple-boot/route/RouterModule';\nimport { ReqMultipartFormBody } from './models/datas/body/ReqMultipartFormBody';\nimport { execValidationInValid, getValidIndex } from '@dooboostore/simple-boot/decorators/validate/Validation';\nimport { ValidException } from '@dooboostore/simple-boot/errors/ValidException';\nimport { HttpError } from './errors/HttpError';\nimport { getRoute } from '@dooboostore/simple-boot/decorators/route/Router';\nimport { OnInit } from './lifecycle/OnInit';\nimport { URLSearchParams } from 'url';\nimport { HttpMethod } from './codes/HttpMethod';\nimport { SessionManager } from './session/SessionManager';\nimport { InjectSituationType } from './inject/InjectSituationType';\n\nexport class SimpleBootHttpServer extends SimpleApplication {\n public server?: HttpServer | HttpsServer;\n private sessionManager: SessionManager;\n constructor(public option: HttpServerOption = new HttpServerOption()) {\n super(option);\n this.sessionManager = new SessionManager(this.option);\n }\n\n\n public run(otherInstanceSim?: Map<ConstructorType<any>, any>) {\n const simstanceManager = super.run(otherInstanceSim);\n const targets = [...this.option.closeEndPoints ?? [], ...this.option.errorEndPoints ?? [], ...this.option.requestEndPoints ?? [], ...this.option.filters ?? []];\n Promise.all(targets.map(it => (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it as ConstructorType<any>}) : it) as OnInit).map(it => it.onInit(this))).then(it => {\n this.startServer();\n });\n return simstanceManager;\n }\n\n private startServer() {\n\n // const a = this.option.serverOption as HttpsServerOption;\n // this.option.serverOption?.\n\n if (this.option.serverOption && 'key' in this.option.serverOption && 'cert' in this.option.serverOption) {\n this.server = new HttpsServer(this.option.serverOption);\n const httpServer = new HttpServer();\n httpServer.on('request', (req: IncomingMessage, res: ServerResponse) => {\n res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` });\n res.end();\n });\n httpServer.listen(80, this.option.listen.hostname, () => {\n console.log('HTTP redirect server running on port 80');\n });\n } else if (this.option.serverOption) {\n this.server = new HttpServer(this.option.serverOption);\n } else {\n this.server = new HttpServer();\n }\n // const thisRef = this;\n this.server.on('request', async (req: IncomingMessage, res: ServerResponse) => {\n // console.log('request', req.url);\n const transactionManager = this.option.transactionManagerFactory ? await this.option.transactionManagerFactory() : undefined;\n res.on('close', async () => {\n if (this.option.closeEndPoints) {\n for (const it of this.option.closeEndPoints) {\n try {\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as EndPoint;\n const endPoint = execute?.endPoint(rr, this);\n if (endPoint instanceof Promise) {\n await endPoint;\n }\n } catch (e) {\n }\n }\n }\n\n if (!rr.resIsDone()) {\n rr.resEnd();\n }\n });\n res.on('error', async () => {\n if (this.option.errorEndPoints) {\n for (const it of this.option.errorEndPoints) {\n try {\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as EndPoint;\n const endPoint = execute?.endPoint(rr, this);\n if (endPoint instanceof Promise) {\n await endPoint;\n }\n } catch (e) {\n }\n }\n }\n\n if (!rr.resIsDone()) {\n rr.resEnd();\n }\n });\n\n const rr = new RequestResponse(req, res,{sessionManager: this.sessionManager, option: this.option});\n /*\n default setting first\n */\n rr.resSetHeader(HttpHeaders.Server, 'simple-boot-http-server');\n const cookie = rr.reqCookieGet(this.option.sessionOption.key);\n if (!cookie) {\n const session = await this.sessionManager.session();\n rr.resSetHeader(HttpHeaders.SetCookie, `${this.option.sessionOption.key}=${session.uuid}; Path=/; HttpOnly`);\n }\n\n const otherStorage = new Map<ConstructorType<any>, any>();\n otherStorage.set(RequestResponse, rr);\n otherStorage.set(IncomingMessage, req);\n otherStorage.set(ServerResponse, res);\n try {\n transactionManager?.try();\n if (this.option.requestEndPoints) {\n for (const it of this.option.requestEndPoints) {\n try {\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim<EndPoint>({target:it}) : it) as EndPoint;\n execute?.endPoint(rr, this);\n } catch (e) {\n }\n }\n }\n\n const filter = {\n carrier: new Map<string, any>(),\n filters: [] as { filter: Filter, sw: boolean }[]\n };\n for (let i = 0; this.option.filters && i < this.option.filters.length; i++) {\n const it = this.option.filters[i];\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as Filter;\n let sw = true;\n if (execute?.proceedBefore) {\n sw = await execute.proceedBefore({rr, app: this, carrier: filter.carrier});\n filter.filters.push({filter: execute, sw});\n }\n if (!sw) {\n break;\n }\n }\n\n // body.. something..\n if (!rr.resIsDone()) {\n const routerModule = await super.routing(rr.reqIntent);\n otherStorage.set(RouterModule, routerModule);\n const moduleInstance = routerModule?.getModuleInstance?.();\n let methods: SaveMappingConfig[] = [];\n if (routerModule && moduleInstance) {\n // router \uD074\uB798\uC2A4 \uB0B4\uBD80\uC5D0\uC11C \uC120\uC5B8\uB41C Route\uC77C\uB54C\n if (routerModule.propertyKeys) {\n const map = routerModule.propertyKeys?.map((it: string | symbol) => {\n return {propertyKey: it, config: getUrlMapping(moduleInstance, it)} as SaveMappingConfig\n });\n methods.push(...(map ?? []));\n } else {\n methods.push(...(getUrlMappings(moduleInstance).filter(it => !getRoute(moduleInstance, it.propertyKey)) ?? []));\n }\n\n // options\uB85C \uC694\uCCAD\uC624\uBA74\uC740 allow\uB85C \uB123\uACE0 \uADF8\uB0E5 200\uCC98\uB9AC\uD574\uC57C\uB428.\n if (rr.reqMethod()?.toUpperCase() === HttpMethod.OPTIONS.toUpperCase()) {\n rr.resSetHeader(HttpHeaders.Allow, methods.map(it => it.config.method).join(', '));\n rr.resStatusCode(HttpStatus.Ok);\n }\n\n // method \uCC3E\uAE30\n methods = methods.filter(it => it && it.propertyKey && it.config && rr.reqMethod()?.toUpperCase() === it.config.method.toUpperCase());\n methods.sort((a, b) => {\n return ((b.config?.req?.contentType?.length ?? 0) + (b.config?.req?.accept?.length ?? 0)) - ((a.config?.req?.contentType?.length ?? 0) + (a.config?.req?.accept?.length ?? 0));\n });\n methods = methods\n .filter(it => it.config?.req?.contentType ? (!!it.config?.req?.contentType?.find(sit => rr.reqHasContentTypeHeader(sit))) : true)\n .filter(it => it.config?.req?.accept ? (!!it.config?.req?.accept?.find(sit => rr.reqHasAcceptHeader(sit))) : true);\n\n if (methods[0]) {\n const it = methods[0];\n const paramTypes = ReflectUtils.getParameterTypes(moduleInstance, it.propertyKey)\n const injects = getInject(moduleInstance, it.propertyKey);\n const validIndexs = getValidIndex(moduleInstance, it.propertyKey);\n if (injects) {\n const isJson = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_JSON_BODY);\n const isFormUrl = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_FORM_URL_BODY);\n const isTransactionManager = injects.find(it => it.config?.situationType === InjectSituationType.TransactionManager);\n const siturationContainers = new SituationTypeContainers();\n if (isJson) {\n let data = await rr.reqBodyJsonData()\n if (isJson.type) {\n data = Object.assign(new isJson.type(), data);\n }\n if (validIndexs.includes(isJson.index)) {\n const inValid = execValidationInValid(data);\n if ((inValid?.length ?? 0) > 0) {\n throw new ValidException(inValid);\n }\n }\n siturationContainers.push(new SituationTypeContainer({\n situationType: UrlMappingSituationType.REQ_JSON_BODY,\n data\n }));\n }\n if (isFormUrl) {\n let data = await rr.reqBodyFormUrlData()\n if (isFormUrl.type) {\n data = Object.assign(new isFormUrl.type(), data);\n }\n if (validIndexs.includes(isFormUrl.index)) {\n const inValid = execValidationInValid(data);\n if ((inValid?.length ?? 0) > 0) {\n throw new ValidException(inValid);\n }\n }\n siturationContainers.push(new SituationTypeContainer({situationType: UrlMappingSituationType.REQ_FORM_URL_BODY, data}));\n }\n\n if (isTransactionManager && isTransactionManager.type && transactionManager && transactionManager.hasTransaction(isTransactionManager.type)) {\n let data = await transactionManager.getTransaction(isTransactionManager.type);\n if (data) {\n data = await data.try(isTransactionManager.config.argument);\n siturationContainers.push(new SituationTypeContainer({situationType: InjectSituationType.TransactionManager, data, index: isTransactionManager.index}));\n }\n }\n if (siturationContainers.length) {\n otherStorage.set(SituationTypeContainers, siturationContainers);\n }\n }\n\n for (const paramType of paramTypes) {\n if (paramType === ReqFormUrlBody) {\n otherStorage.set(ReqFormUrlBody, await rr.reqBodyReqFormUrlBody())\n } else if (paramType === ReqJsonBody) {\n otherStorage.set(ReqJsonBody, await rr.reqBodyReqJsonBody())\n } else if (paramType === URLSearchParams) {\n otherStorage.set(URLSearchParams, rr.reqUrlSearchParams)\n } else if (paramType === ReqMultipartFormBody) {\n otherStorage.set(ReqMultipartFormBody, rr.reqBodyMultipartFormData())\n } else if (paramType === ReqHeader) {\n otherStorage.set(ReqHeader, rr.reqHeaderObj)\n }\n }\n\n // execute !!!\n let data = await this.simstanceManager.executeBindParameterSimPromise({\n target: moduleInstance,\n targetKey: it.propertyKey\n }, otherStorage);\n /*\n \uC5EC\uAE30\uC5D0\uC11C \uC815\uD574\uC9C4 \uD0C0\uC785 \uB9AC\uD134\uC5D0 \uB530\uB978 \uC870\uCE58\n ...\n */\n if (it.config?.resolver) {\n const execute = typeof it.config.resolver === 'function' ? this.simstanceManager.getOrNewSim({target:it.config.resolver}) : it.config.resolver;\n data = await execute?.resolve?.(data, rr);\n }\n const status = it.config?.res?.status ?? HttpStatus.Ok;\n const headers = it.config?.res?.header ?? {};\n if (it.config?.res?.contentType) {\n headers[HttpHeaders.ContentType] = it.config?.res?.contentType;\n }\n if ((it.config?.res?.contentType?.toLowerCase().indexOf(Mimes.ApplicationJson.toLowerCase()) ?? -1) > -1) {\n data = JSON.stringify(data);\n } else if (data && typeof data === 'object') {\n data = JSON.stringify(data);\n }\n rr.resSetHeaders(headers)\n rr.resSetStatusCode(status); \n rr.resWrite(data);\n }\n }\n\n if (this.option.noSuchRouteEndPointMappingThrow && methods.length <= 0 && rr.reqMethod()?.toUpperCase() !== HttpMethod.OPTIONS) {\n throw this.option.noSuchRouteEndPointMappingThrow(rr);\n }\n }\n\n // after\n for (const it of filter.filters.reverse()) {\n if (it.filter?.proceedAfter && !await it.filter.proceedAfter({rr, app:this, before: it.sw, carrier: filter.carrier})) {\n break;\n }\n }\n } catch (e) {\n transactionManager?.catch(e);\n rr.resStatusCode(e instanceof HttpError ? e.status : HttpStatus.InternalServerError)\n const execute = typeof this.option.globalAdvice === 'function' ? this.simstanceManager.getOrNewSim(this.option.globalAdvice) : this.option.globalAdvice;\n if (!execute) {\n rr.resEnd();\n // rr.resEnd().catch(e => {\n // });\n return;\n }\n if (e && typeof e === 'object') {\n otherStorage.set(e.constructor as ConstructorType<any>, e);\n otherStorage.set(SituationTypeContainer, new SituationTypeContainer({\n situationType: ExceptionHandlerSituationType.ERROR_OBJECT,\n data: e\n }));\n }\n const target = targetExceptionHandler(execute, e);\n if (target) {\n await this.simstanceManager.executeBindParameterSimPromise({\n target: execute,\n targetKey: target.propertyKey\n }, otherStorage);\n }\n } finally {\n transactionManager?.finally();\n }\n\n if (!rr.resIsDone()) {\n rr.resEnd();\n }\n });\n\n this.server.listen(this.option.listen.port, this.option.listen.hostname, this.option.listen.backlog, () => {\n this.option.listen.listeningListener?.(this, this.server);\n });\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BAAkC;AAClC,8BAAiC;AAEjC,kBAAsE;AACtE,mBAAsC;AACtC,6BAAgC;AAChC,2BAA0F;AAC1F,wBAA2B;AAC3B,yBAA4B;AAC5B,mBAAsB;
|
|
4
|
+
"sourcesContent": ["import { SimpleApplication } from '@dooboostore/simple-boot/SimpleApplication';\nimport { HttpServerOption } from './option/HttpServerOption';\nimport { ConstructorType } from '@dooboostore/core/types';\nimport { IncomingMessage, Server as HttpServer, ServerResponse } from 'http'\nimport { Server as HttpsServer } from 'https'; // Add HTTPS support\nimport { RequestResponse } from './models/RequestResponse';\nimport { getUrlMapping, getUrlMappings, SaveMappingConfig, UrlMappingSituationType } from './decorators/MethodMapping';\nimport { HttpStatus } from './codes/HttpStatus';\nimport { HttpHeaders } from './codes/HttpHeaders';\nimport { Mimes } from './codes/Mimes';\nimport { Filter } from './filters/Filter';\nimport { ExceptionHandlerSituationType, targetExceptionHandler } from '@dooboostore/simple-boot/decorators/exception/ExceptionDecorator';\nimport { getInject, SituationTypeContainer, SituationTypeContainers } from '@dooboostore/simple-boot/decorators/inject/Inject';\nimport { EndPoint } from './endpoints/EndPoint';\nimport { ReflectUtils } from '@dooboostore/core/reflect/ReflectUtils';\nimport { ReqFormUrlBody } from './models/datas/body/ReqFormUrlBody';\nimport { ReqJsonBody } from './models/datas/body/ReqJsonBody';\nimport { ReqHeader } from './models/datas/ReqHeader';\nimport { RouterModule } from '@dooboostore/simple-boot/route/RouterModule';\nimport { ReqMultipartFormBody } from './models/datas/body/ReqMultipartFormBody';\nimport { execValidationInValid, getValidIndex } from '@dooboostore/simple-boot/decorators/validate/Validation';\nimport { ValidException } from '@dooboostore/simple-boot/errors/ValidException';\nimport { HttpError } from './errors/HttpError';\nimport { getRoute } from '@dooboostore/simple-boot/decorators/route/Router';\nimport { OnInit } from './lifecycle/OnInit';\nimport { URLSearchParams } from 'url';\nimport { HttpMethod } from './codes/HttpMethod';\nimport { SessionManager } from './session/SessionManager';\nimport { InjectSituationType } from './inject/InjectSituationType';\n\nexport class SimpleBootHttpServer extends SimpleApplication {\n public server?: HttpServer | HttpsServer;\n private sessionManager: SessionManager;\n constructor(public option: HttpServerOption = new HttpServerOption()) {\n super(option);\n this.sessionManager = new SessionManager(this.option);\n }\n\n\n public run(otherInstanceSim?: Map<ConstructorType<any>, any>) {\n super.run(otherInstanceSim);\n const targets = [...this.option.closeEndPoints ?? [], ...this.option.errorEndPoints ?? [], ...this.option.requestEndPoints ?? [], ...this.option.filters ?? []];\n Promise.all(targets.map(it => (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it as ConstructorType<any>}) : it) as OnInit).map(it => it.onInit(this))).then(it => {\n this.startServer();\n });\n return this;\n }\n\n private startServer() {\n\n // const a = this.option.serverOption as HttpsServerOption;\n // this.option.serverOption?.\n\n if (this.option.serverOption && 'key' in this.option.serverOption && 'cert' in this.option.serverOption) {\n this.server = new HttpsServer(this.option.serverOption);\n const httpServer = new HttpServer();\n httpServer.on('request', (req: IncomingMessage, res: ServerResponse) => {\n res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` });\n res.end();\n });\n httpServer.listen(80, this.option.listen.hostname, () => {\n console.log('HTTP redirect server running on port 80');\n });\n } else if (this.option.serverOption) {\n this.server = new HttpServer(this.option.serverOption);\n } else {\n this.server = new HttpServer();\n }\n // const thisRef = this;\n this.server.on('request', async (req: IncomingMessage, res: ServerResponse) => {\n // console.log('request', req.url);\n const transactionManager = this.option.transactionManagerFactory ? await this.option.transactionManagerFactory() : undefined;\n res.on('close', async () => {\n if (this.option.closeEndPoints) {\n for (const it of this.option.closeEndPoints) {\n try {\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as EndPoint;\n const endPoint = execute?.endPoint(rr, this);\n if (endPoint instanceof Promise) {\n await endPoint;\n }\n } catch (e) {\n }\n }\n }\n\n if (!rr.resIsDone()) {\n rr.resEnd();\n }\n });\n res.on('error', async () => {\n if (this.option.errorEndPoints) {\n for (const it of this.option.errorEndPoints) {\n try {\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as EndPoint;\n const endPoint = execute?.endPoint(rr, this);\n if (endPoint instanceof Promise) {\n await endPoint;\n }\n } catch (e) {\n }\n }\n }\n\n if (!rr.resIsDone()) {\n rr.resEnd();\n }\n });\n\n const rr = new RequestResponse(req, res,{sessionManager: this.sessionManager, option: this.option});\n /*\n default setting first\n */\n rr.resSetHeader(HttpHeaders.Server, 'simple-boot-http-server');\n const cookie = rr.reqCookieGet(this.option.sessionOption.key);\n if (!cookie) {\n const session = await this.sessionManager.session();\n rr.resSetHeader(HttpHeaders.SetCookie, `${this.option.sessionOption.key}=${session.uuid}; Path=/; HttpOnly`);\n }\n\n const otherStorage = new Map<ConstructorType<any>, any>();\n otherStorage.set(RequestResponse, rr);\n otherStorage.set(IncomingMessage, req);\n otherStorage.set(ServerResponse, res);\n try {\n transactionManager?.try();\n if (this.option.requestEndPoints) {\n for (const it of this.option.requestEndPoints) {\n try {\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim<EndPoint>({target:it}) : it) as EndPoint;\n execute?.endPoint(rr, this);\n } catch (e) {\n }\n }\n }\n\n const filter = {\n carrier: new Map<string, any>(),\n filters: [] as { filter: Filter, sw: boolean }[]\n };\n for (let i = 0; this.option.filters && i < this.option.filters.length; i++) {\n const it = this.option.filters[i];\n const execute = (typeof it === 'function' ? this.simstanceManager.getOrNewSim({target:it}) : it) as Filter;\n let sw = true;\n if (execute?.proceedBefore) {\n sw = await execute.proceedBefore({rr, app: this, carrier: filter.carrier});\n filter.filters.push({filter: execute, sw});\n }\n if (!sw) {\n break;\n }\n }\n\n // body.. something..\n if (!rr.resIsDone()) {\n const routerModule = await super.routing(rr.reqIntent);\n otherStorage.set(RouterModule, routerModule);\n const moduleInstance = routerModule?.getModuleInstance?.();\n let methods: SaveMappingConfig[] = [];\n if (routerModule && moduleInstance) {\n // router \uD074\uB798\uC2A4 \uB0B4\uBD80\uC5D0\uC11C \uC120\uC5B8\uB41C Route\uC77C\uB54C\n if (routerModule.propertyKeys) {\n const map = routerModule.propertyKeys?.map((it: string | symbol) => {\n return {propertyKey: it, config: getUrlMapping(moduleInstance, it)} as SaveMappingConfig\n });\n methods.push(...(map ?? []));\n } else {\n methods.push(...(getUrlMappings(moduleInstance).filter(it => !getRoute(moduleInstance, it.propertyKey)) ?? []));\n }\n\n // options\uB85C \uC694\uCCAD\uC624\uBA74\uC740 allow\uB85C \uB123\uACE0 \uADF8\uB0E5 200\uCC98\uB9AC\uD574\uC57C\uB428.\n if (rr.reqMethod()?.toUpperCase() === HttpMethod.OPTIONS.toUpperCase()) {\n rr.resSetHeader(HttpHeaders.Allow, methods.map(it => it.config.method).join(', '));\n rr.resStatusCode(HttpStatus.Ok);\n }\n\n // method \uCC3E\uAE30\n methods = methods.filter(it => it && it.propertyKey && it.config && rr.reqMethod()?.toUpperCase() === it.config.method.toUpperCase());\n methods.sort((a, b) => {\n return ((b.config?.req?.contentType?.length ?? 0) + (b.config?.req?.accept?.length ?? 0)) - ((a.config?.req?.contentType?.length ?? 0) + (a.config?.req?.accept?.length ?? 0));\n });\n methods = methods\n .filter(it => it.config?.req?.contentType ? (!!it.config?.req?.contentType?.find(sit => rr.reqHasContentTypeHeader(sit))) : true)\n .filter(it => it.config?.req?.accept ? (!!it.config?.req?.accept?.find(sit => rr.reqHasAcceptHeader(sit))) : true);\n\n if (methods[0]) {\n const it = methods[0];\n const paramTypes = ReflectUtils.getParameterTypes(moduleInstance, it.propertyKey)\n const injects = getInject(moduleInstance, it.propertyKey);\n const validIndexs = getValidIndex(moduleInstance, it.propertyKey);\n if (injects) {\n const isJson = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_JSON_BODY);\n const isFormUrl = injects.find(it => it.config?.situationType === UrlMappingSituationType.REQ_FORM_URL_BODY);\n const isTransactionManager = injects.find(it => it.config?.situationType === InjectSituationType.TransactionManager);\n const siturationContainers = new SituationTypeContainers();\n if (isJson) {\n let data = await rr.reqBodyJsonData()\n if (isJson.type) {\n data = Object.assign(new isJson.type(), data);\n }\n if (validIndexs.includes(isJson.index)) {\n const inValid = execValidationInValid(data);\n if ((inValid?.length ?? 0) > 0) {\n throw new ValidException(inValid);\n }\n }\n siturationContainers.push(new SituationTypeContainer({\n situationType: UrlMappingSituationType.REQ_JSON_BODY,\n data\n }));\n }\n if (isFormUrl) {\n let data = await rr.reqBodyFormUrlData()\n if (isFormUrl.type) {\n data = Object.assign(new isFormUrl.type(), data);\n }\n if (validIndexs.includes(isFormUrl.index)) {\n const inValid = execValidationInValid(data);\n if ((inValid?.length ?? 0) > 0) {\n throw new ValidException(inValid);\n }\n }\n siturationContainers.push(new SituationTypeContainer({situationType: UrlMappingSituationType.REQ_FORM_URL_BODY, data}));\n }\n\n if (isTransactionManager && isTransactionManager.type && transactionManager && transactionManager.hasTransaction(isTransactionManager.type)) {\n let data = await transactionManager.getTransaction(isTransactionManager.type);\n if (data) {\n data = await data.try(isTransactionManager.config.argument);\n siturationContainers.push(new SituationTypeContainer({situationType: InjectSituationType.TransactionManager, data, index: isTransactionManager.index}));\n }\n }\n if (siturationContainers.length) {\n otherStorage.set(SituationTypeContainers, siturationContainers);\n }\n }\n\n for (const paramType of paramTypes) {\n if (paramType === ReqFormUrlBody) {\n otherStorage.set(ReqFormUrlBody, await rr.reqBodyReqFormUrlBody())\n } else if (paramType === ReqJsonBody) {\n otherStorage.set(ReqJsonBody, await rr.reqBodyReqJsonBody())\n } else if (paramType === URLSearchParams) {\n otherStorage.set(URLSearchParams, rr.reqUrlSearchParams)\n } else if (paramType === ReqMultipartFormBody) {\n otherStorage.set(ReqMultipartFormBody, rr.reqBodyMultipartFormData())\n } else if (paramType === ReqHeader) {\n otherStorage.set(ReqHeader, rr.reqHeaderObj)\n }\n }\n\n // execute !!!\n let data = await this.simstanceManager.executeBindParameterSimPromise({\n target: moduleInstance,\n targetKey: it.propertyKey\n }, otherStorage);\n /*\n \uC5EC\uAE30\uC5D0\uC11C \uC815\uD574\uC9C4 \uD0C0\uC785 \uB9AC\uD134\uC5D0 \uB530\uB978 \uC870\uCE58\n ...\n */\n if (it.config?.resolver) {\n const execute = typeof it.config.resolver === 'function' ? this.simstanceManager.getOrNewSim({target:it.config.resolver}) : it.config.resolver;\n data = await execute?.resolve?.(data, rr);\n }\n const status = it.config?.res?.status ?? HttpStatus.Ok;\n const headers = it.config?.res?.header ?? {};\n if (it.config?.res?.contentType) {\n headers[HttpHeaders.ContentType] = it.config?.res?.contentType;\n }\n if ((it.config?.res?.contentType?.toLowerCase().indexOf(Mimes.ApplicationJson.toLowerCase()) ?? -1) > -1) {\n data = JSON.stringify(data);\n } else if (data && typeof data === 'object') {\n data = JSON.stringify(data);\n }\n rr.resSetHeaders(headers)\n rr.resSetStatusCode(status); \n rr.resWrite(data);\n }\n }\n\n if (this.option.noSuchRouteEndPointMappingThrow && methods.length <= 0 && rr.reqMethod()?.toUpperCase() !== HttpMethod.OPTIONS) {\n throw this.option.noSuchRouteEndPointMappingThrow(rr);\n }\n }\n\n // after\n for (const it of filter.filters.reverse()) {\n if (it.filter?.proceedAfter && !await it.filter.proceedAfter({rr, app:this, before: it.sw, carrier: filter.carrier})) {\n break;\n }\n }\n } catch (e) {\n transactionManager?.catch(e);\n rr.resStatusCode(e instanceof HttpError ? e.status : HttpStatus.InternalServerError)\n const execute = typeof this.option.globalAdvice === 'function' ? this.simstanceManager.getOrNewSim(this.option.globalAdvice) : this.option.globalAdvice;\n if (!execute) {\n rr.resEnd();\n // rr.resEnd().catch(e => {\n // });\n return;\n }\n if (e && typeof e === 'object') {\n otherStorage.set(e.constructor as ConstructorType<any>, e);\n otherStorage.set(SituationTypeContainer, new SituationTypeContainer({\n situationType: ExceptionHandlerSituationType.ERROR_OBJECT,\n data: e\n }));\n }\n const target = targetExceptionHandler(execute, e);\n if (target) {\n await this.simstanceManager.executeBindParameterSimPromise({\n target: execute,\n targetKey: target.propertyKey\n }, otherStorage);\n }\n } finally {\n transactionManager?.finally();\n }\n\n if (!rr.resIsDone()) {\n rr.resEnd();\n }\n });\n\n this.server.listen(this.option.listen.port, this.option.listen.hostname, this.option.listen.backlog, () => {\n this.option.listen.listeningListener?.(this, this.server);\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["HttpsServer", "HttpServer", "it", "data"]
|
|
7
7
|
}
|
|
@@ -27,26 +27,41 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
var ResourceFilter_exports = {};
|
|
29
29
|
__export(ResourceFilter_exports, {
|
|
30
|
-
ResourceFilter: () => ResourceFilter
|
|
30
|
+
ResourceFilter: () => ResourceFilter,
|
|
31
|
+
isDataDist: () => isDataDist,
|
|
32
|
+
isPathDist: () => isPathDist
|
|
31
33
|
});
|
|
32
34
|
module.exports = __toCommonJS(ResourceFilter_exports);
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
+
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
36
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
35
37
|
var import_mime_types = __toESM(require("mime-types"), 1);
|
|
36
38
|
var import_HttpHeaders = require("../codes/HttpHeaders");
|
|
37
39
|
var import_HttpStatus = require("../codes/HttpStatus");
|
|
40
|
+
var import_node_buffer = require("node:buffer");
|
|
41
|
+
const isPathDist = (item) => {
|
|
42
|
+
return typeof item === "object" && "request" in item && "dist" in item;
|
|
43
|
+
};
|
|
44
|
+
const isDataDist = (item) => {
|
|
45
|
+
return typeof item === "object" && "request" in item && "response" in item;
|
|
46
|
+
};
|
|
38
47
|
class ResourceFilter {
|
|
39
|
-
constructor(
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
constructor(resourceDistPathOrResourceRegex, resourceRegex) {
|
|
49
|
+
if (typeof resourceDistPathOrResourceRegex === "string") {
|
|
50
|
+
this.resourceDistPath = resourceDistPathOrResourceRegex;
|
|
51
|
+
this.resources = resourceRegex;
|
|
52
|
+
} else {
|
|
53
|
+
this.resources = resourceDistPathOrResourceRegex;
|
|
54
|
+
}
|
|
42
55
|
}
|
|
56
|
+
// constructor(private resourceDistPath: string, private resourceRegex: (RequestFilterType | { request: RequestFilterType, dist: string | ((rr: RequestResponse, app: SimpleBootHttpServer) => (string|Promise<Blob |ArrayBuffer| Response>)) })[] = []) {
|
|
57
|
+
// }
|
|
43
58
|
async onInit(app) {
|
|
44
59
|
}
|
|
45
60
|
async proceedBefore({ rr, app }) {
|
|
46
61
|
const url = (rr.reqUrlPathName ?? "").replace(/\.\./g, "");
|
|
47
62
|
const urlObj = rr.reqUrlObject;
|
|
48
63
|
let sw = true;
|
|
49
|
-
const regExps = this.
|
|
64
|
+
const regExps = this.resources?.filter((it) => {
|
|
50
65
|
if (it instanceof RegExp) {
|
|
51
66
|
return it.test(url);
|
|
52
67
|
}
|
|
@@ -62,21 +77,44 @@ class ResourceFilter {
|
|
|
62
77
|
}
|
|
63
78
|
return RegExp(it.request).test(url);
|
|
64
79
|
}
|
|
65
|
-
});
|
|
80
|
+
}) ?? [];
|
|
66
81
|
for (const it of regExps) {
|
|
67
|
-
const resourcePath = import_path.default.join(this.resourceDistPath, typeof it === "object" && "dist" in it ? it.dist : urlObj.pathname);
|
|
68
82
|
sw = false;
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
83
|
+
if (isDataDist(it)) {
|
|
84
|
+
let distValue = typeof it.response === "function" ? it.response(rr, app) : it.response;
|
|
85
|
+
if (distValue instanceof Promise) {
|
|
86
|
+
const result = await distValue;
|
|
87
|
+
if (result instanceof Response) {
|
|
88
|
+
await rr.resEnd(result);
|
|
89
|
+
break;
|
|
90
|
+
} else if (result instanceof import_node_buffer.Blob) {
|
|
91
|
+
rr.resStatusCode(import_HttpStatus.HttpStatus.Ok);
|
|
92
|
+
await rr.resEnd(result);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
74
96
|
} else {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
97
|
+
const dist = typeof it === "object" && "dist" in it ? it.dist : urlObj.pathname;
|
|
98
|
+
let distValue = typeof dist === "function" ? dist(rr, app) : dist;
|
|
99
|
+
if (this.resourceDistPath) {
|
|
100
|
+
const resourcePath = import_node_path.default.join(this.resourceDistPath, distValue);
|
|
101
|
+
if (import_node_fs.default.existsSync(resourcePath)) {
|
|
102
|
+
rr.resStatusCode(import_HttpStatus.HttpStatus.Ok);
|
|
103
|
+
rr.resSetHeader(import_HttpHeaders.HttpHeaders.ContentType, import_mime_types.default.lookup(resourcePath).toString());
|
|
104
|
+
await rr.resEnd(import_node_fs.default.readFileSync(resourcePath));
|
|
105
|
+
break;
|
|
106
|
+
} else {
|
|
107
|
+
rr.resStatusCode(import_HttpStatus.HttpStatus.NotFound);
|
|
108
|
+
await rr.resEnd();
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
rr.resStatusCode(import_HttpStatus.HttpStatus.InternalServerError);
|
|
113
|
+
await rr.resEnd();
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
78
116
|
}
|
|
79
|
-
sw =
|
|
117
|
+
sw = true;
|
|
80
118
|
}
|
|
81
119
|
return sw;
|
|
82
120
|
}
|
|
@@ -86,6 +124,8 @@ class ResourceFilter {
|
|
|
86
124
|
}
|
|
87
125
|
// Annotate the CommonJS export names for ESM import in node:
|
|
88
126
|
0 && (module.exports = {
|
|
89
|
-
ResourceFilter
|
|
127
|
+
ResourceFilter,
|
|
128
|
+
isDataDist,
|
|
129
|
+
isPathDist
|
|
90
130
|
});
|
|
91
131
|
//# sourceMappingURL=ResourceFilter.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/filters/ResourceFilter.ts"],
|
|
4
|
-
"sourcesContent": ["import { Filter } from '../filters/Filter';\nimport fs from 'fs';\nimport path from 'path';\nimport mime from 'mime-types';\nimport { HttpHeaders } from '../codes/HttpHeaders';\nimport { HttpStatus } from '../codes/HttpStatus';\nimport { SimpleBootHttpServer } from '../SimpleBootHttpServer';\nimport { RequestResponse } from '../models/RequestResponse';\n\nexport type RequestFilterType = string | RegExp | ((rr: RequestResponse, app: SimpleBootHttpServer) => boolean) | ((rr: RequestResponse, app: SimpleBootHttpServer) => Promise<boolean>);\n\nexport class ResourceFilter implements Filter {\n constructor(private resourceDistPath: string, private resourceRegex: (RequestFilterType | { request: RequestFilterType, dist: string })[] = []) {\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,
|
|
4
|
+
"sourcesContent": ["import { Filter } from '../filters/Filter';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport mime from 'mime-types';\nimport { HttpHeaders } from '../codes/HttpHeaders';\nimport { HttpStatus } from '../codes/HttpStatus';\nimport { SimpleBootHttpServer } from '../SimpleBootHttpServer';\nimport { RequestResponse } from '../models/RequestResponse';\nimport { Blob } from 'node:buffer';\n\nexport type RequestFilterType = string | RegExp | ((rr: RequestResponse, app: SimpleBootHttpServer) => boolean) | ((rr: RequestResponse, app: SimpleBootHttpServer) => Promise<boolean>);\n\ntype PathDist = RequestFilterType|{request: RequestFilterType, dist: string | ((rr: RequestResponse, app: SimpleBootHttpServer) => string)};\n\ntype DataDist = {request: RequestFilterType, response: (rr: RequestResponse, app: SimpleBootHttpServer) => (string | Promise<Blob | ArrayBuffer | Response>)};\nexport const isPathDist = (item: any): item is PathDist => {\n return typeof item === 'object' && ('request' in item) && ('dist' in item);\n};\nexport const isDataDist = (item: any): item is DataDist => {\n return typeof item === 'object' && ('request' in item) && ('response' in item);\n};\nexport class ResourceFilter implements Filter {\n // private requestFilter: RequestFilterType;\n private resourceDistPath?: string;\n private resources?: (DataDist|PathDist)[];\n constructor(resourceDistPath: string, resourceRegex: PathDist[]);\n constructor(resourceRegex: DataDist[]);\n constructor(resourceDistPathOrResourceRegex: string | DataDist[], resourceRegex?: PathDist[]) {\n if (typeof resourceDistPathOrResourceRegex === 'string') {\n this.resourceDistPath = resourceDistPathOrResourceRegex;\n this.resources = resourceRegex;\n } else {\n this.resources = resourceDistPathOrResourceRegex;\n // this.requestFilter = resourceDistPathOrResourceRegex\n }\n }\n // constructor(private resourceDistPath: string, private resourceRegex: (RequestFilterType | { request: RequestFilterType, dist: string | ((rr: RequestResponse, app: SimpleBootHttpServer) => (string|Promise<Blob |ArrayBuffer| Response>)) })[] = []) {\n // }\n\n async onInit(app: SimpleBootHttpServer) {\n }\n\n async proceedBefore({rr, app}: {rr: RequestResponse, app: SimpleBootHttpServer, carrier: Map<string, any>}) {\n const url = (rr.reqUrlPathName ?? '').replace(/\\.\\./g, '');\n const urlObj = rr.reqUrlObject;\n // const requestUrl = parse(rr.reqUrl ?? '', true);\n // console.log('resource filter!!**-------', url);\n let sw = true;\n const regExps = this.resources?.filter(it => {\n if (it instanceof RegExp) {\n return it.test(url);\n }\n\n if (typeof it === 'string') {\n return RegExp(it).test(url);\n }\n\n if (typeof it === 'function') {\n return it(rr, app);\n }\n\n if (typeof it === 'object' && 'request' in it) {\n if (typeof it.request === 'function') {\n return it.request(rr, app);\n }\n return RegExp(it.request).test(url);\n }\n })??[]\n // console.log('regExps', regExps, url);\n // eslint-disable-next-line no-unused-vars\n for (const it of regExps) {\n sw = false;\n //DataDist\n if (isDataDist(it)) {\n let distValue = typeof it.response === 'function' ? it.response(rr,app) : it.response;\n if (distValue instanceof Promise) {\n const result = await distValue;\n if (result instanceof Response) {\n await rr.resEnd(result);\n break;\n } else if (result instanceof Blob) {\n rr.resStatusCode(HttpStatus.Ok);\n await rr.resEnd(result);\n break;\n }\n }\n } else {\n //PathDist or undefined\n const dist = typeof it === 'object' && 'dist' in it ? it.dist : urlObj.pathname;\n let distValue = typeof dist === 'function' ? dist(rr, app) : dist;\n if (this.resourceDistPath) {\n // It's a string path\n const resourcePath = path.join(this.resourceDistPath, distValue);\n if (fs.existsSync(resourcePath)) {\n rr.resStatusCode(HttpStatus.Ok);\n rr.resSetHeader(HttpHeaders.ContentType, mime.lookup(resourcePath).toString());\n await rr.resEnd(fs.readFileSync(resourcePath));\n break;\n } else {\n rr.resStatusCode(HttpStatus.NotFound);\n await rr.resEnd();\n break;\n }\n } else {\n rr.resStatusCode(HttpStatus.InternalServerError);\n await rr.resEnd();\n break;\n }\n }\n sw = true;\n }\n return sw;\n }\n\n async proceedAfter({rr, app}: {rr: RequestResponse, app: SimpleBootHttpServer, carrier: Map<string, any>}) {\n // console.log('resource filter!!end@@**-------');\n return true;\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["path", "fs", "mime"]
|
|
7
7
|
}
|
|
@@ -29,6 +29,7 @@ var import_ReqFormUrlBody = require("./datas/body/ReqFormUrlBody");
|
|
|
29
29
|
var import_ReqJsonBody = require("./datas/body/ReqJsonBody");
|
|
30
30
|
var import_ReqHeader = require("./datas/ReqHeader");
|
|
31
31
|
var import_node_gzip = require("node-gzip");
|
|
32
|
+
var import_node_buffer = require("node:buffer");
|
|
32
33
|
var import_FileUtils = require("@dooboostore/core-node/file/FileUtils");
|
|
33
34
|
var import_ConvertUtils = require("@dooboostore/core/convert/ConvertUtils");
|
|
34
35
|
var import_ConvertUtils2 = require("@dooboostore/core-node/convert/ConvertUtils");
|
|
@@ -427,7 +428,28 @@ class RequestResponse {
|
|
|
427
428
|
this.res.end(data);
|
|
428
429
|
}
|
|
429
430
|
async resEnd(chunk) {
|
|
430
|
-
|
|
431
|
+
if (chunk instanceof Response) {
|
|
432
|
+
chunk.headers.forEach((value, key) => {
|
|
433
|
+
this.res.setHeader(`ORIGIN-${key}`, value);
|
|
434
|
+
});
|
|
435
|
+
if (!this.resHeader(import_HttpHeaders.HttpHeaders.ContentType)) {
|
|
436
|
+
const contentType = chunk.headers.get(import_HttpHeaders.HttpHeaders.ContentType);
|
|
437
|
+
if (contentType) {
|
|
438
|
+
this.res.setHeader(import_HttpHeaders.HttpHeaders.ContentType, contentType);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
this.res.statusCode = chunk.status;
|
|
442
|
+
this.resWriteChunk = import_buffer.Buffer.from(await chunk.arrayBuffer());
|
|
443
|
+
} else if (chunk instanceof import_node_buffer.Blob) {
|
|
444
|
+
this.resWriteChunk = import_buffer.Buffer.from(await chunk.arrayBuffer());
|
|
445
|
+
if (!this.resHeader(import_HttpHeaders.HttpHeaders.ContentType)) {
|
|
446
|
+
this.res.setHeader(import_HttpHeaders.HttpHeaders.ContentType, chunk.type);
|
|
447
|
+
}
|
|
448
|
+
} else if (chunk instanceof ArrayBuffer) {
|
|
449
|
+
this.resWriteChunk = import_buffer.Buffer.from(chunk);
|
|
450
|
+
} else {
|
|
451
|
+
this.resWriteChunk = chunk ?? this.resWriteChunk;
|
|
452
|
+
}
|
|
431
453
|
if (this.req.readable) {
|
|
432
454
|
await this.reqBodyData();
|
|
433
455
|
await this.resEndChunk();
|