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.
127 lines (125 loc) • 4.53 kB
JavaScript
import { debugPrefix } from "./consts.js";
import { err, ok } from "../types.js";
import { stepSchema } from "../api/schema.js";
import { PREFERRED_ASYNC_EXECUTION_VERSION } from "../components/execution/InngestExecution.js";
import { formatLogMessage } from "./log.js";
import { ZodError, z } from "zod/v3";
import Debug from "debug";
//#region src/helpers/functions.ts
const devDebug = Debug(`${debugPrefix}:functions`);
/**
* Given a value `v`, return `v` if it's not undefined, otherwise return `null`.
*/
const undefinedToNull = (v) => {
return typeof v === "undefined" ? null : v;
};
const createVersionSchema = (internalLogger) => z.literal(-1).or(z.literal(0)).or(z.literal(1)).or(z.literal(2)).optional().transform((v) => {
if (typeof v === "undefined") {
devDebug("No request version specified by executor; using default");
return {
sdkDecided: true,
version: PREFERRED_ASYNC_EXECUTION_VERSION
};
}
if (v === 0) {
internalLogger.error("V0 execution version is no longer supported");
throw new Error("V0 execution version is no longer supported");
}
if (v === -1) return {
sdkDecided: true,
version: PREFERRED_ASYNC_EXECUTION_VERSION
};
return {
sdkDecided: false,
version: v
};
});
const parseFnData = (data, headerVersion, internalLogger) => {
const versionSchema = createVersionSchema(internalLogger);
const fnDataVersionSchema = z.object({ version: versionSchema });
let version;
let sdkDecided = true;
try {
if (typeof headerVersion !== "undefined") try {
const res = versionSchema.parse(headerVersion);
version = res.version;
sdkDecided = res.sdkDecided;
} catch {}
if (typeof version === "undefined") {
const parsedVersionData = fnDataVersionSchema.parse(data);
version = parsedVersionData.version.version;
sdkDecided = parsedVersionData.version.sdkDecided;
}
return {
version,
sdkDecided,
...z.object({
event: z.record(z.any()),
events: z.array(z.record(z.any())).default([]),
steps: stepSchema,
ctx: z.object({
run_id: z.string(),
fn_id: z.string().optional(),
attempt: z.number().default(0),
max_attempts: z.number().optional(),
disable_immediate_execution: z.boolean().default(false),
use_api: z.boolean().default(false),
qi_id: z.string().optional(),
stack: z.object({
stack: z.array(z.string()).nullable().transform((v) => Array.isArray(v) ? v : []),
current: z.number()
}).optional().nullable()
}).optional().nullable()
}).parse(data)
};
} catch (err$1) {
throw new Error(parseFailureErr(err$1));
}
};
const fetchAllFnData = async ({ data, api, logger }) => {
const result = { ...data };
try {
if (result.ctx?.use_api) {
if (!result.ctx?.run_id) return err(formatLogMessage({
message: "Failed to attempt retrieving data from API",
explanation: "Function execution can't continue. run_id is missing from context."
}));
const [evtResp, stepResp] = await Promise.all([api.getRunBatch(result.ctx.run_id), api.getRunSteps(result.ctx.run_id)]);
if (evtResp.ok) result.events = evtResp.value;
else return err(formatLogMessage({
message: "Failed to retrieve list of events",
explanation: `Function execution can't continue.${evtResp.error?.error ? ` ${evtResp.error.error}` : ""}`
}));
if (stepResp.ok) result.steps = stepResp.value;
else return err(formatLogMessage({
message: "Failed to retrieve steps for function run",
explanation: `Function execution can't continue.${stepResp.error?.error ? ` ${stepResp.error.error}` : ""}`
}));
}
const stepIds = Object.keys(result.steps || {});
if (stepIds.length && !result.ctx?.stack?.stack?.length) result.ctx = {
...result.ctx,
stack: {
stack: stepIds,
current: stepIds.length - 1
}
};
return ok(result);
} catch (error) {
logger.error({ err: error }, "Failed to fetch all function data");
return err(parseFailureErr(error));
}
};
const parseFailureErr = (err$1) => {
let why;
if (err$1 instanceof ZodError) why = err$1.toString();
return formatLogMessage({
message: "Failed to parse data from executor",
explanation: `Function execution can't continue.${why ? ` ${why}` : ""}`,
action: "Make sure that your API is set up to parse incoming request bodies as JSON, like body-parser for Express.",
docs: "https://expressjs.com/en/resources/middleware/body-parser.html"
});
};
//#endregion
export { createVersionSchema, fetchAllFnData, parseFnData, undefinedToNull };
//# sourceMappingURL=functions.js.map