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
JavaScript
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