@dooboostore/simple-boot-http-server 1.0.21 → 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/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@dooboostore/simple-boot-http-server",
3
- "version": "1.0.21",
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.22",
67
- "@dooboostore/core-node": "1.0.8",
68
- "@dooboostore/core-web": "1.0.7",
69
- "@dooboostore/dom-render": "1.0.109",
70
- "@dooboostore/simple-boot": "1.0.51"
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,7 +85,17 @@
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",
@@ -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();