@dooboostore/simple-boot-http-server 1.0.31 → 1.0.33

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/dist/cjs/SimpleBootHttpServer.js +2 -1
  2. package/dist/cjs/SimpleBootHttpServer.js.map +2 -2
  3. package/dist/cjs/decorators/MethodMapping.js +9 -0
  4. package/dist/cjs/decorators/MethodMapping.js.map +2 -2
  5. package/dist/cjs/models/RequestResponse.js +15 -2
  6. package/dist/cjs/models/RequestResponse.js.map +2 -2
  7. package/dist/cjs/option/HttpServerOption.js +2 -1
  8. package/dist/cjs/option/HttpServerOption.js.map +2 -2
  9. package/dist/esm/SimpleBootHttpServer.js +2 -1
  10. package/dist/esm/SimpleBootHttpServer.js.map +2 -2
  11. package/dist/esm/decorators/MethodMapping.js +9 -0
  12. package/dist/esm/decorators/MethodMapping.js.map +2 -2
  13. package/dist/esm/models/RequestResponse.js +15 -2
  14. package/dist/esm/models/RequestResponse.js.map +2 -2
  15. package/dist/esm/option/HttpServerOption.js +2 -1
  16. package/dist/esm/option/HttpServerOption.js.map +2 -2
  17. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +64 -23
  18. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +2 -2
  19. package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
  20. package/dist/types/decorators/MethodMapping.d.ts.map +1 -1
  21. package/dist/types/models/RequestResponse.d.ts.map +1 -1
  22. package/dist/types/option/HttpServerOption.d.ts.map +1 -1
  23. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +64 -23
  24. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +2 -2
  25. package/package.json +3 -3
  26. package/src/SimpleBootHttpServer.ts +4 -1
  27. package/src/decorators/MethodMapping.ts +9 -0
  28. package/src/models/RequestResponse.ts +18 -2
  29. package/src/option/HttpServerOption.ts +8 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dooboostore/simple-boot-http-server",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -101,8 +101,8 @@
101
101
  "@dooboostore/core": "1.0.33",
102
102
  "@dooboostore/dom-render": "1.0.115",
103
103
  "@dooboostore/core-node": "1.0.14",
104
- "@dooboostore/simple-boot": "1.0.59",
105
- "@dooboostore/core-web": "1.0.14"
104
+ "@dooboostore/core-web": "1.0.14",
105
+ "@dooboostore/simple-boot": "1.0.60"
106
106
  },
107
107
  "scripts": {
108
108
  "clean": "rm -rf dist",
@@ -390,7 +390,10 @@ export class SimpleBootHttpServer extends SimpleApplication {
390
390
  console.error('request error:', e);
391
391
  transactionManager?.catch(e);
392
392
  rr.resStatusCode(e instanceof HttpError ? e.status : HttpStatus.InternalServerError)
393
- const execute = typeof this.option.globalAdvice === 'function' ? this.simstanceManager.getOrNewSim(this.option.globalAdvice) : this.option.globalAdvice;
393
+ const globalAdvice = this.option.globalAdvice;
394
+ // getOrNewSim takes { target }; passing the class directly
395
+ // destructures to undefined and silently disables globalAdvice.
396
+ const execute = typeof globalAdvice === 'function' ? this.simstanceManager.getOrNewSim({ target: globalAdvice }) : globalAdvice;
394
397
  if (!execute) {
395
398
  rr.resEnd();
396
399
  // rr.resEnd().catch(e => {
@@ -69,6 +69,7 @@ export function GET(configOrTarget?: Omit<MappingConfig, 'method'> | any, proper
69
69
  process({ method: HttpMethod.GET }, configOrTarget, propertyKey, descriptor);
70
70
  } else {
71
71
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
72
+ configOrTarget = configOrTarget ?? {};
72
73
  configOrTarget.method = HttpMethod.GET;
73
74
  process(configOrTarget, target, propertyKey, descriptor);
74
75
  };
@@ -88,6 +89,7 @@ export function POST(configOrTarget?: Omit<MappingConfig, 'method'> | any, prope
88
89
  process({ method: HttpMethod.POST }, configOrTarget, propertyKey, descriptor);
89
90
  } else {
90
91
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
92
+ configOrTarget = configOrTarget ?? {};
91
93
  configOrTarget.method = HttpMethod.POST;
92
94
  process(configOrTarget, target, propertyKey, descriptor);
93
95
  };
@@ -107,6 +109,7 @@ export function DELETE(configOrTarget?: Omit<MappingConfig, 'method'> | any, pro
107
109
  process({ method: HttpMethod.DELETE }, configOrTarget, propertyKey, descriptor);
108
110
  } else {
109
111
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
112
+ configOrTarget = configOrTarget ?? {};
110
113
  configOrTarget.method = HttpMethod.DELETE;
111
114
  process(configOrTarget, target, propertyKey, descriptor);
112
115
  };
@@ -126,6 +129,7 @@ export function PUT(configOrTarget?: Omit<MappingConfig, 'method'> | any, proper
126
129
  process({ method: HttpMethod.PUT }, configOrTarget, propertyKey, descriptor);
127
130
  } else {
128
131
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
132
+ configOrTarget = configOrTarget ?? {};
129
133
  configOrTarget.method = HttpMethod.PUT;
130
134
  process(configOrTarget, target, propertyKey, descriptor);
131
135
  };
@@ -145,6 +149,7 @@ export function PATCH(configOrTarget?: Omit<MappingConfig, 'method'> | any, prop
145
149
  process({ method: HttpMethod.PATCH }, configOrTarget, propertyKey, descriptor);
146
150
  } else {
147
151
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
152
+ configOrTarget = configOrTarget ?? {};
148
153
  configOrTarget.method = HttpMethod.PATCH;
149
154
  process(configOrTarget, target, propertyKey, descriptor);
150
155
  };
@@ -164,6 +169,7 @@ export function OPTIONS(configOrTarget?: Omit<MappingConfig, 'method'> | any, pr
164
169
  process({ method: HttpMethod.OPTIONS }, configOrTarget, propertyKey, descriptor);
165
170
  } else {
166
171
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
172
+ configOrTarget = configOrTarget ?? {};
167
173
  configOrTarget.method = HttpMethod.OPTIONS;
168
174
  process(configOrTarget, target, propertyKey, descriptor);
169
175
  };
@@ -183,6 +189,7 @@ export function HEAD(configOrTarget?: Omit<MappingConfig, 'method'> | any, prope
183
189
  process({ method: HttpMethod.HEAD }, configOrTarget, propertyKey, descriptor);
184
190
  } else {
185
191
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
192
+ configOrTarget = configOrTarget ?? {};
186
193
  configOrTarget.method = HttpMethod.HEAD;
187
194
  process(configOrTarget, target, propertyKey, descriptor);
188
195
  };
@@ -202,6 +209,7 @@ export function TRACE(configOrTarget?: Omit<MappingConfig, 'method'> | any, prop
202
209
  process({ method: HttpMethod.TRACE }, configOrTarget, propertyKey, descriptor);
203
210
  } else {
204
211
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
212
+ configOrTarget = configOrTarget ?? {};
205
213
  configOrTarget.method = HttpMethod.TRACE;
206
214
  process(configOrTarget, target, propertyKey, descriptor);
207
215
  };
@@ -221,6 +229,7 @@ export function CONNECT(configOrTarget?: Omit<MappingConfig, 'method'> | any, pr
221
229
  process({ method: HttpMethod.CONNECT }, configOrTarget, propertyKey, descriptor);
222
230
  } else {
223
231
  return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
232
+ configOrTarget = configOrTarget ?? {};
224
233
  configOrTarget.method = HttpMethod.CONNECT;
225
234
  process(configOrTarget, target, propertyKey, descriptor);
226
235
  };
@@ -22,6 +22,7 @@ import { FileUtils } from '@dooboostore/core-node';
22
22
  import { ConvertUtils as CoreConvertUtils } from '@dooboostore/core';
23
23
  import { ConvertUtils } from '@dooboostore/core-node';
24
24
  import {HttpMethod} from "../codes";
25
+ import { BadRequestError } from '../errors/BadRequestError';
25
26
 
26
27
  type Config = { sessionManager?: SessionManager; option: HttpServerOption };
27
28
 
@@ -346,7 +347,14 @@ export class RequestResponse {
346
347
  }
347
348
 
348
349
  async reqBodyJsonData<T>(): Promise<T> {
349
- return JSON.parse(await this.reqBodyStringData());
350
+ const raw = await this.reqBodyStringData();
351
+ try {
352
+ return JSON.parse(raw);
353
+ } catch (e: any) {
354
+ // Malformed JSON is a client error (400), not a server crash (500).
355
+ // Express-compatible: surface the parse failure as Bad Request.
356
+ throw new BadRequestError({ message: `Invalid JSON body: ${e?.message ?? e}` });
357
+ }
350
358
  }
351
359
 
352
360
  async reqBodyFormUrlData<T>(): Promise<T> {
@@ -372,7 +380,15 @@ export class RequestResponse {
372
380
 
373
381
  async reqBodyReqJsonBody(): Promise<ReqJsonBody> {
374
382
  const data = await this.reqBodyStringData();
375
- return Object.assign(new ReqJsonBody(), data ? JSON.parse(data) : {});
383
+ if (!data) {
384
+ return Object.assign(new ReqJsonBody(), {});
385
+ }
386
+ try {
387
+ return Object.assign(new ReqJsonBody(), JSON.parse(data));
388
+ } catch (e: any) {
389
+ // Malformed JSON is a client error (400), not a server crash (500).
390
+ throw new BadRequestError({ message: `Invalid JSON body: ${e?.message ?? e}` });
391
+ }
376
392
  }
377
393
 
378
394
  resBodyJsonData<T>(): T | null {
@@ -8,6 +8,7 @@ import { RequestResponse } from '../models/RequestResponse';
8
8
  import { SimpleBootHttpServer } from '../SimpleBootHttpServer';
9
9
  import { TransactionManager } from '@dooboostore/core';
10
10
  import { WebSocketEndPoint } from '../endpoints/WebSocketEndPoint';
11
+ import { NotFoundError } from '../errors/NotFoundError';
11
12
 
12
13
  export type Listen = { port?: number, hostname?: string, backlog?: number, listeningListener?: (server: SimpleBootHttpServer, httpServer: HttpServer | HttpsServer) => void };
13
14
 
@@ -107,7 +108,13 @@ export class HttpServerOption extends SimOption {
107
108
  );
108
109
  this.globalAdvice = globalAdvice;
109
110
  this.fileUploadTempPath = fileUploadTempPath;
110
- this.noSuchRouteEndPointMappingThrow = noSuchRouteEndPointMappingThrow;
111
+ // Unmatched routes must not fall through to "200 OK with empty body"
112
+ // like before. Default to 404 (Express-compatible); users can still
113
+ // override with their own noSuchRouteEndPointMappingThrow.
114
+ this.noSuchRouteEndPointMappingThrow =
115
+ noSuchRouteEndPointMappingThrow ??
116
+ ((rr: RequestResponse) =>
117
+ new NotFoundError({ message: `no route ${rr.reqMethod?.() ?? ''} ${rr.reqUrlPathName ?? ''}`.trim() }));
111
118
  this.transactionManagerFactory = transactionManagerFactory;
112
119
  }
113
120