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,292 lines (1,291 loc) • 73.6 kB
TypeScript
import { internalEvents } from "./helpers/consts.js";
import { InngestEndpointAdapter } from "./components/InngestEndpointAdapter.js";
import { AsTuple, IsEqual, IsNever, Public, Simplify, SimplifyDeep } from "./helpers/types.js";
import { Logger } from "./middleware/logger.js";
import { Jsonify } from "./helpers/jsonify.js";
import { DurationLike } from "./helpers/temporal.js";
import { createGroupTools } from "./components/InngestGroupTools.js";
import { Middleware } from "./components/middleware/middleware.js";
import { EventType, EventTypeWithAnySchema } from "./components/triggers/triggers.js";
import { createStepTools } from "./components/InngestStepTools.js";
import { InngestFunction } from "./components/InngestFunction.js";
import { InngestFunctionReference } from "./components/InngestFunctionReference.js";
import { GoInterval } from "./helpers/promises.js";
import { Inngest } from "./components/Inngest.js";
import { z } from "zod/v3";
import { StandardSchemaV1 } from "@standard-schema/spec";
//#region src/types.d.ts
declare namespace types_d_exports {
export { APIStepPayload, ApplyAllMiddlewareCtxExtensions, ApplyAllMiddlewareStepExtensions, ApplyAllMiddlewareTransforms, ApplyMiddlewareStaticTransform, AsyncResponseType, AsyncResponseValue, AuthenticatedIntrospection, BaseContext, Cancellation, CancelledEventPayload, Capabilities, CheckpointingOptions, ClientOptions, ConcurrencyOption, Context, DevServerInfo, EventNameFromTrigger, EventPayload, FailureEventArgs, FailureEventPayload, FinishedEventPayload, FunctionConfig, Handler, HashedOp, InBandRegisterRequest, IncomingOp, InternalCheckpointingOptions, InvocationResult, InvokeTargetFunctionDefinition, InvokedEventPayload, JsonError, Jsonify, LogLevel, MetadataTarget, MinimalEventPayload, Op, OpStack, OpUserland, OutgoingOp, PayloadForAnyInngestFunction, RegisterOptions, RegisterRequest, Response, Result, ScheduledTimerEventPayload, SendEventBaseOutput, SendEventOutput, SendEventOutputWithMiddleware, SendEventResponse, SimplifyDeep, Step, StepMode, StepOpCode, StepOptions, StepOptionsOrId, SubmitOpFn, SupportedFrameworkName, TimeStr, TimeStrBatch, TriggerEventFromFunction, UnauthenticatedIntrospection, WithInvocation, defaultCheckpointingOptions, err, functionConfigSchema, inBandSyncRequestBodySchema, incomingOpSchema, jsonErrorSchema, logLevels, ok, sendEventResponseSchema };
}
declare const baseJsonErrorSchema: z.ZodObject<{
name: z.ZodOptional<z.ZodString>;
error: z.ZodOptional<z.ZodString>;
message: z.ZodOptional<z.ZodString>;
stack: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
name?: string | undefined;
error?: string | undefined;
message?: string | undefined;
stack?: string | undefined;
}, {
name?: string | undefined;
error?: string | undefined;
message?: string | undefined;
stack?: string | undefined;
}>;
type JsonError = z.infer<typeof baseJsonErrorSchema> & {
name: string;
message: string;
cause?: unknown;
};
declare const jsonErrorSchema: z.ZodType<JsonError>;
/**
* The payload for an API endpoint running steps.
*/
type APIStepPayload = {
name: `${internalEvents.HttpRequest}`;
data: {
/**
* The domain that served the original request.
*/
domain: string;
/**
* The method used to trigger the original request.
*/
method: string;
/**
* The URL path of the original request.
*/
path: string;
/**
* The IP that made the original request, fetched from headers.
*/
ip: string;
/**
* The "Content-Type" header of the original request.
*/
content_type: string;
/**
* The query parameters of the original request, as a single string without
* the leading `"?"`.
*/
query_params: string;
/**
* The body of the original request.
*/
body?: string;
/**
* An optional function ID to use for this endpoint. If not provided,
* Inngest will generate a function ID based on the method and path, e.g.
* `"GET /api/hello"`.
*/
fn?: string;
};
};
/**
* The payload for an internal Inngest event that is sent when a function fails.
*
* @public
*/
type FailureEventPayload<P extends EventPayload = EventPayload> = {
name: `${internalEvents.FunctionFailed}`;
data: {
function_id: string;
run_id: string;
error: z.output<typeof jsonErrorSchema>;
event: P;
};
};
/**
* Context arguments specific to a failure event.
*
* @public
*/
type FailureEventArgs<P extends EventPayload = EventPayload> = {
/**
* The event data present in the payload.
*/
event: FailureEventPayload<P>;
/**
* The final error that caused this function to exhaust all retries.
*/
error: Error;
};
/**
* The payload for an internal Inngest event that is sent when a function
* finishes, either by completing successfully or failing.
*
* @public
*/
type FinishedEventPayload = {
name: `${internalEvents.FunctionFinished}`;
data: {
function_id: string;
run_id: string;
correlation_id?: string;
} & ({
error: z.output<typeof jsonErrorSchema>;
} | {
result: unknown;
});
};
/**
* The payload for an internal Inngest event that is sent when a function is
* cancelled.
*/
type CancelledEventPayload = {
name: `${internalEvents.FunctionCancelled}`;
data: {
function_id: string;
run_id: string;
correlation_id?: string;
};
};
/**
* The payload for any generic function invocation event. In practice, the event
* data will be more specific to the function being invoked.
*
* @public
*/
type InvokedEventPayload = Simplify<Omit<EventPayload, "name"> & {
name: `${internalEvents.FunctionInvoked}`;
}>;
/**
* The payload for the event sent to a function when it is triggered by a cron.
*
* @public
*/
type ScheduledTimerEventPayload = Simplify<Omit<EventPayload, "name" | "data" | "id"> & {
name: `${internalEvents.ScheduledTimer}`;
data: {
cron: string;
};
id: string;
}>;
/**
* Unique codes for the different types of operation that can be sent to Inngest
* from SDK step functions.
*/
declare enum StepOpCode {
WaitForSignal = "WaitForSignal",
WaitForEvent = "WaitForEvent",
/**
* Legacy equivalent to `"StepRun"`. Has mixed data wrapping (e.g. `data` or
* `data.data` depending on SDK version), so this is phased out in favour of
* `"StepRun"`, which never wraps.
*
* Note that it is still used for v0 executions for backwards compatibility.
*
* @deprecated Only used for v0 executions; use `"StepRun"` instead.
*/
Step = "Step",
StepRun = "StepRun",
StepError = "StepError",
StepFailed = "StepFailed",
StepPlanned = "StepPlanned",
Sleep = "Sleep",
/**
* Used to signify that the executor has requested that a step run, but we
* could not find that step.
*
* This is likely indicative that a step was renamed or removed from the
* function.
*/
StepNotFound = "StepNotFound",
InvokeFunction = "InvokeFunction",
AiGateway = "AIGateway",
Gateway = "Gateway",
RunComplete = "RunComplete",
DiscoveryRequest = "DiscoveryRequest",
}
/**
* StepModes are used to specify how the SDK should execute a function.
*/
declare enum StepMode {
/**
* A synchronous method of execution, where steps are executed immediately and
* their results are "checkpointed" back to Inngest in real-time.
*/
Sync = "sync",
/**
* The traditional, background method of execution, where all steps are queued
* and executed asynchronously and always triggered by Inngest.
*/
Async = "async",
/**
* The traditional, background method of execution, but step results are
* checkpointed when they can be to reduce latency and the number of requests
* being sent back and forth between Inngest and the SDK.
*/
AsyncCheckpointing = "async_checkpointing",
}
/**
* The type of response you wish to return to an API endpoint when using steps
* within it and we must transition to {@link StepMode.Async}.
*
* In most cases, this defaults to {@link AsyncResponseType.Redirect}.
*/
declare enum AsyncResponseType {
/**
* When switching to {@link StepMode.Async}, respond with a 302 redirect which
* will end the request once the run has completed asynchronously in the
* background.
*/
Redirect = "redirect",
/**
* When switching to {@link StepMode.Async}, respond with a token and run ID
* which can be used to poll for the status of the run.
*/
Token = "token",
}
/**
* The type of response you wish to return to an API endpoint when using steps
* within it and we must transition to {@link StepMode.Async}.
*
* In most cases, this defaults to {@link AsyncResponseType.Redirect}.
*/
type AsyncResponseValue = AsyncResponseType.Redirect | AsyncResponseType.Token;
/**
* The shape of a single operation in a step function. Used to communicate
* desired and received operations to Inngest.
*/
type Op = {
/**
* The unique code for this operation.
*/
op: StepOpCode;
/**
* What {@link StepMode} this step supports. If a step is marked as supporting
* {@link StepMode.Async} we must be in (or switch to) async mode in order to
* execute it.
*/
mode: StepMode;
/**
* The unhashed step name for this operation. This is a legacy field that is
* sometimes used for critical data, like the sleep duration for
* `step.sleep()`.
*
* @deprecated For display name, use `displayName` instead.
*/
name?: string;
/**
* An optional name for this step that can be used to display in the Inngest
* UI.
*/
displayName?: string;
/**
* Any additional data required for this operation to send to Inngest. This
* is not compared when confirming that the operation was completed; use `id`
* for this.
*/
opts?: Record<string, unknown>;
/**
* Any data present for this operation. If data is present, this operation is
* treated as completed.
*/
data?: unknown;
/**
* An error present for this operation. If an error is present, this operation
* is treated as completed, but failed. When this is read from the op stack,
* the SDK will throw the error via a promise rejection when it is read.
*
* This allows users to handle step failures using common tools such as
* try/catch or `.catch()`.
*/
error?: unknown;
/**
* Extra info used to annotate spans associated with this operation.
*/
userland: OpUserland;
/**
* Golang-compatibile `interval.Interval` timing information for this operation.
*/
timing?: GoInterval;
};
/**
* Extra info attached to an operation.
*/
type OpUserland = {
/**
* The unhashed, user-defined ID of the step.
*/
id: string;
/**
* The auto-incremented index for repeated steps (if repeated).
*/
index?: number;
};
declare const incomingOpSchema: z.ZodObject<{
id: z.ZodString;
data: z.ZodOptional<z.ZodAny>;
error: z.ZodOptional<z.ZodAny>;
input: z.ZodOptional<z.ZodAny>;
}, "strip", z.ZodTypeAny, {
id: string;
error?: any;
data?: any;
input?: any;
}, {
id: string;
error?: any;
data?: any;
input?: any;
}>;
type IncomingOp = z.output<typeof incomingOpSchema>;
/**
* The shape of a step operation that is sent to an Inngest Server from an SDK.
*
* @public
*/
type OutgoingOp = Pick<Omit<HashedOp, "userland"> & {
userland?: OpUserland;
}, "id" | "op" | "name" | "opts" | "data" | "error" | "displayName" | "userland" | "timing">;
/**
* The shape of a hashed operation in a step function. Used to communicate
* desired and received operations to Inngest.
*/
type HashedOp = Op & {
/**
* The hashed identifier for this operation, used to confirm that the
* operation was completed when it is received from Inngest.
*/
id: string;
};
/**
* A helper type to represent a stack of operations that will accumulate
* throughout a step function's run. This stack contains an object of
* op hashes to data.
*/
type OpStack = IncomingOp[];
/**
* A function that can be used to submit an operation to Inngest internally.
*/
type SubmitOpFn = (op: Op) => void;
/**
* A sleep-compatible time string such as `"1h30m15s"` that can be sent to
* Inngest to sleep for a given amount of time.
*
* This type includes an empty string too, so make sure to exclude that via
* `Exclude<TimeStr, "">` if you don't want to allow empty strings.
*
* @public
*/
type TimeStr = `${`${number}w` | ""}${`${number}d` | ""}${`${number}h` | ""}${`${number}m` | ""}${`${number}s` | ""}`;
type TimeStrBatch = `${`${number}s`}`;
/**
* Mutates an {@link EventPayload} `T` to include invocation events.
*/
type WithInvocation<T extends EventPayload> = Simplify<{
name: T["name"] | `${internalEvents.FunctionInvoked}`;
} & Omit<T, "name">>;
/**
* Base context object, omitting any extras that may be added by middleware or
* function configuration.
*
* @public
*/
type BaseContext<TClient extends Inngest.Any> = {
/**
* The event data present in the payload.
*/
event: Simplify<EventPayload>;
events: AsTuple<Simplify<EventPayload>>;
/**
* The run ID for the current function execution
*/
runId: string;
step: ReturnType<typeof createStepTools<TClient>>;
/**
* Tools for grouping and coordinating steps.
*/
group: ReturnType<typeof createGroupTools>;
/**
* The current zero-indexed attempt number for this function execution. The
* first attempt will be `0`, the second `1`, and so on. The attempt number
* is incremented every time the function throws an error and is retried.
*/
attempt: number;
/**
* The maximum number of attempts allowed for this function.
*/
maxAttempts?: number;
};
/**
* Builds a context object for an Inngest handler, optionally overriding some
* keys.
*
* @internal
*/
type Context<TClient extends Inngest.Any = Inngest.Any, TOverrides extends Record<string, unknown> = Record<never, never>> = Omit<BaseContext<TClient>, keyof TOverrides> & TOverrides;
/**
* Builds a context object for an Inngest handler, optionally overriding some
* keys.
*
* @internal
*/
declare namespace Context {
/**
* Represents any `Context` object, regardless of generics and inference.
*/
type Any = Context;
}
/**
* The shape of a Inngest function, taking in event, step, ctx, and step
* tooling.
*
* @public
*/
type Handler<TClient extends Inngest.Any, TOverrides extends Record<string, unknown> = Record<never, never>> = (
/**
* The context argument provides access to all data and tooling available to
* the function.
*/
ctx: Context<TClient, TOverrides>) => unknown;
/**
* The shape of a Inngest function, taking in event, step, ctx, and step
* tooling.
*
* @public
*/
declare namespace Handler {
/**
* Represents any `Handler`, regardless of generics and inference.
*/
type Any = Handler<Inngest.Any, any>;
}
/**
* The shape of a single event's payload without any fields used to identify the
* actual event being sent.
*
* This is used to represent an event payload when invoking a function, as the
* event name is not known or needed.
*/
interface MinimalEventPayload<TData = any> {
/**
* A unique id used to idempotently process a given event payload.
*
* Set this when sending events to ensure that the event is only processed
* once; if an event with the same ID is sent again, it will not invoke
* functions.
*/
id?: string;
/**
* Any data pertinent to the event
*/
data?: TData;
/**
* A specific event schema version
* (optional)
*/
v?: string;
}
/**
* The shape of a single event's payload. It should be extended to enforce
* adherence to given events and not used as a method of creating them (i.e. as
* a generic).
*
* @public
*/
interface EventPayload<TData = any> extends MinimalEventPayload<TData> {
/**
* A unique identifier for the type of event. We recommend using lowercase dot
* notation for names, prepending `prefixes/` with a slash for organization.
*
* e.g. `cloudwatch/alarms/triggered`, `cart/session.created`
*/
name: string;
/**
* An integer representing the milliseconds since the unix epoch at which this
* event occurred.
*
* Defaults to the current time.
* (optional)
*/
ts?: number;
}
declare const sendEventResponseSchema: z.ZodObject<{
/**
* Event IDs
*/
ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
/**
* HTTP Status Code. Will be undefined if no request was sent.
*/
status: z.ZodDefault<z.ZodNumber>;
/**
* Error message. Will be undefined if no error occurred.
*/
error: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
status: number;
ids: string[];
error?: string | undefined;
}, {
status?: number | undefined;
error?: string | undefined;
ids?: string[] | undefined;
}>;
/**
* The response from the Inngest Event API
*/
type SendEventResponse = z.output<typeof sendEventResponseSchema>;
/**
* The response in code from sending an event to Inngest.
*
* @public
*/
type SendEventBaseOutput = {
ids: SendEventResponse["ids"];
};
type SendEventOutput<TOpts extends ClientOptions> = Omit<SendEventBaseOutput, keyof SendEventOutputWithMiddleware<TOpts>> & SendEventOutputWithMiddleware<TOpts>;
type SendEventOutputWithMiddleware<_TOpts extends ClientOptions> = SendEventBaseOutput;
/**
* Discriminator for which output transform to extract from middleware.
*/
type TransformKind = "functionOutputTransform" | "stepOutputTransform";
/**
* Extract the `functionOutputTransform` from a middleware class.
*/
type GetMiddlewareRunTransformer<TMw> = TMw extends Middleware.Class ? InstanceType<TMw> extends {
functionOutputTransform: infer TTransform extends Middleware.StaticTransform;
} ? TTransform : Middleware.DefaultStaticTransform : Middleware.DefaultStaticTransform;
/**
* Extract the `stepOutputTransform` from a middleware class.
*/
type GetMiddlewareStepTransformer<TMw> = TMw extends Middleware.Class ? InstanceType<TMw> extends {
stepOutputTransform: infer TTransform extends Middleware.StaticTransform;
} ? TTransform : Middleware.DefaultStaticTransform : Middleware.DefaultStaticTransform;
/**
* Dispatch to the correct transformer extractor based on `TKind`.
*/
type GetMiddlewareTransformerByKind<TMw, TKind extends TransformKind> = TKind extends "functionOutputTransform" ? GetMiddlewareRunTransformer<TMw> : GetMiddlewareStepTransformer<TMw>;
/**
* Apply all middleware transforms in sequence.
* Each middleware's transform is applied to the result of the previous one.
* When no middleware is provided, applies Jsonify as the default transform.
*/
type ApplyAllMiddlewareTransforms<TMw extends Middleware.Class[] | undefined, T, TKind extends TransformKind = "stepOutputTransform"> = TMw extends [Middleware.Class, ...Middleware.Class[]] ? ApplyMiddlewareTransformsInternal<TMw, T, TKind> : Jsonify<T>;
/**
* Internal helper that recursively applies middleware transforms.
* Does NOT apply Jsonify at the end, as that's only for the no-middleware case.
*
* Processes from the end of the array first to match the runtime onion model:
* the last middleware in the array is innermost and transforms first, while the
* first middleware is outermost and transforms last. For `[MW1, MW2]` with
* input `T`, this gives `MW1(MW2(T))`.
*/
type ApplyMiddlewareTransformsInternal<TMw extends Middleware.Class[] | undefined, T, TKind extends TransformKind> = TMw extends [...infer Rest extends Middleware.Class[], infer Last] ? ApplyMiddlewareTransformsInternal<Rest, ApplyMiddlewareStaticTransform<GetMiddlewareTransformerByKind<Last, TKind>, T>, TKind> : T;
/**
* Apply the output transformation using the In/Out interface pattern.
*
* @example
* ```ts
* interface PreserveDate extends MiddlewareStaticTransform {
* Out: this["In"] extends Date ? Date : Jsonify<this["In"]>;
* }
*
* // ApplyStaticTransform<PreserveDate, Date> = Date
* ```
*/
type ApplyMiddlewareStaticTransform<TTransformer extends {
In: unknown;
Out: unknown;
}, T> = (TTransformer & {
In: T;
})["Out"];
/**
* Extract the context extensions from a middleware class (constructor).
* Looks at the return type of `transformFunctionInput` and extracts additional
* properties on `ctx` (excluding base `TransformFunctionInputArgs["ctx"]` properties).
*/
type GetMiddlewareCtxExtensions<T> = T extends Middleware.Class ? InstanceType<T> extends {
transformFunctionInput(arg: Middleware.TransformFunctionInputArgs): {
ctx: infer TCtx;
};
} ? Omit<TCtx, keyof Middleware.TransformFunctionInputArgs["ctx"]> : {} : {};
/**
* Apply all middleware context extensions.
* Each middleware's ctx extensions are merged into the final type.
* When no middleware is provided, returns an empty object.
*/
type ApplyAllMiddlewareCtxExtensions<TMw extends Middleware.Class[] | undefined> = TMw extends [Middleware.Class, ...Middleware.Class[]] ? ApplyMiddlewareCtxExtensionsInternal<TMw> : {};
/**
* Internal helper that recursively merges middleware ctx extensions.
*/
type ApplyMiddlewareCtxExtensionsInternal<TMw extends Middleware.Class[] | undefined> = TMw extends [infer First, ...infer Rest extends Middleware.Class[]] ? GetMiddlewareCtxExtensions<First> & ApplyMiddlewareCtxExtensionsInternal<Rest> : {};
/**
* Extract the step extensions from a middleware class (constructor).
* Looks at the return type of `transformFunctionInput` and extracts additional
* properties on `ctx.step` (excluding base `StepTools` properties).
*/
type GetMiddlewareStepExtensions<T> = T extends Middleware.Class ? InstanceType<T> extends {
transformFunctionInput(arg: Middleware.TransformFunctionInputArgs): {
ctx: {
step: infer TStep;
};
};
} ? Omit<TStep, keyof Middleware.StepTools> : {} : {};
/**
* Apply all middleware step extensions.
* Each middleware's step extensions are merged into the final type.
* When no middleware is provided, returns an empty object.
*/
type ApplyAllMiddlewareStepExtensions<TMw extends Middleware.Class[] | undefined> = TMw extends [Middleware.Class, ...Middleware.Class[]] ? ApplyMiddlewareStepExtensionsInternal<TMw> : {};
/**
* Internal helper that recursively merges middleware step extensions.
*/
type ApplyMiddlewareStepExtensionsInternal<TMw extends Middleware.Class[] | undefined> = TMw extends [infer First, ...infer Rest extends Middleware.Class[]] ? GetMiddlewareStepExtensions<First> & ApplyMiddlewareStepExtensionsInternal<Rest> : {};
/**
* An HTTP-like, standardised response format that allows Inngest to help
* orchestrate steps and retries.
*
* @internal
*/
interface Response {
/**
* A step response must contain an HTTP status code.
*
* A `2xx` response indicates success; this is not a failure and no retry is
* necessary.
*
* A `4xx` response indicates a bad request; this step will not be retried as
* it is deemed irrecoverable. Examples of this might be an event with
* insufficient data or concerning a user that no longer exists.
*
* A `5xx` status indicates a temporary internal error; this will be retried
* according to the step and function's retry policy (3 times, by default).
*
* {@link https://www.inngest.com/docs/functions/function-input-and-output#response-format}
* {@link https://www.inngest.com/docs/functions/retries}
*/
status: number;
/**
* The output of the function - the `body` - can be any arbitrary
* JSON-compatible data. It is then usable by any future steps.
*
* {@link https://www.inngest.com/docs/functions/function-input-and-output#response-format}
*/
body?: unknown;
}
/**
* A single step within a function.
*
* @internal
*/
type Step<TContext = unknown> = (
/**
* The context for this step, including the triggering event and any previous
* step output.
*/
context: TContext) => Promise<Response> | Response;
/**
* A set of options for configuring the Inngest client.
*
* @public
*/
interface ClientOptions {
/**
* The ID of this instance, most commonly a reference to the application it
* resides in.
*
* The ID of your client should remain the same for its lifetime; if you'd
* like to change the name of your client as it appears in the Inngest UI,
* change the `name` property instead.
*/
id: string;
/**
* Inngest event key, used to send events to Inngest Cloud. If not provided,
* will search for the `INNGEST_EVENT_KEY` environment variable. If neither
* can be found, however, a warning will be shown and any attempts to send
* events will throw an error.
*/
eventKey?: string;
/**
* The base URL to use when contacting Inngest.
*
* Defaults to https://inn.gs/ for sending events and https://api.inngest.com
* for all other communication with Inngest.
*/
baseUrl?: string;
/**
* If provided, will override the used `fetch` implementation. Useful for
* giving the library a particular implementation if accessing it is not done
* via globals.
*
* By default the library will try to use the native Web API fetch, falling
* back to a Node implementation if no global fetch can be found.
*
* If you wish to specify your own fetch, make sure that you preserve its
* binding, either by using `.bind` or by wrapping it in an anonymous
* function.
*/
fetch?: typeof fetch;
/**
* The Inngest environment to send events to. Defaults to whichever
* environment this client's event key is associated with.
*
* It's likely you never need to change this unless you're trying to sync
* multiple systems together using branch names.
*/
env?: string;
/**
* The logger provided by the user.
* The user can passed in their winston, pino, and other loggers for
* handling log delivery to external services.
*
* The provider logger is expected to implement the following API interfaces
* - .info()
* - .warn()
* - .debug()
* - .error()
* which most loggers already do.
*
* Defaults to a dummy logger that just log things to the console if nothing is provided.
*/
logger?: Logger;
/**
* A separate logger for SDK internal messages (registration, middleware
* errors, request parsing, etc.). If not provided, falls back to `logger`.
*
* Use this to route SDK internals to a different destination or to tag them
* for filtering, e.g. `pino.child({ component: "inngest" })`.
*
* User function logs via `ctx.logger` are not affected.
*/
internalLogger?: Logger;
/**
* Middleware classes that provide simpler hooks for common operations.
* Each class is instantiated fresh per-request so that middleware can safely
* use `this` for request-scoped state.
*/
middleware?: Middleware.Class[];
/**
* Can be used to explicitly set the client to Development Mode, which will
* turn off signature verification and default to using a local URL to access
* a local Dev Server.
*
* This is useful for forcing the client to use a local Dev Server while also
* running in a production-like environment.
*/
isDev?: boolean;
/**
* The application-specific version identifier. This can be an arbitrary value
* such as a version string, a Git commit SHA, or any other unique identifier.
*/
appVersion?: string;
/**
* Optimizes parallel steps to reduce traffic during `Promise` resolution,
* reducing time and requests per run. `Promise.*()` waits for all promises
* to settle before resolving. Use `group.parallel()` for `Promise.race()`
* semantics.
*
* @default true
*/
optimizeParallelism?: boolean;
/**
* Whether or not to use checkpointing by default for executions of functions
* created using this client.
*
* If `true`, enables checkpointing with default settings, which is a safe,
* blocking version of checkpointing, where we check in with Inngest after
* every step is run.
*
* If an object, you can tweak the settings to batch, set a maximum runtime
* before going async, and more. Note that if your server dies before the
* checkpoint completes, step data will be lost and steps will be rerun.
*
* We recommend starting with the default `true` configuration and only tweak
* the parameters directly if necessary.
*
* @deprecated Use `checkpointing` instead.
*/
experimentalCheckpointing?: CheckpointingOptions;
/**
* Whether or not to use checkpointing by default for executions of functions
* created using this client.
*
* If `false`, disables checkpointing.
*
* If `true`, enables checkpointing with default settings, which is a safe,
* blocking version of checkpointing, where we check in with Inngest after
* every step is run.
*
* If an object, you can tweak the settings to batch, set a maximum runtime
* before going async, and more. Note that if your server dies before the
* checkpoint completes, step data will be lost and steps will be rerun.
*
* We recommend starting with the default `true` configuration and only tweak
* the parameters directly if necessary.
*
* @default true
*/
checkpointing?: CheckpointingOptions;
/**
* The signing key used to authenticate requests from Inngest.
* If not provided, will search for the `INNGEST_SIGNING_KEY` environment variable.
*/
signingKey?: string;
/**
* A fallback signing key used to authenticate requests from Inngest during key rotation.
* If not provided, will search for the `INNGEST_SIGNING_KEY_FALLBACK` environment variable.
*/
signingKeyFallback?: string;
/**
* An optional endpoint adapter to use when creating Durable Endpoints using
* `inngest.endpoint()`.
*/
endpointAdapter?: InngestEndpointAdapter.Like;
}
type CheckpointingOptions = boolean | {
/**
* The maximum amount of time the function should be allowed to checkpoint
* before falling back to async execution.
*
* We recommend setting this to a value slightly lower than your
* platform's request timeout to ensure that functions can complete
* checkpointing before being forcefully terminated.
*
* Set to `0` to disable maximum runtime.
*
* @default 0
*/
maxRuntime?: number | string | DurationLike;
/**
* The number of steps to buffer together before checkpointing. This can
* help reduce the number of requests made to Inngest when running many
* steps in sequence.
*
* Set to `1` to checkpoint after every step.
*
* @default 1
*/
bufferedSteps?: number;
/**
* The maximum interval to wait before checkpointing, even if the buffered
* step count has not been reached.
*/
maxInterval?: number | string | DurationLike;
};
/**
* Internal version of {@link CheckpointingOptions} with the `true` option
* excluded, as that just suggests using the default options.
*/
type InternalCheckpointingOptions = Exclude<Required<CheckpointingOptions>, boolean>;
/**
* Default config options if `true` has been passed by a user.
*/
declare const defaultCheckpointingOptions: InternalCheckpointingOptions;
/**
* A set of log levels that can be used to control the amount of logging output
* from various parts of the Inngest library.
*
* @public
*/
declare const logLevels: readonly ["fatal", "error", "warn", "info", "debug", "silent"];
/**
* A set of log levels that can be used to control the amount of logging output
* from various parts of the Inngest library.
*
* @public
*/
type LogLevel = (typeof logLevels)[number];
/**
* A set of options for configuring the registration of Inngest functions.
*
* @public
*/
interface RegisterOptions {
/**
* The path to the Inngest serve endpoint. e.g.:
*
* "/some/long/path/to/inngest/endpoint"
*
* By default, the library will try to infer this using request details such
* as the "Host" header and request path, but sometimes this isn't possible
* (e.g. when running in a more controlled environments such as AWS Lambda or
* when dealing with proxies/rediects).
*
* Provide the custom path (excluding the hostname) here to ensure that the
* path is reported correctly when registering functions with Inngest.
*
* To also provide a custom hostname, use `serveOrigin`.
*/
servePath?: string;
/**
* The origin used to access the Inngest serve endpoint, e.g.:
*
* "https://myapp.com" or "https://myapp.com:1234"
*
* By default, the library will try to infer this using request details such
* as the "Host" header and request path, but sometimes this isn't possible
* (e.g. when running in a more controlled environments such as AWS Lambda or
* when dealing with proxies/redirects).
*
* Provide the custom origin here to ensure that the path is reported
* correctly when registering functions with Inngest.
*
* To also provide a custom path, use `servePath`.
*/
serveOrigin?: string;
/**
* Some serverless providers (especially those with edge compute) may support
* streaming responses back to Inngest. This can be used to circumvent
* restrictive request timeouts and other limitations. It is only available if
* the serve handler being used supports streaming.
*
* If this is `"true"`, the SDK will attempt to stream responses back
* to Inngest. If the serve handler does not support streaming, an error will be thrown.
*
* If this is `false`, streaming will never be used.
*
* Defaults to `false`.
*/
streaming?: true | false;
}
interface ConcurrencyOption {
/**
* The concurrency limit for this option, adding a limit on how many concurrent
* steps can execute at once.
*/
limit: number;
/**
* An optional concurrency key, as an expression using the common expression language
* (CEL). The result of this expression is used to create new concurrency groups, or
* sub-queues, for each function run.
*
* The event is passed into this expression as "event".
*
* Examples:
* - `event.data.user_id`: this evaluates to the user_id in the event.data object.
* - `event.data.user_id + "-" + event.data.account_id`: creates a new group per user/account
* - `"ai"`: references a custom string
*/
key?: string;
/**
* An optional scope for the concurrency group. By default, concurrency limits are
* scoped to functions - one function's concurrency limits do not impact other functions.
*
* Changing this "scope" allows concurrency limits to work across environments (eg. production
* vs branch environments) or across your account (global).
*/
scope?: "fn" | "env" | "account";
}
/**
* Configuration for cancelling a function run based on an incoming event.
*
* @public
*/
type Cancellation = {
/**
* The name of the event that should cancel the function run.
*/
event: string | EventTypeWithAnySchema<string>;
/**
* The expression that must evaluate to true in order to cancel the function run. There
* are two variables available in this expression:
* - event, referencing the original function's event trigger
* - async, referencing the new cancel event.
*
* @example
*
* Ensures the cancel event's data.user_id field matches the triggering event's data.user_id
* field:
*
* ```ts
* "async.data.user_id == event.data.user_id"
* ```
*/
if?: string;
/**
* If provided, the step function will wait for the incoming event to match
* particular criteria. If the event does not match, it will be ignored and
* the step function will wait for another event.
*
* It must be a string of a dot-notation field name within both events to
* compare, e.g. `"data.id"` or `"user.email"`.
*
* ```
* // Wait for an event where the `user.email` field matches
* match: "user.email"
* ```
*
* All of these are helpers for the `if` option, which allows you to specify
* a custom condition to check. This can be useful if you need to compare
* multiple fields or use a more complex condition.
*
* See the Inngest expressions docs for more information.
*
* {@link https://www.inngest.com/docs/functions/expressions}
*
* @deprecated Use `if` instead.
*/
match?: string;
/**
* An optional timeout that the cancel is valid for. If this isn't
* specified, cancellation triggers are valid for up to a year or until the
* function ends.
*
* The time to wait can be specified using a `number` of milliseconds, an
* `ms`-compatible time string like `"1 hour"`, `"30 mins"`, or `"2.5d"`, or
* a `Date` object.
*
* {@link https://npm.im/ms}
*/
timeout?: number | string | Date;
};
/**
* The response to send to Inngest when pushing function config either directly
* or when pinged by Inngest Cloud.
*
* @internal
*/
interface RegisterRequest {
/**
* The API handler's URL to invoke SDK based functions.
*/
url: string;
/**
* Response version, allowing Inngest to change any top-level field.
*/
v: `${number}.${number}`;
/**
* SDK version from `package.json` for our internal metrics and to warn users
* they need to upgrade.
*/
sdk: `js:v${number}.${number}.${number}${"" | `-${string}.${number}`}`;
/**
* The method used to deploy these functions.
*/
deployType: "ping";
/**
* The name of the framework being used for this instance, e.g. "nextjs",
* "vercel", "netlify", "lambda", etc. Uses the `framework` specified when
* creating a new `InngestCommHandler`.
*/
framework: string;
/**
* The name of this particular app, used for grouping and easier viewing in
* the UI.
*/
appName: string;
/**
* AppVersion represents an optional application version identifier. This should change
* whenever code within one of your Inngest function or any dependency thereof changes.
*/
appVersion?: string;
/**
* The functions available at this particular handler.
*/
functions: FunctionConfig[];
/**
* The deploy ID used to identify this particular deployment.
*/
deployId?: string;
/**
* Capabilities of the SDK.
*/
capabilities: Capabilities;
}
interface Capabilities {
trust_probe: "v1";
connect: "v1";
}
interface InBandRegisterRequest extends Pick<RegisterRequest, "capabilities" | "framework" | "functions" | "sdk" | "url" | "appVersion">, Pick<AuthenticatedIntrospection, "sdk_language" | "sdk_version" | "env"> {
/**
* The ID of the app that this handler is associated with.
*/
app_id: string;
/**
* The result of the introspection request.
*/
inspection: AuthenticatedIntrospection | UnauthenticatedIntrospection;
/**
* ?
*/
platform?: string;
/**
* The person or organization that authored this SDK. Ideally this is
* synonymous with a GitHub username or organization name.
*/
sdk_author: "inngest";
}
/**
* The response to send to the local SDK UI when an introspection request is
* made.
*
* @internal
*/
interface UnauthenticatedIntrospection {
extra: {
native_crypto: boolean;
};
function_count: number;
has_event_key: boolean;
has_signing_key: boolean;
mode: "cloud" | "dev";
schema_version: "2024-05-24";
}
interface AuthenticatedIntrospection extends Omit<UnauthenticatedIntrospection, "authentication_succeeded" | "extra"> {
api_origin: string;
app_id: string;
authentication_succeeded: true;
capabilities: Capabilities;
env: string | null;
event_api_origin: string;
event_key_hash: string | null;
extra: {
is_streaming: boolean;
native_crypto: boolean;
};
framework: string;
sdk_language: string;
sdk_version: string;
serve_origin: string | null;
serve_path: string | null;
signing_key_fallback_hash: string | null;
signing_key_hash: string | null;
}
/**
* The schema used to represent an individual function being synced with
* Inngest.
*
* Note that this should only be used to validate the shape of a config object
* and not used for feature compatibility, such as feature X being exclusive
* with feature Y; these should be handled on the Inngest side.
*/
declare const functionConfigSchema: z.ZodObject<{
name: z.ZodOptional<z.ZodString>;
id: z.ZodString;
triggers: z.ZodArray<z.ZodUnion<[z.ZodObject<{
event: z.ZodString;
expression: z.ZodOptional<z.ZodString>;
}, "strict", z.ZodTypeAny, {
event: string;
expression?: string | undefined;
}, {
event: string;
expression?: string | undefined;
}>, z.ZodObject<{
cron: z.ZodString;
}, "strict", z.ZodTypeAny, {
cron: string;
}, {
cron: string;
}>]>, "many">;
steps: z.ZodRecord<z.ZodString, z.ZodObject<{
id: z.ZodString;
name: z.ZodString;
runtime: z.ZodObject<{
type: z.ZodUnion<[z.ZodLiteral<"http">, z.ZodLiteral<"ws">]>;
url: z.ZodString;
}, "strict", z.ZodTypeAny, {
type: "http" | "ws";
url: string;
}, {
type: "http" | "ws";
url: string;
}>;
retries: z.ZodOptional<z.ZodObject<{
attempts: z.ZodOptional<z.ZodNumber>;
}, "strict", z.ZodTypeAny, {
attempts?: number | undefined;
}, {
attempts?: number | undefined;
}>>;
}, "strict", z.ZodTypeAny, {
name: string;
id: string;
runtime: {
type: "http" | "ws";
url: string;
};
retries?: {
attempts?: number | undefined;
} | undefined;
}, {
name: string;
id: string;
runtime: {
type: "http" | "ws";
url: string;
};
retries?: {
attempts?: number | undefined;
} | undefined;
}>>;
idempotency: z.ZodOptional<z.ZodString>;
batchEvents: z.ZodOptional<z.ZodObject<{
maxSize: z.ZodNumber;
timeout: z.ZodString;
key: z.ZodOptional<z.ZodString>;
if: z.ZodOptional<z.ZodString>;
}, "strict", z.ZodTypeAny, {
maxSize: number;
timeout: string;
key?: string | undefined;
if?: string | undefined;
}, {
maxSize: number;
timeout: string;
key?: string | undefined;
if?: string | undefined;
}>>;
rateLimit: z.ZodOptional<z.ZodObject<{
key: z.ZodOptional<z.ZodString>;
limit: z.ZodNumber;
period: z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>;
}, "strict", z.ZodTypeAny, {
limit: number;
period: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`;
key?: string | undefined;
}, {
limit: number;
period: string;
key?: string | undefined;
}>>;
throttle: z.ZodOptional<z.ZodObject<{
key: z.ZodOptional<z.ZodString>;
limit: z.ZodNumber;
period: z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>;
burst: z.ZodOptional<z.ZodNumber>;
}, "strict", z.ZodTypeAny, {
limit: number;
period: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`;
key?: string | undefined;
burst?: number | undefined;
}, {
limit: number;
period: string;
key?: string | undefined;
burst?: number | undefined;
}>>;
singleton: z.ZodOptional<z.ZodObject<{
key: z.ZodOptional<z.ZodString>;
mode: z.ZodEnum<["skip", "cancel"]>;
}, "strict", z.ZodTypeAny, {
mode: "skip" | "cancel";
key?: string | undefined;
}, {
mode: "skip" | "cancel";
key?: string | undefined;
}>>;
cancel: z.ZodOptional<z.ZodArray<z.ZodObject<{
event: z.ZodString;
if: z.ZodOptional<z.ZodString>;
timeout: z.ZodOptional<z.ZodString>;
}, "strict", z.ZodTypeAny, {
event: string;
timeout?: string | undefined;
if?: string | undefined;
}, {
event: string;
timeout?: string | undefined;
if?: string | undefined;
}>, "many">>;
debounce: z.ZodOptional<z.ZodObject<{
key: z.ZodOptional<z.ZodString>;
period: z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>;
timeout: z.ZodOptional<z.ZodEffects<z.ZodString, "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w${number}d${number}s` | `${number}w${number}d${number}m` | `${number}w${number}d${number}m${number}s` | `${number}w${number}d${number}h` | `${number}w${number}d${number}h${number}s` | `${number}w${number}d${number}h${number}m` | `${number}w${number}d${number}h${number}m${number}s`, string>>;
}, "strict", z.ZodTypeAny, {
period: "" | `${number}w` | `${number}d` | `${number}h` | `${number}m` | `${number}s` | `${number}m${number}s` | `${number}h${number}s` | `${number}h${number}m` | `${number}h${number}m${number}s` | `${number}d${number}s` | `${number}d${number}m` | `${number}d${number}m${number}s` | `${number}d${number}h` | `${number}d${number}h${number}s` | `${number}d${number}h${number}m` | `${number}d${number}h${number}m${number}s` | `${number}w${number}s` | `${number}w${number}m` | `${number}w${number}m${number}s` | `${number}w${number}h` | `${number}w${number}h${number}s` | `${number}w${number}h${number}m` | `${number}w${number}h${number}m${number}s` | `${number}w${number}d` | `${number}w$