@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/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dooboostore/simple-boot-http-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.22",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
7
7
|
"module": "./dist/esm/index.js",
|
|
8
8
|
"types": "./dist/types/index.d.ts",
|
|
9
9
|
"typesVersions": {
|
|
10
|
-
"
|
|
10
|
+
"*": {
|
|
11
11
|
"*": [
|
|
12
12
|
"dist/types/*"
|
|
13
13
|
]
|
|
@@ -62,17 +62,7 @@
|
|
|
62
62
|
"url": "https://github.com/dooboostore-develop/packages"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
-
"reflect-metadata": "^0.2.2"
|
|
66
|
-
"@dooboostore/core": "1.0.21",
|
|
67
|
-
"@dooboostore/simple-boot": "1.0.49",
|
|
68
|
-
"@dooboostore/core-node": "1.0.7",
|
|
69
|
-
"@dooboostore/dom-render": "1.0.108",
|
|
70
|
-
"@dooboostore/core-web": "1.0.6"
|
|
71
|
-
},
|
|
72
|
-
"dependencies": {
|
|
73
|
-
"fast-json-patch": "^3.1.0",
|
|
74
|
-
"mime-types": "^2.1.34",
|
|
75
|
-
"node-gzip": "^1.1.2"
|
|
65
|
+
"reflect-metadata": "^0.2.2"
|
|
76
66
|
},
|
|
77
67
|
"devDependencies": {
|
|
78
68
|
"@babel/core": "^7.24.0",
|
|
@@ -95,19 +85,30 @@
|
|
|
95
85
|
"typescript": "^5.9.2",
|
|
96
86
|
"@types/node-gzip": "^1.1.0",
|
|
97
87
|
"esbuild-plugin-tsc": "^0.5.0",
|
|
98
|
-
"esbuild": "^0.23.0"
|
|
88
|
+
"esbuild": "^0.23.0",
|
|
89
|
+
"@dooboostore/core": "1.0.26",
|
|
90
|
+
"@dooboostore/core-node": "1.0.9",
|
|
91
|
+
"@dooboostore/dom-render": "1.0.110",
|
|
92
|
+
"@dooboostore/core-web": "1.0.8",
|
|
93
|
+
"@dooboostore/simple-boot": "1.0.52"
|
|
94
|
+
},
|
|
95
|
+
"dependencies": {
|
|
96
|
+
"fast-json-patch": "^3.1.0",
|
|
97
|
+
"mime-types": "^2.1.34",
|
|
98
|
+
"node-gzip": "^1.1.2"
|
|
99
99
|
},
|
|
100
100
|
"scripts": {
|
|
101
101
|
"clean": "rm -rf dist",
|
|
102
102
|
"build:esm": "node build.mjs esm",
|
|
103
103
|
"watch:esm": "pnpm run build:esm && node build.mjs esm --watch",
|
|
104
|
-
"build:cjs": "node build.mjs cjs
|
|
104
|
+
"build:cjs": "node build.mjs cjs",
|
|
105
105
|
"watch:cjs": "pnpm run build:cjs && node build.mjs cjs --watch",
|
|
106
106
|
"build": "pnpm run clean && node build.mjs all",
|
|
107
107
|
"build:umd-bundle": "node build.mjs umd-bundle",
|
|
108
108
|
"watch:umd-bundle": "pnpm run build:umd-bundle && node build.mjs umd-bundle --watch",
|
|
109
109
|
"build:esm-bundle": "node build.mjs esm-bundle",
|
|
110
110
|
"watch:esm-bundle": "pnpm run build:esm-bundle && node build.mjs esm-bundle --watch",
|
|
111
|
+
"watch": "node build.mjs all --watch",
|
|
111
112
|
"publish:npm": "pnpm run build && cp package.json package.json.back && pnpm pack && TARBALL_NAME=$(ls dooboostore-simple-boot-http-server-*.tgz | head -n 1) && tar -xzf \"$TARBALL_NAME\" -C . --strip-components=1 package/package.json && rm \"$TARBALL_NAME\" && (pnpm publish --no-git-checks || true) && cp package.json.back package.json && rm -rf package.json.back ",
|
|
112
113
|
"ts:clean": "find . -name '*.js' -o -name '*.map' -o -name '*.d.ts' | xargs rm -f",
|
|
113
114
|
"typecheck": "tsc --noEmit",
|
|
@@ -9,7 +9,6 @@ import { HttpStatus } from './codes/HttpStatus';
|
|
|
9
9
|
import { HttpHeaders } from './codes/HttpHeaders';
|
|
10
10
|
import { Mimes } from './codes/Mimes';
|
|
11
11
|
import { Filter } from './filters/Filter';
|
|
12
|
-
import { SimstanceManager } from '@dooboostore/simple-boot/simstance/SimstanceManager';
|
|
13
12
|
import { ExceptionHandlerSituationType, targetExceptionHandler } from '@dooboostore/simple-boot/decorators/exception/ExceptionDecorator';
|
|
14
13
|
import { getInject, SituationTypeContainer, SituationTypeContainers } from '@dooboostore/simple-boot/decorators/inject/Inject';
|
|
15
14
|
import { EndPoint } from './endpoints/EndPoint';
|
|
@@ -39,12 +38,12 @@ export class SimpleBootHttpServer extends SimpleApplication {
|
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
public run(otherInstanceSim?: Map<ConstructorType<any>, any>) {
|
|
42
|
-
|
|
41
|
+
super.run(otherInstanceSim);
|
|
43
42
|
const targets = [...this.option.closeEndPoints ?? [], ...this.option.errorEndPoints ?? [], ...this.option.requestEndPoints ?? [], ...this.option.filters ?? []];
|
|
44
43
|
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 => {
|
|
45
44
|
this.startServer();
|
|
46
45
|
});
|
|
47
|
-
return
|
|
46
|
+
return this;
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
private startServer() {
|
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
import { Filter } from '../filters/Filter';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
import mime from 'mime-types';
|
|
5
5
|
import { HttpHeaders } from '../codes/HttpHeaders';
|
|
6
6
|
import { HttpStatus } from '../codes/HttpStatus';
|
|
7
7
|
import { SimpleBootHttpServer } from '../SimpleBootHttpServer';
|
|
8
8
|
import { RequestResponse } from '../models/RequestResponse';
|
|
9
|
+
import { Blob } from 'node:buffer';
|
|
9
10
|
|
|
10
11
|
export type RequestFilterType = string | RegExp | ((rr: RequestResponse, app: SimpleBootHttpServer) => boolean) | ((rr: RequestResponse, app: SimpleBootHttpServer) => Promise<boolean>);
|
|
11
12
|
|
|
13
|
+
type PathDist = RequestFilterType|{request: RequestFilterType, dist: string | ((rr: RequestResponse, app: SimpleBootHttpServer) => string)};
|
|
14
|
+
|
|
15
|
+
type DataDist = {request: RequestFilterType, response: (rr: RequestResponse, app: SimpleBootHttpServer) => (string | Promise<Blob | ArrayBuffer | Response>)};
|
|
16
|
+
export const isPathDist = (item: any): item is PathDist => {
|
|
17
|
+
return typeof item === 'object' && ('request' in item) && ('dist' in item);
|
|
18
|
+
};
|
|
19
|
+
export const isDataDist = (item: any): item is DataDist => {
|
|
20
|
+
return typeof item === 'object' && ('request' in item) && ('response' in item);
|
|
21
|
+
};
|
|
12
22
|
export class ResourceFilter implements Filter {
|
|
13
|
-
|
|
23
|
+
// private requestFilter: RequestFilterType;
|
|
24
|
+
private resourceDistPath?: string;
|
|
25
|
+
private resources?: (DataDist|PathDist)[];
|
|
26
|
+
constructor(resourceDistPath: string, resourceRegex: PathDist[]);
|
|
27
|
+
constructor(resourceRegex: DataDist[]);
|
|
28
|
+
constructor(resourceDistPathOrResourceRegex: string | DataDist[], resourceRegex?: PathDist[]) {
|
|
29
|
+
if (typeof resourceDistPathOrResourceRegex === 'string') {
|
|
30
|
+
this.resourceDistPath = resourceDistPathOrResourceRegex;
|
|
31
|
+
this.resources = resourceRegex;
|
|
32
|
+
} else {
|
|
33
|
+
this.resources = resourceDistPathOrResourceRegex;
|
|
34
|
+
// this.requestFilter = resourceDistPathOrResourceRegex
|
|
14
35
|
}
|
|
36
|
+
}
|
|
37
|
+
// constructor(private resourceDistPath: string, private resourceRegex: (RequestFilterType | { request: RequestFilterType, dist: string | ((rr: RequestResponse, app: SimpleBootHttpServer) => (string|Promise<Blob |ArrayBuffer| Response>)) })[] = []) {
|
|
38
|
+
// }
|
|
15
39
|
|
|
16
40
|
async onInit(app: SimpleBootHttpServer) {
|
|
17
41
|
}
|
|
@@ -20,8 +44,9 @@ export class ResourceFilter implements Filter {
|
|
|
20
44
|
const url = (rr.reqUrlPathName ?? '').replace(/\.\./g, '');
|
|
21
45
|
const urlObj = rr.reqUrlObject;
|
|
22
46
|
// const requestUrl = parse(rr.reqUrl ?? '', true);
|
|
47
|
+
// console.log('resource filter!!**-------', url);
|
|
23
48
|
let sw = true;
|
|
24
|
-
const regExps = this.
|
|
49
|
+
const regExps = this.resources?.filter(it => {
|
|
25
50
|
if (it instanceof RegExp) {
|
|
26
51
|
return it.test(url);
|
|
27
52
|
}
|
|
@@ -40,33 +65,55 @@ export class ResourceFilter implements Filter {
|
|
|
40
65
|
}
|
|
41
66
|
return RegExp(it.request).test(url);
|
|
42
67
|
}
|
|
43
|
-
})
|
|
44
|
-
// console.log('regExps', regExps, url
|
|
68
|
+
})??[]
|
|
69
|
+
// console.log('regExps', regExps, url);
|
|
45
70
|
// eslint-disable-next-line no-unused-vars
|
|
46
71
|
for (const it of regExps) {
|
|
47
|
-
const resourcePath = path.join(this.resourceDistPath, typeof it === 'object' && 'dist' in it ? it.dist : urlObj.pathname);
|
|
48
|
-
// console.log('ResourceFilter', resourcePath, it, urlObj.pathname, url);
|
|
49
72
|
sw = false;
|
|
50
|
-
//
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
73
|
+
//DataDist
|
|
74
|
+
if (isDataDist(it)) {
|
|
75
|
+
let distValue = typeof it.response === 'function' ? it.response(rr,app) : it.response;
|
|
76
|
+
if (distValue instanceof Promise) {
|
|
77
|
+
const result = await distValue;
|
|
78
|
+
if (result instanceof Response) {
|
|
79
|
+
await rr.resEnd(result);
|
|
80
|
+
break;
|
|
81
|
+
} else if (result instanceof Blob) {
|
|
82
|
+
rr.resStatusCode(HttpStatus.Ok);
|
|
83
|
+
await rr.resEnd(result);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
59
87
|
} else {
|
|
60
|
-
|
|
88
|
+
//PathDist or undefined
|
|
89
|
+
const dist = typeof it === 'object' && 'dist' in it ? it.dist : urlObj.pathname;
|
|
90
|
+
let distValue = typeof dist === 'function' ? dist(rr, app) : dist;
|
|
91
|
+
if (this.resourceDistPath) {
|
|
92
|
+
// It's a string path
|
|
93
|
+
const resourcePath = path.join(this.resourceDistPath, distValue);
|
|
94
|
+
if (fs.existsSync(resourcePath)) {
|
|
95
|
+
rr.resStatusCode(HttpStatus.Ok);
|
|
96
|
+
rr.resSetHeader(HttpHeaders.ContentType, mime.lookup(resourcePath).toString());
|
|
97
|
+
await rr.resEnd(fs.readFileSync(resourcePath));
|
|
98
|
+
break;
|
|
99
|
+
} else {
|
|
100
|
+
rr.resStatusCode(HttpStatus.NotFound);
|
|
101
|
+
await rr.resEnd();
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
rr.resStatusCode(HttpStatus.InternalServerError);
|
|
61
106
|
await rr.resEnd();
|
|
62
107
|
break;
|
|
108
|
+
}
|
|
63
109
|
}
|
|
64
|
-
|
|
110
|
+
sw = true;
|
|
65
111
|
}
|
|
66
112
|
return sw;
|
|
67
113
|
}
|
|
68
114
|
|
|
69
115
|
async proceedAfter({rr, app}: {rr: RequestResponse, app: SimpleBootHttpServer, carrier: Map<string, any>}) {
|
|
116
|
+
// console.log('resource filter!!end@@**-------');
|
|
70
117
|
return true;
|
|
71
118
|
}
|
|
72
|
-
}
|
|
119
|
+
}
|
|
@@ -13,6 +13,7 @@ import { HttpStatus } from '../codes/HttpStatus';
|
|
|
13
13
|
import { gzip } from 'node-gzip';
|
|
14
14
|
import { SessionManager } from '../session/SessionManager';
|
|
15
15
|
import { HttpServerOption } from '../option/HttpServerOption';
|
|
16
|
+
import { Blob } from 'node:buffer';
|
|
16
17
|
import * as fs from 'fs';
|
|
17
18
|
import * as os from 'os';
|
|
18
19
|
import { RandomUtils } from '@dooboostore/core/random/RandomUtils';
|
|
@@ -595,8 +596,31 @@ export class RequestResponse {
|
|
|
595
596
|
this.res.end(data);
|
|
596
597
|
}
|
|
597
598
|
|
|
598
|
-
async resEnd(chunk?: string | Buffer) {
|
|
599
|
-
|
|
599
|
+
async resEnd(chunk?: string | Buffer | Blob | ArrayBuffer | Response) {
|
|
600
|
+
if (chunk instanceof Response) {
|
|
601
|
+
// 헤더를 직접 설정하여 체이닝 오버헤드 제거
|
|
602
|
+
chunk.headers.forEach((value, key) => {
|
|
603
|
+
this.res.setHeader(`ORIGIN-${key}`, value);
|
|
604
|
+
});
|
|
605
|
+
if (!this.resHeader(HttpHeaders.ContentType)) {
|
|
606
|
+
const contentType = chunk.headers.get(HttpHeaders.ContentType);
|
|
607
|
+
if (contentType) {
|
|
608
|
+
this.res.setHeader(HttpHeaders.ContentType, contentType);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
this.res.statusCode = chunk.status;
|
|
612
|
+
this.resWriteChunk = Buffer.from(await chunk.arrayBuffer());
|
|
613
|
+
} else if (chunk instanceof Blob) {
|
|
614
|
+
this.resWriteChunk = Buffer.from(await chunk.arrayBuffer());
|
|
615
|
+
if (!this.resHeader(HttpHeaders.ContentType)) {
|
|
616
|
+
this.res.setHeader(HttpHeaders.ContentType, chunk.type);
|
|
617
|
+
}
|
|
618
|
+
} else if (chunk instanceof ArrayBuffer) {
|
|
619
|
+
this.resWriteChunk = Buffer.from(chunk);
|
|
620
|
+
} else {
|
|
621
|
+
this.resWriteChunk = chunk ?? this.resWriteChunk;
|
|
622
|
+
}
|
|
623
|
+
|
|
600
624
|
if (this.req.readable) {
|
|
601
625
|
await this.reqBodyData();
|
|
602
626
|
await this.resEndChunk();
|