@panter/cloud-tasks 1.0.3 → 1.1.1

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/README.md CHANGED
@@ -25,24 +25,27 @@ This library eliminates much of this complexity by leveraging **tRPC** to define
25
25
 
26
26
  ## 📂 Example Usage
27
27
 
28
- Suppose we have two task workers (`when-multiple` and `this-is-nice-convention`) and a backend API (`some-backend-api`) that schedules tasks.
28
+ Suppose we have one tasks worker (`tasks-worker`) and a backend API (`api`) that will be scheduling tasks.
29
29
 
30
30
  ### Project Structure
31
31
 
32
+ An example project structure with Turborepo might look like this:
33
+
32
34
  ```plaintext
33
35
  .
34
36
  └── apps/
35
- ├── tasks-worker-when-multiple/
36
- │ ├── api.ts
37
- │ └── index.ts
38
- ├── tasks-worker-this-is-nice-convention/
37
+ ├── tasks-worker/
39
38
  │ ├── api.ts
40
39
  │ └── index.ts
41
- └── some-backend-api/
40
+ └── api/
42
41
  └── src/
43
42
  └── someEndpoint.ts
44
43
  ```
45
44
 
45
+ > Pro tip: If you have multiple task workers, use naming convention `tasks-worker-<name>`.
46
+
47
+ Two apps that are deployed as two services: `api` and `tasks-worker`.
48
+
46
49
  ---
47
50
 
48
51
  ### 🛠 Step 1: Create the Task Worker (`api.ts`)
@@ -50,7 +53,10 @@ Suppose we have two task workers (`when-multiple` and `this-is-nice-convention`)
50
53
  Define a **tRPC-powered task server**:
51
54
 
52
55
  ```ts
56
+ // apps/tasks-worker/api.ts
57
+
53
58
  import { logger } from "@repo/logger";
59
+ // yarn add @panter/cloud-tasks
54
60
  import { createTasksServer } from "@panter/cloud-tasks/server";
55
61
  import { z } from "zod";
56
62
 
@@ -58,19 +64,17 @@ logger.info("Starting tasks server...");
58
64
 
59
65
  export const { runServer, router } = createTasksServer((t) =>
60
66
  t.router({
61
- getUser: t.procedure.input(z.string()).query((opts) => {
62
- return { id: opts.input, name: "Bilbo" };
63
- }),
64
67
  createUser: t.procedure
65
68
  .input(z.object({ name: z.string().min(5) }))
66
69
  .mutation(async (opts) => {
67
- await new Promise((resolve) => setTimeout(resolve, 1000));
68
- return { id: "1", name: opts.input.name };
70
+ logger.info(`creating user ${opts.input.name}`);
69
71
  }),
70
72
  doNothing: t.procedure.mutation(() => {
71
- logger.info("Executing a no-op task");
73
+ logger.info("doing nothing");
74
+ }),
75
+ sendEmail: t.procedure.mutation(() => {
76
+ logger.info("sending email");
72
77
  }),
73
- sendEmail: t.procedure.mutation(() => {}),
74
78
  }),
75
79
  );
76
80
 
@@ -78,6 +82,10 @@ export const { runServer, router } = createTasksServer((t) =>
78
82
  export type Router = typeof router;
79
83
  ```
80
84
 
85
+ This creates a task server with three tRPC mutations: `createUser`, `doNothing`, and `sendEmail`.
86
+
87
+ Notice that mutations return nothing, as they are called by Google Cloud Tasks and their response is ignored.
88
+
81
89
  ---
82
90
 
83
91
  ### 🚀 Step 2: Start the Task Worker (`index.ts`)
@@ -85,6 +93,8 @@ export type Router = typeof router;
85
93
  Initialize the worker server:
86
94
 
87
95
  ```ts
96
+ // apps/tasks-worker/index.ts
97
+
88
98
  import { logger } from "@repo/logger";
89
99
  import { runServer } from "./api";
90
100
 
@@ -93,24 +103,48 @@ runServer(port);
93
103
  logger.info(`🚀 Task worker tRPC server running at http://localhost:${port}/`);
94
104
  ```
95
105
 
106
+ > Pro tip: Set execution environment for tasks workers to "gen2", deny unauthenticated requests and set higher timeout in catladder:
107
+
108
+ ```ts
109
+ // catladder.ts
110
+
111
+ "tasks-worker": {
112
+ dir: "./apps/tasks-worker",
113
+ deploy: {
114
+ service: {
115
+ allowUnauthenticated: false,
116
+ executionEnvironment: "gen2",
117
+ timeout: "1800s",
118
+ },
119
+ },
120
+ }
121
+ ```
122
+
96
123
  ---
97
124
 
98
- ### 🏗 Step 3: Create the Task Client (`some-backend-api`)
125
+ ### 🏗 Step 3: Create the Task Client in `api`
99
126
 
100
- Now, in the backend API (`some-backend-api`), define a **task client** to send tasks:
127
+ Now, in the backend API (`api`), define a **task client** to send tasks:
101
128
 
102
129
  ```ts
130
+ // apps/api/src/someEndpoint.ts
131
+
103
132
  import { builder } from "../builder";
104
133
  import { logger } from "@repo/logger";
105
134
 
106
- // Import the router type from the worker
107
- import type { Router } from "@repo/tasks-worker-when-multiple/api";
135
+ // NOTE: we import Router type from the tasks-worker without introducing a runtime dependency
136
+ import type { Router } from "../../tasks-worker-gitlab/api.ts";
137
+ // yarn add @panter/cloud-tasks
108
138
  import { createTasksClient } from "@panter/cloud-tasks/client";
109
139
 
110
140
  const tasks = createTasksClient<Router>({
141
+ // TASKS_WORKER_URL is the URL of the task worker service
111
142
  tasksWorkerUrl: new URL(process.env.TASKS_WORKER_URL),
143
+ // special characters are not allowed in queue name
112
144
  queueName: "reasonable-queue-name",
113
- useEmulator: process.env.ENV_SHORT === "local", // Enable emulator in local development
145
+ // enable emulator in local development
146
+ useEmulator: process.env.ENV_SHORT === "local",
147
+ // optional: provide a custom logger
114
148
  logger,
115
149
  });
116
150
 
@@ -127,21 +161,25 @@ builder.mutationField("runJob", (t) =>
127
161
  );
128
162
  ```
129
163
 
130
- #### 📌 Important: Avoid Circular Dependencies
131
-
132
- Notice that `Router` is **imported as a type** from `api.ts`. This prevents circular dependencies since `@repo/tasks-worker-when-multiple` is only included as a `devDependency`:
164
+ > Pro tip: Set the `TASKS_WORKER_URL` environment variable to the URL of the task worker service in catladder:
133
165
 
134
- ```json
135
- {
136
- "dependencies": {
137
- "@panter/cloud-tasks": "^0.0.1"
166
+ ```ts
167
+ // catladder.ts
168
+
169
+ api: {
170
+ dir: "./apps/api",
171
+ vars: {
172
+ public: {
173
+ TASKS_WORKER_URL: "${tasks-worker:ROOT_URL_INTERNAL}",
174
+ }
138
175
  },
139
- "devDependencies": {
140
- "@repo/tasks-worker-when-multiple": "workspace:*"
141
- }
142
176
  }
143
177
  ```
144
178
 
179
+ #### 📌 Important: Avoid Circular Dependencies
180
+
181
+ Notice that `Router` is **imported as a type** and by relative path. This makes sure there won't be a circular dependency when e.g. `taks-worker` needs to import `api` to use some business logic.
182
+
145
183
  ---
146
184
 
147
185
  ## 🛠 Local Development: Using Cloud Tasks Emulator
@@ -149,7 +187,7 @@ Notice that `Router` is **imported as a type** from `api.ts`. This prevents circ
149
187
  For local testing, use the **Cloud Tasks Emulator** with Docker:
150
188
 
151
189
  ```yml
152
- version: "3.1"
190
+ # docker-compose.yml
153
191
 
154
192
  services:
155
193
  gcloud-tasks-emulator:
package/dist/client.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var p=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var i=(s,t)=>p(s,"name",{value:t,configurable:!0});var I=(s,t)=>{for(var e in t)p(s,e,{get:t[e],enumerable:!0})},x=(s,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of v(t))!E.call(s,n)&&n!==e&&p(s,n,{get:()=>t[n],enumerable:!(r=C(t,n))||r.enumerable});return s};var S=s=>x(p({},"__esModule",{value:!0}),s);var L={};I(L,{createTasksClient:()=>O});module.exports=S(L);var y=require("@google-cloud/tasks"),R=require("@grpc/grpc-js"),q=require("google-auth-library"),g=require("google-gax"),a=require("ts-results-es");var h=class{constructor(t,e,r,n){this.client=t;this.location=e;this.queueName=r;this.logger=n;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new q.GoogleAuth().getCredentials().then(o=>o.client_email??null)}static{i(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),n=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:n},"upserting tasks queue");let o="create";try{await this.client.getQueue({name:r}),o="update"}catch(u){if(k(u)&&u.code===g.Status.NOT_FOUND)o="create";else throw u}return o==="update"?(this.logger.info({queuePath:r},"updating existing queue"),await this.client.updateQueue({queue:{name:r,...t}})):(this.logger.info({queuePath:r},"creating new queue"),await this.client.createQueue({parent:n,queue:{name:r,...t}})),a.Ok.EMPTY}catch(e){return(0,a.Err)(l(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[r]=await this.client.listTasks({parent:e});return(0,a.Ok)(r)}catch(t){return(0,a.Err)(l(t))}}async createTask(t,e){try{let r=await this.projectIdPromise,n=this.client.queuePath(r,this.location,this.queueName),o=this.client.taskPath(r,this.location,this.queueName,N(t)),u=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:n,taskPath:o,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:u},"scheduling task"),await this.client.createTask({parent:n,task:{...e,name:o,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:u}}}}),(0,a.Ok)(o)}catch(r){return(0,a.Err)(l(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return(0,a.Ok)(e)}catch(e){return k(e)&&e.code===g.Status.NOT_FOUND?(0,a.Ok)(null):(0,a.Err)(l(e))}}},d=class extends h{static{i(this,"RegularTasksClient")}constructor(t,e,r){super(new y.CloudTasksClient({}),t,e,r)}},m=class extends h{static{i(this,"EmulatorTasksClient")}constructor(t,e,r){super(new y.CloudTasksClient({sslCreds:R.credentials.createInsecure(),servicePath:"localhost",port:6020}),t,e,r)}async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),n=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:n},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:n,queue:{name:r,...t}}),a.Ok.EMPTY}catch(o){return k(o)&&o.code!==g.Status.ALREADY_EXISTS?(0,a.Err)(l(o)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),a.Ok.EMPTY)}}catch(e){return(0,a.Err)(l(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function N(s){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${s}-${new Date().getTime()}-${e}`}i(N,"createUniqueName");function k(s){return s instanceof Error&&"code"in s&&Number.isInteger(s.code)}i(k,"isRpcError");function l(s){return k(s)?{...s,type:"rpc"}:{type:"unknown",error:s}}i(l,"toTasksError");function O({queueName:s,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:r,queueOptions:n,logger:o}){o.info({queueName:s,useEmulator:t,location:e,tasksWorkerUrl:r},"creating tasks client");let u=t?new m(e,s,o):new d(e,s,o);return new Proxy({},{get:i((j,f)=>f==="_manage"?{find:i(c=>u.getTask(c).then(T=>T.unwrap()),"find"),list:i(()=>u.listTasks().then(c=>c.unwrap()),"list")}:{schedule:i(async(c,T)=>{let w=f.toString();await u.upsertQueue(n);let P=new URL(`/trpc/${w}`,r).toString();return o.info({url:P,input:c},"scheduling http request that calls trpc mutation of tasks worker"),(await u.createTask(w,{...T,httpRequest:{httpMethod:"POST",url:P,headers:{"Content-Type":"application/json"},body:c?Buffer.from(JSON.stringify(c)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}i(O,"createTasksClient");
1
+ "use strict";var p=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var i=(o,t)=>p(o,"name",{value:t,configurable:!0});var I=(o,t)=>{for(var e in t)p(o,e,{get:t[e],enumerable:!0})},x=(o,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of v(t))!E.call(o,n)&&n!==e&&p(o,n,{get:()=>t[n],enumerable:!(r=C(t,n))||r.enumerable});return o};var S=o=>x(p({},"__esModule",{value:!0}),o);var L={};I(L,{createTasksClient:()=>O});module.exports=S(L);var y=require("@google-cloud/tasks"),R=require("@grpc/grpc-js"),q=require("google-auth-library"),g=require("google-gax"),a=require("ts-results-es");var h=class{constructor(t,e,r,n){this.client=t;this.location=e;this.queueName=r;this.logger=n;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new q.GoogleAuth().getCredentials().then(s=>s.client_email??null)}static{i(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),n=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:n},"upserting tasks queue");let s="create";try{await this.client.getQueue({name:r}),s="update"}catch(u){if(k(u)&&u.code===g.Status.NOT_FOUND)s="create";else throw u}return s==="update"?(this.logger.info({queuePath:r},"updating existing queue"),await this.client.updateQueue({queue:{name:r,...t}})):(this.logger.info({queuePath:r},"creating new queue"),await this.client.createQueue({parent:n,queue:{name:r,...t}})),a.Ok.EMPTY}catch(e){return(0,a.Err)(l(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[r]=await this.client.listTasks({parent:e});return(0,a.Ok)(r)}catch(t){return(0,a.Err)(l(t))}}async createTask(t,e){try{let r=await this.projectIdPromise,n=this.client.queuePath(r,this.location,this.queueName),s=this.client.taskPath(r,this.location,this.queueName,N(t)),u=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:n,taskPath:s,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:u},"scheduling task"),await this.client.createTask({parent:n,task:{...e,name:s,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:u}}}}),(0,a.Ok)(s)}catch(r){return(0,a.Err)(l(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return(0,a.Ok)(e)}catch(e){return k(e)&&e.code===g.Status.NOT_FOUND?(0,a.Ok)(null):(0,a.Err)(l(e))}}},d=class extends h{static{i(this,"RegularTasksClient")}constructor(t,e,r){super(new y.CloudTasksClient({}),t,e,r)}},m=class extends h{static{i(this,"EmulatorTasksClient")}constructor(t,e,r){super(new y.CloudTasksClient({sslCreds:R.credentials.createInsecure(),servicePath:"localhost",port:6020}),t,e,r)}async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),n=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:n},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:n,queue:{name:r,...t}}),a.Ok.EMPTY}catch(s){return k(s)&&s.code!==g.Status.ALREADY_EXISTS?(0,a.Err)(l(s)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),a.Ok.EMPTY)}}catch(e){return(0,a.Err)(l(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function N(o){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${o}-${new Date().getTime()}-${e}`}i(N,"createUniqueName");function k(o){return o instanceof Error&&"code"in o&&Number.isInteger(o.code)}i(k,"isRpcError");function l(o){return k(o)?{...o,type:"rpc"}:{type:"unknown",error:o}}i(l,"toTasksError");function O({queueName:o,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:r,queueOptions:n,logger:s={error:console.error,info:console.info,warn:console.warn}}){s.info({queueName:o,useEmulator:t,location:e,tasksWorkerUrl:r},"creating tasks client");let u=t?new m(e,o,s):new d(e,o,s);return new Proxy({},{get:i((j,f)=>f==="_manage"?{find:i(c=>u.getTask(c).then(T=>T.unwrap()),"find"),list:i(()=>u.listTasks().then(c=>c.unwrap()),"list")}:{schedule:i(async(c,T)=>{let w=f.toString();await u.upsertQueue(n);let P=new URL(`/trpc/${w}`,r).toString();return s.info({url:P,input:c},"scheduling http request that calls trpc mutation of tasks worker"),(await u.createTask(w,{...T,httpRequest:{httpMethod:"POST",url:P,headers:{"Content-Type":"application/json"},body:c?Buffer.from(JSON.stringify(c)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}i(O,"createTasksClient");
package/dist/client.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare function createTasksClient<Router extends AnyRouter>({ queueName,
13
13
  location?: GcpLocation;
14
14
  queueOptions?: Omit<google.cloud.tasks.v2.IQueue, "name">;
15
15
  tasksWorkerUrl: URL;
16
- logger: Logger;
16
+ logger?: Logger;
17
17
  }): ScheduleClient<CreateTRPCProxyClient<Router>, RemoveNeverKeys<CreateTRPCProxyClient<Router> extends infer T ? { [K in keyof T]: CreateTRPCProxyClient<Router>[K] extends {
18
18
  mutate: (...args: infer _A) => unknown;
19
19
  } ? CreateTRPCProxyClient<Router>[K] : never; } : never>>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.mjs CHANGED
@@ -1 +1 @@
1
- var R=Object.defineProperty;var n=(s,t)=>R(s,"name",{value:t,configurable:!0});import{CloudTasksClient as P}from"@google-cloud/tasks";import{credentials as q}from"@grpc/grpc-js";import{GoogleAuth as C}from"google-auth-library";import{Status as T}from"google-gax";import{Err as l,Ok as c}from"ts-results-es";var g=class{constructor(t,e,r,a){this.client=t;this.location=e;this.queueName=r;this.logger=a;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new C().getCredentials().then(o=>o.client_email??null)}static{n(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting tasks queue");let o="create";try{await this.client.getQueue({name:r}),o="update"}catch(i){if(m(i)&&i.code===T.NOT_FOUND)o="create";else throw i}return o==="update"?(this.logger.info({queuePath:r},"updating existing queue"),await this.client.updateQueue({queue:{name:r,...t}})):(this.logger.info({queuePath:r},"creating new queue"),await this.client.createQueue({parent:a,queue:{name:r,...t}})),c.EMPTY}catch(e){return l(p(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[r]=await this.client.listTasks({parent:e});return c(r)}catch(t){return l(p(t))}}async createTask(t,e){try{let r=await this.projectIdPromise,a=this.client.queuePath(r,this.location,this.queueName),o=this.client.taskPath(r,this.location,this.queueName,v(t)),i=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:a,taskPath:o,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:i},"scheduling task"),await this.client.createTask({parent:a,task:{...e,name:o,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:i}}}}),c(o)}catch(r){return l(p(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return c(e)}catch(e){return m(e)&&e.code===T.NOT_FOUND?c(null):l(p(e))}}},h=class extends g{static{n(this,"RegularTasksClient")}constructor(t,e,r){super(new P({}),t,e,r)}},d=class extends g{static{n(this,"EmulatorTasksClient")}constructor(t,e,r){super(new P({sslCreds:q.createInsecure(),servicePath:"localhost",port:6020}),t,e,r)}async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:a,queue:{name:r,...t}}),c.EMPTY}catch(o){return m(o)&&o.code!==T.ALREADY_EXISTS?l(p(o)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),c.EMPTY)}}catch(e){return l(p(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function v(s){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${s}-${new Date().getTime()}-${e}`}n(v,"createUniqueName");function m(s){return s instanceof Error&&"code"in s&&Number.isInteger(s.code)}n(m,"isRpcError");function p(s){return m(s)?{...s,type:"rpc"}:{type:"unknown",error:s}}n(p,"toTasksError");function K({queueName:s,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:r,queueOptions:a,logger:o}){o.info({queueName:s,useEmulator:t,location:e,tasksWorkerUrl:r},"creating tasks client");let i=t?new d(e,s,o):new h(e,s,o);return new Proxy({},{get:n((E,y)=>y==="_manage"?{find:n(u=>i.getTask(u).then(k=>k.unwrap()),"find"),list:n(()=>i.listTasks().then(u=>u.unwrap()),"list")}:{schedule:n(async(u,k)=>{let f=y.toString();await i.upsertQueue(a);let w=new URL(`/trpc/${f}`,r).toString();return o.info({url:w,input:u},"scheduling http request that calls trpc mutation of tasks worker"),(await i.createTask(f,{...k,httpRequest:{httpMethod:"POST",url:w,headers:{"Content-Type":"application/json"},body:u?Buffer.from(JSON.stringify(u)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}n(K,"createTasksClient");export{K as createTasksClient};
1
+ var R=Object.defineProperty;var n=(o,t)=>R(o,"name",{value:t,configurable:!0});import{CloudTasksClient as P}from"@google-cloud/tasks";import{credentials as q}from"@grpc/grpc-js";import{GoogleAuth as C}from"google-auth-library";import{Status as T}from"google-gax";import{Err as l,Ok as c}from"ts-results-es";var g=class{constructor(t,e,r,a){this.client=t;this.location=e;this.queueName=r;this.logger=a;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new C().getCredentials().then(s=>s.client_email??null)}static{n(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting tasks queue");let s="create";try{await this.client.getQueue({name:r}),s="update"}catch(i){if(m(i)&&i.code===T.NOT_FOUND)s="create";else throw i}return s==="update"?(this.logger.info({queuePath:r},"updating existing queue"),await this.client.updateQueue({queue:{name:r,...t}})):(this.logger.info({queuePath:r},"creating new queue"),await this.client.createQueue({parent:a,queue:{name:r,...t}})),c.EMPTY}catch(e){return l(p(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[r]=await this.client.listTasks({parent:e});return c(r)}catch(t){return l(p(t))}}async createTask(t,e){try{let r=await this.projectIdPromise,a=this.client.queuePath(r,this.location,this.queueName),s=this.client.taskPath(r,this.location,this.queueName,v(t)),i=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:a,taskPath:s,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:i},"scheduling task"),await this.client.createTask({parent:a,task:{...e,name:s,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:i}}}}),c(s)}catch(r){return l(p(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return c(e)}catch(e){return m(e)&&e.code===T.NOT_FOUND?c(null):l(p(e))}}},h=class extends g{static{n(this,"RegularTasksClient")}constructor(t,e,r){super(new P({}),t,e,r)}},d=class extends g{static{n(this,"EmulatorTasksClient")}constructor(t,e,r){super(new P({sslCreds:q.createInsecure(),servicePath:"localhost",port:6020}),t,e,r)}async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:a,queue:{name:r,...t}}),c.EMPTY}catch(s){return m(s)&&s.code!==T.ALREADY_EXISTS?l(p(s)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),c.EMPTY)}}catch(e){return l(p(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function v(o){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${o}-${new Date().getTime()}-${e}`}n(v,"createUniqueName");function m(o){return o instanceof Error&&"code"in o&&Number.isInteger(o.code)}n(m,"isRpcError");function p(o){return m(o)?{...o,type:"rpc"}:{type:"unknown",error:o}}n(p,"toTasksError");function K({queueName:o,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:r,queueOptions:a,logger:s={error:console.error,info:console.info,warn:console.warn}}){s.info({queueName:o,useEmulator:t,location:e,tasksWorkerUrl:r},"creating tasks client");let i=t?new d(e,o,s):new h(e,o,s);return new Proxy({},{get:n((E,y)=>y==="_manage"?{find:n(u=>i.getTask(u).then(k=>k.unwrap()),"find"),list:n(()=>i.listTasks().then(u=>u.unwrap()),"list")}:{schedule:n(async(u,k)=>{let f=y.toString();await i.upsertQueue(a);let w=new URL(`/trpc/${f}`,r).toString();return s.info({url:w,input:u},"scheduling http request that calls trpc mutation of tasks worker"),(await i.createTask(f,{...k,httpRequest:{httpMethod:"POST",url:w,headers:{"Content-Type":"application/json"},body:u?Buffer.from(JSON.stringify(u)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}n(K,"createTasksClient");export{K as createTasksClient};
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var I=Object.create;var p=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var O=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var a=(r,t)=>p(r,"name",{value:t,configurable:!0});var A=(r,t)=>{for(var e in t)p(r,e,{get:t[e],enumerable:!0})},R=(r,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of N(t))!L.call(r,s)&&s!==e&&p(r,s,{get:()=>t[s],enumerable:!(o=S(t,s))||o.enumerable});return r};var M=(r,t,e)=>(e=r!=null?I(O(r)):{},R(t||!r||!r.__esModule?p(e,"default",{value:r,enumerable:!0}):e,r)),j=r=>R(p({},"__esModule",{value:!0}),r);var _={};A(_,{createTasksClient:()=>K,createTasksServer:()=>b});module.exports=j(_);var y=require("@google-cloud/tasks"),q=require("@grpc/grpc-js"),C=require("google-auth-library"),g=require("google-gax"),i=require("ts-results-es");var m=class{constructor(t,e,o,s){this.client=t;this.location=e;this.queueName=o;this.logger=s;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new C.GoogleAuth().getCredentials().then(n=>n.client_email??null)}static{a(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,o=this.client.queuePath(e,this.location,this.queueName),s=this.client.locationPath(e,this.location);this.logger.info({queuePath:o,parentPath:s},"upserting tasks queue");let n="create";try{await this.client.getQueue({name:o}),n="update"}catch(u){if(k(u)&&u.code===g.Status.NOT_FOUND)n="create";else throw u}return n==="update"?(this.logger.info({queuePath:o},"updating existing queue"),await this.client.updateQueue({queue:{name:o,...t}})):(this.logger.info({queuePath:o},"creating new queue"),await this.client.createQueue({parent:s,queue:{name:o,...t}})),i.Ok.EMPTY}catch(e){return(0,i.Err)(l(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[o]=await this.client.listTasks({parent:e});return(0,i.Ok)(o)}catch(t){return(0,i.Err)(l(t))}}async createTask(t,e){try{let o=await this.projectIdPromise,s=this.client.queuePath(o,this.location,this.queueName),n=this.client.taskPath(o,this.location,this.queueName,Q(t)),u=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:s,taskPath:n,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:u},"scheduling task"),await this.client.createTask({parent:s,task:{...e,name:n,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:u}}}}),(0,i.Ok)(n)}catch(o){return(0,i.Err)(l(o))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return(0,i.Ok)(e)}catch(e){return k(e)&&e.code===g.Status.NOT_FOUND?(0,i.Ok)(null):(0,i.Err)(l(e))}}},h=class extends m{static{a(this,"RegularTasksClient")}constructor(t,e,o){super(new y.CloudTasksClient({}),t,e,o)}},d=class extends m{static{a(this,"EmulatorTasksClient")}constructor(t,e,o){super(new y.CloudTasksClient({sslCreds:q.credentials.createInsecure(),servicePath:"localhost",port:6020}),t,e,o)}async upsertQueue(t){try{let e=await this.projectIdPromise,o=this.client.queuePath(e,this.location,this.queueName),s=this.client.locationPath(e,this.location);this.logger.info({queuePath:o,parentPath:s},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:s,queue:{name:o,...t}}),i.Ok.EMPTY}catch(n){return k(n)&&n.code!==g.Status.ALREADY_EXISTS?(0,i.Err)(l(n)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),i.Ok.EMPTY)}}catch(e){return(0,i.Err)(l(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function Q(r){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${r}-${new Date().getTime()}-${e}`}a(Q,"createUniqueName");function k(r){return r instanceof Error&&"code"in r&&Number.isInteger(r.code)}a(k,"isRpcError");function l(r){return k(r)?{...r,type:"rpc"}:{type:"unknown",error:r}}a(l,"toTasksError");function K({queueName:r,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:o,queueOptions:s,logger:n}){n.info({queueName:r,useEmulator:t,location:e,tasksWorkerUrl:o},"creating tasks client");let u=t?new d(e,r,n):new h(e,r,n);return new Proxy({},{get:a((U,f)=>f==="_manage"?{find:a(c=>u.getTask(c).then(T=>T.unwrap()),"find"),list:a(()=>u.listTasks().then(c=>c.unwrap()),"list")}:{schedule:a(async(c,T)=>{let w=f.toString();await u.upsertQueue(s);let P=new URL(`/trpc/${w}`,o).toString();return n.info({url:P,input:c},"scheduling http request that calls trpc mutation of tasks worker"),(await u.createTask(w,{...T,httpRequest:{httpMethod:"POST",url:P,headers:{"Content-Type":"application/json"},body:c?Buffer.from(JSON.stringify(c)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}a(K,"createTasksClient");var v=require("@trpc/server"),E=require("@trpc/server/adapters/express"),x=M(require("express"));function b(r){let t=v.initTRPC.create(),e=r(t),o=(0,x.default)();return o.use("/trpc",(0,E.createExpressMiddleware)({router:e})),{runServer:a(s=>{o.listen({port:s})},"runServer"),router:e}}a(b,"createTasksServer");
1
+ "use strict";var I=Object.create;var p=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var O=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var a=(r,t)=>p(r,"name",{value:t,configurable:!0});var A=(r,t)=>{for(var e in t)p(r,e,{get:t[e],enumerable:!0})},R=(r,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of N(t))!L.call(r,s)&&s!==e&&p(r,s,{get:()=>t[s],enumerable:!(o=S(t,s))||o.enumerable});return r};var M=(r,t,e)=>(e=r!=null?I(O(r)):{},R(t||!r||!r.__esModule?p(e,"default",{value:r,enumerable:!0}):e,r)),j=r=>R(p({},"__esModule",{value:!0}),r);var _={};A(_,{createTasksClient:()=>K,createTasksServer:()=>b});module.exports=j(_);var f=require("@google-cloud/tasks"),q=require("@grpc/grpc-js"),C=require("google-auth-library"),g=require("google-gax"),i=require("ts-results-es");var m=class{constructor(t,e,o,s){this.client=t;this.location=e;this.queueName=o;this.logger=s;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new C.GoogleAuth().getCredentials().then(n=>n.client_email??null)}static{a(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,o=this.client.queuePath(e,this.location,this.queueName),s=this.client.locationPath(e,this.location);this.logger.info({queuePath:o,parentPath:s},"upserting tasks queue");let n="create";try{await this.client.getQueue({name:o}),n="update"}catch(u){if(k(u)&&u.code===g.Status.NOT_FOUND)n="create";else throw u}return n==="update"?(this.logger.info({queuePath:o},"updating existing queue"),await this.client.updateQueue({queue:{name:o,...t}})):(this.logger.info({queuePath:o},"creating new queue"),await this.client.createQueue({parent:s,queue:{name:o,...t}})),i.Ok.EMPTY}catch(e){return(0,i.Err)(l(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[o]=await this.client.listTasks({parent:e});return(0,i.Ok)(o)}catch(t){return(0,i.Err)(l(t))}}async createTask(t,e){try{let o=await this.projectIdPromise,s=this.client.queuePath(o,this.location,this.queueName),n=this.client.taskPath(o,this.location,this.queueName,Q(t)),u=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:s,taskPath:n,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:u},"scheduling task"),await this.client.createTask({parent:s,task:{...e,name:n,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:u}}}}),(0,i.Ok)(n)}catch(o){return(0,i.Err)(l(o))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return(0,i.Ok)(e)}catch(e){return k(e)&&e.code===g.Status.NOT_FOUND?(0,i.Ok)(null):(0,i.Err)(l(e))}}},h=class extends m{static{a(this,"RegularTasksClient")}constructor(t,e,o){super(new f.CloudTasksClient({}),t,e,o)}},d=class extends m{static{a(this,"EmulatorTasksClient")}constructor(t,e,o){super(new f.CloudTasksClient({sslCreds:q.credentials.createInsecure(),servicePath:"localhost",port:6020}),t,e,o)}async upsertQueue(t){try{let e=await this.projectIdPromise,o=this.client.queuePath(e,this.location,this.queueName),s=this.client.locationPath(e,this.location);this.logger.info({queuePath:o,parentPath:s},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:s,queue:{name:o,...t}}),i.Ok.EMPTY}catch(n){return k(n)&&n.code!==g.Status.ALREADY_EXISTS?(0,i.Err)(l(n)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),i.Ok.EMPTY)}}catch(e){return(0,i.Err)(l(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function Q(r){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${r}-${new Date().getTime()}-${e}`}a(Q,"createUniqueName");function k(r){return r instanceof Error&&"code"in r&&Number.isInteger(r.code)}a(k,"isRpcError");function l(r){return k(r)?{...r,type:"rpc"}:{type:"unknown",error:r}}a(l,"toTasksError");function K({queueName:r,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:o,queueOptions:s,logger:n={error:console.error,info:console.info,warn:console.warn}}){n.info({queueName:r,useEmulator:t,location:e,tasksWorkerUrl:o},"creating tasks client");let u=t?new d(e,r,n):new h(e,r,n);return new Proxy({},{get:a((U,y)=>y==="_manage"?{find:a(c=>u.getTask(c).then(T=>T.unwrap()),"find"),list:a(()=>u.listTasks().then(c=>c.unwrap()),"list")}:{schedule:a(async(c,T)=>{let w=y.toString();await u.upsertQueue(s);let P=new URL(`/trpc/${w}`,o).toString();return n.info({url:P,input:c},"scheduling http request that calls trpc mutation of tasks worker"),(await u.createTask(w,{...T,httpRequest:{httpMethod:"POST",url:P,headers:{"Content-Type":"application/json"},body:c?Buffer.from(JSON.stringify(c)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}a(K,"createTasksClient");var v=require("@trpc/server"),E=require("@trpc/server/adapters/express"),x=M(require("express"));function b(r){let t=v.initTRPC.create(),e=r(t),o=(0,x.default)();return o.use("/trpc",(0,E.createExpressMiddleware)({router:e})),{runServer:a(s=>{o.listen({port:s})},"runServer"),router:e}}a(b,"createTasksServer");
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var R=Object.defineProperty;var n=(o,t)=>R(o,"name",{value:t,configurable:!0});import{CloudTasksClient as P}from"@google-cloud/tasks";import{credentials as q}from"@grpc/grpc-js";import{GoogleAuth as C}from"google-auth-library";import{Status as T}from"google-gax";import{Err as l,Ok as c}from"ts-results-es";var g=class{constructor(t,e,r,a){this.client=t;this.location=e;this.queueName=r;this.logger=a;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new C().getCredentials().then(s=>s.client_email??null)}static{n(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting tasks queue");let s="create";try{await this.client.getQueue({name:r}),s="update"}catch(i){if(d(i)&&i.code===T.NOT_FOUND)s="create";else throw i}return s==="update"?(this.logger.info({queuePath:r},"updating existing queue"),await this.client.updateQueue({queue:{name:r,...t}})):(this.logger.info({queuePath:r},"creating new queue"),await this.client.createQueue({parent:a,queue:{name:r,...t}})),c.EMPTY}catch(e){return l(p(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[r]=await this.client.listTasks({parent:e});return c(r)}catch(t){return l(p(t))}}async createTask(t,e){try{let r=await this.projectIdPromise,a=this.client.queuePath(r,this.location,this.queueName),s=this.client.taskPath(r,this.location,this.queueName,v(t)),i=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:a,taskPath:s,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:i},"scheduling task"),await this.client.createTask({parent:a,task:{...e,name:s,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:i}}}}),c(s)}catch(r){return l(p(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return c(e)}catch(e){return d(e)&&e.code===T.NOT_FOUND?c(null):l(p(e))}}},m=class extends g{static{n(this,"RegularTasksClient")}constructor(t,e,r){super(new P({}),t,e,r)}},h=class extends g{static{n(this,"EmulatorTasksClient")}constructor(t,e,r){super(new P({sslCreds:q.createInsecure(),servicePath:"localhost",port:6020}),t,e,r)}async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:a,queue:{name:r,...t}}),c.EMPTY}catch(s){return d(s)&&s.code!==T.ALREADY_EXISTS?l(p(s)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),c.EMPTY)}}catch(e){return l(p(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function v(o){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${o}-${new Date().getTime()}-${e}`}n(v,"createUniqueName");function d(o){return o instanceof Error&&"code"in o&&Number.isInteger(o.code)}n(d,"isRpcError");function p(o){return d(o)?{...o,type:"rpc"}:{type:"unknown",error:o}}n(p,"toTasksError");function U({queueName:o,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:r,queueOptions:a,logger:s}){s.info({queueName:o,useEmulator:t,location:e,tasksWorkerUrl:r},"creating tasks client");let i=t?new h(e,o,s):new m(e,o,s);return new Proxy({},{get:n((S,y)=>y==="_manage"?{find:n(u=>i.getTask(u).then(k=>k.unwrap()),"find"),list:n(()=>i.listTasks().then(u=>u.unwrap()),"list")}:{schedule:n(async(u,k)=>{let f=y.toString();await i.upsertQueue(a);let w=new URL(`/trpc/${f}`,r).toString();return s.info({url:w,input:u},"scheduling http request that calls trpc mutation of tasks worker"),(await i.createTask(f,{...k,httpRequest:{httpMethod:"POST",url:w,headers:{"Content-Type":"application/json"},body:u?Buffer.from(JSON.stringify(u)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}n(U,"createTasksClient");import{initTRPC as E}from"@trpc/server";import{createExpressMiddleware as x}from"@trpc/server/adapters/express";import I from"express";function B(o){let t=E.create(),e=o(t),r=I();return r.use("/trpc",x({router:e})),{runServer:n(a=>{r.listen({port:a})},"runServer"),router:e}}n(B,"createTasksServer");export{U as createTasksClient,B as createTasksServer};
1
+ var R=Object.defineProperty;var n=(o,t)=>R(o,"name",{value:t,configurable:!0});import{CloudTasksClient as P}from"@google-cloud/tasks";import{credentials as q}from"@grpc/grpc-js";import{GoogleAuth as C}from"google-auth-library";import{Status as T}from"google-gax";import{Err as l,Ok as c}from"ts-results-es";var g=class{constructor(t,e,r,a){this.client=t;this.location=e;this.queueName=r;this.logger=a;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new C().getCredentials().then(s=>s.client_email??null)}static{n(this,"CommonTasksClient")}serviceAccountEmailPromise;projectIdPromise;async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting tasks queue");let s="create";try{await this.client.getQueue({name:r}),s="update"}catch(i){if(d(i)&&i.code===T.NOT_FOUND)s="create";else throw i}return s==="update"?(this.logger.info({queuePath:r},"updating existing queue"),await this.client.updateQueue({queue:{name:r,...t}})):(this.logger.info({queuePath:r},"creating new queue"),await this.client.createQueue({parent:a,queue:{name:r,...t}})),c.EMPTY}catch(e){return l(p(e))}}async listTasks(){try{let t=await this.projectIdPromise,e=this.client.queuePath(t,this.location,this.queueName),[r]=await this.client.listTasks({parent:e});return c(r)}catch(t){return l(p(t))}}async createTask(t,e){try{let r=await this.projectIdPromise,a=this.client.queuePath(r,this.location,this.queueName),s=this.client.taskPath(r,this.location,this.queueName,v(t)),i=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:a,taskPath:s,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:i},"scheduling task"),await this.client.createTask({parent:a,task:{...e,name:s,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:i}}}}),c(s)}catch(r){return l(p(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return c(e)}catch(e){return d(e)&&e.code===T.NOT_FOUND?c(null):l(p(e))}}},m=class extends g{static{n(this,"RegularTasksClient")}constructor(t,e,r){super(new P({}),t,e,r)}},h=class extends g{static{n(this,"EmulatorTasksClient")}constructor(t,e,r){super(new P({sslCreds:q.createInsecure(),servicePath:"localhost",port:6020}),t,e,r)}async upsertQueue(t){try{let e=await this.projectIdPromise,r=this.client.queuePath(e,this.location,this.queueName),a=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:a},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:a,queue:{name:r,...t}}),c.EMPTY}catch(s){return d(s)&&s.code!==T.ALREADY_EXISTS?l(p(s)):(this.logger.warn({},"dev warning: the queue was not updated due to the emulator not supporting update"),this.logger.warn({},"if you need to update queue options, restart the emulator"),c.EMPTY)}}catch(e){return l(p(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function v(o){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${o}-${new Date().getTime()}-${e}`}n(v,"createUniqueName");function d(o){return o instanceof Error&&"code"in o&&Number.isInteger(o.code)}n(d,"isRpcError");function p(o){return d(o)?{...o,type:"rpc"}:{type:"unknown",error:o}}n(p,"toTasksError");function U({queueName:o,useEmulator:t=!1,location:e="europe-west6",tasksWorkerUrl:r,queueOptions:a,logger:s={error:console.error,info:console.info,warn:console.warn}}){s.info({queueName:o,useEmulator:t,location:e,tasksWorkerUrl:r},"creating tasks client");let i=t?new h(e,o,s):new m(e,o,s);return new Proxy({},{get:n((S,f)=>f==="_manage"?{find:n(u=>i.getTask(u).then(k=>k.unwrap()),"find"),list:n(()=>i.listTasks().then(u=>u.unwrap()),"list")}:{schedule:n(async(u,k)=>{let y=f.toString();await i.upsertQueue(a);let w=new URL(`/trpc/${y}`,r).toString();return s.info({url:w,input:u},"scheduling http request that calls trpc mutation of tasks worker"),(await i.createTask(y,{...k,httpRequest:{httpMethod:"POST",url:w,headers:{"Content-Type":"application/json"},body:u?Buffer.from(JSON.stringify(u)).toString("base64"):null}})).unwrap()},"schedule")},"get")})}n(U,"createTasksClient");import{initTRPC as E}from"@trpc/server";import{createExpressMiddleware as x}from"@trpc/server/adapters/express";import I from"express";function B(o){let t=E.create(),e=o(t),r=I();return r.use("/trpc",x({router:e})),{runServer:n(a=>{r.listen({port:a})},"runServer"),router:e}}n(B,"createTasksServer");export{U as createTasksClient,B as createTasksServer};
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://git.panter.ch/open-source/cloud-tasks.git"
6
6
  },
7
- "version": "1.0.3",
7
+ "version": "1.1.1",
8
8
  "sideEffects": false,
9
9
  "exports": {
10
10
  ".": {