@panter/cloud-tasks 0.0.0-fix-types-e385e6ee

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 ADDED
@@ -0,0 +1,176 @@
1
+ # 🚀 Google Cloud Tasks, Simplified
2
+
3
+ A lightweight library that streamlines the use of **Google Cloud Tasks**.
4
+
5
+ ## 🔹 Why Use This Library?
6
+
7
+ Using Google Cloud Tasks typically requires:
8
+
9
+ 1. Implementing a worker service.
10
+ 2. Defining and managing the API between the worker and client.
11
+ 3. Handling task queue management and scheduling.
12
+ 4. Setting up a local development environment.
13
+ 5. Configuring Google Cloud Tasks to send HTTP requests to the worker.
14
+
15
+ This library eliminates much of this complexity by leveraging **tRPC** to define the API between the worker and the client.
16
+
17
+ ### ✅ Key Features
18
+
19
+ - **Seamless API communication** between workers and clients.
20
+ - **Simple task scheduling** with an intuitive API.
21
+ - **Type safety and jump-to-definition** support via tRPC.
22
+ - **Built-in support for local development** with a Cloud Tasks emulator.
23
+
24
+ ---
25
+
26
+ ## 📂 Example Usage
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.
29
+
30
+ ### Project Structure
31
+
32
+ ```plaintext
33
+ .
34
+ └── apps/
35
+ ├── tasks-worker-when-multiple/
36
+ │ ├── api.ts
37
+ │ └── index.ts
38
+ ├── tasks-worker-this-is-nice-convention/
39
+ │ ├── api.ts
40
+ │ └── index.ts
41
+ └── some-backend-api/
42
+ └── src/
43
+ └── someEndpoint.ts
44
+ ```
45
+
46
+ ---
47
+
48
+ ### 🛠 Step 1: Create the Task Worker (`api.ts`)
49
+
50
+ Define a **tRPC-powered task server**:
51
+
52
+ ```ts
53
+ import { logger } from "@repo/logger";
54
+ import { createTasksServer } from "@panter/cloud-tasks/server";
55
+ import { z } from "zod";
56
+
57
+ logger.info("Starting tasks server...");
58
+
59
+ export const { runServer, router } = createTasksServer((t) =>
60
+ t.router({
61
+ getUser: t.procedure.input(z.string()).query((opts) => {
62
+ return { id: opts.input, name: "Bilbo" };
63
+ }),
64
+ createUser: t.procedure
65
+ .input(z.object({ name: z.string().min(5) }))
66
+ .mutation(async (opts) => {
67
+ await new Promise((resolve) => setTimeout(resolve, 1000));
68
+ return { id: "1", name: opts.input.name };
69
+ }),
70
+ doNothing: t.procedure.mutation(() => {
71
+ logger.info("Executing a no-op task");
72
+ }),
73
+ sendEmail: t.procedure.mutation(() => {}),
74
+ }),
75
+ );
76
+
77
+ // Export the router type for use in the client
78
+ export type Router = typeof router;
79
+ ```
80
+
81
+ ---
82
+
83
+ ### 🚀 Step 2: Start the Task Worker (`index.ts`)
84
+
85
+ Initialize the worker server:
86
+
87
+ ```ts
88
+ import { logger } from "@repo/logger";
89
+ import { runServer } from "./api";
90
+
91
+ const port = parseInt(process.env.PORT);
92
+ runServer(port);
93
+ logger.info(`🚀 Task worker tRPC server running at http://localhost:${port}/`);
94
+ ```
95
+
96
+ ---
97
+
98
+ ### 🏗 Step 3: Create the Task Client (`some-backend-api`)
99
+
100
+ Now, in the backend API (`some-backend-api`), define a **task client** to send tasks:
101
+
102
+ ```ts
103
+ import { builder } from "../builder";
104
+ import { logger } from "@repo/logger";
105
+
106
+ // Import the router type from the worker
107
+ import type { Router } from "@repo/tasks-worker-when-multiple/api";
108
+ import { createTasksClient } from "@panter/cloud-tasks/client";
109
+
110
+ const tasks = createTasksClient<Router>({
111
+ tasksWorkerUrl: new URL(process.env.TASKS_WORKER_URL),
112
+ queueName: "reasonable-queue-name",
113
+ useEmulator: process.env.ENV_SHORT === "local", // Enable emulator in local development
114
+ logger,
115
+ });
116
+
117
+ builder.mutationField("runJob", (t) =>
118
+ t.field({
119
+ type: "String",
120
+ resolve: async () => {
121
+ // Schedule a task with a payload
122
+ await tasks.createUser.schedule({ name: "Bilbo Baggins" });
123
+ // ^^^^^^^^^^ Try jumping to definition here!
124
+ return "ok";
125
+ },
126
+ }),
127
+ );
128
+ ```
129
+
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`:
133
+
134
+ ```json
135
+ {
136
+ "dependencies": {
137
+ "@panter/cloud-tasks": "^0.0.1"
138
+ },
139
+ "devDependencies": {
140
+ "@repo/tasks-worker-when-multiple": "workspace:*"
141
+ }
142
+ }
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 🛠 Local Development: Using Cloud Tasks Emulator
148
+
149
+ For local testing, use the **Cloud Tasks Emulator** with Docker:
150
+
151
+ ```yml
152
+ version: "3.1"
153
+
154
+ services:
155
+ gcloud-tasks-emulator:
156
+ image: ghcr.io/aertje/cloud-tasks-emulator:latest
157
+ command: -host 0.0.0.0 -port 8123
158
+ ports:
159
+ - "6020:8123"
160
+ # NOTE: Comment out `extra_hosts` if using Podman (see: https://github.com/containers/podman/issues/21681)
161
+ extra_hosts:
162
+ - "host.containers.internal:host-gateway"
163
+ ```
164
+
165
+ ---
166
+
167
+ ## 🎯 Summary
168
+
169
+ This library makes **Google Cloud Tasks** easy to use by:
170
+
171
+ - Removing the need for manual HTTP request handling.
172
+ - Providing a **type-safe, tRPC-powered API**.
173
+ - Enabling seamless communication between workers and clients.
174
+ - Offering **built-in support for local development**.
175
+
176
+ 💡 **With this library, scheduling background tasks is as simple as calling a function!** 🚀
@@ -0,0 +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");
@@ -0,0 +1,60 @@
1
+ import type { google } from "@google-cloud/tasks/build/protos";
2
+ import type { CreateTRPCProxyClient } from "@trpc/client";
3
+ import type { AnyRouter } from "@trpc/server";
4
+ import type { GcpLocation, TaskConfig } from "./tasksClients";
5
+ export type Logger = {
6
+ info: (metadata: Record<string, unknown>, message: string) => void;
7
+ warn: (metadata: Record<string, unknown>, message: string) => void;
8
+ error: (metadata: Record<string, unknown>, message: string) => void;
9
+ };
10
+ export declare function createTasksClient<Router extends AnyRouter>({ queueName, useEmulator, location, tasksWorkerUrl, queueOptions, logger, }: {
11
+ queueName: string;
12
+ useEmulator?: boolean;
13
+ location?: GcpLocation;
14
+ queueOptions?: Omit<google.cloud.tasks.v2.IQueue, "name">;
15
+ tasksWorkerUrl: URL;
16
+ logger: Logger;
17
+ }): ScheduleClient<CreateTRPCProxyClient<Router>, RemoveNeverKeys<CreateTRPCProxyClient<Router> extends infer T ? { [K in keyof T]: CreateTRPCProxyClient<Router>[K] extends {
18
+ mutate: (...args: infer _A) => unknown;
19
+ } ? CreateTRPCProxyClient<Router>[K] : never; } : never>>;
20
+ type RemoveNeverKeys<T> = {
21
+ [K in keyof T as T[K] extends never ? never : K]: T[K];
22
+ };
23
+ type OnlyMutate<T> = RemoveNeverKeys<{
24
+ [K in keyof T]: T[K] extends {
25
+ mutate: (...args: infer _A) => unknown;
26
+ } ? T[K] : never;
27
+ }>;
28
+ type ScheduleResult = string;
29
+ type ExtractScheduleFunc<T> = T extends {
30
+ mutate: (...args: infer _A) => unknown;
31
+ } ? (input: Parameters<T["mutate"]>[0], taskConfig?: TaskConfig) => Promise<ScheduleResult> : never;
32
+ type ScheduleClientManage = {
33
+ find: (taskPath: string) => Promise<google.cloud.tasks.v2.ITask | null>;
34
+ list: () => Promise<google.cloud.tasks.v2.ITask[]>;
35
+ };
36
+ /**
37
+ * implementation is in return of `createTasksClient` function
38
+ */
39
+ type ScheduleClient<T, M = OnlyMutate<T>> = {
40
+ [K in keyof M]: {
41
+ /**
42
+ * Schedule a task with given input.
43
+ * Implementation is in return of `createTasksClient` function.
44
+ *
45
+ * @param input - input for the task
46
+ * @param taskConfig - additional configuration for the task
47
+ *
48
+ * @returns full task path
49
+ * @throws {Error} if task scheduling fails, `cause` property contains details
50
+ */
51
+ schedule: ExtractScheduleFunc<M[K]>;
52
+ };
53
+ } & {
54
+ /**
55
+ * implementation is in return of `createTasksClient` function
56
+ */
57
+ _manage: ScheduleClientManage;
58
+ };
59
+ export {};
60
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +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,MAAM,GACP,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,YAAY,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1D,cAAc,EAAE,GAAG,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,oHA+DE,CAAC;YAAqC,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO;0DAPtE;AAED,KAAK,eAAe,CAAC,CAAC,IAAI;KACvB,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACvD,CAAC;AAEF,KAAK,UAAU,CAAC,CAAC,IAAI,eAAe,CAAC;KAClC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAA;KAAE,GACnE,CAAC,CAAC,CAAC,CAAC,GACJ,KAAK;CACV,CAAC,CAAC;AAEH,KAAK,cAAc,GAAG,MAAM,CAAC;AAE7B,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,SAAS;IACtC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;CACxC,GACG,CACE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EACjC,UAAU,CAAC,EAAE,UAAU,KACpB,OAAO,CAAC,cAAc,CAAC,GAC5B,KAAK,CAAC;AAEV,KAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACxE,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,KAAK,cAAc,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI;KACzC,CAAC,IAAI,MAAM,CAAC,GAAG;QACd;;;;;;;;;WASG;QACH,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACrC;CACF,GAAG;IACF;;OAEG;IACH,OAAO,EAAE,oBAAoB,CAAC;CAC/B,CAAC"}
@@ -0,0 +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};
package/dist/index.cjs ADDED
@@ -0,0 +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");
@@ -0,0 +1,3 @@
1
+ export * from "./client";
2
+ export * from "./server";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
package/dist/index.mjs ADDED
@@ -0,0 +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};
@@ -0,0 +1 @@
1
+ "use strict";var a=Object.create;var p=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty;var s=(e,r)=>p(e,"name",{value:r,configurable:!0});var T=(e,r)=>{for(var t in r)p(e,t,{get:r[t],enumerable:!0})},i=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of f(r))!x.call(e,o)&&o!==t&&p(e,o,{get:()=>r[o],enumerable:!(n=R(r,o))||n.enumerable});return e};var d=(e,r,t)=>(t=e!=null?a(y(e)):{},i(r||!e||!e.__esModule?p(t,"default",{value:e,enumerable:!0}):t,e)),v=e=>i(p({},"__esModule",{value:!0}),e);var A={};T(A,{createTasksServer:()=>l});module.exports=v(A);var u=require("@trpc/server"),c=require("@trpc/server/adapters/express"),m=d(require("express"));function l(e){let r=u.initTRPC.create(),t=e(r),n=(0,m.default)();return n.use("/trpc",(0,c.createExpressMiddleware)({router:t})),{runServer:s(o=>{n.listen({port:o})},"runServer"),router:t}}s(l,"createTasksServer");
@@ -0,0 +1,7 @@
1
+ import type { AnyRouter } from "@trpc/server";
2
+ import { initTRPC } from "@trpc/server";
3
+ export declare function createTasksServer<Router extends AnyRouter>(createRouter: (t: ReturnType<(typeof initTRPC)["create"]>) => Router): {
4
+ runServer: (port: number) => void;
5
+ router: Router;
6
+ };
7
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,iBAAiB,CAAC,MAAM,SAAS,SAAS,EACxD,YAAY,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,MAAM;sBAShD,MAAM;;EAK3B"}
@@ -0,0 +1 @@
1
+ var s=Object.defineProperty;var t=(e,r)=>s(e,"name",{value:r,configurable:!0});import{initTRPC as i}from"@trpc/server";import{createExpressMiddleware as u}from"@trpc/server/adapters/express";import c from"express";function y(e){let r=i.create(),o=e(r),n=c();return n.use("/trpc",u({router:o})),{runServer:t(p=>{n.listen({port:p})},"runServer"),router:o}}t(y,"createTasksServer");export{y as createTasksServer};
@@ -0,0 +1 @@
1
+ "use strict";var l=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var i=(o,t)=>l(o,"name",{value:t,configurable:!0});var q=(o,t)=>{for(var e in t)l(o,e,{get:t[e],enumerable:!0})},E=(o,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of w(t))!f.call(o,s)&&s!==e&&l(o,s,{get:()=>t[s],enumerable:!(r=T(t,s))||r.enumerable});return o};var I=o=>E(l({},"__esModule",{value:!0}),o);var v={};q(v,{EmulatorTasksClient:()=>d,RegularTasksClient:()=>m});module.exports=I(v);var k=require("@google-cloud/tasks"),P=require("@grpc/grpc-js"),y=require("google-auth-library"),p=require("google-gax"),n=require("ts-results-es");var h=class{constructor(t,e,r,s){this.client=t;this.location=e;this.queueName=r;this.logger=s;this.projectIdPromise=this.client.getProjectId(),this.serviceAccountEmailPromise=new y.GoogleAuth().getCredentials().then(a=>a.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),s=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:s},"upserting tasks queue");let a="create";try{await this.client.getQueue({name:r}),a="update"}catch(u){if(g(u)&&u.code===p.Status.NOT_FOUND)a="create";else throw u}return a==="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:s,queue:{name:r,...t}})),n.Ok.EMPTY}catch(e){return(0,n.Err)(c(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,n.Ok)(r)}catch(t){return(0,n.Err)(c(t))}}async createTask(t,e){try{let r=await this.projectIdPromise,s=this.client.queuePath(r,this.location,this.queueName),a=this.client.taskPath(r,this.location,this.queueName,R(t)),u=await this.serviceAccountEmailPromise;return this.logger.info({queuePath:s,taskPath:a,url:e?.httpRequest?.url,payload:e?.httpRequest?.body,serviceAccountEmail:u},"scheduling task"),await this.client.createTask({parent:s,task:{...e,name:a,httpRequest:{...e?.httpRequest,oidcToken:{serviceAccountEmail:u}}}}),(0,n.Ok)(a)}catch(r){return(0,n.Err)(c(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return(0,n.Ok)(e)}catch(e){return g(e)&&e.code===p.Status.NOT_FOUND?(0,n.Ok)(null):(0,n.Err)(c(e))}}},m=class extends h{static{i(this,"RegularTasksClient")}constructor(t,e,r){super(new k.CloudTasksClient({}),t,e,r)}},d=class extends h{static{i(this,"EmulatorTasksClient")}constructor(t,e,r){super(new k.CloudTasksClient({sslCreds:P.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),s=this.client.locationPath(e,this.location);this.logger.info({queuePath:r,parentPath:s},"upserting simulator tasks queue");try{return await this.client.createQueue({parent:s,queue:{name:r,...t}}),n.Ok.EMPTY}catch(a){return g(a)&&a.code!==p.Status.ALREADY_EXISTS?(0,n.Err)(c(a)):(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"),n.Ok.EMPTY)}}catch(e){return(0,n.Err)(c(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function R(o){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${o}-${new Date().getTime()}-${e}`}i(R,"createUniqueName");function g(o){return o instanceof Error&&"code"in o&&Number.isInteger(o.code)}i(g,"isRpcError");function c(o){return g(o)?{...o,type:"rpc"}:{type:"unknown",error:o}}i(c,"toTasksError");
@@ -0,0 +1,46 @@
1
+ import { CloudTasksClient } from "@google-cloud/tasks";
2
+ import type { google } from "@google-cloud/tasks/build/protos";
3
+ import { Status } from "google-gax";
4
+ import type { Result } from "ts-results-es";
5
+ import { Err, Ok } from "ts-results-es";
6
+ import type { Logger } from "./client";
7
+ export type GcpLocation = "europe-west6" | (string & NonNullable<unknown>);
8
+ type RpcError = {
9
+ type: "rpc";
10
+ code: Status;
11
+ } & Error;
12
+ type UnknownError = {
13
+ type: "unknown";
14
+ error: unknown;
15
+ };
16
+ export type TasksError = RpcError | UnknownError;
17
+ export type TaskConfig = Omit<google.cloud.tasks.v2.ITask, "name">;
18
+ export interface TasksClient {
19
+ upsertQueue(options?: Omit<google.cloud.tasks.v2.IQueue, "name">): Promise<Result<void, TasksError>>;
20
+ getTask(taskPath: string): Promise<Result<google.cloud.tasks.v2.ITask | null, TasksError>>;
21
+ listTasks(): Promise<Result<google.cloud.tasks.v2.ITask[], TasksError>>;
22
+ createTask(taskName: string, task: TaskConfig): Promise<Result<string, TasksError>>;
23
+ }
24
+ declare class CommonTasksClient implements TasksClient {
25
+ protected readonly client: CloudTasksClient;
26
+ protected readonly location: GcpLocation;
27
+ protected readonly queueName: string;
28
+ protected readonly logger: Logger;
29
+ protected serviceAccountEmailPromise: Promise<string | null>;
30
+ protected projectIdPromise: Promise<string>;
31
+ constructor(client: CloudTasksClient, location: GcpLocation, queueName: string, logger: Logger);
32
+ upsertQueue(options?: Omit<google.cloud.tasks.v2.IQueue, "name">): Promise<Err<TasksError> | import("ts-results-es").OkImpl<void>>;
33
+ listTasks(): Promise<Err<TasksError> | Ok<google.cloud.tasks.v2.ITask[]>>;
34
+ createTask(taskName: string, task: TaskConfig): Promise<Err<TasksError> | Ok<string>>;
35
+ getTask(name: string): Promise<Err<TasksError> | Ok<google.cloud.tasks.v2.ITask> | Ok<null>>;
36
+ }
37
+ export declare class RegularTasksClient extends CommonTasksClient {
38
+ constructor(location: GcpLocation, queueName: string, logger: Logger);
39
+ }
40
+ export declare class EmulatorTasksClient extends CommonTasksClient {
41
+ constructor(location: GcpLocation, queueName: string, logger: Logger);
42
+ upsertQueue(options?: Omit<google.cloud.tasks.v2.IQueue, "name">): Promise<Err<TasksError> | import("ts-results-es").OkImpl<void>>;
43
+ createTask(taskName: string, task: TaskConfig): Promise<Err<TasksError> | Ok<string>>;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=tasksClients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasksClients.d.ts","sourceRoot":"","sources":["../src/tasksClients.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,CAAC,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;AAE3E,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,KAAK,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,KAAK,CAAC;AAEV,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEjD,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,WAAW,CACT,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GACnD,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;IAErC,OAAO,CACL,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;IAEnE,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;IAExE,UAAU,CACR,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CACxC;AAED,cAAM,iBAAkB,YAAW,WAAW;IAK1C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB;IAC3C,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW;IACxC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM;IACpC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAPnC,SAAS,CAAC,0BAA0B,EAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7D,SAAS,CAAC,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAGvB,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,WAAW,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM;IAQ7B,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IAkDhE,SAAS;IAgBT,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU;IA+C7C,OAAO,CAAC,IAAI,EAAE,MAAM;CAW3B;AAED,qBAAa,kBAAmB,SAAQ,iBAAiB;gBAC3C,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAGrE;AAED,qBAAa,mBAAoB,SAAQ,iBAAiB;gBAC5C,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAarD,WAAW,CACxB,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IAiDvC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU;CAY7D"}
@@ -0,0 +1 @@
1
+ var P=Object.defineProperty;var a=(o,t)=>P(o,"name",{value:t,configurable:!0});import{CloudTasksClient as k}from"@google-cloud/tasks";import{credentials as y}from"@grpc/grpc-js";import{GoogleAuth as T}from"google-auth-library";import{Status as g}from"google-gax";import{Err as c,Ok as i}from"ts-results-es";var p=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 T().getCredentials().then(s=>s.client_email??null)}static{a(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(h(u)&&u.code===g.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}})),i.EMPTY}catch(e){return c(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 i(r)}catch(t){return c(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,w(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}}}}),i(s)}catch(r){return c(l(r))}}async getTask(t){try{let[e]=await this.client.getTask({name:t});return i(e)}catch(e){return h(e)&&e.code===g.NOT_FOUND?i(null):c(l(e))}}},m=class extends p{static{a(this,"RegularTasksClient")}constructor(t,e,r){super(new k({}),t,e,r)}},d=class extends p{static{a(this,"EmulatorTasksClient")}constructor(t,e,r){super(new k({sslCreds:y.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}}),i.EMPTY}catch(s){return h(s)&&s.code!==g.ALREADY_EXISTS?c(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"),i.EMPTY)}}catch(e){return c(l(e))}}async createTask(t,e){return super.createTask(t,{...e,httpRequest:{...e?.httpRequest,url:e?.httpRequest?.url?.replace("//localhost","//host.containers.internal")}})}};function w(o){let t=new Uint8Array(3);crypto.getRandomValues(t);let e=Buffer.from(t).toString("hex");return`${o}-${new Date().getTime()}-${e}`}a(w,"createUniqueName");function h(o){return o instanceof Error&&"code"in o&&Number.isInteger(o.code)}a(h,"isRpcError");function l(o){return h(o)?{...o,type:"rpc"}:{type:"unknown",error:o}}a(l,"toTasksError");export{d as EmulatorTasksClient,m as RegularTasksClient};
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@panter/cloud-tasks",
3
+ "repository": {
4
+ "type": "git",
5
+ "url": "https://git.panter.ch/open-source/cloud-tasks.git"
6
+ },
7
+ "version": "0.0.0-fix-types-e385e6ee",
8
+ "sideEffects": false,
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.mjs"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./client": {
21
+ "import": {
22
+ "types": "./dist/client.d.ts",
23
+ "default": "./dist/client.mjs"
24
+ },
25
+ "require": {
26
+ "types": "./dist/client.d.ts",
27
+ "default": "./dist/client.cjs"
28
+ }
29
+ },
30
+ "./server": {
31
+ "import": {
32
+ "types": "./dist/server.d.ts",
33
+ "default": "./dist/server.mjs"
34
+ },
35
+ "require": {
36
+ "types": "./dist/server.d.ts",
37
+ "default": "./dist/server.cjs"
38
+ }
39
+ }
40
+ },
41
+ "files": [
42
+ "dist"
43
+ ],
44
+ "scripts": {
45
+ "build": "rm -rf dist/ && tsc -d --emitDeclarationOnly --declarationDir ./dist/ --noEmit false && node build.mjs",
46
+ "lint": "yarn biome check .",
47
+ "test": "echo 'todo: write tests'"
48
+ },
49
+ "dependencies": {
50
+ "@google-cloud/tasks": "^5.5.2",
51
+ "@trpc/client": "^10.45.2",
52
+ "@trpc/server": "^10.45.2",
53
+ "express": "^4.21.2",
54
+ "ts-results-es": "^4.2.0"
55
+ },
56
+ "devDependencies": {
57
+ "@biomejs/biome": "1.9.4",
58
+ "@types/express": "^4.17.21",
59
+ "esbuild": "^0.24.2",
60
+ "prettier": "^3.4.2",
61
+ "typescript": "5.7.3"
62
+ },
63
+ "packageManager": "yarn@4.6.0",
64
+ "stableVersion": "0.0.0"
65
+ }