@dooboostore/simple-boot-http-server 1.0.27 → 1.0.28

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 (49) hide show
  1. package/README.md +44 -9
  2. package/dist/cjs/SimpleBootHttpServer.js +15 -2
  3. package/dist/cjs/SimpleBootHttpServer.js.map +2 -2
  4. package/dist/cjs/decorators/MethodMapping.js.map +2 -2
  5. package/dist/cjs/models/RequestResponse.js +52 -0
  6. package/dist/cjs/models/RequestResponse.js.map +3 -3
  7. package/dist/cjs/proxy/RequestResponseInjectProxy.js +35 -0
  8. package/dist/cjs/proxy/RequestResponseInjectProxy.js.map +7 -0
  9. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js +1 -1
  10. package/dist/cjs/proxy/SymbolIntentApiServiceProxy.js.map +2 -2
  11. package/dist/cjs/proxy/index.js +3 -1
  12. package/dist/cjs/proxy/index.js.map +2 -2
  13. package/dist/cjs/resolvers/Resolver.js.map +1 -1
  14. package/dist/esm/SimpleBootHttpServer.js +16 -3
  15. package/dist/esm/SimpleBootHttpServer.js.map +2 -2
  16. package/dist/esm/decorators/MethodMapping.js.map +2 -2
  17. package/dist/esm/models/RequestResponse.js +52 -0
  18. package/dist/esm/models/RequestResponse.js.map +2 -2
  19. package/dist/esm/proxy/RequestResponseInjectProxy.js +12 -0
  20. package/dist/esm/proxy/RequestResponseInjectProxy.js.map +7 -0
  21. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js +1 -1
  22. package/dist/esm/proxy/SymbolIntentApiServiceProxy.js.map +2 -2
  23. package/dist/esm/proxy/index.js +1 -0
  24. package/dist/esm/proxy/index.js.map +2 -2
  25. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js +295 -252
  26. package/dist/esm-bundle/dooboostore-simple-boot-http-server.esm.js.map +4 -4
  27. package/dist/types/SimpleBootHttpServer.d.ts.map +1 -1
  28. package/dist/types/decorators/MethodMapping.d.ts +13 -16
  29. package/dist/types/decorators/MethodMapping.d.ts.map +1 -1
  30. package/dist/types/models/RequestResponse.d.ts +9 -0
  31. package/dist/types/models/RequestResponse.d.ts.map +1 -1
  32. package/dist/types/proxy/RequestResponseInjectProxy.d.ts +22 -0
  33. package/dist/types/proxy/RequestResponseInjectProxy.d.ts.map +1 -0
  34. package/dist/types/proxy/index.d.ts +1 -0
  35. package/dist/types/proxy/index.d.ts.map +1 -1
  36. package/dist/types/resolvers/Resolver.d.ts +2 -1
  37. package/dist/types/resolvers/Resolver.d.ts.map +1 -1
  38. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js +295 -252
  39. package/dist/umd-bundle/dooboostore-simple-boot-http-server.umd.js.map +4 -4
  40. package/dist/umd-bundle/websocket-client.umd.js +106 -140
  41. package/dist/umd-bundle/websocket-client.umd.js.map +2 -2
  42. package/package.json +7 -7
  43. package/src/SimpleBootHttpServer.ts +19 -3
  44. package/src/decorators/MethodMapping.ts +151 -159
  45. package/src/models/RequestResponse.ts +50 -0
  46. package/src/proxy/RequestResponseInjectProxy.ts +30 -0
  47. package/src/proxy/SymbolIntentApiServiceProxy.ts +1 -1
  48. package/src/proxy/index.ts +1 -0
  49. package/src/resolvers/Resolver.ts +2 -1
@@ -182,6 +182,12 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
182
182
  return false;
183
183
  }
184
184
  };
185
+ ValidUtils2.isGenerator = (value) => {
186
+ return value !== null && typeof value === "object" && typeof value.next === "function" && typeof value[Symbol.iterator] === "function";
187
+ };
188
+ ValidUtils2.isAsyncGenerator = (value) => {
189
+ return value !== null && typeof value === "object" && typeof value.next === "function" && typeof value[Symbol.asyncIterator] === "function";
190
+ };
185
191
  ValidUtils2.isFrozen = (obj) => {
186
192
  return Object.isFrozen(obj);
187
193
  };
@@ -4626,87 +4632,64 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
4626
4632
  // ../core/dist/esm/promise/AbortablePromise.js
4627
4633
  var AbortablePromise = class _AbortablePromise {
4628
4634
  constructor(executor, signal) {
4629
- this.steps = [];
4630
- this.initialExecutor = executor;
4631
4635
  this.signal = signal;
4636
+ if (typeof executor !== "function") {
4637
+ this.source = Promise.resolve(executor);
4638
+ } else if (signal?.aborted) {
4639
+ this.source = Promise.reject(signal.reason);
4640
+ } else {
4641
+ this.source = Promise.resolve().then(executor);
4642
+ }
4643
+ }
4644
+ /**
4645
+ * source 를 abort 와 경쟁시킨 promise. 실제로 소비될 때(then/toPromise) 한 번만 만든다 —
4646
+ * await 는 then() 이 돌려준 새 인스턴스를 버리므로, 미리 만들면 아무도 안 받는 reject 가 unhandled 로 남는다.
4647
+ */
4648
+ get promise() {
4649
+ if (this.guarded) return this.guarded;
4650
+ const signal = this.signal;
4651
+ if (!signal) return this.guarded = this.source;
4652
+ if (signal.aborted) {
4653
+ this.source.catch(() => {
4654
+ });
4655
+ return this.guarded = Promise.reject(signal.reason);
4656
+ }
4657
+ return this.guarded = new Promise((resolve, reject) => {
4658
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
4659
+ const onAbort = () => reject(signal.reason);
4660
+ signal.addEventListener("abort", onAbort, { once: true });
4661
+ this.source.then(
4662
+ (value) => {
4663
+ cleanup();
4664
+ resolve(value);
4665
+ },
4666
+ (reason) => {
4667
+ cleanup();
4668
+ reject(reason);
4669
+ }
4670
+ );
4671
+ });
4632
4672
  }
4633
4673
  then(onfulfilled, onrejected) {
4634
- const newPromise = new _AbortablePromise(
4635
- this.initialExecutor,
4636
- this.signal
4674
+ const signal = this.signal;
4675
+ const next = this.promise.then(
4676
+ onfulfilled ? (value) => {
4677
+ if (signal?.aborted) throw signal.reason;
4678
+ return onfulfilled(value);
4679
+ } : void 0,
4680
+ onrejected
4637
4681
  );
4638
- newPromise.steps = [...this.steps];
4639
- if (onfulfilled) {
4640
- newPromise.steps.push(onfulfilled);
4641
- }
4642
- if (onrejected) {
4643
- newPromise.errorHandler = onrejected;
4644
- } else if (this.errorHandler) {
4645
- newPromise.errorHandler = this.errorHandler;
4646
- }
4647
- return newPromise;
4682
+ return new _AbortablePromise(next, signal);
4648
4683
  }
4649
4684
  catch(onrejected) {
4650
4685
  return this.then(void 0, onrejected);
4651
4686
  }
4652
4687
  finally(onfinally) {
4653
- return this.then(
4654
- (value) => {
4655
- onfinally?.();
4656
- return value;
4657
- },
4658
- (reason) => {
4659
- onfinally?.();
4660
- throw reason;
4661
- }
4662
- );
4688
+ return new _AbortablePromise(this.promise.finally(onfinally), this.signal);
4663
4689
  }
4664
- async execute() {
4665
- try {
4666
- if (this.signal?.aborted) {
4667
- throw new Error(this.signal.reason || "Aborted");
4668
- }
4669
- const abortPromise = new Promise((_, reject) => {
4670
- if (this.signal?.aborted) {
4671
- return reject(new Error(this.signal.reason || "Aborted"));
4672
- }
4673
- const callback = (e) => {
4674
- const target = e.target;
4675
- this.signal?.removeEventListener("abort", callback);
4676
- reject(new Error(target.reason || "Aborted"));
4677
- };
4678
- this.signal?.addEventListener("abort", callback, { once: true });
4679
- });
4680
- const pipelineRunner = async () => {
4681
- let lastResult;
4682
- if (typeof this.initialExecutor === "function") {
4683
- if (this.signal?.aborted) {
4684
- throw new Error(this.signal.reason || "Aborted");
4685
- }
4686
- lastResult = await this.initialExecutor();
4687
- } else {
4688
- lastResult = await this.initialExecutor;
4689
- }
4690
- for (let i = 0; i < this.steps.length; i++) {
4691
- if (this.signal?.aborted) {
4692
- throw new Error(this.signal.reason || "Aborted");
4693
- }
4694
- const step = this.steps[i];
4695
- lastResult = await step(lastResult);
4696
- }
4697
- return lastResult;
4698
- };
4699
- return await Promise.race([pipelineRunner(), abortPromise]);
4700
- } catch (error) {
4701
- if (this.errorHandler) {
4702
- return await this.errorHandler(error);
4703
- }
4704
- throw error;
4705
- }
4706
- }
4707
- // Convert to native Promise
4690
+ // 네이티브 Promise 로 변환 (그냥 await 해도 된다)
4708
4691
  toPromise() {
4709
- return this.execute();
4692
+ return this.promise;
4710
4693
  }
4711
4694
  };
4712
4695
 
@@ -5579,11 +5562,15 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
5579
5562
  resolve(gdata);
5580
5563
  }).catch(async (e) => {
5581
5564
  this.error(config, pipe, e);
5582
- config?.error?.();
5565
+ config?.error?.(e);
5583
5566
  if (config?.errorTransform) {
5584
5567
  e = await config.errorTransform(e);
5585
5568
  }
5586
- e = await this.errorTransform(e);
5569
+ try {
5570
+ e = await this.errorTransform(e);
5571
+ } catch (ee) {
5572
+ e = ee;
5573
+ }
5587
5574
  reject(e);
5588
5575
  }).finally(() => {
5589
5576
  this.finally(config, pipe);
@@ -5600,41 +5587,30 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
5600
5587
  return data instanceof HttpResponseError;
5601
5588
  };
5602
5589
  var HttpFetcher = class extends Fetcher {
5590
+ // get/post/put/patch/head/delete가 전부 config.config.fetch.method를 세팅하려고 caller가
5591
+ // 넘긴 config(.fetch) 객체를 직접 mutate했다 - 같은 config 객체를 여러 호출이 공유하면
5592
+ // (예: Promise.all로 동시에 get/post) 서로의 method를 덮어쓰는 레이스가 생겼다. caller의
5593
+ // 객체는 절대 건드리지 않고, 얕은 복사본 위에 method만 얹어서 반환한다.
5594
+ withMethod(config, method) {
5595
+ return { ...config, config: { ...config.config, fetch: { ...config.config?.fetch, method } } };
5596
+ }
5603
5597
  get(config) {
5604
- config.config ?? (config.config = {});
5605
- config.config.fetch = config.config?.fetch ?? {};
5606
- config.config.fetch.method = "GET";
5607
- return this.fetch(config);
5598
+ return this.fetch(this.withMethod(config, "GET"));
5608
5599
  }
5609
5600
  post(config) {
5610
- config.config ?? (config.config = {});
5611
- config.config.fetch = config.config?.fetch ?? {};
5612
- config.config.fetch.method = "POST";
5613
- return this.fetch(config);
5601
+ return this.fetch(this.withMethod(config, "POST"));
5614
5602
  }
5615
5603
  patch(config) {
5616
- config.config ?? (config.config = {});
5617
- config.config.fetch = config.config?.fetch ?? {};
5618
- config.config.fetch.method = "PATCH";
5619
- return this.fetch(config);
5604
+ return this.fetch(this.withMethod(config, "PATCH"));
5620
5605
  }
5621
5606
  put(config) {
5622
- config.config ?? (config.config = {});
5623
- config.config.fetch = config.config?.fetch ?? {};
5624
- config.config.fetch.method = "PUT";
5625
- return this.fetch(config);
5607
+ return this.fetch(this.withMethod(config, "PUT"));
5626
5608
  }
5627
5609
  head(config) {
5628
- config.config ?? (config.config = {});
5629
- config.config.fetch = config.config?.fetch ?? {};
5630
- config.config.fetch.method = "HEAD";
5631
- return this.fetch(config);
5610
+ return this.fetch(this.withMethod(config, "HEAD"));
5632
5611
  }
5633
5612
  delete(config) {
5634
- config.config ?? (config.config = {});
5635
- config.config.fetch = config.config?.fetch ?? {};
5636
- config.config.fetch.method = "DELETE";
5637
- return this.fetch(config);
5613
+ return this.fetch(this.withMethod(config, "DELETE"));
5638
5614
  }
5639
5615
  async beforeProxyFetch(config) {
5640
5616
  return config;
@@ -5671,7 +5647,7 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
5671
5647
  }
5672
5648
  } else {
5673
5649
  httpResponseError.body = e;
5674
- httpResponseError.message = e.message;
5650
+ httpResponseError.message = e?.message;
5675
5651
  }
5676
5652
  return httpResponseError;
5677
5653
  }
@@ -5681,7 +5657,7 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
5681
5657
  if (!(target instanceof URL) && typeof target !== "string") {
5682
5658
  const searchParams = ConvertUtils.toURLSearchParams(target.searchParams ?? {});
5683
5659
  try {
5684
- const url = typeof target.url === "string" ? new URL(target.url) : target.url;
5660
+ const url = new URL(target.url);
5685
5661
  searchParams.forEach((value, key) => {
5686
5662
  url.searchParams.append(key, value);
5687
5663
  });
@@ -5696,43 +5672,30 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
5696
5672
  }
5697
5673
  }
5698
5674
  const beforeProxyData = { requestInfo: target, init: config?.fetch };
5699
- let beforeData = config?.beforeProxyFetch ? await config?.beforeProxyFetch(config) : beforeProxyData.requestInfo;
5700
- beforeData = config?.skipGlobalBeforeProxyFetch ? beforeProxyData : await this.beforeProxyFetch(beforeProxyData);
5675
+ let beforeData = config?.beforeProxyFetch ? await config?.beforeProxyFetch(beforeProxyData) : beforeProxyData;
5676
+ beforeData = config?.skipGlobalBeforeProxyFetch ? beforeData : await this.beforeProxyFetch(beforeData);
5701
5677
  target = beforeData.requestInfo;
5702
5678
  if (beforeData.init) {
5703
5679
  config ?? (config = {});
5704
5680
  config.fetch = beforeData.init;
5705
5681
  }
5706
- let abortedTimeout;
5682
+ let requestInit = config?.fetch;
5707
5683
  if (config?.fetch && "timeout" in config.fetch) {
5708
- const abortController = new AbortController();
5709
- abortedTimeout = setTimeout(() => {
5710
- if (config?.fetch?.signal) {
5711
- const inputSignal = config.fetch.signal;
5712
- const listener = () => {
5713
- if (!abortController.signal.aborted) {
5714
- abortController.abort();
5715
- }
5716
- inputSignal.removeEventListener("abort", listener);
5717
- };
5718
- inputSignal.addEventListener("abort", listener);
5719
- }
5720
- if (!abortController.signal.aborted) {
5721
- abortController.abort();
5722
- }
5723
- }, config.fetch.timeout);
5724
- config.fetch.signal = abortController.signal;
5684
+ const timeoutSignal = AbortSignal.timeout(config.fetch.timeout);
5685
+ const signal = config.fetch.signal ? AbortSignal.any([timeoutSignal, config.fetch.signal]) : timeoutSignal;
5686
+ requestInit = { ...config.fetch, signal };
5725
5687
  }
5726
- this.beforeFetch({ target, requestInit: config?.fetch });
5727
- return (config.fetcher ?? fetch)(target, config?.fetch).then(async (it) => {
5728
- this.afterFetch({ target, requestInit: config?.fetch }, it);
5688
+ this.beforeFetch({ target, requestInit });
5689
+ return (config.fetcher ?? fetch)(target, requestInit).then(async (it) => {
5690
+ this.afterFetch({ target, requestInit }, it);
5729
5691
  const afterProxyData = {
5730
- fetch: { target, requestInit: config.fetch },
5692
+ fetch: { target, requestInit },
5731
5693
  config: beforeData,
5732
5694
  response: it
5733
5695
  };
5734
- it = config?.afterProxyFetch ? await config.afterProxyFetch(afterProxyData) : it;
5735
- it = config?.skipGlobalAfterProxyFetch ? it : await this.afterProxyFetch(afterProxyData);
5696
+ afterProxyData.response = config?.afterProxyFetch ? await config.afterProxyFetch(afterProxyData) : it;
5697
+ afterProxyData.response = config?.skipGlobalAfterProxyFetch ? afterProxyData.response : await this.afterProxyFetch(afterProxyData);
5698
+ it = afterProxyData.response;
5736
5699
  config?.fetchResponseAfterCallBack?.(it, config);
5737
5700
  if (!config?.allowedResponseNotOk && !it.ok) {
5738
5701
  throw it;
@@ -5742,30 +5705,31 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
5742
5705
  throw data;
5743
5706
  }
5744
5707
  return it;
5745
- }).finally(() => {
5746
- if (abortedTimeout) {
5747
- clearTimeout(abortedTimeout);
5748
- }
5749
5708
  });
5750
5709
  }
5751
5710
  };
5752
5711
 
5753
5712
  // ../core/dist/esm/fetch/HttpJsonFetcher.js
5754
5713
  var HttpJsonFetcher = class extends HttpFetcher {
5714
+ // config.config/config.config.fetch를 직접 mutate하면(예전처럼) 같은 config 객체를 여러
5715
+ // postJson/patchJson/putJson 호출이 동시에 공유할 때 서로의 headers/body를 덮어쓰는 레이스가
5716
+ // 생긴다(HttpFetcher.get/post의 method 레이스랑 같은 문제). caller의 객체는 안 건드리고,
5717
+ // 얕은 복사본을 만들어서 새 config 객체를 리턴한다.
5755
5718
  updateJsonFetchConfigAndData(config) {
5756
- var _a, _b;
5757
5719
  const headers = {
5758
5720
  "Content-Type": "application/json",
5759
5721
  Accept: "application/json, text/plain, */*"
5760
5722
  };
5761
- config.config ?? (config.config = {});
5762
- (_a = config.config).fetch ?? (_a.fetch = {});
5763
- (_b = config.config.fetch).headers ?? (_b.headers = {});
5764
- config.config.fetch.headers = { ...headers, ...config.config.fetch?.headers };
5765
- if (config.config?.fetch?.body && typeof config.config?.fetch?.body !== "string") {
5766
- config.config.fetch.body = JSON.stringify(config.config.fetch.body);
5723
+ const fetchInit = { ...config.config?.fetch };
5724
+ const merged = new Headers(headers);
5725
+ if (fetchInit.headers) {
5726
+ new Headers(fetchInit.headers).forEach((value, key) => merged.set(key, value));
5767
5727
  }
5768
- return config;
5728
+ fetchInit.headers = merged;
5729
+ if (fetchInit.body && typeof fetchInit.body !== "string") {
5730
+ fetchInit.body = JSON.stringify(fetchInit.body);
5731
+ }
5732
+ return { ...config, config: { ...config.config, fetch: fetchInit } };
5769
5733
  }
5770
5734
  get(config) {
5771
5735
  return super.get(config);
@@ -7589,12 +7553,13 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
7589
7553
  ReflectUtils2.findMetadata = (metadataKey, target, propertyKey) => {
7590
7554
  if (target == null) return void 0;
7591
7555
  let searchTarget = typeof target === "object" && typeof target !== "function" ? target.constructor : target;
7592
- while (searchTarget && searchTarget !== Object) {
7556
+ const seen = /* @__PURE__ */ new Set();
7557
+ while (searchTarget && searchTarget !== Object && !seen.has(searchTarget)) {
7558
+ seen.add(searchTarget);
7593
7559
  const data = propertyKey ? Reflect.getOwnMetadata(metadataKey, searchTarget, propertyKey) : Reflect.getOwnMetadata(metadataKey, searchTarget);
7594
7560
  if (data !== void 0) return data;
7595
7561
  const proto = Object.getPrototypeOf(searchTarget);
7596
7562
  searchTarget = proto && typeof proto === "function" ? proto : proto?.constructor || null;
7597
- if (searchTarget === target) break;
7598
7563
  }
7599
7564
  return void 0;
7600
7565
  };
@@ -7602,12 +7567,13 @@ var dooboostoreSimpleBootHttpServerWebSocketClient = (() => {
7602
7567
  const results = [];
7603
7568
  if (target == null) return results;
7604
7569
  let searchTarget = typeof target === "object" && typeof target !== "function" ? target.constructor : target;
7605
- while (searchTarget && searchTarget !== Object) {
7570
+ const seen = /* @__PURE__ */ new Set();
7571
+ while (searchTarget && searchTarget !== Object && !seen.has(searchTarget)) {
7572
+ seen.add(searchTarget);
7606
7573
  const data = propertyKey ? Reflect.getOwnMetadata(metadataKey, searchTarget, propertyKey) : Reflect.getOwnMetadata(metadataKey, searchTarget);
7607
7574
  if (data !== void 0) results.unshift(data);
7608
7575
  const proto = Object.getPrototypeOf(searchTarget);
7609
7576
  searchTarget = proto && typeof proto === "function" ? proto : proto?.constructor || null;
7610
- if (searchTarget === target) break;
7611
7577
  }
7612
7578
  return results;
7613
7579
  };