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.
620 lines (619 loc) • 25.7 kB
text/typescript
import { AsArray, IsNever, MaybePromise, SendEventPayload, SimplifyDeep, SingleOrArray } from "../helpers/types.cjs";
import { Logger, ProxyLogger } from "../middleware/logger.cjs";
import { Jsonify } from "../helpers/jsonify.cjs";
import { Middleware } from "./middleware/middleware.cjs";
import { Realtime } from "./realtime/types.cjs";
import { createStepTools } from "./InngestStepTools.cjs";
import { MetadataBuilder } from "./InngestMetadata.cjs";
import { InngestFunction } from "./InngestFunction.cjs";
import { InngestFunctionReference } from "./InngestFunctionReference.cjs";
import { ApplyAllMiddlewareCtxExtensions, ApplyAllMiddlewareStepExtensions, ApplyAllMiddlewareTransforms, BaseContext, ClientOptions, EventPayload, FailureEventArgs, Handler, InvokeTargetFunctionDefinition, JsonError, SendEventBaseOutput, SendEventOutput, TimeStr, TimeStrBatch } from "../types.cjs";
import { InngestApi } from "../api/api.cjs";
import { HandlerWithTriggers } from "./triggers/typeHelpers.cjs";
import { Mode } from "../helpers/env.cjs";
//#region src/components/Inngest.d.ts
type ChannelTopicNames<InputChannel extends Realtime.ChannelInput> = Extract<keyof Realtime.Channel.InferTopics<InputChannel>, string>;
type ChannelTopicsInput<InputChannel extends Realtime.ChannelInput> = [ChannelTopicNames<InputChannel>] extends [never] ? string[] : string extends ChannelTopicNames<InputChannel> ? string[] : ChannelTopicNames<InputChannel>[];
/**
* Capturing the global type of fetch so that we can reliably access it below.
*/
type FetchT = typeof fetch;
/**
* A client used to interact with the Inngest API by sending or reacting to
* events.
*
* ```ts
* const inngest = new Inngest({ id: "my-app" });
* ```
*
* @public
*/
/**
* Symbol for accessing the SDK's internal logger. Not part of the public API.
* @internal
*/
declare const internalLoggerSymbol: unique symbol;
declare class Inngest<const TClientOpts extends ClientOptions = ClientOptions> implements Inngest.Like {
get [Symbol.toStringTag](): typeof Inngest.Tag;
/**
* 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.
*/
readonly id: string;
/**
* Stores the options so we can remember explicit settings the user has
* provided.
*/
private readonly options;
private readonly inngestApi;
private readonly _userProvidedFetch?;
private _cachedFetch?;
private readonly _logger;
/**
* Logger for SDK internal messages. Falls back to the user's `logger` if
* `internalLogger` is not provided in client options.
*
* @internal
*/
readonly [internalLoggerSymbol]: Logger;
private localFns;
/**
* Middleware instances that provide simpler hooks.
*/
readonly middleware: Middleware.Class[];
private _env;
private _appVersion;
/**
* @internal
* Flag set by metadataMiddleware to enable step.metadata()
*/
protected experimentalMetadataEnabled: boolean;
/**
* A dummy Inngest function used in Durable Endpoints. This is necessary
* because the vast majority of middleware hooks require the Inngest function.
* But for Durable Endpoints, there is no Inngest function. So we need some
* placeholder.
*/
private dummyDurableEndpointFunction;
private getDummyDurableEndpointFunction;
/**
* Try to parse the `INNGEST_DEV` environment variable as a URL.
* Returns the URL if valid, otherwise `undefined`.
*/
get explicitDevUrl(): URL | undefined;
/**
* Given a default cloud URL, return the appropriate URL based on the
* current mode and environment variables.
*
* If `INNGEST_DEV` is set to a URL, that URL is used. Otherwise, we use
* the default cloud URL in cloud mode or the default dev server host in
* dev mode.
*/
private resolveDefaultUrl;
get apiBaseUrl(): string;
get eventBaseUrl(): string;
get eventKey(): string | undefined;
get fetch(): FetchT;
get signingKey(): string | undefined;
get signingKeyFallback(): string | undefined;
get headers(): Record<string, string>;
/**
* The base logger for this client. Passed to user functions as `ctx.logger`.
*/
get logger(): Logger;
get env(): string | null;
get appVersion(): string | undefined;
/**
* Access the metadata builder for updating run and step metadata.
*
* @example
* ```ts
* // Update metadata for the current run
* await inngest.metadata.update({ status: "processing" });
*
* // Update metadata for a different run
* await inngest.metadata.run(otherRunId).update({ key: "val" });
*
* ```
*/
get metadata(): MetadataBuilder;
/**
* A client used to interact with the Inngest API by sending or reacting to
* events.
*
* ```ts
* const inngest = new Inngest({ id: "my-app" });
* ```
*/
constructor(options: TClientOpts);
/**
* Returns a `Promise` that resolves when the app is ready and all middleware
* has been initialized.
*/
get ready(): Promise<void>;
/**
* Set the environment variables for this client. This is useful if you are
* passed environment variables at runtime instead of as globals and need to
* update the client with those values as requests come in.
*/
setEnvVars(env?: Record<string, string | undefined>): this;
get mode(): Mode;
/**
* Given a response from Inngest, relay the error to the caller.
*/
private getResponseError;
private eventKeySet;
/**
* EXPERIMENTAL: This API is not yet stable and may change in the future
* without a major version bump.
*
* Send a Signal to Inngest.
*/
sendSignal({
signal,
data,
env
}: {
/**
* The signal to send.
*/
signal: string;
/**
* The data to send with the signal.
*/
data?: unknown;
/**
* The Inngest environment to send the signal to. Defaults to whichever
* environment this client's key is associated with.
*
* It's like you never need to change this unless you're trying to sync
* multiple systems together using branch names.
*/
env?: string;
}): Promise<InngestApi.SendSignalResponse>;
private _sendSignal;
private updateMetadata;
private warnMetadata;
/**
* Realtime-related functionality for this Inngest client.
*/
realtime: {
/**
* Publish data to a realtime channel topic.
*
* This is a non-durable publish, it executes immediately and is not
* memoized. If called inside an Inngest function, it will automatically
* include the current run ID. For durable publishing inside functions, use
* `step.realtime.publish()`.
*
* ```ts
* await inngest.realtime.publish(ch.status, { message: "Processing..." });
* ```
*/
publish: Realtime.TypedPublishFn;
/**
* Subscribe to realtime messages on a channel, returning a readable stream.
*/
subscribe: {
<const InputChannel extends Realtime.ChannelInput, const InputTopics extends ChannelTopicsInput<InputChannel>, const TToken extends Realtime.Subscribe.Token<InputChannel, InputTopics>>(opts: {
channel: InputChannel;
topics: InputTopics;
validate?: boolean;
onMessage: Realtime.Subscribe.Callback<TToken>;
onError?: (err: unknown) => void;
}): Promise<Realtime.Subscribe.CallbackSubscription>;
<const InputChannel extends Realtime.ChannelInput, const InputTopics extends ChannelTopicsInput<InputChannel>, const TToken extends Realtime.Subscribe.Token<InputChannel, InputTopics>>(opts: {
channel: InputChannel;
topics: InputTopics;
validate?: boolean;
}): Promise<Realtime.Subscribe.StreamSubscription<TToken>>;
};
/**
* Generate a subscription token for subscribing to realtime messages.
*/
token: <const InputChannel extends Realtime.ChannelInput, const InputTopics extends ChannelTopicsInput<InputChannel>, const TToken extends Realtime.Subscribe.Token<InputChannel, InputTopics>>(opts: {
channel: InputChannel;
topics: InputTopics;
}) => Promise<TToken>;
};
endpoint<THandler extends Inngest.EndpointHandler<this>>(handler: THandler): THandler;
/**
* Creates a proxy handler that polls Inngest for durable endpoint results.
*
* The proxy:
* - Extracts `runId` and `token` from query params
* - Fetches the result from Inngest API
* - Runs the response through middleware (e.g., decryption)
* - Adds CORS headers
*
* Use this in combination with the `asyncRedirectUrl` option on your
* endpoint adapter to redirect users to your own proxy endpoint instead
* of directly to Inngest.
*
* @example
* ```ts
* import { Inngest } from "inngest";
* import { endpointAdapter } from "inngest/edge";
*
* const inngest = new Inngest({
* id: "my-app",
* endpointAdapter: endpointAdapter.withOptions({
* asyncRedirectUrl: "/api/inngest/poll",
* }),
* });
*
* // Durable endpoint
* export const GET = inngest.endpoint(async (req) => {
* const result = await step.run("work", () => "done");
* return new Response(result);
* });
*
* // Proxy endpoint at /api/inngest/poll
* export const GET = inngest.endpointProxy();
* ```
*/
endpointProxy(): Inngest.ProxyHandler<this>;
/**
* Decrypt a proxy response using the client's middleware stack.
*
* Runs `transformFunctionInput` on each middleware instance to decrypt
* step data (used by encryption middleware).
*
* Uses type assertions because we're creating a minimal "fake" execution
* context just to run the decryption middleware hooks - not a full execution.
*
* @internal
*/
private decryptProxyResult;
/**
* Send one or many events to Inngest. Takes an entire payload (including
* name) as each input.
*
* ```ts
* await inngest.send({ name: "app/user.created", data: { id: 123 } });
* ```
*
* Returns a promise that will resolve if the event(s) were sent successfully,
* else throws with an error explaining what went wrong.
*/
send(payload: SendEventPayload, options?: {
/**
* 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;
}): Promise<SendEventOutput<TClientOpts>>;
/**
* Internal method for sending an event, used to allow Inngest internals to
* further customize the request sent to an Inngest Server.
*/
private _send;
createFunction: Inngest.CreateFunction<this>;
get funcs(): InngestFunction.Any[];
private _createFunction;
/**
* Runtime-only validation.
*/
private sanitizeTriggers;
}
/**
* Default middleware that is included in every client, placed before the user's
* middleware. Returns new-style `Middleware.Class` constructors. Uses a closure
* so the no-arg constructors can capture the base logger.
*/
declare function builtInMiddleware(baseLogger: Logger): readonly [{
new ({
client
}: {
client: Inngest.Any;
}): {
readonly id: "inngest:logger";
proxyLogger: ProxyLogger;
transformFunctionInput(arg: Middleware.TransformFunctionInputArgs): {
ctx: Omit<BaseContext<Inngest.Any>, never> & Record<never, never> & {
logger: Logger;
};
fn: {
readonly opts: {
readonly triggers?: any;
readonly id: string;
readonly name?: string | undefined;
readonly description?: string | undefined;
readonly concurrency?: number | {
readonly limit: number;
readonly key?: string | undefined;
readonly scope?: "fn" | "env" | "account" | undefined;
} | readonly {
readonly limit: number;
readonly key?: string | undefined;
readonly scope?: "fn" | "env" | "account" | undefined;
}[] | undefined;
readonly batchEvents?: {
readonly maxSize: number;
readonly timeout: TimeStrBatch;
readonly key?: string | undefined;
readonly if?: string | undefined;
} | undefined;
readonly idempotency?: string | undefined;
readonly rateLimit?: {
readonly key?: string | undefined;
readonly limit: number;
readonly period: TimeStr;
} | undefined;
readonly throttle?: {
readonly key?: string | undefined;
readonly limit: number;
readonly period: TimeStr;
readonly burst?: number | undefined;
} | undefined;
readonly debounce?: {
readonly key?: string | undefined;
readonly period: TimeStr;
readonly timeout?: TimeStr | undefined;
} | undefined;
readonly priority?: {
readonly run?: string | undefined;
} | undefined;
readonly timeouts?: {
readonly start?: TimeStr | undefined;
readonly finish?: TimeStr | undefined;
} | undefined;
readonly singleton?: {
readonly key?: string | undefined;
readonly mode: "skip" | "cancel";
} | undefined;
readonly cancelOn?: readonly {
readonly event: string | {
readonly event: string;
readonly name: string;
readonly schema: any;
readonly version?: string | undefined;
readonly create: (...args: [data?: Record<string, unknown> | undefined, options?: {
id?: string;
ts?: number;
v?: string;
} | undefined] | [data: unknown, options?: {
id?: string;
ts?: number;
v?: string;
} | undefined]) => {
data: unknown;
name: string;
id?: string;
ts?: number;
v?: string;
} & {
validate: () => Promise<void>;
};
};
readonly if?: string | undefined;
readonly match?: string | undefined;
readonly timeout?: string | number | Readonly<Date> | undefined;
}[] | undefined;
readonly retries?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | undefined;
readonly onFailure?: any;
readonly middleware?: readonly Middleware.Class[] | undefined;
readonly optimizeParallelism?: boolean | undefined;
readonly experimentalCheckpointing?: boolean | {
readonly maxRuntime?: string | number | {
readonly [Symbol.toStringTag]: "Temporal.Duration";
} | undefined;
readonly bufferedSteps?: number | undefined;
readonly maxInterval?: string | number | {
readonly [Symbol.toStringTag]: "Temporal.Duration";
} | undefined;
} | undefined;
readonly checkpointing?: boolean | {
readonly maxRuntime?: string | number | {
readonly [Symbol.toStringTag]: "Temporal.Duration";
} | undefined;
readonly bufferedSteps?: number | undefined;
readonly maxInterval?: string | number | {
readonly [Symbol.toStringTag]: "Temporal.Duration";
} | undefined;
} | undefined;
};
readonly id: (prefix?: string) => string;
readonly name: string;
readonly description: string | undefined;
readonly [Symbol.toStringTag]: typeof InngestFunction.Tag;
};
steps: {
[x: string]: {
type: "data";
data: unknown;
} | {
type: "error";
error: JsonError;
} | {
type: "input";
input: unknown;
};
};
};
onMemoizationEnd(): void;
onStepError(arg: Middleware.OnStepErrorArgs): void;
wrapFunctionHandler({
next
}: Middleware.WrapFunctionHandlerArgs): Promise<unknown>;
wrapRequest({
next
}: Middleware.WrapRequestArgs): Promise<Middleware.Response>;
readonly client: Inngest.Any;
functionOutputTransform: Middleware.DefaultStaticTransform;
stepOutputTransform: Middleware.DefaultStaticTransform;
onRunComplete?(arg: Middleware.OnRunCompleteArgs): MaybePromise<void>;
onRunError?(arg: Middleware.OnRunErrorArgs): MaybePromise<void>;
onRunStart?(arg: Middleware.OnRunStartArgs): MaybePromise<void>;
onStepComplete?(arg: Middleware.OnStepCompleteArgs): MaybePromise<void>;
onStepStart?(arg: Middleware.OnStepStartArgs): MaybePromise<void>;
transformSendEvent?(arg: Middleware.TransformSendEventArgs): MaybePromise<Middleware.TransformSendEventArgs>;
transformStepInput?(arg: Middleware.TransformStepInputArgs): MaybePromise<Middleware.TransformStepInputArgs>;
wrapSendEvent?(args: Middleware.WrapSendEventArgs): Promise<SendEventBaseOutput>;
wrapStep?(args: Middleware.WrapStepArgs): Promise<unknown>;
wrapStepHandler?(args: Middleware.WrapStepHandlerArgs): Promise<unknown>;
};
onRegister?(args: Middleware.OnRegisterArgs): void;
}];
/**
* A client used to interact with the Inngest API by sending or reacting to
* events.
*
* ```ts
* const inngest = new Inngest({ id: "my-app" });
* ```
*
* @public
*/
declare namespace Inngest {
export const Tag: "Inngest.App";
/**
* Represents any `Inngest` instance, regardless of generics and inference.
*
* Prefer use of `Inngest.Like` where possible to ensure compatibility with
* multiple versions.
*/
export type Any = Inngest;
/**
* References any `Inngest` instance across library versions, useful for use
* in public APIs to ensure compatibility with multiple versions.
*
* Prefer use of `Inngest.Any` internally and `Inngest.Like` for public APIs.
*/
export interface Like {
readonly [Symbol.toStringTag]: typeof Inngest.Tag;
}
export type EndpointHandler<TClient extends Inngest.Any> = ReturnType<NonNullable<ClientOptionsFromInngest<TClient>["endpointAdapter"]>>;
type ResolveTriggers<T> = T extends undefined ? [] : AsArray<NonNullable<T>>;
/**
* Input type for createFunction that accepts raw trigger input (single, array, or undefined)
* while keeping all other fields from InngestFunction.Options.
*/
export type CreateFunctionInput<TFnMiddleware extends Middleware.Class[] | undefined, TTriggers extends SingleOrArray<InngestFunction.Trigger<string>> | undefined, TFailureHandler extends Handler.Any> = Omit<InngestFunction.Options<InngestFunction.Trigger<string>[], TFailureHandler>, "triggers"> & {
triggers?: TTriggers;
middleware?: TFnMiddleware;
};
/**
* The type of the proxy handler returned by `endpointProxy()`.
*
* This type is inferred from the `createProxyHandler` function of the
* endpoint adapter configured on the client.
*/
export type ProxyHandler<TClient extends Inngest.Any> = ReturnType<NonNullable<NonNullable<ClientOptionsFromInngest<TClient>["endpointAdapter"]>["createProxyHandler"]>>;
export type CreateFunction<TClient extends Inngest.Any> = <const TTriggers extends SingleOrArray<InngestFunction.Trigger<string>> | undefined = undefined, const TFnMiddleware extends Middleware.Class[] | undefined = undefined, THandler extends Handler.Any = HandlerWithTriggers<ReturnType<typeof createStepTools<TClient, TFnMiddleware>>, ResolveTriggers<TTriggers>, ApplyAllMiddlewareCtxExtensions<[...ReturnType<typeof builtInMiddleware>]> & ApplyAllMiddlewareCtxExtensions<ClientOptionsFromInngest<TClient>["middleware"]> & {
step: ReturnType<typeof createStepTools<TClient, TFnMiddleware>> & ApplyAllMiddlewareStepExtensions<ClientOptionsFromInngest<TClient>["middleware"]>;
}>, TFailureHandler extends Handler.Any = HandlerWithTriggers<ReturnType<typeof createStepTools<TClient, TFnMiddleware>>, ResolveTriggers<TTriggers>, ApplyAllMiddlewareCtxExtensions<[...ReturnType<typeof builtInMiddleware>]> & FailureEventArgs<EventPayload> & ApplyAllMiddlewareCtxExtensions<ClientOptionsFromInngest<TClient>["middleware"]> & {
step: ReturnType<typeof createStepTools<TClient, TFnMiddleware>> & ApplyAllMiddlewareStepExtensions<ClientOptionsFromInngest<TClient>["middleware"]>;
}>>(options: CreateFunctionInput<TFnMiddleware, TTriggers, TFailureHandler>, handler: THandler) => InngestFunction<InngestFunction.Options<ResolveTriggers<TTriggers>, TFailureHandler>, THandler, TFailureHandler, TClient, ResolveTriggers<TTriggers>>;
export {};
}
/**
* A helper type to extract the type of a set of event tooling from a given
* Inngest instance and optionally a trigger.
*
* @example Get generic step tools for an Inngest instance.
* ```ts
* type StepTools = GetStepTools<typeof inngest>;
* ```
*
* @example Get step tools with a trigger, ensuring tools like `waitForEvent` are typed.
* ```ts
* type StepTools = GetStepTools<typeof Inngest, "github/pull_request">;
* ```
*
* @public
*/
type GetStepTools<TInngest extends Inngest.Any> = GetFunctionInput<TInngest> extends {
step: infer TStep;
} ? TStep : never;
/**
* A helper type to extract the type of the input to a function from a given
* Inngest instance and optionally a trigger.
*
* @example Get generic function input for an Inngest instance.
* ```ts
* type Input = GetFunctionInput<typeof inngest>;
* ```
*
* @example Get function input with a trigger, ensuring tools like `waitForEvent` are typed.
* ```ts
* type Input = GetFunctionInput<typeof Inngest, "github/pull_request">;
* ```
*
* @public
*/
type GetFunctionInput<TClient extends Inngest.Any> = Parameters<Handler<TClient, ApplyAllMiddlewareCtxExtensions<[...ReturnType<typeof builtInMiddleware>]> & ApplyAllMiddlewareCtxExtensions<ClientOptionsFromInngest<TClient>["middleware"]> & {
step: ReturnType<typeof createStepTools<TClient>> & ApplyAllMiddlewareStepExtensions<ClientOptionsFromInngest<TClient>["middleware"]>;
}>>[0];
/**
* A helper type to extract the type of the output of an Inngest function.
*
* @example Get a function's output
* ```ts
* type Output = GetFunctionOutput<typeof myFunction>;
* ```
*
* @public
*/
type GetFunctionOutput<TFunction extends InvokeTargetFunctionDefinition> = TFunction extends InngestFunction.Any ? GetFunctionOutputFromInngestFunction<TFunction> : TFunction extends InngestFunctionReference.Any ? GetFunctionOutputFromReferenceInngestFunction<TFunction> : unknown;
/**
* A helper type to extract the type of the output of an Inngest function.
*
* Used internally for {@link GetFunctionOutput}. Code outside of this package
* should use {@link GetFunctionOutput} instead.
*
* @internal
*/
type GetFunctionOutputFromInngestFunction<TFunction extends InngestFunction.Any> = TFunction extends InngestFunction<any, infer IHandler, any, infer TClient, any> ? IsNever<VoidToNull<SimplifyDeep<Awaited<ReturnType<IHandler>>>>> extends true ? null : ApplyAllMiddlewareTransforms<ClientOptionsFromInngest<TClient>["middleware"], VoidToNull<SimplifyDeep<Awaited<ReturnType<IHandler>>>>, "functionOutputTransform"> : unknown;
/**
* A helper type to extract the type of the output of a referenced Inngest
* function.
*
* Used internally for {@link GetFunctionOutput}. Code outside of this package
* should use {@link GetFunctionOutput} instead.
*
* @internal
*/
type GetFunctionOutputFromReferenceInngestFunction<TFunction extends InngestFunctionReference.Any> = TFunction extends InngestFunctionReference<any, infer IOutput> ? IsNever<SimplifyDeep<Jsonify<IOutput>>> extends true ? null : SimplifyDeep<Jsonify<IOutput>> : unknown;
/**
* A helper type to extract the raw (non-Jsonified) output type of an Inngest
* function. This is used when middleware transforms will handle serialization.
*
* @internal
*/
type GetFunctionOutputRaw<TFunction extends InvokeTargetFunctionDefinition> = TFunction extends InngestFunction.Any ? GetFunctionOutputRawFromInngestFunction<TFunction> : TFunction extends InngestFunctionReference.Any ? GetFunctionOutputRawFromReferenceInngestFunction<TFunction> : unknown;
/**
* @internal
*/
type GetFunctionOutputRawFromInngestFunction<TFunction extends InngestFunction.Any> = TFunction extends InngestFunction<any, infer IHandler, any, any, any> ? VoidToNull<Awaited<ReturnType<IHandler>>> : unknown;
/**
* @internal
*/
type GetFunctionOutputRawFromReferenceInngestFunction<TFunction extends InngestFunctionReference.Any> = TFunction extends InngestFunctionReference<any, infer IOutput> ? VoidToNull<SimplifyDeep<IOutput>> : unknown;
/**
* Helper type that converts void/undefined/never to null.
* Uses ReturnType trick to check for void without directly using void in type position.
* @internal
*/
type VoidToNull<T> = IsNever<T> extends true ? null : T extends ReturnType<() => void> ? null : T;
/**
* A helper type to extract the inferred options from a given Inngest instance.
*
* @example
* ```ts
* type Options = ClientOptionsFromInngest<typeof inngest>;
* ```
*
* @public
*/
type ClientOptionsFromInngest<TInngest extends Inngest.Any> = TInngest extends Inngest<infer U> ? U : ClientOptions;
//#endregion
export { ClientOptionsFromInngest, GetFunctionInput, GetFunctionOutput, GetFunctionOutputRaw, GetStepTools, Inngest };
//# sourceMappingURL=Inngest.d.cts.map