@webpieces/cloudtasks-client 0.4.880 → 0.4.881

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/cloudtasks-client",
3
- "version": "0.4.880",
3
+ "version": "0.4.881",
4
4
  "description": "Cloud Tasks enqueue client generated from a shared @PubSub API contract (twin of http-client)",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -23,9 +23,9 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@webpieces/core-context": "0.4.880",
27
- "@webpieces/core-util": "0.4.880",
28
- "@webpieces/gcp-identity": "0.4.880",
26
+ "@webpieces/core-context": "0.4.881",
27
+ "@webpieces/core-util": "0.4.881",
28
+ "@webpieces/gcp-identity": "0.4.881",
29
29
  "@google-cloud/tasks": "5.5.2",
30
30
  "inversify": "7.10.4",
31
31
  "reflect-metadata": "0.2.2"
@@ -47,6 +47,7 @@ let ClientCloudTasksFactory = class ClientCloudTasksFactory {
47
47
  // Fresh instance per contract — TaskProxyClient is transient.
48
48
  const proxyClient = this.taskProxyClientProvider.get();
49
49
  proxyClient.init(apiClass, config);
50
+ const apiName = apiClass.name || 'UnknownApi';
50
51
  return new Proxy({}, {
51
52
  // webpieces-disable no-any-unknown -- proxy get trap returns either an endpoint method or undefined
52
53
  get(target, prop) {
@@ -57,8 +58,19 @@ let ClientCloudTasksFactory = class ClientCloudTasksFactory {
57
58
  throw new Error(`No @PubSub endpoint '${prop}' on ${apiClass.name || 'Unknown'}. ` +
58
59
  `Check for typos or a missing @Endpoint() decorator.`);
59
60
  }
61
+ // Same call-site capture as the HTTP clients (#1175): synchronous, trimmed to the
62
+ // caller, parked on the SAME rejected instance.
60
63
  // webpieces-disable no-any-unknown -- request DTO type is erased at the proxy layer
61
- return (requestDto) => proxyClient.enqueue(prop, requestDto);
64
+ const clientMethod = (requestDto) => {
65
+ const callSite = core_util_1.ApiCallSite.capture(apiName, prop, clientMethod);
66
+ // webpieces-disable no-any-unknown -- a rejection value is genuinely unknown
67
+ return proxyClient.enqueue(prop, requestDto).catch((failure) => {
68
+ callSite.attachTo(failure);
69
+ // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- rethrows the caller's own failure unchanged
70
+ throw failure;
71
+ });
72
+ };
73
+ return clientMethod;
62
74
  },
63
75
  });
64
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ClientCloudTasksFactory.js","sourceRoot":"","sources":["../../../../../packages/cloud/cloudtasks-client/src/ClientCloudTasksFactory.ts"],"names":[],"mappings":";;;;AAAA,yCAAmC;AACnC,oDAAsD;AACtD,0DAAqG;AACrG,uDAAgF;AAGhF,iGAAiG;AACjG,6EAA6E;AAC7E,IAAA,oCAAqB,EAAC,4CAA0B,EAAE,iCAAe,CAAC,CAAC;AAEnE;;;GAGG;AACH,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAS;IACpD,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS;IAC3E,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU;CACrE,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AAGI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAEyB;IADzD,YACyD,uBAAkD;QAAlD,4BAAuB,GAAvB,uBAAuB,CAA2B;IACxG,CAAC;IAEJ,kFAAkF;IAClF,kBAAkB,CAAmB,QAAyB,EAAE,MAAwB;QACpF,8DAA8D;QAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,CAAC;QACvD,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEnC,OAAO,IAAI,KAAK,CAAC,EAAO,EAAE;YACtB,oGAAoG;YACpG,GAAG,CAAC,MAAS,EAAE,IAAqB;gBAChC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,+BAA+B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxE,OAAO,SAAS,CAAC;gBACrB,CAAC;gBACD,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjC,MAAM,IAAI,KAAK,CACX,wBAAwB,IAAI,QAAQ,QAAQ,CAAC,IAAI,IAAI,SAAS,IAAI;wBAClE,qDAAqD,CACxD,CAAC;gBACN,CAAC;gBACD,oFAAoF;gBACpF,OAAO,CAAC,UAAmB,EAAiB,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACzF,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;CACJ,CAAA;AA5BY,0DAAuB;kCAAvB,uBAAuB;IAFnC,IAAA,0BAAc,GAAE;IAChB,IAAA,wCAAyB,GAAE;IAGnB,mBAAA,IAAA,kBAAM,EAAC,4CAA0B,CAAC,CAAA;6CAA2C,uBAAQ;GAFjF,uBAAuB,CA4BnC","sourcesContent":["import { inject } from 'inversify';\nimport { DocumentDesign } from '@webpieces/core-util';\nimport { Provider, bindFrameworkProvider, provideFrameworkSingleton } from '@webpieces/core-context';\nimport { TASK_PROXY_CLIENT_PROVIDER, TaskProxyClient } from './TaskProxyClient';\nimport { ApiPrototype, TaskClientConfig } from './TaskClientConfig';\n\n// Teach the container how to hand out fresh TaskProxyClients. TaskProxyClient is bound TRANSIENT\n// (@provideFrameworkTransient), so each provider.get() constructs a new one.\nbindFrameworkProvider(TASK_PROXY_CLIENT_PROVIDER, TaskProxyClient);\n\n/**\n * Properties DI frameworks / Promise checks / serializers probe on the proxy; return\n * undefined instead of treating them as endpoints. Mirrors http-client-core's buildClientProxy.\n */\nconst FRAMEWORK_INSPECTION_PROPERTIES = new Set<string>([\n 'constructor', 'prototype', '__proto__', 'name', 'then', 'catch', 'finally',\n 'toJSON', 'valueOf', 'toString', 'nodeType', 'tagName', '$$typeof',\n]);\n\n/**\n * ClientCloudTasksFactory - builds Cloud Tasks enqueue clients from a shared @PubSub API\n * contract. The fire-and-forget twin of http-client-node's ClientHttpFactory.\n *\n * Calling a method on the returned client ENQUEUES a task (it does not call remotely); the task\n * is later delivered to the same endpoint's controller through the full server filter chain.\n *\n * ```typescript\n * // same project + region as this container; the URL is derived, you maintain nothing\n * const emailTasks = factory.createPubSubClient(EmailApi, new TaskClientConfig('email-svc'));\n * await scheduler.addToQueue(() => emailTasks.sendEmail(req), { dedupName });\n * ```\n *\n * Every client it builds gets its OWN {@link TaskProxyClient} from the injected\n * `Provider<TaskProxyClient>` (bound transient), which `createPubSubClient` then `init`s for one\n * contract. Their collaborators (TaskInvoker, RequestContextHeaders) come from the container.\n *\n * Node-only, so the factory IS the inversify entry point. An enqueue outside\n * `RequestContext.run(...)` throws rather than silently dropping the caller's trace.\n */\n@DocumentDesign()\n@provideFrameworkSingleton()\nexport class ClientCloudTasksFactory {\n constructor(\n @inject(TASK_PROXY_CLIENT_PROVIDER) private readonly taskProxyClientProvider: Provider<TaskProxyClient>,\n ) {}\n\n /** Typed enqueue client for a @PubSub contract, delivered to `config.svcName`. */\n createPubSubClient<T extends object>(apiClass: ApiPrototype<T>, config: TaskClientConfig): T {\n // Fresh instance per contract — TaskProxyClient is transient.\n const proxyClient = this.taskProxyClientProvider.get();\n proxyClient.init(apiClass, config);\n\n return new Proxy({} as T, {\n // webpieces-disable no-any-unknown -- proxy get trap returns either an endpoint method or undefined\n get(target: T, prop: string | symbol): unknown {\n if (typeof prop !== 'string' || FRAMEWORK_INSPECTION_PROPERTIES.has(prop)) {\n return undefined;\n }\n if (!proxyClient.hasEndpoint(prop)) {\n throw new Error(\n `No @PubSub endpoint '${prop}' on ${apiClass.name || 'Unknown'}. ` +\n `Check for typos or a missing @Endpoint() decorator.`,\n );\n }\n // webpieces-disable no-any-unknown -- request DTO type is erased at the proxy layer\n return (requestDto: unknown): Promise<void> => proxyClient.enqueue(prop, requestDto);\n },\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ClientCloudTasksFactory.js","sourceRoot":"","sources":["../../../../../packages/cloud/cloudtasks-client/src/ClientCloudTasksFactory.ts"],"names":[],"mappings":";;;;AAAA,yCAAmC;AACnC,oDAAmE;AACnE,0DAAqG;AACrG,uDAAgF;AAGhF,iGAAiG;AACjG,6EAA6E;AAC7E,IAAA,oCAAqB,EAAC,4CAA0B,EAAE,iCAAe,CAAC,CAAC;AAEnE;;;GAGG;AACH,MAAM,+BAA+B,GAAG,IAAI,GAAG,CAAS;IACpD,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS;IAC3E,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU;CACrE,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AAGI,IAAM,uBAAuB,GAA7B,MAAM,uBAAuB;IAEyB;IADzD,YACyD,uBAAkD;QAAlD,4BAAuB,GAAvB,uBAAuB,CAA2B;IACxG,CAAC;IAEJ,kFAAkF;IAClF,kBAAkB,CAAmB,QAAyB,EAAE,MAAwB;QACpF,8DAA8D;QAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,CAAC;QACvD,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,IAAI,YAAY,CAAC;QAE9C,OAAO,IAAI,KAAK,CAAC,EAAO,EAAE;YACtB,oGAAoG;YACpG,GAAG,CAAC,MAAS,EAAE,IAAqB;gBAChC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,+BAA+B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxE,OAAO,SAAS,CAAC;gBACrB,CAAC;gBACD,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjC,MAAM,IAAI,KAAK,CACX,wBAAwB,IAAI,QAAQ,QAAQ,CAAC,IAAI,IAAI,SAAS,IAAI;wBAClE,qDAAqD,CACxD,CAAC;gBACN,CAAC;gBACD,kFAAkF;gBAClF,gDAAgD;gBAChD,oFAAoF;gBACpF,MAAM,YAAY,GAAG,CAAC,UAAmB,EAAiB,EAAE;oBACxD,MAAM,QAAQ,GAAG,uBAAW,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;oBAClE,6EAA6E;oBAC7E,OAAO,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,OAAgB,EAAE,EAAE;wBACpE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;wBAC3B,6GAA6G;wBAC7G,MAAM,OAAO,CAAC;oBAClB,CAAC,CAAC,CAAC;gBACP,CAAC,CAAC;gBACF,OAAO,YAAY,CAAC;YACxB,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;CACJ,CAAA;AAxCY,0DAAuB;kCAAvB,uBAAuB;IAFnC,IAAA,0BAAc,GAAE;IAChB,IAAA,wCAAyB,GAAE;IAGnB,mBAAA,IAAA,kBAAM,EAAC,4CAA0B,CAAC,CAAA;6CAA2C,uBAAQ;GAFjF,uBAAuB,CAwCnC","sourcesContent":["import { inject } from 'inversify';\nimport { ApiCallSite, DocumentDesign } from '@webpieces/core-util';\nimport { Provider, bindFrameworkProvider, provideFrameworkSingleton } from '@webpieces/core-context';\nimport { TASK_PROXY_CLIENT_PROVIDER, TaskProxyClient } from './TaskProxyClient';\nimport { ApiPrototype, TaskClientConfig } from './TaskClientConfig';\n\n// Teach the container how to hand out fresh TaskProxyClients. TaskProxyClient is bound TRANSIENT\n// (@provideFrameworkTransient), so each provider.get() constructs a new one.\nbindFrameworkProvider(TASK_PROXY_CLIENT_PROVIDER, TaskProxyClient);\n\n/**\n * Properties DI frameworks / Promise checks / serializers probe on the proxy; return\n * undefined instead of treating them as endpoints. Mirrors http-client-core's buildClientProxy.\n */\nconst FRAMEWORK_INSPECTION_PROPERTIES = new Set<string>([\n 'constructor', 'prototype', '__proto__', 'name', 'then', 'catch', 'finally',\n 'toJSON', 'valueOf', 'toString', 'nodeType', 'tagName', '$$typeof',\n]);\n\n/**\n * ClientCloudTasksFactory - builds Cloud Tasks enqueue clients from a shared @PubSub API\n * contract. The fire-and-forget twin of http-client-node's ClientHttpFactory.\n *\n * Calling a method on the returned client ENQUEUES a task (it does not call remotely); the task\n * is later delivered to the same endpoint's controller through the full server filter chain.\n *\n * ```typescript\n * // same project + region as this container; the URL is derived, you maintain nothing\n * const emailTasks = factory.createPubSubClient(EmailApi, new TaskClientConfig('email-svc'));\n * await scheduler.addToQueue(() => emailTasks.sendEmail(req), { dedupName });\n * ```\n *\n * Every client it builds gets its OWN {@link TaskProxyClient} from the injected\n * `Provider<TaskProxyClient>` (bound transient), which `createPubSubClient` then `init`s for one\n * contract. Their collaborators (TaskInvoker, RequestContextHeaders) come from the container.\n *\n * Node-only, so the factory IS the inversify entry point. An enqueue outside\n * `RequestContext.run(...)` throws rather than silently dropping the caller's trace.\n */\n@DocumentDesign()\n@provideFrameworkSingleton()\nexport class ClientCloudTasksFactory {\n constructor(\n @inject(TASK_PROXY_CLIENT_PROVIDER) private readonly taskProxyClientProvider: Provider<TaskProxyClient>,\n ) {}\n\n /** Typed enqueue client for a @PubSub contract, delivered to `config.svcName`. */\n createPubSubClient<T extends object>(apiClass: ApiPrototype<T>, config: TaskClientConfig): T {\n // Fresh instance per contract — TaskProxyClient is transient.\n const proxyClient = this.taskProxyClientProvider.get();\n proxyClient.init(apiClass, config);\n const apiName = apiClass.name || 'UnknownApi';\n\n return new Proxy({} as T, {\n // webpieces-disable no-any-unknown -- proxy get trap returns either an endpoint method or undefined\n get(target: T, prop: string | symbol): unknown {\n if (typeof prop !== 'string' || FRAMEWORK_INSPECTION_PROPERTIES.has(prop)) {\n return undefined;\n }\n if (!proxyClient.hasEndpoint(prop)) {\n throw new Error(\n `No @PubSub endpoint '${prop}' on ${apiClass.name || 'Unknown'}. ` +\n `Check for typos or a missing @Endpoint() decorator.`,\n );\n }\n // Same call-site capture as the HTTP clients (#1175): synchronous, trimmed to the\n // caller, parked on the SAME rejected instance.\n // webpieces-disable no-any-unknown -- request DTO type is erased at the proxy layer\n const clientMethod = (requestDto: unknown): Promise<void> => {\n const callSite = ApiCallSite.capture(apiName, prop, clientMethod);\n // webpieces-disable no-any-unknown -- a rejection value is genuinely unknown\n return proxyClient.enqueue(prop, requestDto).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}\n"]}