@webpieces/http-client-core 0.4.880 → 0.4.882

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/http-client-core",
3
- "version": "0.4.880",
3
+ "version": "0.4.882",
4
4
  "description": "Isomorphic core of the webpieces HTTP client: the decorator-driven ProxyClient, error translation, and the Proxy trap shared by http-client-node and http-client-browser",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -21,6 +21,6 @@
21
21
  "access": "public"
22
22
  },
23
23
  "dependencies": {
24
- "@webpieces/core-util": "0.4.880"
24
+ "@webpieces/core-util": "0.4.882"
25
25
  }
26
26
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildClientProxy = buildClientProxy;
4
+ const core_util_1 = require("@webpieces/core-util");
4
5
  /**
5
6
  * Properties accessed by DI frameworks (Angular, Vue), debuggers, Promise checks, and serializers.
6
7
  * These should return undefined instead of throwing, allowing frameworks to inspect the proxy.
@@ -57,10 +58,21 @@ function buildClientProxy(apiPrototype, proxyClient) {
57
58
  `Check for typos or ensure the method has @Endpoint() decorator.`);
58
59
  }
59
60
  const route = proxyClient.getRoute(prop);
61
+ const apiName = apiPrototype.name || 'UnknownApi';
62
+ // NOT async: the call site must be captured synchronously, on the CALLER's stack, and
63
+ // `clientMethod` itself is the trim boundary so the top frame is the app's own line
64
+ // (#1175). On rejection the SAME error instance is rethrown, carrying it.
60
65
  // webpieces-disable no-any-unknown -- request DTO types are erased at the proxy boundary
61
- return async (...args) => {
62
- return proxyClient.makeRequest(route, args);
66
+ const clientMethod = (...args) => {
67
+ const callSite = core_util_1.ApiCallSite.capture(apiName, prop, clientMethod);
68
+ // webpieces-disable no-any-unknown -- a rejection value is genuinely unknown
69
+ return proxyClient.makeRequest(route, args).catch((failure) => {
70
+ callSite.attachTo(failure);
71
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- rethrows the caller's own failure unchanged
72
+ throw failure;
73
+ });
63
74
  };
75
+ return clientMethod;
64
76
  },
65
77
  });
66
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"buildClientProxy.js","sourceRoot":"","sources":["../../../../../packages/http/http-client-core/src/buildClientProxy.ts"],"names":[],"mappings":";;AA+CA,4CAiCC;AAvED;;;;;;;;;GASG;AACH,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC;IAC5C,aAAa,EAAM,wCAAwC;IAC3D,WAAW,EAAQ,6BAA6B;IAChD,WAAW,EAAQ,0BAA0B;IAC7C,MAAM,EAAa,6DAA6D;IAChF,MAAM,EAAa,6BAA6B;IAChD,OAAO,EAAY,gBAAgB;IACnC,SAAS,EAAU,gBAAgB;IACnC,QAAQ,EAAW,iBAAiB;IACpC,SAAS,EAAU,gBAAgB;IACnC,UAAU,EAAS,kBAAkB;IACrC,UAAU,EAAS,oBAAoB;IACvC,SAAS,EAAU,oBAAoB;IACvC,UAAU,EAAS,gCAAgC;IACnD,SAAS,EAAU,iBAAiB;IACpC,QAAQ,EAAW,eAAe;IAClC,UAAU,EAAS,+BAA+B;IAClD,aAAa,EAAM,+BAA+B;IAClD,aAAa,EAAM,+BAA+B;IAClD,iBAAiB,EAAE,wBAAwB;CAC9C,CAAC,CAAC;AAEH;;;;GAIG;AACH,sGAAsG;AACtG,SAAgB,gBAAgB,CAAmB,YAA6B,EAAE,WAAwB;IACtG,OAAO,IAAI,KAAK,CAAC,EAAO,EAAE;QACtB,GAAG,CAAC,MAAS,EAAE,IAAqB;YAChC,+FAA+F;YAC/F,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACX,4CAA4C,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,IAAI,KAAK;oBACnF,uDAAuD,CAC1D,CAAC;YACN,CAAC;YAED,iFAAiF;YACjF,kEAAkE;YAClE,IAAI,+BAA+B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5C,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,+DAA+D;gBAC/D,MAAM,IAAI,KAAK,CACX,8BAA8B,IAAI,QAAQ,YAAY,CAAC,IAAI,IAAI,SAAS,IAAI;oBAC5E,iEAAiE,CACpE,CAAC;YACN,CAAC;YAED,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAEzC,yFAAyF;YACzF,OAAO,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBAC5B,OAAO,WAAW,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAChD,CAAC,CAAC;QACN,CAAC;KACJ,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { ApiPrototype } from './ApiPrototype';\nimport { ProxyClient } from './ProxyClient';\n\n/**\n * Return type for the Proxy get trap — either an async method or undefined for framework inspection.\n */\n// webpieces-disable no-any-unknown -- Proxy get trap returns generic response promises\ntype ProxyGetResult = (...args: never[]) => Promise<unknown>;\n\n/**\n * Properties accessed by DI frameworks (Angular, Vue), debuggers, Promise checks, and serializers.\n * These should return undefined instead of throwing, allowing frameworks to inspect the proxy.\n *\n * Why this exists:\n * - Angular's injector profiler accesses `constructor` after useFactory returns\n * - Promise.resolve() checks for `then` to detect thenables\n * - JSON.stringify checks for `toJSON`\n * - Debuggers access `prototype`, `__proto__`, etc.\n */\nconst FRAMEWORK_INSPECTION_PROPERTIES = new Set([\n 'constructor', // Angular DI profiler, class inspection\n 'prototype', // Prototype chain inspection\n '__proto__', // Legacy prototype access\n 'name', // Angular isNotFound() check, function/class name inspection\n 'then', // Promise/thenable detection\n 'catch', // Promise check\n 'finally', // Promise check\n 'toJSON', // JSON.stringify\n 'valueOf', // Type coercion\n 'toString', // String coercion\n 'nodeType', // DOM element check\n 'tagName', // DOM element check\n '$$typeof', // React element/component check\n '$typeof', // React internal\n '_isVue', // Vue internal\n 'ngOnInit', // Angular lifecycle hook check\n 'ngOnDestroy', // Angular lifecycle hook check\n 'ngOnChanges', // Angular lifecycle hook check\n 'asymmetricMatch', // Jest matcher protocol\n]);\n\n/**\n * Wrap an already-init'd {@link ProxyClient} in the typed Proxy that IS the client: every\n * `@Endpoint` method call becomes an HTTP request. Shared by the browser and Node factories so\n * the two environments cannot drift on framework-inspection behavior.\n */\n// webpieces-disable no-function-outside-class -- returns a Proxy; it holds no state a class could own\nexport function buildClientProxy<T extends object>(apiPrototype: ApiPrototype<T>, proxyClient: ProxyClient): T {\n return new Proxy({} as T, {\n get(target: T, prop: string | symbol): ProxyGetResult | undefined {\n // Symbols (Symbol.toStringTag, Symbol.iterator, etc.) - throw for now to learn if this happens\n if (typeof prop !== 'string') {\n throw new Error(\n `Proxy accessed with non-string property: ${String(prop)} (type: ${typeof prop}). ` +\n `Please report this so we can add it to the whitelist.`\n );\n }\n\n // Framework inspection properties - return undefined to allow inspection WITHOUT\n // throwing. This is critical for Angular DI, Promise checks, etc.\n if (FRAMEWORK_INSPECTION_PROPERTIES.has(prop)) {\n return undefined;\n }\n\n if (!proxyClient.hasRoute(prop)) {\n // For unknown properties (likely typos), throw a helpful error\n throw new Error(\n `No route found for method '${prop}' on ${apiPrototype.name || 'Unknown'}. ` +\n `Check for typos or ensure the method has @Endpoint() decorator.`\n );\n }\n\n const route = proxyClient.getRoute(prop);\n\n // webpieces-disable no-any-unknown -- request DTO types are erased at the proxy boundary\n return async (...args: any[]) => {\n return proxyClient.makeRequest(route, args);\n };\n },\n });\n}\n"]}
1
+ {"version":3,"file":"buildClientProxy.js","sourceRoot":"","sources":["../../../../../packages/http/http-client-core/src/buildClientProxy.ts"],"names":[],"mappings":";;AAgDA,4CA4CC;AA5FD,oDAAmD;AAUnD;;;;;;;;;GASG;AACH,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAC;IAC5C,aAAa,EAAM,wCAAwC;IAC3D,WAAW,EAAQ,6BAA6B;IAChD,WAAW,EAAQ,0BAA0B;IAC7C,MAAM,EAAa,6DAA6D;IAChF,MAAM,EAAa,6BAA6B;IAChD,OAAO,EAAY,gBAAgB;IACnC,SAAS,EAAU,gBAAgB;IACnC,QAAQ,EAAW,iBAAiB;IACpC,SAAS,EAAU,gBAAgB;IACnC,UAAU,EAAS,kBAAkB;IACrC,UAAU,EAAS,oBAAoB;IACvC,SAAS,EAAU,oBAAoB;IACvC,UAAU,EAAS,gCAAgC;IACnD,SAAS,EAAU,iBAAiB;IACpC,QAAQ,EAAW,eAAe;IAClC,UAAU,EAAS,+BAA+B;IAClD,aAAa,EAAM,+BAA+B;IAClD,aAAa,EAAM,+BAA+B;IAClD,iBAAiB,EAAE,wBAAwB;CAC9C,CAAC,CAAC;AAEH;;;;GAIG;AACH,sGAAsG;AACtG,SAAgB,gBAAgB,CAAmB,YAA6B,EAAE,WAAwB;IACtG,OAAO,IAAI,KAAK,CAAC,EAAO,EAAE;QACtB,GAAG,CAAC,MAAS,EAAE,IAAqB;YAChC,+FAA+F;YAC/F,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACX,4CAA4C,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,IAAI,KAAK;oBACnF,uDAAuD,CAC1D,CAAC;YACN,CAAC;YAED,iFAAiF;YACjF,kEAAkE;YAClE,IAAI,+BAA+B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5C,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,+DAA+D;gBAC/D,MAAM,IAAI,KAAK,CACX,8BAA8B,IAAI,QAAQ,YAAY,CAAC,IAAI,IAAI,SAAS,IAAI;oBAC5E,iEAAiE,CACpE,CAAC;YACN,CAAC;YAED,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,IAAI,YAAY,CAAC;YAElD,sFAAsF;YACtF,oFAAoF;YACpF,0EAA0E;YAC1E,yFAAyF;YACzF,MAAM,YAAY,GAAG,CAAC,GAAG,IAAW,EAAoB,EAAE;gBACtD,MAAM,QAAQ,GAAG,uBAAW,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;gBAClE,6EAA6E;gBAC7E,OAAO,WAAW,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAgB,EAAE,EAAE;oBACnE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBAC3B,6GAA6G;oBAC7G,MAAM,OAAO,CAAC;gBAClB,CAAC,CAAC,CAAC;YACP,CAAC,CAAC;YACF,OAAO,YAAY,CAAC;QACxB,CAAC;KACJ,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { ApiCallSite } from '@webpieces/core-util';\nimport { ApiPrototype } from './ApiPrototype';\nimport { ProxyClient } from './ProxyClient';\n\n/**\n * Return type for the Proxy get trap — either an async method or undefined for framework inspection.\n */\n// webpieces-disable no-any-unknown -- Proxy get trap returns generic response promises\ntype ProxyGetResult = (...args: never[]) => Promise<unknown>;\n\n/**\n * Properties accessed by DI frameworks (Angular, Vue), debuggers, Promise checks, and serializers.\n * These should return undefined instead of throwing, allowing frameworks to inspect the proxy.\n *\n * Why this exists:\n * - Angular's injector profiler accesses `constructor` after useFactory returns\n * - Promise.resolve() checks for `then` to detect thenables\n * - JSON.stringify checks for `toJSON`\n * - Debuggers access `prototype`, `__proto__`, etc.\n */\nconst FRAMEWORK_INSPECTION_PROPERTIES = new Set([\n 'constructor', // Angular DI profiler, class inspection\n 'prototype', // Prototype chain inspection\n '__proto__', // Legacy prototype access\n 'name', // Angular isNotFound() check, function/class name inspection\n 'then', // Promise/thenable detection\n 'catch', // Promise check\n 'finally', // Promise check\n 'toJSON', // JSON.stringify\n 'valueOf', // Type coercion\n 'toString', // String coercion\n 'nodeType', // DOM element check\n 'tagName', // DOM element check\n '$$typeof', // React element/component check\n '$typeof', // React internal\n '_isVue', // Vue internal\n 'ngOnInit', // Angular lifecycle hook check\n 'ngOnDestroy', // Angular lifecycle hook check\n 'ngOnChanges', // Angular lifecycle hook check\n 'asymmetricMatch', // Jest matcher protocol\n]);\n\n/**\n * Wrap an already-init'd {@link ProxyClient} in the typed Proxy that IS the client: every\n * `@Endpoint` method call becomes an HTTP request. Shared by the browser and Node factories so\n * the two environments cannot drift on framework-inspection behavior.\n */\n// webpieces-disable no-function-outside-class -- returns a Proxy; it holds no state a class could own\nexport function buildClientProxy<T extends object>(apiPrototype: ApiPrototype<T>, proxyClient: ProxyClient): T {\n return new Proxy({} as T, {\n get(target: T, prop: string | symbol): ProxyGetResult | undefined {\n // Symbols (Symbol.toStringTag, Symbol.iterator, etc.) - throw for now to learn if this happens\n if (typeof prop !== 'string') {\n throw new Error(\n `Proxy accessed with non-string property: ${String(prop)} (type: ${typeof prop}). ` +\n `Please report this so we can add it to the whitelist.`\n );\n }\n\n // Framework inspection properties - return undefined to allow inspection WITHOUT\n // throwing. This is critical for Angular DI, Promise checks, etc.\n if (FRAMEWORK_INSPECTION_PROPERTIES.has(prop)) {\n return undefined;\n }\n\n if (!proxyClient.hasRoute(prop)) {\n // For unknown properties (likely typos), throw a helpful error\n throw new Error(\n `No route found for method '${prop}' on ${apiPrototype.name || 'Unknown'}. ` +\n `Check for typos or ensure the method has @Endpoint() decorator.`\n );\n }\n\n const route = proxyClient.getRoute(prop);\n const apiName = apiPrototype.name || 'UnknownApi';\n\n // NOT async: the call site must be captured synchronously, on the CALLER's stack, and\n // `clientMethod` itself is the trim boundary so the top frame is the app's own line\n // (#1175). On rejection the SAME error instance is rethrown, carrying it.\n // webpieces-disable no-any-unknown -- request DTO types are erased at the proxy boundary\n const clientMethod = (...args: any[]): Promise<unknown> => {\n const callSite = ApiCallSite.capture(apiName, prop, clientMethod);\n // webpieces-disable no-any-unknown -- a rejection value is genuinely unknown\n return proxyClient.makeRequest(route, args).catch((failure: unknown) => {\n callSite.attachTo(failure);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- rethrows the caller's own failure unchanged\n throw failure;\n });\n };\n return clientMethod;\n },\n });\n}\n"]}