@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.
Files changed (29) hide show
  1. package/README.MD +24 -248
  2. package/dist/cjs/SimpleBootHttpServer.js +2 -2
  3. package/dist/cjs/SimpleBootHttpServer.js.map +2 -2
  4. package/dist/cjs/filters/ResourceFilter.js +59 -19
  5. package/dist/cjs/filters/ResourceFilter.js.map +2 -2
  6. package/dist/cjs/models/RequestResponse.js +23 -1
  7. package/dist/cjs/models/RequestResponse.js.map +2 -2
  8. package/dist/cjs/package.json +5 -0
  9. package/dist/esm/SimpleBootHttpServer.js +2 -2
  10. package/dist/esm/SimpleBootHttpServer.js.map +2 -2
  11. package/dist/esm/filters/ResourceFilter.js +56 -18
  12. package/dist/esm/filters/ResourceFilter.js.map +2 -2
  13. package/dist/esm/models/RequestResponse.js +23 -1
  14. package/dist/esm/models/RequestResponse.js.map +2 -2
  15. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +166 -149
  16. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +4 -4
  17. package/dist/types/SimpleBootHttpServer.d.ts +1 -2
  18. package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
  19. package/dist/types/filters/ResourceFilter.d.ts +16 -6
  20. package/dist/types/filters/ResourceFilter.d.ts.map +1 -1
  21. package/dist/types/index.d.ts +0 -38
  22. package/dist/types/models/RequestResponse.d.ts +2 -1
  23. package/dist/types/models/RequestResponse.d.ts.map +1 -1
  24. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +173 -156
  25. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +4 -4
  26. package/package.json +16 -15
  27. package/src/SimpleBootHttpServer.ts +2 -3
  28. package/src/filters/ResourceFilter.ts +67 -20
  29. 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.20",
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
- ">=4.2": {
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 && cp package.cjs.json dist/cjs/package.json",
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
- const simstanceManager = super.run(otherInstanceSim);
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 simstanceManager;
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
- constructor(private resourceDistPath: string, private resourceRegex: (RequestFilterType | { request: RequestFilterType, dist: string })[] = []) {
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.resourceRegex.filter(it => {
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, this.resourceRegex);
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
- // console.log('-----', resourcePath);
51
- if (fs.existsSync(resourcePath)) {
52
- // const header = {} as any;
53
- // header[HttpHeaders.ContentType] = mime.lookup(resourcePath);
54
- // res.writeHead(HttpStatus.Ok, header);
55
- rr.resStatusCode(HttpStatus.Ok);
56
- rr.resSetHeader(HttpHeaders.ContentType, mime.lookup(resourcePath).toString());
57
- await rr.resEnd(fs.readFileSync(resourcePath));
58
- break;
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
- rr.resStatusCode(HttpStatus.NotFound)
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
- sw = false;
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
- this.resWriteChunk = chunk ?? this.resWriteChunk;
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();