inngest
Version:
Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.
1 lines • 21.6 kB
Source Map (JSON)
{"version":3,"file":"api.cjs","names":["z","hashSigningKey","finalUrl: URL","ok","fetchWithAuthFallback","err","data: unknown","stepSchema","errorSchema","getErrorMessage","batchSchema","json: unknown","rawData: unknown"],"sources":["../../src/api/api.ts"],"sourcesContent":["import type { fetch } from \"cross-fetch\";\nimport { z } from \"zod/v3\";\nimport type { ExecutionVersion } from \"../helpers/consts.ts\";\nimport { getErrorMessage } from \"../helpers/errors.ts\";\nimport { fetchWithAuthFallback } from \"../helpers/net.ts\";\nimport { hashSigningKey } from \"../helpers/strings.ts\";\nimport {\n type APIStepPayload,\n err,\n type MetadataTarget,\n type OutgoingOp,\n ok,\n type Result,\n} from \"../types.ts\";\nimport {\n type BatchResponse,\n batchSchema,\n type ErrorResponse,\n errorSchema,\n type StepsResponse,\n stepSchema,\n} from \"./schema.ts\";\n\ntype FetchT = typeof fetch;\n\nconst realtimeSubscriptionTokenSchema = z.object({\n jwt: z.string(),\n});\n\nconst sendSignalSuccessResponseSchema = z.object({\n data: z.object({\n run_id: z.string().min(1),\n }),\n});\n\nconst checkpointNewRunResponseSchema = z.object({\n data: z.object({\n fn_id: z.string().min(1),\n app_id: z.string().min(1),\n run_id: z.string().min(1),\n token: z.string().min(1).optional(),\n }),\n});\n\nexport namespace InngestApi {\n export interface Options {\n baseUrl: () => string | undefined;\n signingKey: () => string | undefined;\n signingKeyFallback: () => string | undefined;\n fetch: () => FetchT;\n }\n\n export interface Subscription {\n topics: string[];\n channel: string;\n }\n\n export interface PublishOptions extends Subscription {\n runId?: string;\n }\n\n export interface SendSignalOptions {\n signal: string;\n data?: unknown;\n }\n\n export interface SendSignalResponse {\n /**\n * The ID of the run that was signaled.\n *\n * If this is undefined, the signal could not be matched to a run.\n */\n runId: string | undefined;\n }\n}\n\nexport class InngestApi {\n private readonly _signingKey: () => string | undefined;\n private readonly _signingKeyFallback: () => string | undefined;\n private readonly _apiBaseUrl: () => string | undefined;\n private readonly _fetch: () => FetchT;\n\n constructor({\n baseUrl,\n signingKey,\n signingKeyFallback,\n fetch,\n }: InngestApi.Options) {\n this._apiBaseUrl = baseUrl;\n this._signingKey = signingKey;\n this._signingKeyFallback = signingKeyFallback;\n this._fetch = fetch;\n }\n\n private get apiBaseUrl(): string | undefined {\n return this._apiBaseUrl();\n }\n\n private get signingKey(): string | undefined {\n return this._signingKey();\n }\n\n private get signingKeyFallback(): string | undefined {\n return this._signingKeyFallback();\n }\n\n private get hashedKey(): string {\n return hashSigningKey(this.signingKey);\n }\n\n private get hashedFallbackKey(): string | undefined {\n if (!this.signingKeyFallback) {\n return;\n }\n\n return hashSigningKey(this.signingKeyFallback);\n }\n\n private async getTargetUrl(path: string): Promise<URL> {\n return new URL(path, this.apiBaseUrl);\n }\n\n private async req(\n url: string | URL,\n options?: RequestInit,\n ): Promise<Result<Response, unknown>> {\n const finalUrl: URL =\n typeof url === \"string\" ? await this.getTargetUrl(url) : url;\n\n try {\n const res = await fetchWithAuthFallback({\n authToken: this.hashedKey,\n authTokenFallback: this.hashedFallbackKey,\n fetch: this._fetch(),\n url: finalUrl,\n options: {\n ...options,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n },\n });\n\n return ok(res);\n } catch (error) {\n return err(error);\n }\n }\n\n async getRunSteps(\n runId: string,\n ): Promise<Result<StepsResponse, ErrorResponse>> {\n const result = await this.req(`/v0/runs/${runId}/actions`);\n if (result.ok) {\n const res = result.value;\n const data: unknown = await res.json();\n\n if (res.ok) {\n return ok(stepSchema.parse(data));\n }\n\n return err(errorSchema.parse(data));\n }\n\n return err({\n error: getErrorMessage(\n result.error,\n \"Unknown error retrieving step data\",\n ),\n status: 500,\n });\n }\n\n async getRunBatch(\n runId: string,\n ): Promise<Result<BatchResponse, ErrorResponse>> {\n const result = await this.req(`/v0/runs/${runId}/batch`);\n if (result.ok) {\n const res = result.value;\n const data: unknown = await res.json();\n\n if (res.ok) {\n return ok(batchSchema.parse(data));\n }\n\n return err(errorSchema.parse(data));\n }\n\n return err({\n error: getErrorMessage(\n result.error,\n \"Unknown error retrieving event batch\",\n ),\n status: 500,\n });\n }\n\n async publish(\n publishOptions: InngestApi.PublishOptions,\n // biome-ignore lint/suspicious/noExplicitAny: anything is acceptable\n data: any,\n ): Promise<Result<void, ErrorResponse>> {\n // todo it may not be a \"text/stream\"\n const isStream = data instanceof ReadableStream;\n\n const url = await this.getTargetUrl(\"/v1/realtime/publish\");\n url.searchParams.set(\"channel\", publishOptions.channel || \"\");\n if (publishOptions.runId) {\n url.searchParams.set(\"run_id\", publishOptions.runId);\n }\n for (const topic of publishOptions.topics) {\n url.searchParams.append(\"topic\", topic);\n }\n\n const result = await this.req(url, {\n body: isStream\n ? data\n : typeof data === \"string\"\n ? data\n : JSON.stringify(data),\n method: \"POST\",\n headers: {\n \"Content-Type\": isStream ? \"text/stream\" : \"application/json\",\n },\n ...(isStream ? { duplex: \"half\" } : {}),\n });\n if (result.ok) {\n const res = result.value;\n if (!res.ok) {\n throw new Error(\n `Failed to publish event: ${res.status} ${res.statusText}`,\n );\n }\n\n return ok<void>(undefined);\n }\n\n return err({\n error: getErrorMessage(result.error, \"Unknown error publishing event\"),\n status: 500,\n });\n }\n\n async sendSignal(\n signalOptions: InngestApi.SendSignalOptions,\n options?: {\n headers?: Record<string, string>;\n },\n ): Promise<Result<InngestApi.SendSignalResponse, ErrorResponse>> {\n const url = await this.getTargetUrl(\"/v1/signals\");\n\n const body = {\n signal: signalOptions.signal,\n data: signalOptions.data,\n };\n\n return fetchWithAuthFallback({\n authToken: this.hashedKey,\n authTokenFallback: this.hashedFallbackKey,\n fetch: this._fetch(),\n url,\n options: {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: {\n \"Content-Type\": \"application/json\",\n ...options?.headers,\n },\n },\n })\n .then(async (res) => {\n // A 404 is valid if the signal was not found.\n if (res.status === 404) {\n return ok<InngestApi.SendSignalResponse>({\n runId: undefined,\n });\n }\n\n // Save a clone of the response we can use to get the text of if we fail\n // to parse the JSON.\n const resClone = res.clone();\n\n // JSON!\n let json: unknown;\n try {\n json = await res.json();\n } catch {\n // res.json() failed so not a valid JSON response\n return err({\n error: `Failed to send signal: ${res.status} ${\n res.statusText\n } - ${await resClone.text()}`,\n status: res.status,\n });\n }\n\n // If we're not 2xx, something went wrong.\n if (!res.ok) {\n try {\n return err(errorSchema.parse(json));\n } catch {\n // schema parse failed\n return err({\n error: `Failed to send signal: ${res.status} ${\n res.statusText\n } - ${await res.text()}`,\n status: res.status,\n });\n }\n }\n\n // If we are 2xx, we should have a run_id.\n const parseRes = sendSignalSuccessResponseSchema.safeParse(json);\n if (!parseRes.success) {\n return err({\n error: `Successfully sent signal, but response parsing failed: ${\n res.status\n } ${res.statusText} - ${await resClone.text()}`,\n status: res.status,\n });\n }\n\n return ok({\n runId: parseRes.data.data.run_id,\n });\n })\n .catch((error) => {\n // Catch-all if various things go wrong\n return err({\n error: getErrorMessage(error, \"Unknown error sending signal\"),\n status: 500,\n });\n });\n }\n\n async getSubscriptionToken(\n channel: string,\n topics: string[],\n ): Promise<string> {\n const url = await this.getTargetUrl(\"/v1/realtime/token\");\n\n const body = topics.map((topic) => ({\n channel,\n name: topic,\n kind: \"run\",\n }));\n\n return fetchWithAuthFallback({\n authToken: this.hashedKey,\n authTokenFallback: this.hashedFallbackKey,\n fetch: this._fetch(),\n url,\n options: {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n },\n })\n .then(async (res) => {\n if (!res.ok) {\n throw new Error(\n `Failed to get subscription token: ${res.status} ${\n res.statusText\n } - ${await res.text()}`,\n );\n }\n\n const data = realtimeSubscriptionTokenSchema.parse(await res.json());\n\n return data.jwt;\n })\n .catch((error) => {\n throw new Error(\n getErrorMessage(error, \"Unknown error getting subscription token\"),\n );\n });\n }\n\n async updateMetadata(\n args: {\n target: MetadataTarget;\n metadata: Array<{\n kind: string;\n op: string;\n values: Record<string, unknown>;\n }>;\n },\n options?: {\n headers?: Record<string, string>;\n },\n ): Promise<Result<void, ErrorResponse>> {\n const payload = { target: args.target, metadata: args.metadata };\n\n const result = await this.req(`/v1/runs/${args.target.run_id}/metadata`, {\n method: \"POST\",\n body: JSON.stringify(payload),\n headers: options?.headers,\n });\n\n if (!result.ok) {\n return err({\n error: getErrorMessage(result.error, \"Unknown error updating metadata\"),\n status: 500,\n });\n }\n\n const res = result.value;\n if (res.ok) {\n return ok<void>(undefined);\n }\n\n const resClone = res.clone();\n\n let json: unknown;\n try {\n json = await res.json();\n } catch {\n return err({\n error: `Failed to update metadata: ${res.status} ${\n res.statusText\n } - ${await resClone.text()}`,\n status: res.status,\n });\n }\n\n try {\n return err(errorSchema.parse(json));\n } catch {\n return err({\n error: `Failed to update metadata: ${res.status} ${res.statusText}`,\n status: res.status,\n });\n }\n }\n\n /**\n * Start a new run, optionally passing in a number of steps to initialize the\n * run with.\n */\n async checkpointNewRun(args: {\n runId: string;\n event: APIStepPayload;\n executionVersion: ExecutionVersion;\n retries: number;\n steps?: OutgoingOp[];\n }): Promise<z.output<typeof checkpointNewRunResponseSchema>> {\n const body = JSON.stringify({\n run_id: args.runId,\n event: args.event,\n steps: args.steps,\n ts: new Date().valueOf(),\n request_version: args.executionVersion,\n retries: args.retries,\n });\n\n const result = await this.req(\"/v1/checkpoint\", {\n method: \"POST\",\n body,\n });\n\n if (!result.ok) {\n throw new Error(\n getErrorMessage(result.error, \"Unknown error checkpointing new run\"),\n );\n }\n\n const res = result.value;\n if (res.ok) {\n const rawData: unknown = await res.json();\n const data = checkpointNewRunResponseSchema.parse(rawData);\n\n return data;\n }\n\n throw new Error(\n `Failed to checkpoint new run: ${res.status} ${\n res.statusText\n } - ${await res.text()}`,\n );\n }\n\n /**\n * Checkpoint steps for a given sync run.\n */\n async checkpointSteps(args: {\n runId: string;\n fnId: string;\n appId: string;\n steps: OutgoingOp[];\n }): Promise<void> {\n const body = JSON.stringify({\n fn_id: args.fnId,\n app_id: args.appId,\n run_id: args.runId,\n steps: args.steps,\n ts: new Date().valueOf(),\n });\n\n const result = await this.req(`/v1/checkpoint/${args.runId}/steps`, {\n method: \"POST\",\n body,\n });\n\n if (!result.ok) {\n throw new Error(\n getErrorMessage(result.error, \"Unknown error checkpointing steps\"),\n );\n }\n\n const res = result.value;\n if (!res.ok) {\n throw new Error(\n `Failed to checkpoint steps: ${res.status} ${\n res.statusText\n } - ${await res.text()}`,\n );\n }\n }\n\n /**\n * Checkpoint steps for a given async run.\n */\n async checkpointStepsAsync(args: {\n runId: string;\n fnId: string;\n queueItemId: string;\n steps: OutgoingOp[];\n }): Promise<void> {\n const body = JSON.stringify({\n run_id: args.runId,\n fn_id: args.fnId,\n qi_id: args.queueItemId,\n steps: args.steps,\n ts: new Date().valueOf(),\n });\n\n const result = await this.req(`/v1/checkpoint/${args.runId}/async`, {\n method: \"POST\",\n body,\n });\n\n if (!result.ok) {\n throw new Error(\n getErrorMessage(result.error, \"Unknown error checkpointing async\"),\n );\n }\n\n const res = result.value;\n if (!res.ok) {\n throw new Error(\n `Failed to checkpoint async: ${res.status} ${\n res.statusText\n } - ${await res.text()}`,\n );\n }\n }\n\n /**\n * Fetch the output of a completed run using a token.\n *\n * This uses token-based auth (not signing key) and is intended for use by\n * proxy endpoints that fetch results on behalf of users.\n *\n * @param runId - The ID of the run to fetch output for\n * @param token - The token used to authenticate the request\n * @returns The raw Response from the API\n */\n async getRunOutput(runId: string, token: string): Promise<Response> {\n const url = await this.getTargetUrl(`/v1/http/runs/${runId}/output`);\n url.searchParams.set(\"token\", token);\n\n return this._fetch()(url.toString(), {\n method: \"GET\",\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n}\n"],"mappings":"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"}