UNPKG

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.

312 lines (310 loc) • 10.3 kB
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs'); const require_errors = require('../helpers/errors.cjs'); const require_types = require('../types.cjs'); const require_schema = require('./schema.cjs'); const require_net = require('../helpers/net.cjs'); const require_strings = require('../helpers/strings.cjs'); let zod_v3 = require("zod/v3"); //#region src/api/api.ts const realtimeSubscriptionTokenSchema = zod_v3.z.object({ jwt: zod_v3.z.string() }); const sendSignalSuccessResponseSchema = zod_v3.z.object({ data: zod_v3.z.object({ run_id: zod_v3.z.string().min(1) }) }); const checkpointNewRunResponseSchema = zod_v3.z.object({ data: zod_v3.z.object({ fn_id: zod_v3.z.string().min(1), app_id: zod_v3.z.string().min(1), run_id: zod_v3.z.string().min(1), token: zod_v3.z.string().min(1).optional() }) }); var InngestApi = class { _signingKey; _signingKeyFallback; _apiBaseUrl; _fetch; constructor({ baseUrl, signingKey, signingKeyFallback, fetch }) { this._apiBaseUrl = baseUrl; this._signingKey = signingKey; this._signingKeyFallback = signingKeyFallback; this._fetch = fetch; } get apiBaseUrl() { return this._apiBaseUrl(); } get signingKey() { return this._signingKey(); } get signingKeyFallback() { return this._signingKeyFallback(); } get hashedKey() { return require_strings.hashSigningKey(this.signingKey); } get hashedFallbackKey() { if (!this.signingKeyFallback) return; return require_strings.hashSigningKey(this.signingKeyFallback); } async getTargetUrl(path) { return new URL(path, this.apiBaseUrl); } async req(url, options) { const finalUrl = typeof url === "string" ? await this.getTargetUrl(url) : url; try { return require_types.ok(await require_net.fetchWithAuthFallback({ authToken: this.hashedKey, authTokenFallback: this.hashedFallbackKey, fetch: this._fetch(), url: finalUrl, options: { ...options, headers: { "Content-Type": "application/json", ...options?.headers } } })); } catch (error) { return require_types.err(error); } } async getRunSteps(runId) { const result = await this.req(`/v0/runs/${runId}/actions`); if (result.ok) { const res = result.value; const data = await res.json(); if (res.ok) return require_types.ok(require_schema.stepSchema.parse(data)); return require_types.err(require_schema.errorSchema.parse(data)); } return require_types.err({ error: require_errors.getErrorMessage(result.error, "Unknown error retrieving step data"), status: 500 }); } async getRunBatch(runId) { const result = await this.req(`/v0/runs/${runId}/batch`); if (result.ok) { const res = result.value; const data = await res.json(); if (res.ok) return require_types.ok(require_schema.batchSchema.parse(data)); return require_types.err(require_schema.errorSchema.parse(data)); } return require_types.err({ error: require_errors.getErrorMessage(result.error, "Unknown error retrieving event batch"), status: 500 }); } async publish(publishOptions, data) { const isStream = data instanceof ReadableStream; const url = await this.getTargetUrl("/v1/realtime/publish"); url.searchParams.set("channel", publishOptions.channel || ""); if (publishOptions.runId) url.searchParams.set("run_id", publishOptions.runId); for (const topic of publishOptions.topics) url.searchParams.append("topic", topic); const result = await this.req(url, { body: isStream ? data : typeof data === "string" ? data : JSON.stringify(data), method: "POST", headers: { "Content-Type": isStream ? "text/stream" : "application/json" }, ...isStream ? { duplex: "half" } : {} }); if (result.ok) { const res = result.value; if (!res.ok) throw new Error(`Failed to publish event: ${res.status} ${res.statusText}`); return require_types.ok(void 0); } return require_types.err({ error: require_errors.getErrorMessage(result.error, "Unknown error publishing event"), status: 500 }); } async sendSignal(signalOptions, options) { const url = await this.getTargetUrl("/v1/signals"); const body = { signal: signalOptions.signal, data: signalOptions.data }; return require_net.fetchWithAuthFallback({ authToken: this.hashedKey, authTokenFallback: this.hashedFallbackKey, fetch: this._fetch(), url, options: { method: "POST", body: JSON.stringify(body), headers: { "Content-Type": "application/json", ...options?.headers } } }).then(async (res) => { if (res.status === 404) return require_types.ok({ runId: void 0 }); const resClone = res.clone(); let json; try { json = await res.json(); } catch { return require_types.err({ error: `Failed to send signal: ${res.status} ${res.statusText} - ${await resClone.text()}`, status: res.status }); } if (!res.ok) try { return require_types.err(require_schema.errorSchema.parse(json)); } catch { return require_types.err({ error: `Failed to send signal: ${res.status} ${res.statusText} - ${await res.text()}`, status: res.status }); } const parseRes = sendSignalSuccessResponseSchema.safeParse(json); if (!parseRes.success) return require_types.err({ error: `Successfully sent signal, but response parsing failed: ${res.status} ${res.statusText} - ${await resClone.text()}`, status: res.status }); return require_types.ok({ runId: parseRes.data.data.run_id }); }).catch((error) => { return require_types.err({ error: require_errors.getErrorMessage(error, "Unknown error sending signal"), status: 500 }); }); } async getSubscriptionToken(channel, topics) { const url = await this.getTargetUrl("/v1/realtime/token"); const body = topics.map((topic) => ({ channel, name: topic, kind: "run" })); return require_net.fetchWithAuthFallback({ authToken: this.hashedKey, authTokenFallback: this.hashedFallbackKey, fetch: this._fetch(), url, options: { method: "POST", body: JSON.stringify(body), headers: { "Content-Type": "application/json" } } }).then(async (res) => { if (!res.ok) throw new Error(`Failed to get subscription token: ${res.status} ${res.statusText} - ${await res.text()}`); return realtimeSubscriptionTokenSchema.parse(await res.json()).jwt; }).catch((error) => { throw new Error(require_errors.getErrorMessage(error, "Unknown error getting subscription token")); }); } async updateMetadata(args, options) { const payload = { target: args.target, metadata: args.metadata }; const result = await this.req(`/v1/runs/${args.target.run_id}/metadata`, { method: "POST", body: JSON.stringify(payload), headers: options?.headers }); if (!result.ok) return require_types.err({ error: require_errors.getErrorMessage(result.error, "Unknown error updating metadata"), status: 500 }); const res = result.value; if (res.ok) return require_types.ok(void 0); const resClone = res.clone(); let json; try { json = await res.json(); } catch { return require_types.err({ error: `Failed to update metadata: ${res.status} ${res.statusText} - ${await resClone.text()}`, status: res.status }); } try { return require_types.err(require_schema.errorSchema.parse(json)); } catch { return require_types.err({ error: `Failed to update metadata: ${res.status} ${res.statusText}`, status: res.status }); } } /** * Start a new run, optionally passing in a number of steps to initialize the * run with. */ async checkpointNewRun(args) { const body = JSON.stringify({ run_id: args.runId, event: args.event, steps: args.steps, ts: (/* @__PURE__ */ new Date()).valueOf(), request_version: args.executionVersion, retries: args.retries }); const result = await this.req("/v1/checkpoint", { method: "POST", body }); if (!result.ok) throw new Error(require_errors.getErrorMessage(result.error, "Unknown error checkpointing new run")); const res = result.value; if (res.ok) { const rawData = await res.json(); return checkpointNewRunResponseSchema.parse(rawData); } throw new Error(`Failed to checkpoint new run: ${res.status} ${res.statusText} - ${await res.text()}`); } /** * Checkpoint steps for a given sync run. */ async checkpointSteps(args) { const body = JSON.stringify({ fn_id: args.fnId, app_id: args.appId, run_id: args.runId, steps: args.steps, ts: (/* @__PURE__ */ new Date()).valueOf() }); const result = await this.req(`/v1/checkpoint/${args.runId}/steps`, { method: "POST", body }); if (!result.ok) throw new Error(require_errors.getErrorMessage(result.error, "Unknown error checkpointing steps")); const res = result.value; if (!res.ok) throw new Error(`Failed to checkpoint steps: ${res.status} ${res.statusText} - ${await res.text()}`); } /** * Checkpoint steps for a given async run. */ async checkpointStepsAsync(args) { const body = JSON.stringify({ run_id: args.runId, fn_id: args.fnId, qi_id: args.queueItemId, steps: args.steps, ts: (/* @__PURE__ */ new Date()).valueOf() }); const result = await this.req(`/v1/checkpoint/${args.runId}/async`, { method: "POST", body }); if (!result.ok) throw new Error(require_errors.getErrorMessage(result.error, "Unknown error checkpointing async")); const res = result.value; if (!res.ok) throw new Error(`Failed to checkpoint async: ${res.status} ${res.statusText} - ${await res.text()}`); } /** * Fetch the output of a completed run using a token. * * This uses token-based auth (not signing key) and is intended for use by * proxy endpoints that fetch results on behalf of users. * * @param runId - The ID of the run to fetch output for * @param token - The token used to authenticate the request * @returns The raw Response from the API */ async getRunOutput(runId, token) { const url = await this.getTargetUrl(`/v1/http/runs/${runId}/output`); url.searchParams.set("token", token); return this._fetch()(url.toString(), { method: "GET", headers: { "Content-Type": "application/json" } }); } }; //#endregion exports.InngestApi = InngestApi; //# sourceMappingURL=api.cjs.map