@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 +67 -29
- package/dist/client.cjs +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.mjs +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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
|
-
└──
|
|
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
|
-
|
|
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("
|
|
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
|
|
125
|
+
### 🏗 Step 3: Create the Task Client in `api`
|
|
99
126
|
|
|
100
|
-
Now, in the backend API (`
|
|
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
|
-
//
|
|
107
|
-
import type { Router } from "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
```
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
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=(
|
|
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
|
|
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>>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAe,MAAM,gBAAgB,CAAC;AAG3E,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnE,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrE,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,SAAS,SAAS,EAAE,EAC1D,SAAS,EACT,WAAmB,EACnB,QAAyB,EACzB,cAAc,EACd,YAAY,EACZ,
|
|
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=(
|
|
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
|
|
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,
|
|
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};
|