{"version":3,"file":"InngestCommHandler.cjs","names":["stringify","z","getProcessEnv","logPrefix","DefaultMaxRuntime","internalLoggerSymbol","entries: Record<string, FnRegistryEntry>","isDeferredFunction","InngestFunction","handlerKind: FnRegistryEntry[\"handlerKind\"]","envKeys","defaultStreamingOption: typeof this.streaming","parseAsBoolean","hashEventKey","hashSigningKey","queryKeys","headerKeys","ServerTiming","protectEnv","forwardedHeaders","inngestHeaders","defaultMaxRetries","AsyncResponseType","v","body","internalEvents","getAsyncCtx","ExecutionVersion","StepMode","result","undefinedToNull","redirectUrl: string","method","headers: Record<string, string>","PREFERRED_ASYNC_EXECUTION_VERSION","signature: string | undefined","serializeError","signature","actionResponseVersion: ExecutionVersion | null | undefined","filteredHeaders: Record<string, string>","chainResult: Promise<Middleware.Response>","requestInfo: Middleware.Request","isRecord","buildWrapRequestChain","shouldStream: boolean","createStream","rethrowError","actions: HandlerResponseWithErrors","args","runAsPromise","fn: FnRegistryEntry | undefined","fnId: string | undefined","probe","enumFromValue","probeEnum","headerReqVersion: ExecutionVersion | undefined","createVersionSchema","runCompleteOp: OutgoingOp","_internals","StepOpCode","deployId","syncKind","inBandSyncRequestBodySchema","parseFnData","version","fetchAllFnData","data","executionOptions: CreateExecutionOptions","functionConfigSchema","body: InBandRegisterRequest","getPlatformName","introspection:\n      | UnauthenticatedIntrospection\n      | AuthenticatedIntrospection","signingKeyHash: string | null","removeSigningKeyPrefix","signingKeyFallbackHash: string | null","res: globalThis.Response","fetchWithAuthFallback","err: unknown","data: z.input<typeof registerResSchema>","status: number","error: string","skipped: boolean","modified: boolean","checkModeConfiguration","signDataWithKey","#verifySignature","timingSafeEqual"],"sources":["../../src/components/InngestCommHandler.ts"],"sourcesContent":["import { z } from \"zod/v3\";\nimport {\n  defaultMaxRetries,\n  ExecutionVersion,\n  envKeys,\n  forwardedHeaders,\n  headerKeys,\n  internalEvents,\n  logPrefix,\n  probe as probeEnum,\n  queryKeys,\n  syncKind,\n} from \"../helpers/consts.ts\";\nimport { enumFromValue } from \"../helpers/enum.ts\";\nimport {\n  checkModeConfiguration,\n  type Env,\n  getPlatformName,\n  getProcessEnv,\n  inngestHeaders,\n  parseAsBoolean,\n  protectEnv,\n} from \"../helpers/env.ts\";\nimport { rethrowError, serializeError } from \"../helpers/errors.ts\";\nimport {\n  createVersionSchema,\n  type FnData,\n  fetchAllFnData,\n  parseFnData,\n  undefinedToNull,\n} from \"../helpers/functions.ts\";\nimport { warnOnce } from \"../helpers/log.ts\";\nimport { isDeferredFunction } from \"../helpers/marker.ts\";\nimport { fetchWithAuthFallback, signDataWithKey } from \"../helpers/net.ts\";\nimport { runAsPromise } from \"../helpers/promises.ts\";\nimport { ServerTiming } from \"../helpers/ServerTiming.ts\";\nimport { createStream } from \"../helpers/stream.ts\";\nimport {\n  hashEventKey,\n  hashSigningKey,\n  removeSigningKeyPrefix,\n  stringify,\n  timingSafeEqual,\n} from \"../helpers/strings.ts\";\nimport { isRecord, type MaybePromise } from \"../helpers/types.ts\";\nimport type { Logger } from \"../middleware/logger.ts\";\nimport {\n  type APIStepPayload,\n  AsyncResponseType,\n  type AsyncResponseValue,\n  type AuthenticatedIntrospection,\n  DefaultMaxRuntime,\n  type EventPayload,\n  type FunctionConfig,\n  functionConfigSchema,\n  type InBandRegisterRequest,\n  inBandSyncRequestBodySchema,\n  type OutgoingOp,\n  type RegisterOptions,\n  type RegisterRequest,\n  StepMode,\n  StepOpCode,\n  type UnauthenticatedIntrospection,\n} from \"../types.ts\";\nimport { version } from \"../version.ts\";\nimport { getAsyncCtx } from \"./execution/als.ts\";\nimport { _internals } from \"./execution/engine.ts\";\nimport {\n  type ExecutionResult,\n  type ExecutionResultHandler,\n  type ExecutionResultHandlers,\n  type InngestExecutionOptions,\n  PREFERRED_ASYNC_EXECUTION_VERSION,\n} from \"./execution/InngestExecution.ts\";\nimport { type Inngest, internalLoggerSymbol } from \"./Inngest.ts\";\nimport {\n  type CreateExecutionOptions,\n  InngestFunction,\n} from \"./InngestFunction.ts\";\nimport { buildWrapRequestChain, type Middleware } from \"./middleware/index.ts\";\n\n/**\n * An entry in the function registry, tracking which config ID maps to which\n * function and what kind of handler it is (main, failure, or defer).\n */\ninterface FnRegistryEntry {\n  fn: InngestFunction.Any;\n  handlerKind: \"main\" | \"failure\" | \"defer\";\n}\n\n// A response object for when an internal server error occurs. When that\n// happens, we don't to leak any internal details to the client.\nconst internalServerErrorResponse = {\n  body: stringify({ code: \"internal_server_error\" }),\n  headers: { \"Content-Type\": \"application/json\" },\n  status: 500,\n  version: undefined,\n} as const;\n\n/**\n * A set of options that can be passed to a serve handler, intended to be used\n * by internal and custom serve handlers to provide a consistent interface.\n *\n * @public\n */\nexport interface ServeHandlerOptions extends RegisterOptions {\n  /**\n   * The `Inngest` instance used to declare all functions.\n   */\n  client: Inngest.Like;\n\n  /**\n   * An array of the functions to serve and register with Inngest.\n   */\n  functions: readonly InngestFunction.Like[];\n}\n\n/**\n * Parameters passed to the asyncRedirectUrl function.\n */\nexport interface AsyncRedirectUrlParams {\n  /**\n   * The unique identifier for this run.\n   */\n  runId: string;\n\n  /**\n   * The token used to authenticate the request to fetch run output.\n   */\n  token: string;\n}\n\nexport interface SyncHandlerOptions extends RegisterOptions {\n  /**\n   * The `Inngest` instance used to declare all functions.\n   */\n  client: Inngest.Like;\n\n  /**\n   * The type of response you wish to return to an API endpoint when using steps\n   * within it and we must transition to {@link StepMode.Async}.\n   *\n   * In most cases, this defaults to {@link AsyncResponseType.Redirect}.\n   */\n  asyncResponse?: AsyncResponseValue;\n\n  /**\n   * Custom URL to redirect to when switching from sync to async mode.\n   *\n   * Can be:\n   * - A string path (e.g., \"/api/inngest/poll\") - resolved relative to request origin\n   * - A function that receives `{ runId, token }` and returns a full URL\n   *\n   * When a string path is provided, `runId` and `token` query parameters are\n   * automatically appended.\n   *\n   * @example\n   * ```ts\n   * // String path - resolved relative to request origin\n   * asyncRedirectUrl: \"/api/inngest/poll\"\n   *\n   * // Function - full control over URL construction\n   * asyncRedirectUrl: ({ runId, token }) =>\n   *   `https://my-app.com/poll?run=${runId}&t=${token}`\n   * ```\n   */\n  asyncRedirectUrl?:\n    | string\n    | ((params: AsyncRedirectUrlParams) => string | Promise<string>);\n\n  /**\n   * If defined, this sets the function ID that represents this endpoint.\n   * Without this set, it defaults to using the detected method and path of the\n   * request, for example: `GET /api/my-endpoint`.\n   */\n  functionId?: string;\n\n  /**\n   * Specifies the maximum number of retries for all steps.\n   *\n   * Can be a number from `0` to `20`. Defaults to `3`.\n   */\n  retries?:\n    | 0\n    | 1\n    | 2\n    | 3\n    | 4\n    | 5\n    | 6\n    | 7\n    | 8\n    | 9\n    | 10\n    | 11\n    | 12\n    | 13\n    | 14\n    | 15\n    | 16\n    | 17\n    | 18\n    | 19\n    | 20;\n}\n\nexport type SyncAdapterOptions = Omit<SyncHandlerOptions, \"client\">;\n\nexport interface InternalServeHandlerOptions extends ServeHandlerOptions {\n  /**\n   * Can be used to override the framework name given to a particular serve\n   * handler.\n   */\n  frameworkName?: string;\n\n  /**\n   * Can be used to force the handler to always execute functions regardless of\n   * the request method or other factors.\n   *\n   * This is primarily intended for use with Inngest in APIs, where requests may\n   * not have the usual shape of an Inngest payload, but we want to pull data\n   * and execute.\n   */\n  // forceExecution?: boolean;\n}\n\ninterface InngestCommHandlerOptions<\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  Input extends any[] = any[],\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  Output = any,\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  StreamOutput = any,\n> extends RegisterOptions {\n  /**\n   * The name of the framework this handler is designed for. Should be\n   * lowercase, alphanumeric characters inclusive of `-` and `/`.\n   *\n   * This should never be defined by the user; a {@link ServeHandler} should\n   * abstract this.\n   */\n  frameworkName: string;\n\n  /**\n   * The name of this serve handler, e.g. `\"My App\"`. It's recommended that this\n   * value represents the overarching app/service that this set of functions is\n   * being served from.\n   *\n   * This can also be an `Inngest` client, in which case the name given when\n   * instantiating the client is used. This is useful if you're sending and\n   * receiving events from the same service, as you can reuse a single\n   * definition of Inngest.\n   */\n  client: Inngest.Like;\n\n  /**\n   * An array of the functions to serve and register with Inngest.\n   */\n  functions?: readonly InngestFunction.Like[];\n\n  /**\n   * The `handler` is the function that will be called with your framework's\n   * request arguments and returns a set of functions that the SDK will use to\n   * access various parts of the request, such as the body, headers, and query\n   * string parameters.\n   *\n   * It also defines how to transform a response from the SDK into a response\n   * that your framework can understand, ensuring headers, status codes, and\n   * body are all set correctly.\n   *\n   * @example\n   * ```ts\n   * function handler (req: Request, res: Response) {\n   *   return {\n   *     method: () => req.method,\n   *     body: () => req.json(),\n   *     headers: (key) => req.headers.get(key),\n   *     url: () => req.url,\n   *     transformResponse: ({ body, headers, status }) => {\n   *       return new Response(body, { status, headers });\n   *     },\n   *   };\n   * };\n   * ```\n   *\n   * See any existing handler for a full example.\n   */\n  handler: Handler<Input, Output, StreamOutput>;\n\n  skipSignatureValidation?: boolean;\n\n  /**\n   * The default `maxRuntime` in milliseconds to use for checkpointing when the\n   * user hasn't explicitly configured one at the function or client level.\n   *\n   * Defaults to {@link DefaultMaxRuntime.serve} (10 seconds).\n   */\n  defaultMaxRuntime?: DefaultMaxRuntime;\n\n  /**\n   * Options for when this comm handler executes a synchronous (API) function.\n   */\n  syncOptions?: SyncHandlerOptions;\n}\n\n/**\n * A schema for the response from Inngest when registering.\n */\nconst registerResSchema = z.object({\n  status: z.number().default(200),\n  skipped: z.boolean().optional().default(false),\n  modified: z.boolean().optional().default(false),\n  error: z.string().default(\"Successfully registered\"),\n});\n\n/**\n * `InngestCommHandler` is a class for handling incoming requests from Inngest (or\n * Inngest's tooling such as the dev server or CLI) and taking appropriate\n * action for any served functions.\n *\n * All handlers (Next.js, RedwoodJS, Remix, Deno Fresh, etc.) are created using\n * this class; the exposed `serve` function will - most commonly - create an\n * instance of `InngestCommHandler` and then return `instance.createHandler()`.\n *\n * See individual parameter details for more information, or see the\n * source code for an existing handler, e.g.\n * {@link https://github.com/inngest/inngest-js/blob/main/src/next.ts}\n *\n * @example\n * ```\n * // my-custom-handler.ts\n * import {\n *   InngestCommHandler,\n *   type ServeHandlerOptions,\n * } from \"./components/InngestCommHandler\";\n *\n * export const serve = (options: ServeHandlerOptions) => {\n *   const handler = new InngestCommHandler({\n *     frameworkName: \"my-custom-handler\",\n *     ...options,\n *     handler: (req: Request) => {\n *       return {\n *         body: () => req.json(),\n *         headers: (key) => req.headers.get(key),\n *         method: () => req.method,\n *         url: () => new URL(req.url, `https://${req.headers.get(\"host\") || \"\"}`),\n *         transformResponse: ({ body, status, headers }) => {\n *           return new Response(body, { status, headers });\n *         },\n *       };\n *     },\n *   });\n *\n *   return handler.createHandler();\n * };\n * ```\n *\n * @public\n */\nexport class InngestCommHandler<\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  Input extends any[] = any[],\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  Output = any,\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  StreamOutput = any,\n> {\n  /**\n   * The handler specified during instantiation of the class.\n   */\n  public readonly handler: Handler;\n\n  /**\n   * The URL of the Inngest function registration endpoint.\n   */\n  private readonly inngestRegisterUrl: URL;\n\n  /**\n   * The name of the framework this handler is designed for. Should be\n   * lowercase, alphanumeric characters inclusive of `-` and `/`.\n   */\n  protected readonly frameworkName: string;\n\n  /**\n   * The origin used to access the Inngest serve endpoint, e.g.:\n   *\n   *     \"https://myapp.com\" or \"https://myapp.com:1234\"\n   *\n   * By default, the library will try to infer this using request details such\n   * as the \"Host\" header and request path, but sometimes this isn't possible\n   * (e.g. when running in a more controlled environments such as AWS Lambda or\n   * when dealing with proxies/redirects).\n   *\n   * Provide the custom origin here to ensure that the path is reported\n   * correctly when registering functions with Inngest.\n   *\n   * To also provide a custom path, use `servePath`.\n   */\n  private readonly _serveOrigin: string | undefined;\n\n  /**\n   * The path to the Inngest serve endpoint. e.g.:\n   *\n   *     \"/some/long/path/to/inngest/endpoint\"\n   *\n   * By default, the library will try to infer this using request details such\n   * as the \"Host\" header and request path, but sometimes this isn't possible\n   * (e.g. when running in a more controlled environments such as AWS Lambda or\n   * when dealing with proxies/redirects).\n   *\n   * Provide the custom path (excluding the hostname) here to ensure that the\n   * path is reported correctly when registering functions with Inngest.\n   *\n   * To also provide a custom hostname, use `serveOrigin`.\n   */\n  private readonly _servePath: string | undefined;\n\n  protected readonly streaming: RegisterOptions[\"streaming\"];\n\n  /**\n   * A private collection of just Inngest functions, as they have been passed\n   * when instantiating the class.\n   */\n  private readonly rawFns: InngestFunction.Any[];\n\n  private readonly client: Inngest.Any;\n\n  /**\n   * A private collection of functions that are being served. This map is used\n   * to find and register functions when interacting with Inngest Cloud.\n   */\n  private readonly fns: Record<string, FnRegistryEntry> = {};\n\n  private env: Env = getProcessEnv();\n\n  private allowExpiredSignatures: boolean;\n\n  private readonly _options: InngestCommHandlerOptions<\n    Input,\n    Output,\n    StreamOutput\n  >;\n\n  private readonly skipSignatureValidation: boolean;\n\n  private readonly defaultMaxRuntime: DefaultMaxRuntime;\n\n  constructor(options: InngestCommHandlerOptions<Input, Output, StreamOutput>) {\n    // Set input options directly so we can reference them later\n    this._options = options;\n\n    /**\n     * v2 -> v3 migration error.\n     * TODO: do we need to handle people going from v2->v4?\n     *\n     * If a serve handler is passed a client as the first argument, it'll be\n     * spread in to these options. We should be able to detect this by picking\n     * up a unique property on the object.\n     */\n    if (Object.hasOwn(options, \"eventKey\")) {\n      throw new Error(\n        `${logPrefix} You've passed an Inngest client as the first argument to your serve handler. This is no longer supported in v3; please pass the Inngest client as the \\`client\\` property of an options object instead. See https://www.inngest.com/docs/sdk/migration`,\n      );\n    }\n\n    this.frameworkName = options.frameworkName;\n    this.client = options.client as Inngest.Any;\n    this.defaultMaxRuntime =\n      options.defaultMaxRuntime ?? DefaultMaxRuntime.serve;\n\n    this.handler = options.handler as Handler;\n\n    /**\n     * Provide a hidden option to allow expired signatures to be accepted during\n     * testing.\n     */\n    this.allowExpiredSignatures = Boolean(\n      // biome-ignore lint/complexity/noArguments: intentional\n      arguments[\"0\"]?.__testingAllowExpiredSignatures,\n    );\n\n    // Ensure we filter any undefined functions in case of missing imports.\n    this.rawFns = (options.functions?.filter(Boolean) ??\n      []) as InngestFunction.Any[];\n\n    if (this.rawFns.length !== (options.functions ?? []).length) {\n      this.client[internalLoggerSymbol].warn(\n        `Some functions passed to serve() are undefined and misconfigured.  Please check your imports.`,\n      );\n    }\n\n    // Build the id -> entry registry. Each main fn contributes either a\n    // single `main` entry or, when it has `onFailure`, a `main` + `failure`\n    // pair; each `DeferredFunction` (created via `createDefer`) contributes\n    // a single `defer` entry.\n    const entries: Record<string, FnRegistryEntry> = {};\n    for (const fn of this.rawFns) {\n      const isDefer = isDeferredFunction(fn);\n      const mainId = fn.id(this.client.id);\n      const failureId = `${mainId}${InngestFunction.failureSuffix}`;\n\n      const configs = fn[\"getConfig\"]({\n        baseUrl: new URL(\"https://example.com\"),\n        appPrefix: this.client.id,\n      });\n\n      for (const { id } of configs) {\n        if (entries[id]) {\n          throw new Error(\n            `Duplicate function ID \"${id}\"; please change a function's name or provide an explicit ID to avoid conflicts.`,\n          );\n        }\n\n        let handlerKind: FnRegistryEntry[\"handlerKind\"];\n        if (isDefer) {\n          handlerKind = \"defer\";\n        } else if (id === failureId) {\n          handlerKind = \"failure\";\n        } else {\n          handlerKind = \"main\";\n        }\n\n        entries[id] = { fn, handlerKind };\n      }\n    }\n    this.fns = entries;\n\n    this.inngestRegisterUrl = new URL(\"/fn/register\", this.client.apiBaseUrl);\n\n    this._serveOrigin =\n      options.serveOrigin || this.env[envKeys.InngestServeOrigin];\n    this._servePath = options.servePath || this.env[envKeys.InngestServePath];\n\n    this.skipSignatureValidation = options.skipSignatureValidation || false;\n\n    const defaultStreamingOption: typeof this.streaming = false;\n    this.streaming = z\n      .boolean()\n      .default(defaultStreamingOption)\n      .catch((ctx) => {\n        this.client[internalLoggerSymbol].warn(\n          { input: ctx.input, default: defaultStreamingOption },\n          \"Unknown streaming option; using default\",\n        );\n\n        return defaultStreamingOption;\n      })\n      .parse(\n        options.streaming || parseAsBoolean(this.env[envKeys.InngestStreaming]),\n      );\n\n    // Early validation for environments where process.env is available (Node.js).\n    // Edge environments will skip this and validate at request time instead.\n    this.client.setEnvVars(this.env);\n  }\n\n  /**\n   * The origin used to access the Inngest serve endpoint, e.g.:\n   *\n   *     \"https://myapp.com\"\n   *\n   * By default, the library will try to infer this using request details such\n   * as the \"Host\" header and request path, but sometimes this isn't possible\n   * (e.g. when running in a more controlled environments such as AWS Lambda or\n   * when dealing with proxies/redirects).\n   *\n   * Provide the custom origin here to ensure that the path is reported\n   * correctly when registering functions with Inngest.\n   *\n   * To also provide a custom path, use `servePath`.\n   */\n  protected get serveOrigin(): string | undefined {\n    if (this._serveOrigin) {\n      return this._serveOrigin;\n    }\n\n    const envOrigin = this.env[envKeys.InngestServeOrigin];\n    if (envOrigin) {\n      return envOrigin;\n    }\n\n    const envHost = this.env[envKeys.InngestServeHost];\n    if (envHost) {\n      warnOnce(\n        this.client[internalLoggerSymbol],\n        \"serve-host-deprecated\",\n        \"INNGEST_SERVE_HOST is deprecated; use INNGEST_SERVE_ORIGIN instead\",\n      );\n      return envHost;\n    }\n\n    return undefined;\n  }\n\n  /**\n   * The path to the Inngest serve endpoint. e.g.:\n   *\n   *     \"/some/long/path/to/inngest/endpoint\"\n   *\n   * By default, the library will try to infer this using request details such\n   * as the \"Host\" header and request path, but sometimes this isn't possible\n   * (e.g. when running in a more controlled environments such as AWS Lambda or\n   * when dealing with proxies/redirects).\n   *\n   * Provide the custom path (excluding the hostname) here to ensure that the\n   * path is reported correctly when registering functions with Inngest.\n   *\n   * To also provide a custom hostname, use `serveOrigin`.\n   *\n   * This is a getter to encourage checking the environment for the serve path\n   * each time it's accessed, as it may change during execution.\n   */\n  protected get servePath(): string | undefined {\n    return this._servePath || this.env[envKeys.InngestServePath];\n  }\n\n  private get hashedEventKey(): string | undefined {\n    if (!this.client.eventKey) {\n      return undefined;\n    }\n    return hashEventKey(this.client.eventKey);\n  }\n\n  // hashedSigningKey creates a sha256 checksum of the signing key with the\n  // same signing key prefix.\n  private get hashedSigningKey(): string | undefined {\n    if (!this.client.signingKey) {\n      return undefined;\n    }\n    return hashSigningKey(this.client.signingKey);\n  }\n\n  private get hashedSigningKeyFallback(): string | undefined {\n    if (!this.client.signingKeyFallback) {\n      return undefined;\n    }\n    return hashSigningKey(this.client.signingKeyFallback);\n  }\n\n  /**\n   * Returns a `boolean` representing whether this handler will stream responses\n   * or not. Takes into account the user's preference and the platform's\n   * capabilities.\n   */\n  private async shouldStream(\n    actions: HandlerResponseWithErrors,\n  ): Promise<boolean> {\n    const rawProbe = await actions.queryStringWithDefaults(\n      \"testing for probe\",\n      queryKeys.Probe,\n    );\n    if (rawProbe !== undefined) {\n      return false;\n    }\n\n    const envStreaming = this.env[envKeys.InngestStreaming];\n    if (envStreaming === \"allow\" || envStreaming === \"force\") {\n      warnOnce(\n        this.client[internalLoggerSymbol],\n        \"streaming-allow-force-deprecated\",\n        { value: envStreaming },\n        `INNGEST_STREAMING=\"${envStreaming}\" is deprecated; set INNGEST_STREAMING=true instead`,\n      );\n    }\n\n    const streamingRequested =\n      this.streaming === true ||\n      parseAsBoolean(this.env[envKeys.InngestStreaming]) === true ||\n      envStreaming === \"allow\" ||\n      envStreaming === \"force\";\n\n    // We must be able to stream responses to continue.\n    if (!actions.transformStreamingResponse) {\n      if (streamingRequested) {\n        throw new Error(\n          `${logPrefix} Streaming has been forced but the serve handler does not support streaming. Please either remove the streaming option or use a serve handler that supports streaming.`,\n        );\n      }\n      return false;\n    }\n\n    return streamingRequested;\n  }\n\n  private async isInngestReq(\n    actions: HandlerResponseWithErrors,\n  ): Promise<boolean> {\n    const reqMessage = `checking if this is an Inngest request`;\n\n    const [runId, signature] = await Promise.all([\n      actions.headers(reqMessage, headerKeys.InngestRunId),\n      actions.headers(reqMessage, headerKeys.Signature),\n    ]);\n\n    // Note that the signature just has to be present; in Dev it'll be empty,\n    // but still set to `\"\"`.\n    return Boolean(runId && typeof signature === \"string\");\n  }\n\n  /**\n   * Start handling a request, setting up environments, modes, and returning\n   * some helpers.\n   */\n  private async initRequest(...args: Input): Promise<{\n    timer: ServerTiming;\n    actions: HandlerResponseWithErrors;\n    getHeaders: () => Promise<Record<string, string>>;\n  }> {\n    const timer = new ServerTiming(this.client[internalLoggerSymbol]);\n    const actions = await this.getActions(timer, ...args);\n\n    const [env, expectedServerKind] = await Promise.all([\n      actions.env?.(\"starting to handle request\"),\n      actions.headers(\n        \"checking expected server kind\",\n        headerKeys.InngestServerKind,\n      ),\n    ]);\n\n    // Always make sure to merge whatever env we've been given with\n    // `process.env`; some platforms may not provide all the necessary\n    // environment variables or may use two sources.\n    // Update both handler's env and client's env to ensure consistency.\n    this.env = protectEnv({ ...getProcessEnv(), ...env });\n    this.client.setEnvVars(this.env);\n\n    const headerPromises = forwardedHeaders.map(async (header) => {\n      const value = await actions.headers(\n        `fetching ${header} for forwarding`,\n        header,\n      );\n\n      return { header, value };\n    });\n\n    const headersToForwardP = Promise.all(headerPromises).then(\n      (fetchedHeaders) => {\n        return fetchedHeaders.reduce<Record<string, string>>(\n          (acc, { header, value }) => {\n            if (value) {\n              acc[header] = value;\n            }\n\n            return acc;\n          },\n          {},\n        );\n      },\n    );\n\n    const getHeaders = async (): Promise<Record<string, string>> => ({\n      ...inngestHeaders({\n        env: this.env,\n        framework: this.frameworkName,\n        client: this.client,\n        expectedServerKind: expectedServerKind || undefined,\n        extras: {\n          \"Server-Timing\": timer.getHeader(),\n        },\n      }),\n      ...(await headersToForwardP),\n    });\n\n    return {\n      timer,\n      actions,\n      getHeaders,\n    };\n  }\n\n  /**\n   * `createSyncHandler` should be used to return a type-equivalent version of\n   * the `handler` specified during instantiation.\n   */\n  public createSyncHandler<\n    THandler extends (...args: Input) => Promise<Awaited<Output>>,\n  >(): (handler: THandler) => THandler {\n    // Return a function that can be used to wrap endpoints\n    return (handler) => {\n      return this.wrapHandler((async (...args) => {\n        const reqInit = await this.initRequest(...args);\n\n        const fn = new InngestFunction(\n          this.client,\n          {\n            id: this._options.syncOptions?.functionId ?? \"\",\n            retries: this._options.syncOptions?.retries ?? defaultMaxRetries,\n          },\n          () => handler(...args),\n        );\n\n        // Decide if this request looks like an Inngest request. If it does,\n        // we'll just use the regular `serve()` handler for this request, as\n        // it's async.\n        if (await this.isInngestReq(reqInit.actions)) {\n          // If we have a run ID, we can just use the normal serve path\n          // return this.createHandler()(...args);\n          return this.handleAsyncRequest({\n            ...reqInit,\n            forceExecution: true,\n            args,\n            fns: [fn],\n          });\n        }\n\n        // Otherwise, we know this is a sync request, so we can proceed with\n        // creating a sync request to Inngest.\n        return this.handleSyncRequest({\n          ...reqInit,\n          args,\n          asyncMode:\n            this._options.syncOptions?.asyncResponse ??\n            AsyncResponseType.Redirect,\n          asyncRedirectUrl: this._options.syncOptions?.asyncRedirectUrl,\n          fn,\n        });\n      }) as THandler);\n    };\n  }\n\n  /**\n   * `createHandler` should be used to return a type-equivalent version of the\n   * `handler` specified during instantiation.\n   *\n   * @example\n   * ```\n   * // my-custom-handler.ts\n   * import {\n   *   InngestCommHandler,\n   *   type ServeHandlerOptions,\n   * } from \"./components/InngestCommHandler\";\n   *\n   * export const serve = (options: ServeHandlerOptions) => {\n   *   const handler = new InngestCommHandler({\n   *     frameworkName: \"my-custom-handler\",\n   *     ...options,\n   *     handler: (req: Request) => {\n   *       return {\n   *         body: () => req.json(),\n   *         headers: (key) => req.headers.get(key),\n   *         method: () => req.method,\n   *         url: () => new URL(req.url, `https://${req.headers.get(\"host\") || \"\"}`),\n   *         transformResponse: ({ body, status, headers }) => {\n   *           return new Response(body, { status, headers });\n   *         },\n   *       };\n   *     },\n   *   });\n   *\n   *   return handler.createHandler();\n   * };\n   * ```\n   */\n  public createHandler<\n    THandler extends (...args: Input) => Promise<Awaited<Output>>,\n  >(): THandler {\n    return this.wrapHandler((async (...args) => {\n      return this.handleAsyncRequest({\n        ...(await this.initRequest(...args)),\n        args,\n      });\n    }) as THandler);\n  }\n\n  /**\n   * Given a set of actions that let us access the incoming request, create an\n   * event that repesents a run starting from an HTTP request.\n   */\n  private async createHttpEvent(\n    actions: HandlerResponseWithErrors,\n    fn: InngestFunction.Any,\n  ): Promise<APIStepPayload> {\n    const reason = \"creating sync event\";\n\n    const contentTypePromise = actions\n      .headers(reason, headerKeys.ContentType)\n      .then((v) => v ?? \"\");\n\n    const ipPromise = actions\n      .headers(reason, headerKeys.ForwardedFor)\n      .then((v) => {\n        if (v) return v;\n\n        return actions.headers(reason, headerKeys.RealIp).then((v) => v ?? \"\");\n      });\n\n    const methodPromise = actions.method(reason);\n\n    const urlPromise = actions.url(reason).then((v) => this.reqUrl(v));\n\n    const domainPromise = urlPromise.then(\n      (url) => `${url.protocol}//${url.host}`,\n    );\n\n    const pathPromise = urlPromise.then((url) => url.pathname);\n\n    const queryParamsPromise = urlPromise.then((url) =>\n      url.searchParams.toString(),\n    );\n\n    const bodyPromise = actions.body(reason).then((body) => {\n      return typeof body === \"string\" ? body : stringify(body);\n    });\n\n    const [contentType, domain, ip, method, path, queryParams, body] =\n      await Promise.all([\n        contentTypePromise,\n        domainPromise,\n        ipPromise,\n        methodPromise,\n        pathPromise,\n        queryParamsPromise,\n        bodyPromise,\n      ]);\n\n    return {\n      name: internalEvents.HttpRequest,\n      data: {\n        content_type: contentType,\n        domain,\n        ip,\n        method,\n        path,\n        query_params: queryParams,\n        body,\n        fn: fn.id(),\n      },\n    };\n  }\n\n  private async handleSyncRequest({\n    timer,\n    actions,\n    fn,\n    asyncMode,\n    asyncRedirectUrl,\n    args,\n  }: {\n    timer: ServerTiming;\n    actions: HandlerResponseWithErrors;\n    fn: InngestFunction.Any;\n    asyncMode: AsyncResponseValue;\n    asyncRedirectUrl: SyncHandlerOptions[\"asyncRedirectUrl\"];\n    args: unknown[];\n  }): Promise<Awaited<Output>> {\n    // Do we have actions for handling sync requests? We must!\n    if (!actions.experimentalTransformSyncResponse) {\n      throw new Error(\n        \"This platform does not support synchronous Inngest function executions.\",\n      );\n    }\n\n    // Check we're not in a context already...\n    const ctx = await getAsyncCtx();\n    if (ctx) {\n      throw new Error(\n        \"We already seem to be in the context of an Inngest execution, but didn't expect to be. Did you already wrap this handler?\",\n      );\n    }\n\n    // We create a new run ID here in the SDK.\n    const { ulid } = await import(\"ulid\"); // lazy loading for edge envs\n    const runId = ulid();\n    const event = await this.createHttpEvent(actions, fn);\n\n    const acceptHeader = await actions.headers(\n      \"checking accept header\",\n      \"Accept\",\n    );\n    const acceptsSse = acceptHeader?.includes(\"text/event-stream\") ?? false;\n\n    const exeVersion = ExecutionVersion.V2;\n\n    const exe = fn[\"createExecution\"]({\n      partialOptions: {\n        client: this.client,\n        data: {\n          runId,\n          event,\n          attempt: 0,\n          events: [event],\n          maxAttempts: fn.opts.retries ?? defaultMaxRetries,\n        },\n        runId,\n        headers: {},\n        reqArgs: args,\n        stepCompletionOrder: [],\n        stepState: {},\n        disableImmediateExecution: false,\n        handlerKind: \"main\",\n        acceptsSse,\n        timer,\n        createResponse: (data: unknown) =>\n          actions.experimentalTransformSyncResponse!(\n            \"creating sync execution\",\n            data,\n          ).then((res) => ({\n            ...res,\n            version: exeVersion,\n          })),\n        stepMode: StepMode.Sync,\n      },\n    });\n\n    const result = await exe.start();\n\n    const resultHandlers: ExecutionResultHandlers<unknown> = {\n      \"step-not-found\": () => {\n        throw new Error(\n          \"We should not get the result 'step-not-found' when checkpointing. This is a bug in the `inngest` SDK\",\n        );\n      },\n      \"steps-found\": () => {\n        throw new Error(\n          \"We should not get the result 'steps-found' when checkpointing. This is a bug in the `inngest` SDK\",\n        );\n      },\n      \"step-ran\": () => {\n        throw new Error(\n          \"We should not get the result 'step-ran' when checkpointing. This is a bug in the `inngest` SDK\",\n        );\n      },\n      \"function-rejected\": (result) => {\n        return actions.transformResponse(\"creating sync error response\", {\n          status: result.retriable ? 500 : 400,\n          headers: {\n            \"Content-Type\": \"application/json\",\n            [headerKeys.NoRetry]: result.retriable ? \"false\" : \"true\",\n            ...(typeof result.retriable === \"string\"\n              ? { [headerKeys.RetryAfter]: result.retriable }\n              : {}),\n          },\n          version: exeVersion,\n          body: stringify(undefinedToNull(result.error)),\n        });\n      },\n      \"function-resolved\": ({ data }) => {\n        // If the execution returned a Response (SSE streaming from the\n        // engine, or a user-constructed Response in a durable endpoint),\n        // pass it through directly — the headers and body are already set.\n        if (data instanceof Response) {\n          return data;\n        }\n\n        // Non-streaming path: plain return values from the function are\n        // JSON-serialized and wrapped in a framework response.\n        return actions.transformResponse(\"creating sync success response\", {\n          status: 200,\n          headers: {\n            \"Content-Type\": \"application/json\",\n          },\n          version: exeVersion,\n          body: stringify(undefinedToNull(data)),\n        });\n      },\n      \"change-mode\": async ({ token }) => {\n        switch (asyncMode) {\n          case AsyncResponseType.Redirect: {\n            let redirectUrl: string;\n\n            if (asyncRedirectUrl) {\n              if (typeof asyncRedirectUrl === \"function\") {\n                // Full control: user provides complete URL\n                redirectUrl = await asyncRedirectUrl({ runId, token });\n              } else {\n                // String path: resolve relative to request origin\n                // new URL(\"/api/poll\", \"https://example.com\") → \"https://example.com/api/poll\"\n                // new URL(\"https://other.com/poll\", \"https://example.com\") → \"https://other.com/poll\"\n                const baseUrl = await actions.url(\"getting request origin\");\n                const url = new URL(asyncRedirectUrl, baseUrl.origin);\n                url.searchParams.set(\"runId\", runId);\n                url.searchParams.set(\"token\", token);\n                redirectUrl = url.toString();\n              }\n            } else {\n              // Default: redirect to Inngest API\n              redirectUrl = await this.client[\"inngestApi\"]\n                [\"getTargetUrl\"](`/v1/http/runs/${runId}/output?token=${token}`)\n                .then((url) => url.toString());\n            }\n\n            return actions.transformResponse(\n              \"creating sync->async redirect response\",\n              {\n                status: 302,\n                headers: {\n                  [headerKeys.Location]: redirectUrl,\n                },\n                version: exeVersion,\n                body: \"\",\n              },\n            );\n          }\n\n          case AsyncResponseType.Token: {\n            return actions.transformResponse(\n              \"creating sync->async token response\",\n              {\n                status: 200,\n                headers: {},\n                version: exeVersion,\n                body: stringify({ run_id: runId, token }),\n              },\n            );\n          }\n\n          default: {\n            // TODO user-provided hook mate, incl. req args\n            break;\n          }\n        }\n\n        throw new Error(\"Not implemented: change-mode\");\n      },\n    };\n\n    const resultHandler = resultHandlers[\n      result.type\n    ] as ExecutionResultHandler<unknown>;\n    if (!resultHandler) {\n      throw new Error(\n        `No handler for execution result type: ${result.type}. This is a bug in the \\`inngest\\` SDK`,\n      );\n    }\n\n    return resultHandler(result) as Awaited<Output>;\n  }\n\n  private async handleAsyncRequest({\n    timer,\n    actions,\n    args,\n    getHeaders,\n    forceExecution,\n    fns,\n  }: {\n    timer: ServerTiming;\n    actions: HandlerResponseWithErrors;\n    args: Input;\n    getHeaders: () => Promise<Record<string, string>>;\n    forceExecution?: boolean;\n    fns?: InngestFunction.Any[];\n  }): Promise<Awaited<Output>> {\n    if (forceExecution && !actions.experimentalTransformSyncResponse) {\n      throw new Error(\n        \"This platform does not support async executions in Inngest for APIs.\",\n      );\n    }\n\n    const methodP = actions.method(\"starting to handle request\");\n\n    const [signature, method, body] = await Promise.all([\n      actions\n        .headers(\"checking signature for request\", headerKeys.Signature)\n        .then((headerSignature) => {\n          return headerSignature ?? undefined;\n        }),\n      methodP,\n      methodP.then(async (method) => {\n        if (method === \"POST\" || method === \"PUT\") {\n          const body = await actions.body(\n            `checking body for request signing as method is ${method}`,\n          );\n          if (!body) {\n            // Empty body can happen with PUT requests\n            return \"\";\n          }\n          // Some adapters return strings (req.text()), others return\n          // pre-parsed objects (req.body). Handle both cases.\n          if (typeof body === \"string\") {\n            return JSON.parse(body);\n          }\n          return body;\n        }\n\n        return \"\";\n      }),\n    ]);\n\n    const signatureValidation = this.validateSignature(signature, body);\n\n    // Create middleware instances once; shared by wrapRequest and execution hooks.\n    // Starts with client-level middleware; function-level middleware is appended\n    // for POST requests once the target function is known.\n    const mwInstances = this.client.middleware.map(\n      (Cls) => new Cls({ client: this.client }),\n    );\n\n    /**\n     * Prepares an action response by merging returned data to provide\n     * trailing information such as `Server-Timing` headers.\n     *\n     * It should always prioritize the headers returned by the action, as they\n     * may contain important information such as `Content-Type`.\n     */\n    const prepareActionRes = async (\n      res: ActionResponse,\n    ): Promise<ActionResponse> => {\n      const headers: Record<string, string> = {\n        ...(await getHeaders()),\n        ...res.headers,\n        ...(res.version === null\n          ? {}\n          : {\n              [headerKeys.RequestVersion]: (\n                res.version ?? PREFERRED_ASYNC_EXECUTION_VERSION\n              ).toString(),\n            }),\n      };\n\n      let signature: string | undefined;\n\n      try {\n        signature = await signatureValidation.then(async (result) => {\n          if (!result.success || !result.keyUsed) {\n            return undefined;\n          }\n\n          return await this.getResponseSignature(result.keyUsed, res.body);\n        });\n      } catch (err) {\n        // If we fail to sign, retun a 500 with the error.\n        return {\n          ...res,\n          headers,\n          body: stringify(serializeError(err)),\n          status: 500,\n        };\n      }\n\n      if (signature) {\n        headers[headerKeys.Signature] = signature;\n      }\n\n      return {\n        ...res,\n        headers,\n      };\n    };\n\n    // Build the inner handler that wraps handleAction + prepareActionRes.\n    // We capture `version` via closure so it can be passed to transformResponse.\n    let actionResponseVersion: ExecutionVersion | null | undefined;\n\n    const handleAndPrepare = async (): Promise<ActionResponse> => {\n      const rawRes = await timer.wrap(\"action\", () =>\n        this.handleAction({\n          actions,\n          timer,\n          getHeaders,\n          reqArgs: args,\n          signatureValidation,\n          body,\n          method,\n          forceExecution: Boolean(forceExecution),\n          fns,\n          mwInstances,\n        }),\n      );\n      actionResponseVersion = rawRes.version;\n      const prepared = await prepareActionRes(rawRes);\n\n      // Unauthenticated responses must not leak SDK identification headers,\n      // so we strip every `x-inngest-*` header except `x-inngest-sdk-handled`\n      // (which the Inngest backend uses to know that the SDK produced the\n      // response, useful for troubleshooting). `User-Agent` is also stripped\n      // since it advertises the SDK and version. In dev mode, signature\n      // validation short-circuits to success so this branch is a no-op.\n      const validation = await signatureValidation;\n      if (!validation.success) {\n        const filteredHeaders: Record<string, string> = {};\n        for (const [k, v] of Object.entries(prepared.headers)) {\n          const lower = k.toLowerCase();\n          if (lower === \"user-agent\") {\n            // User-Agent contains the SDK version\n            continue;\n          }\n          if (\n            lower.startsWith(\"x-inngest-\") &&\n            lower !== headerKeys.SdkHandled.toLowerCase()\n          ) {\n            continue;\n          }\n          filteredHeaders[k] = v;\n        }\n\n        return { ...prepared, headers: filteredHeaders };\n      }\n\n      return prepared;\n    };\n\n    // Only wrap POST requests with the wrapRequest middleware chain.\n    // GET/PUT (introspection, registration) bypass the middleware.\n    let chainResult: Promise<Middleware.Response>;\n    if (method === \"POST\") {\n      const url = await actions.url(\"building requestInfo for middleware\");\n\n      // Append function-level middleware so it is scoped to this function only.\n      const fnId = url.searchParams.get(queryKeys.FnId);\n      const matchedFn = fnId ? this.fns[fnId] : undefined;\n      const fnMw = matchedFn?.fn?.opts?.middleware ?? [];\n      mwInstances.push(\n        ...fnMw.map((Cls) => {\n          return new Cls({ client: this.client });\n        }),\n      );\n\n      const fn = matchedFn?.fn ?? null;\n\n      const requestInfo: Middleware.Request = {\n        headers: Object.freeze({ ...(await getHeaders()) }),\n        method,\n        url,\n        body: () => Promise.resolve(body),\n      };\n\n      let runId = \"\";\n      if (\n        isRecord(body) &&\n        isRecord(body.ctx) &&\n        body.ctx.run_id &&\n        typeof body.ctx.run_id === \"string\"\n      ) {\n        runId = body.ctx.run_id;\n      }\n\n      const innerHandler = async (): Promise<Middleware.Response> => {\n        const prepared = await handleAndPrepare();\n        return {\n          status: prepared.status,\n          headers: prepared.headers,\n          body: prepared.body,\n        };\n      };\n\n      const wrappedHandler = buildWrapRequestChain({\n        fn,\n        handler: innerHandler,\n        middleware: mwInstances,\n        requestArgs: args,\n        requestInfo,\n        runId,\n      });\n\n      // Start eagerly (matches prior behavior where handleAction starts before\n      // the shouldStream check).\n      chainResult = wrappedHandler();\n    } else {\n      chainResult = handleAndPrepare().then((prepared) => ({\n        status: prepared.status,\n        headers: prepared.headers,\n        body: prepared.body,\n      }));\n    }\n\n    // Attach error handling: if wrapRequest middleware throws, convert to 500.\n    const safeChainResult = chainResult.catch(\n      (err): Middleware.Response => ({\n        status: 500,\n        headers: { \"Content-Type\": \"application/json\" },\n        body: stringify({\n          type: \"internal\",\n          ...serializeError(err as Error),\n        }),\n      }),\n    );\n\n    let shouldStream: boolean;\n    try {\n      shouldStream = await this.shouldStream(actions);\n    } catch (err) {\n      return actions.transformResponse(\"sending back response\", {\n        status: 500,\n        headers: {\n          ...(await getHeaders()),\n          \"Content-Type\": \"application/json\",\n        },\n        body: stringify(serializeError(err)),\n        version: undefined,\n      });\n    }\n\n    if (shouldStream) {\n      const method = await actions.method(\"starting streaming response\");\n\n      if (method === \"POST\") {\n        const { stream, finalize } = await createStream();\n\n        /**\n         * Errors are handled by `handleAction` here to ensure that an\n         * appropriate response is always given.\n         */\n        void safeChainResult.then((res) => {\n          return finalize(\n            Promise.resolve({\n              ...res,\n              version: actionResponseVersion,\n            }),\n          );\n        });\n\n        return timer.wrap(\"res\", async () => {\n          return actions.transformStreamingResponse?.(\n            \"starting streaming response\",\n            {\n              status: 201,\n              headers: await getHeaders(),\n              body: stream,\n              version: null,\n            },\n          );\n        });\n      }\n    }\n\n    return timer.wrap(\"res\", async () => {\n      return safeChainResult.then((res) => {\n        return actions.transformResponse(\"sending back response\", {\n          ...res,\n          version: actionResponseVersion,\n        });\n      });\n    });\n  }\n\n  private async getActions(\n    timer: ServerTiming,\n    ...args: Input\n  ): Promise<HandlerResponseWithErrors> {\n    /**\n     * Used for testing, allow setting action overrides externally when\n     * calling the handler. Always search the final argument.\n     */\n    const lastArg = args[args.length - 1] as unknown;\n    const actionOverrides =\n      typeof lastArg === \"object\" &&\n      lastArg !== null &&\n      \"actionOverrides\" in lastArg &&\n      typeof lastArg[\"actionOverrides\"] === \"object\" &&\n      lastArg[\"actionOverrides\"] !== null\n        ? lastArg[\"actionOverrides\"]\n        : {};\n\n    /**\n     * We purposefully `await` the handler, as it could be either sync or\n     * async.\n     */\n    const rawActions = {\n      ...(await timer\n        .wrap(\"handler\", () => this.handler(...args))\n        .catch(rethrowError(\"Serve handler failed to run\"))),\n      ...actionOverrides,\n    };\n\n    /**\n     * Map over every `action` in `rawActions` and create a new `actions`\n     * object where each function is safely promisified with each access\n     * requiring a reason.\n     *\n     * This helps us provide high quality errors about what's going wrong for\n     * each access without having to wrap every access in a try/catch.\n     */\n    const promisifiedActions: ActionHandlerResponseWithErrors = Object.entries(\n      rawActions,\n    ).reduce((acc, [key, value]) => {\n      if (typeof value !== \"function\") {\n        return acc;\n      }\n\n      return {\n        ...acc,\n        [key]: (reason: string, ...args: unknown[]) => {\n          const errMessage = [\n            `Failed calling \\`${key}\\` from serve handler`,\n            reason,\n          ]\n            .filter(Boolean)\n            .join(\" when \");\n\n          const fn = () => (value as (...args: unknown[]) => unknown)(...args);\n\n          return runAsPromise(fn)\n            .catch(rethrowError(errMessage))\n            .catch((err) => {\n              this.client[internalLoggerSymbol].error({ err }, errMessage);\n              throw err;\n            });\n        },\n      };\n    }, {} as ActionHandlerResponseWithErrors);\n\n    /**\n     * Mapped promisified handlers from userland `serve()` function mixed in\n     * with some helpers.\n     */\n    const actions: HandlerResponseWithErrors = {\n      ...promisifiedActions,\n      queryStringWithDefaults: async (\n        reason: string,\n        key: string,\n      ): Promise<string | undefined> => {\n        const url = await actions.url(reason);\n\n        const ret =\n          (await actions.queryString?.(reason, key, url)) ||\n          url.searchParams.get(key) ||\n          undefined;\n\n        return ret;\n      },\n      ...actionOverrides,\n    };\n\n    return actions;\n  }\n\n  // biome-ignore lint/suspicious/noExplicitAny: any fn\n  private wrapHandler<THandler extends (...args: any[]) => any>(\n    handler: THandler,\n  ): THandler {\n    /**\n     * Some platforms check (at runtime) the length of the function being used\n     * to handle an endpoint. If this is a variadic function, it will fail that\n     * check.\n     *\n     * Therefore, we expect the arguments accepted to be the same length as the\n     * `handler` function passed internally.\n     *\n     * We also set a name to avoid a common useless name in tracing such as\n     * `\"anonymous\"` or `\"bound function\"`.\n     *\n     * https://github.com/getsentry/sentry-javascript/issues/3284\n     */\n    Object.defineProperties(handler, {\n      name: {\n        value: \"InngestHandler\",\n      },\n      length: {\n        value: this.handler.length,\n      },\n    });\n\n    return handler;\n  }\n\n  /**\n   * Given a set of functions to check if an action is available from the\n   * instance's handler, enact any action that is found.\n   *\n   * This method can fetch varying payloads of data, but ultimately is the place\n   * where _decisions_ are made regarding functionality.\n   *\n   * For example, if we find that we should be viewing the UI, this function\n   * will decide whether the UI should be visible based on the payload it has\n   * found (e.g. env vars, options, etc).\n   */\n  private async handleAction({\n    actions,\n    timer,\n    getHeaders,\n    reqArgs,\n    signatureValidation,\n    body: rawBody,\n    method,\n    forceExecution,\n    fns,\n    mwInstances,\n  }: {\n    actions: HandlerResponseWithErrors;\n    timer: ServerTiming;\n    getHeaders: () => Promise<Record<string, string>>;\n    reqArgs: unknown[];\n    signatureValidation: ReturnType<InngestCommHandler[\"validateSignature\"]>;\n    body: unknown;\n    method: string;\n    forceExecution: boolean;\n    fns?: InngestFunction.Any[];\n    mwInstances?: Middleware.BaseMiddleware[];\n  }): Promise<ActionResponse> {\n    if (!this.checkModeConfiguration()) {\n      return internalServerErrorResponse;\n    }\n\n    // This is when the request body is completely missing. This commonly\n    // happens when the HTTP framework doesn't have body parsing middleware,\n    // or for PUT requests that don't require a body.\n    const isMissingBody = !rawBody;\n    let body = rawBody;\n\n    try {\n      let url = await actions.url(\"starting to handle request\");\n\n      if (method === \"POST\" || forceExecution) {\n        if (!forceExecution && isMissingBody) {\n          this.client[internalLoggerSymbol].error(\n            \"Missing body when executing, possibly due to missing request body middleware\",\n          );\n\n          return {\n            status: 401,\n            headers: {\n              \"Content-Type\": \"application/json\",\n            },\n            body: stringify({ message: \"Unauthorized\" }),\n            version: undefined,\n          };\n        }\n\n        const validationResult = await signatureValidation;\n        if (!validationResult.success) {\n          this.client[internalLoggerSymbol].error(\n            { err: validationResult.err },\n            \"Signature validation failed\",\n          );\n\n          return {\n            status: 401,\n            headers: {\n              \"Content-Type\": \"application/json\",\n            },\n            body: stringify({ message: \"Unauthorized\" }),\n            version: undefined,\n          };\n        }\n\n        let fn: FnRegistryEntry | undefined;\n        let fnId: string | undefined;\n\n        if (forceExecution) {\n          fn =\n            fns?.length && fns[0]\n              ? {\n                  fn: fns[0],\n                  handlerKind: \"main\" as const,\n                }\n              : Object.values(this.fns)[0];\n          fnId = fn?.fn.id();\n\n          // Grab \"force step plan\" flag from headers\n          let die = false;\n          const dieHeader = await actions.headers(\n            \"getting step plan force control for forced execution\",\n            headerKeys.InngestForceStepPlan,\n          );\n          if (dieHeader) {\n            const parsed = parseAsBoolean(dieHeader);\n            if (typeof parsed === \"boolean\") {\n              die = parsed;\n            } else {\n              this.client[internalLoggerSymbol].warn(\n                { header: headerKeys.InngestForceStepPlan, value: dieHeader },\n                \"Invalid boolean header value; defaulting to false\",\n              );\n            }\n          }\n\n          body = {\n            event: {},\n            events: [],\n            steps: {},\n            version: PREFERRED_ASYNC_EXECUTION_VERSION,\n            sdkDecided: true,\n            ctx: {\n              attempt: 0,\n              disable_immediate_execution: die,\n              use_api: true,\n              // This execution path doesn't control max attempts; it's already\n              // been reported and Inngest is now in control of when to stop, so\n              // we remove this restriction.\n              max_attempts: Infinity,\n              run_id: await actions.headers(\n                \"getting run ID for forced execution\",\n                headerKeys.InngestRunId,\n              ),\n              // TODO We need this to be given to us or the API to return it\n              stack: { stack: [], current: 0 },\n            },\n          } as Extract<\n            FnData,\n            { version: typeof PREFERRED_ASYNC_EXECUTION_VERSION }\n          >;\n        } else {\n          const rawProbe = await actions.queryStringWithDefaults(\n            \"testing for probe\",\n            queryKeys.Probe,\n          );\n          if (rawProbe) {\n            const probe = enumFromValue(probeEnum, rawProbe);\n            if (!probe) {\n              // If we're here, we've received a probe that we don't recognize.\n              // Fail.\n              return {\n                status: 400,\n                headers: {\n                  \"Content-Type\": \"application/json\",\n                },\n                body: stringify(\n                  serializeError(new Error(`Unknown probe \"${rawProbe}\"`)),\n                ),\n                version: undefined,\n              };\n            }\n\n            // Provide actions for every probe available.\n            const probeActions: Record<\n              probeEnum,\n              () => MaybePromise<ActionResponse>\n            > = {\n              [probeEnum.Trust]: () => ({\n                status: 200,\n                headers: {\n                  \"Content-Type\": \"application/json\",\n                },\n                body: \"\",\n                version: undefined,\n              }),\n            };\n\n            return probeActions[probe]();\n          }\n\n          fnId = await actions.queryStringWithDefaults(\n            \"processing run request\",\n            queryKeys.FnId,\n          );\n          if (!fnId) {\n            throw new Error(\"No function ID found in async request\");\n          }\n\n          fn = this.fns[fnId];\n        }\n\n        if (typeof fnId === \"undefined\" || !fn) {\n          throw new Error(\"No function ID found in request\");\n        }\n\n        // Always try and grab the step ID; in regular async flows this will be\n        // in the querystring, and in sync modes it'll be in the headers.\n        const stepId =\n          (await actions.queryStringWithDefaults(\n            \"processing run request\",\n            queryKeys.StepId,\n          )) ||\n          (await actions.headers(\n            \"processing run request\",\n            headerKeys.InngestStepId,\n          )) ||\n          null;\n\n        // Try get the request version from headers for sync executions.\n        let headerReqVersion: ExecutionVersion | undefined;\n\n        try {\n          const rawVersionHeader = await actions.headers(\n            \"processing run request\",\n            headerKeys.RequestVersion,\n          );\n\n          // We only obey the request version header if it's actually a number,\n          // even though the underlying schema allows more values; that schema\n          // is intended to _always_ find a valid version and made for request\n          // bodies.\n          //\n          // Note that the header will be a `string` at this point.\n          if (rawVersionHeader && Number.isFinite(Number(rawVersionHeader))) {\n            const res = createVersionSchema(\n              this.client[internalLoggerSymbol],\n            ).parse(Number(rawVersionHeader));\n\n            if (!res.sdkDecided) {\n              headerReqVersion = res.version;\n            }\n          }\n        } catch {\n          // no-op\n        }\n\n        const resolvedHeaders = await getHeaders();\n        const { version, result } = this.runStep({\n          functionId: fnId,\n          data: body,\n          stepId,\n          timer,\n          reqArgs,\n          headers: resolvedHeaders,\n          fn,\n          forceExecution,\n          actions,\n          headerReqVersion,\n          requestInfo: {\n            headers: Object.freeze({ ...resolvedHeaders }),\n            method,\n            url,\n            body: () => Promise.resolve(body),\n          },\n          mwInstances,\n        });\n        const stepOutput = await result;\n\n        /**\n         * Functions can return `undefined`, but we'll always convert this to\n         * `null`, as this is appropriately serializable by JSON.\n         */\n        const opDataUndefinedToNull = (op: OutgoingOp) => {\n          op.data = undefinedToNull(op.data);\n          return op;\n        };\n\n        const resultHandlers: ExecutionResultHandlers<ActionResponse> = {\n          \"function-rejected\": (result) => {\n            return {\n              status: result.retriable ? 500 : 400,\n              headers: {\n                \"Content-Type\": \"application/json\",\n                [headerKeys.NoRetry]: result.retriable ? \"false\" : \"true\",\n                ...(typeof result.retriable === \"string\"\n                  ? { [headerKeys.RetryAfter]: result.retriable }\n                  : {}),\n              },\n              body: stringify(undefinedToNull(result.error)),\n              version,\n            };\n          },\n          \"function-resolved\": (result) => {\n            if (forceExecution) {\n              const runCompleteOp: OutgoingOp = {\n                id: _internals.hashId(\"complete\"),\n                op: StepOpCode.RunComplete,\n                data: undefinedToNull(result.data),\n              };\n\n              return {\n                status: 206,\n                headers: {\n                  \"Content-Type\": \"application/json\",\n                },\n                body: stringify(runCompleteOp),\n                version,\n              };\n            }\n\n            return {\n              status: 200,\n              headers: {\n                \"Content-Type\": \"application/json\",\n              },\n              body: stringify(undefinedToNull(result.data)),\n              version,\n            };\n          },\n          \"step-not-found\": (result) => {\n            // we want to show the names and IDs of any steps that were found during the\n            // run process\n            const missingStepId = result.step.displayName || result.step.id;\n\n            let error = `Could not find step \"${missingStepId}\" to run; timed out.`;\n\n            if (result.foundSteps.length > 0) {\n              const foundStepsSummary = result.foundSteps\n                .map((step) => {\n                  const name = step.displayName || step.id;\n                  return `${name} (${step.id})`;\n                })\n                .join(\"\\n\");\n              error = `${error} Found new steps: \\n${foundStepsSummary}.`;\n            }\n\n            if (result.totalFoundSteps > result.foundSteps.length) {\n              error = `${error} (showing ${result.foundSteps.length} of ${result.totalFoundSteps})`;\n            }\n\n            return {\n              status: 500,\n              headers: {\n                \"Content-Type\": \"application/json\",\n                [headerKeys.NoRetry]: \"false\",\n              },\n              body: stringify({\n                error,\n                requestedStep: result.step.id,\n                foundSteps: result.foundSteps,\n                totalFoundSteps: result.totalFoundSteps,\n              }),\n              version,\n            };\n          },\n          \"step-ran\": (result) => {\n            const step = opDataUndefinedToNull(result.step);\n\n            return {\n              status: 206,\n              headers: {\n                \"Content-Type\": \"application/json\",\n                ...(typeof result.retriable !== \"undefined\"\n                  ? {\n                      [headerKeys.NoRetry]: result.retriable ? \"false\" : \"true\",\n                      ...(typeof result.retriable === \"string\"\n                        ? { [headerKeys.RetryAfter]: result.retriable }\n                        : {}),\n                    }\n                  : {}),\n              },\n              body: stringify([step]),\n              version,\n            };\n          },\n          \"steps-found\": (result) => {\n            const steps = result.steps.map(opDataUndefinedToNull);\n\n            return {\n              status: 206,\n              headers: {\n                \"Content-Type\": \"application/json\",\n              },\n              body: stringify(steps),\n              version,\n            };\n          },\n          \"change-mode\": (result) => {\n            return {\n              status: 500,\n              headers: {\n                \"Content-Type\": \"application/json\",\n                [headerKeys.NoRetry]: \"true\",\n              },\n              body: stringify({\n                error: `We wanted to change mode to \"${result.to}\", but this is not supported within the InngestCommHandler. This is a bug in the Inngest SDK.`,\n              }),\n              version,\n            };\n          },\n        };\n\n        const handler = resultHandlers[\n          stepOutput.type\n        ] as ExecutionResultHandler<ActionResponse>;\n\n        try {\n          return await handler(stepOutput);\n        } catch (err) {\n          this.client[internalLoggerSymbol].error(\n            { err },\n            \"Error handling execution result\",\n          );\n          throw err;\n        }\n      }\n\n      // TODO: This feels hacky, so we should probably make it not hacky.\n      const env = (await getHeaders())[headerKeys.Environment] ?? null;\n\n      if (method === \"GET\") {\n        // In cloud mode, introspection requires a valid signature. We don't\n        // serve an unauthenticated introspection body to anonymous callers\n        // because it leaks deployment fingerprint (mode, function count,\n        // event/signing key presence).\n        if (this.client.mode === \"cloud\") {\n          const validationResult = await signatureValidation;\n          if (!validationResult.success) {\n            this.client[internalLoggerSymbol].error(\n              { err: validationResult.err },\n              \"Signature validation failed\",\n            );\n\n            return {\n              status: 401,\n              headers: {\n                \"Content-Type\": \"application/json\",\n              },\n              body: stringify({ message: \"Unauthorized\" }),\n              version: undefined,\n            };\n          }\n        }\n\n        return {\n          status: 200,\n          body: stringify(\n            await this.introspectionBody({\n              actions,\n              env,\n              signatureValidation,\n              url,\n            }),\n          ),\n          headers: {\n            \"Content-Type\": \"application/json\",\n          },\n          version: undefined,\n        };\n      }\n\n      if (method === \"PUT\") {\n        const [deployId, inBandSyncRequested] = await Promise.all([\n          actions\n            .queryStringWithDefaults(\n              \"processing deployment request\",\n              queryKeys.DeployId,\n            )\n            .then((deployId) => {\n              return deployId === \"undefined\" ? undefined : deployId;\n            }),\n\n          Promise.resolve(\n            parseAsBoolean(this.env[envKeys.InngestAllowInBandSync]),\n          )\n            .then((allowInBandSync) => {\n              if (allowInBandSync !== undefined && !allowInBandSync) {\n                return syncKind.OutOfBand;\n              }\n\n              return actions.headers(\n                \"processing deployment request\",\n                headerKeys.InngestSyncKind,\n              );\n            })\n            .then((kind) => {\n              return kind === syncKind.InBand;\n            }),\n        ]);\n\n        if (inBandSyncRequested) {\n          if (isMissingBody) {\n            this.client[internalLoggerSymbol].error(\n              \"Missing body when syncing, possibly due to missing request body middleware\",\n            );\n\n            return {\n              status: 500,\n              headers: {\n                \"Content-Type\": \"application/json\",\n              },\n              body: stringify(\n                serializeError(\n                  new Error(\n                    \"Missing request body when syncing, possibly due to missing request body middleware\",\n                  ),\n                ),\n              ),\n              version: undefined,\n            };\n          }\n\n          // Validation can be successful if we're in dev mode and did not\n          // actually validate a key. In this case, also check that we did indeed\n          // use a particular key to validate.\n          const sigCheck = await signatureValidation;\n\n          if (!sigCheck.success) {\n            return {\n              status: 401,\n              body: stringify({\n                code: \"sig_verification_failed\",\n              }),\n              headers: {\n                \"Content-Type\": \"application/json\",\n              },\n              version: undefined,\n            };\n          }\n\n          const res = inBandSyncRequestBodySchema.safeParse(body);\n          if (!res.success) {\n            return {\n              status: 400,\n              body: stringify({\n                code: \"invalid_request\",\n                message: res.error.message,\n              }),\n              headers: {\n                \"Content-Type\": \"application/json\",\n              },\n              version: undefined,\n            };\n          }\n\n          // We can trust the URL here because it's coming from\n          // signature-verified request.\n          url = this.reqUrl(new URL(res.data.url));\n\n          // This should be an in-band sync\n          const respBody = await this.inBandRegisterBody({\n            actions,\n            deployId,\n            env,\n            signatureValidation,\n            url,\n          });\n\n          return {\n            status: 200,\n            body: stringify(respBody),\n            headers: {\n              \"Content-Type\": \"application/json\",\n              [headerKeys.InngestSyncKind]: syncKind.InBand,\n            },\n            version: undefined,\n          };\n        }\n\n        // If we're here, this is a legacy out-of-band sync\n        const { status, message, modified } = await this.register(\n          this.reqUrl(url),\n          deployId,\n          getHeaders,\n        );\n\n        return {\n          status,\n          body: stringify({ message, modified }),\n          headers: {\n            \"Content-Type\": \"application/json\",\n            [headerKeys.InngestSyncKind]: syncKind.OutOfBand,\n          },\n          version: undefined,\n        };\n      }\n    } catch (err) {\n      return {\n        status: 500,\n        body: stringify({\n          type: \"internal\",\n          ...serializeError(err as Error),\n        }),\n        headers: {\n          \"Content-Type\": \"application/json\",\n        },\n        version: undefined,\n      };\n    }\n\n    this.client[internalLoggerSymbol].error(\n      { method },\n      \"Received unhandled HTTP method; expected POST, PUT, or GET\",\n    );\n\n    return {\n      status: 405,\n      body: JSON.stringify({ message: \"Method not allowed\" }),\n      headers: {\n        \"Content-Type\": \"application/json\",\n      },\n      version: undefined,\n    };\n  }\n\n  protected runStep({\n    actions,\n    functionId,\n    stepId,\n    data,\n    timer,\n    reqArgs,\n    headers,\n    fn,\n    forceExecution,\n    headerReqVersion,\n    requestInfo,\n    mwInstances,\n  }: {\n    actions: HandlerResponseWithErrors;\n    functionId: string;\n    stepId: string | null;\n    data: unknown;\n    timer: ServerTiming;\n    reqArgs: unknown[];\n    headers: Record<string, string>;\n    fn: FnRegistryEntry;\n    forceExecution: boolean;\n    headerReqVersion?: ExecutionVersion;\n    requestInfo?: InngestExecutionOptions[\"requestInfo\"];\n    mwInstances?: Middleware.BaseMiddleware[];\n  }): { version: ExecutionVersion; result: Promise<ExecutionResult> } {\n    if (!fn) {\n      throw new Error(`Could not find function with ID \"${functionId}\"`);\n    }\n\n    // Try to get the request version from headers before falling back to\n    // parsing it from the body.\n    const immediateFnData = parseFnData(\n      data,\n      headerReqVersion,\n      this.client[internalLoggerSymbol],\n    );\n    const { sdkDecided } = immediateFnData;\n    let version = ExecutionVersion.V2;\n\n    // Handle opting out of optimized parallelism\n    if (\n      version === ExecutionVersion.V2 &&\n      sdkDecided &&\n      fn.fn[\"shouldOptimizeParallelism\"]?.() === false\n    ) {\n      version = ExecutionVersion.V1;\n    }\n\n    const result = runAsPromise(async () => {\n      const anyFnData = await fetchAllFnData({\n        data: immediateFnData,\n        api: this.client[\"inngestApi\"],\n        logger: this.client[internalLoggerSymbol],\n      });\n\n      if (!anyFnData.ok) {\n        throw new Error(anyFnData.error);\n      }\n\n      const createResponse =\n        forceExecution && actions.experimentalTransformSyncResponse\n          ? (data: unknown) =>\n              actions.experimentalTransformSyncResponse!(\n                \"created sync->async response\",\n                data,\n              ).then((res) => ({\n                ...res,\n                version,\n              }))\n          : undefined;\n\n      const { defers, event, events, steps, ctx } = anyFnData.value;\n      const requestId = await actions.headers(\n        \"getting request ID for execution\",\n        headerKeys.RequestId,\n      );\n      const jobId = await actions.headers(\n        \"getting job ID for execution\",\n        headerKeys.InngestJobId,\n      );\n\n      const stepState = Object.entries(steps ?? {}).reduce<\n        InngestExecutionOptions[\"stepState\"]\n      >((acc, [id, result]) => {\n        return {\n          ...acc,\n          [id]:\n            result.type === \"data\"\n              ? { id, data: result.data }\n              : result.type === \"input\"\n                ? { id, input: result.input }\n                : { id, error: result.error },\n        };\n      }, {});\n\n      const requestedRunStep =\n        stepId === \"step\" ? undefined : stepId || undefined;\n\n      const checkpointingConfig = fn.fn[\"shouldAsyncCheckpoint\"](\n        requestedRunStep,\n        ctx?.fn_id,\n        Boolean(ctx?.disable_immediate_execution),\n        this.defaultMaxRuntime,\n      );\n\n      const executionOptions: CreateExecutionOptions = {\n        partialOptions: {\n          client: this.client,\n          runId: ctx?.run_id || \"\",\n          stepMode: checkpointingConfig\n            ? StepMode.AsyncCheckpointing\n            : StepMode.Async,\n          checkpointingConfig,\n          data: {\n            event: event as EventPayload,\n            events: events as [EventPayload, ...EventPayload[]],\n            runId: ctx?.run_id || \"\",\n            attempt: ctx?.attempt ?? 0,\n            maxAttempts: ctx?.max_attempts,\n            requestId: requestId ?? undefined,\n            jobId: jobId ?? undefined,\n          },\n          internalFnId: ctx?.fn_id,\n          queueItemId: ctx?.qi_id,\n          stepState,\n          priorDefers: defers,\n          requestedRunStep,\n          timer,\n          handlerKind: fn.handlerKind,\n          disableImmediateExecution: ctx?.disable_immediate_execution,\n          stepCompletionOrder: ctx?.stack?.stack ?? [],\n          reqArgs,\n          headers,\n          createResponse,\n          requestInfo,\n          middlewareInstances: mwInstances,\n        },\n      };\n\n      return fn.fn[\"createExecution\"](executionOptions).start();\n    });\n\n    return { version, result };\n  }\n\n  protected configs(url: URL): FunctionConfig[] {\n    const configs = this.rawFns.reduce<FunctionConfig[]>(\n      (acc, fn) => [\n        ...acc,\n        ...fn[\"getConfig\"]({ baseUrl: url, appPrefix: this.client.id }),\n      ],\n      [],\n    );\n\n    for (const config of configs) {\n      const check = functionConfigSchema.safeParse(config);\n      if (!check.success) {\n        const errors = check.error.errors.map((err) => err.message).join(\"; \");\n\n        this.client[internalLoggerSymbol].warn(\n          { functionId: config.id, errors },\n          \"Invalid function config\",\n        );\n      }\n    }\n\n    return configs;\n  }\n\n  /**\n   * Return an Inngest serve endpoint URL given a potential `path` and `host`.\n   *\n   * Will automatically use the `serveOrigin` and `servePath` if they have been\n   * set when registering.\n   */\n  protected reqUrl(url: URL): URL {\n    let ret = new URL(url);\n\n    const servePath = this.servePath || this.env[envKeys.InngestServePath];\n\n    if (servePath) {\n      ret.pathname = servePath;\n    }\n\n    if (this.serveOrigin) {\n      ret = new URL(ret.pathname + ret.search, this.serveOrigin);\n    }\n\n    return ret;\n  }\n\n  protected registerBody({\n    url,\n    deployId,\n  }: {\n    url: URL;\n\n    /**\n     * Non-optional to ensure we always consider if we have a deploy ID\n     * available to us to use.\n     */\n    deployId: string | undefined | null;\n  }): RegisterRequest {\n    const body: RegisterRequest = {\n      url: url.href,\n      deployType: \"ping\",\n      framework: this.frameworkName,\n      appName: this.client.id,\n      functions: this.configs(url),\n      sdk: `js:v${version}`,\n      v: \"0.1\",\n      deployId: deployId || undefined,\n      capabilities: {\n        trust_probe: \"v1\",\n        connect: \"v1\",\n      },\n      appVersion: this.client.appVersion,\n    };\n\n    return body;\n  }\n\n  protected async inBandRegisterBody({\n    actions,\n    deployId,\n    env,\n    signatureValidation,\n    url,\n  }: {\n    actions: HandlerResponseWithErrors;\n\n    /**\n     * Non-optional to ensure we always consider if we have a deploy ID\n     * available to us to use.\n     */\n    deployId: string | undefined | null;\n\n    env: string | null;\n    signatureValidation: ReturnType<InngestCommHandler[\"validateSignature\"]>;\n\n    url: URL;\n  }): Promise<InBandRegisterRequest> {\n    const registerBody = this.registerBody({ deployId, url });\n    const introspectionBody = await this.introspectionBody({\n      actions,\n      env,\n      signatureValidation,\n      url,\n    });\n\n    const body: InBandRegisterRequest = {\n      app_id: this.client.id,\n      appVersion: this.client.appVersion,\n      capabilities: registerBody.capabilities,\n      env,\n      framework: registerBody.framework,\n      functions: registerBody.functions,\n      inspection: introspectionBody,\n      platform: getPlatformName({\n        ...getProcessEnv(),\n        ...this.env,\n      }),\n      sdk_author: \"inngest\",\n      sdk_language: \"\",\n      sdk_version: \"\",\n      sdk: registerBody.sdk,\n      url: registerBody.url,\n    };\n\n    if (\n      \"authentication_succeeded\" in introspectionBody &&\n      introspectionBody.authentication_succeeded\n    ) {\n      body.sdk_language = introspectionBody.sdk_language;\n      body.sdk_version = introspectionBody.sdk_version;\n    }\n\n    return body;\n  }\n\n  protected async introspectionBody({\n    actions,\n    env,\n    signatureValidation,\n    url,\n  }: {\n    actions: HandlerResponseWithErrors;\n    env: string | null;\n    signatureValidation: ReturnType<InngestCommHandler[\"validateSignature\"]>;\n    url: URL;\n  }): Promise<UnauthenticatedIntrospection | AuthenticatedIntrospection> {\n    const registerBody = this.registerBody({\n      url: this.reqUrl(url),\n      deployId: null,\n    });\n\n    if (!this.client.mode) {\n      throw new Error(\"No mode set; cannot introspect without mode\");\n    }\n\n    let introspection:\n      | UnauthenticatedIntrospection\n      | AuthenticatedIntrospection = {\n      extra: {\n        native_crypto: globalThis.crypto?.subtle ? true : false,\n      },\n      has_event_key: this.client[\"eventKeySet\"](),\n      has_signing_key: Boolean(this.client.signingKey),\n      function_count: registerBody.functions.length,\n      mode: this.client.mode,\n      schema_version: \"2024-05-24\",\n    } satisfies UnauthenticatedIntrospection;\n\n    // Only allow authenticated introspection in Cloud mode, since Dev mode skips\n    // signature validation\n    if (this.client.mode === \"cloud\") {\n      try {\n        const validationResult = await signatureValidation;\n        if (!validationResult.success) {\n          throw new Error(\"Signature validation failed\");\n        }\n\n        // For the signing keys, only send the first 12 characters of the hash.\n        // It's technically safe to send the full hash since the request was\n        // authenticated, but we'll play it safe and only send the first 12\n        // characters. 12 characters is enough to uniquely identify the key\n        // without revealing the full hash.\n        let signingKeyHash: string | null = null;\n        if (this.hashedSigningKey) {\n          signingKeyHash = removeSigningKeyPrefix(this.hashedSigningKey).slice(\n            0,\n            12,\n          );\n        }\n        let signingKeyFallbackHash: string | null = null;\n        if (this.hashedSigningKeyFallback) {\n          signingKeyFallbackHash = removeSigningKeyPrefix(\n            this.hashedSigningKeyFallback,\n          ).slice(0, 12);\n        }\n\n        introspection = {\n          ...introspection,\n          authentication_succeeded: true,\n          api_origin: this.client.apiBaseUrl,\n          app_id: this.client.id,\n          capabilities: {\n            trust_probe: \"v1\",\n            connect: \"v1\",\n          },\n          env,\n          event_api_origin: this.client.eventBaseUrl,\n          event_key_hash: this.hashedEventKey ?? null,\n          extra: {\n            ...introspection.extra,\n            is_streaming: await this.shouldStream(actions),\n            native_crypto: globalThis.crypto?.subtle ? true : false,\n          },\n          framework: this.frameworkName,\n          sdk_language: \"js\",\n          sdk_version: version,\n          serve_origin: this.serveOrigin ?? null,\n          serve_path: this.servePath ?? null,\n          signing_key_fallback_hash: signingKeyFallbackHash,\n          signing_key_hash: signingKeyHash,\n        } satisfies AuthenticatedIntrospection;\n      } catch {\n        // Swallow signature validation error since we'll just return the\n        // unauthenticated introspection\n        introspection = {\n          ...introspection,\n        } satisfies UnauthenticatedIntrospection;\n      }\n    }\n\n    return introspection;\n  }\n\n  protected async register(\n    url: URL,\n    deployId: string | undefined | null,\n    getHeaders: () => Promise<Record<string, string>>,\n  ): Promise<{ status: number; message: string; modified: boolean }> {\n    const body = this.registerBody({ url, deployId });\n\n    let res: globalThis.Response;\n\n    // Clone the URL object to avoid mutating the property between requests.\n    const registerUrl = new URL(this.inngestRegisterUrl.href);\n\n    if (deployId) {\n      registerUrl.searchParams.set(queryKeys.DeployId, deployId);\n    }\n\n    try {\n      res = await fetchWithAuthFallback({\n        authToken: this.hashedSigningKey,\n        authTokenFallback: this.hashedSigningKeyFallback,\n        fetch: this.client.fetch,\n        url: registerUrl.href,\n        options: {\n          method: \"POST\",\n          body: stringify(body),\n          headers: {\n            ...(await getHeaders()),\n            [headerKeys.InngestSyncKind]: syncKind.OutOfBand,\n          },\n          redirect: \"follow\",\n        },\n      });\n    } catch (err: unknown) {\n      this.client[internalLoggerSymbol].error({ err }, \"Failed to register\");\n\n      return {\n        status: 500,\n        message: `Failed to register${\n          err instanceof Error ? `; ${err.message}` : \"\"\n        }`,\n        modified: false,\n      };\n    }\n\n    const raw = await res.text();\n\n    let data: z.input<typeof registerResSchema> = {};\n\n    try {\n      data = JSON.parse(raw);\n    } catch (err) {\n      this.client[internalLoggerSymbol].warn(\n        { err },\n        \"Couldn't unpack register response\",\n      );\n\n      let message = \"Failed to register\";\n      if (err instanceof Error) {\n        message += `; ${err.message}`;\n      }\n      message += `; status code: ${res.status}`;\n\n      return {\n        status: 500,\n        message,\n        modified: false,\n      };\n    }\n\n    let status: number;\n    let error: string;\n    let skipped: boolean;\n    let modified: boolean;\n    try {\n      ({ status, error, skipped, modified } = registerResSchema.parse(data));\n    } catch (err) {\n      this.client[internalLoggerSymbol].warn(\n        { err },\n        \"Invalid register response schema\",\n      );\n\n      let message = \"Failed to register\";\n      if (err instanceof Error) {\n        message += `; ${err.message}`;\n      }\n      message += `; status code: ${res.status}`;\n\n      return {\n        status: 500,\n        message,\n        modified: false,\n      };\n    }\n\n    // The dev server polls this endpoint to register functions every few\n    // seconds, but we only want to log that we've registered functions if\n    // the function definitions change.  Therefore, we compare the body sent\n    // during registration with the body of the current functions and refuse\n    // to register if the functions are the same.\n    if (!skipped) {\n      this.client[internalLoggerSymbol].debug(\"Registered inngest functions\");\n    }\n\n    return { status, message: error, modified };\n  }\n\n  /**\n   * Check that the current mode has the configuration it requires.\n   * Returns `true` if valid, `false` if not.\n   */\n  checkModeConfiguration(): boolean {\n    this.client.setEnvVars(this.env);\n\n    return checkModeConfiguration({\n      mode: this.client.mode,\n      signingKey: this.client.signingKey,\n      internalLogger: this.client[internalLoggerSymbol],\n    });\n  }\n\n  /**\n   * Validate the signature of a request and return the signing key used to\n   * validate it.\n   */\n\n  protected async validateSignature(\n    sig: string | undefined,\n    body: unknown,\n  ): Promise<\n    { success: true; keyUsed: string } | { success: false; err: Error }\n  > {\n    try {\n      // Skip signature validation if requested (used by connect)\n      if (this.skipSignatureValidation) {\n        return { success: true, keyUsed: \"\" };\n      }\n\n      // Never validate signatures outside of prod. Make sure to check the mode\n      // exists here instead of using nullish coalescing to confirm that the check\n      // has been completed.\n      if (this.client.mode !== \"cloud\") {\n        return { success: true, keyUsed: \"\" };\n      }\n\n      // If we're here, we're in production; lack of a signing key is an error.\n      if (!this.client.signingKey) {\n        throw new Error(\n          `No signing key found in client options or ${envKeys.InngestSigningKey} env var. Find your keys at https://app.inngest.com/env/production/manage/signing-key`,\n        );\n      }\n\n      // If we're here, we're in production; lack of a req signature is an error.\n      if (!sig) {\n        throw new Error(`No ${headerKeys.Signature} provided`);\n      }\n\n      // Validate the signature\n      return {\n        success: true,\n        keyUsed: await new RequestSignature(sig).verifySignature({\n          body,\n          allowExpiredSignatures: this.allowExpiredSignatures,\n          signingKey: this.client.signingKey,\n          signingKeyFallback: this.client.signingKeyFallback,\n          logger: this.client[internalLoggerSymbol],\n        }),\n      };\n    } catch (err) {\n      return { success: false, err: err as Error };\n    }\n  }\n\n  protected async getResponseSignature(\n    key: string,\n    body: string,\n  ): Promise<string> {\n    const now = Math.round(Date.now() / 1000);\n    const mac = await signDataWithKey(\n      body,\n      key,\n      now.toString(),\n      this.client[internalLoggerSymbol],\n    );\n\n    return `t=${now}&s=${mac}`;\n  }\n}\n\n/**\n * @internal Exported for testing; not part of the public API.\n */\nexport class RequestSignature {\n  public timestamp: string;\n  public signature: string;\n\n  constructor(sig: string) {\n    const params = new URLSearchParams(sig);\n    this.timestamp = params.get(\"t\") || \"\";\n    this.signature = params.get(\"s\") || \"\";\n\n    if (!this.timestamp || !this.signature) {\n      throw new Error(`Invalid ${headerKeys.Signature} provided`);\n    }\n  }\n\n  private hasExpired(allowExpiredSignatures?: boolean) {\n    if (allowExpiredSignatures) {\n      return false;\n    }\n\n    const ts = Number.parseInt(this.timestamp, 10);\n    if (!Number.isFinite(ts)) {\n      return true;\n    }\n\n    const delta = Date.now() - ts * 1000;\n    // Clamp both ends: negative delta (future-skewed `t`) would otherwise give\n    // captured requests an unbounded replay\n    return Math.abs(delta) > 1000 * 60 * 5;\n  }\n\n  async #verifySignature({\n    body,\n    signingKey,\n    allowExpiredSignatures,\n    logger,\n  }: {\n    body: unknown;\n    signingKey: string;\n    allowExpiredSignatures: boolean;\n    logger: Logger;\n  }): Promise<void> {\n    if (this.hasExpired(allowExpiredSignatures)) {\n      throw new Error(\"Signature has expired\");\n    }\n\n    const mac = await signDataWithKey(body, signingKey, this.timestamp, logger);\n    if (!timingSafeEqual(mac, this.signature)) {\n      throw new Error(\"Invalid signature\");\n    }\n  }\n\n  public async verifySignature({\n    body,\n    signingKey,\n    signingKeyFallback,\n    allowExpiredSignatures,\n    logger,\n  }: {\n    body: unknown;\n    signingKey: string;\n    signingKeyFallback: string | undefined;\n    allowExpiredSignatures: boolean;\n    logger: Logger;\n  }): Promise<string> {\n    try {\n      await this.#verifySignature({\n        body,\n        signingKey,\n        allowExpiredSignatures,\n        logger,\n      });\n\n      return signingKey;\n    } catch (err) {\n      if (!signingKeyFallback) {\n        throw err;\n      }\n\n      await this.#verifySignature({\n        body,\n        signingKey: signingKeyFallback,\n        allowExpiredSignatures,\n        logger,\n      });\n\n      return signingKeyFallback;\n    }\n  }\n}\n\n/**\n * The broad definition of a handler passed when instantiating an\n * {@link InngestCommHandler} instance.\n */\nexport type Handler<\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  Input extends any[] = any[],\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  Output = any,\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  StreamOutput = any,\n> = (...args: Input) => HandlerResponse<Output, StreamOutput>;\n\n// biome-ignore lint/suspicious/noExplicitAny: intentional\nexport type HandlerResponse<Output = any, StreamOutput = any> = {\n  // biome-ignore lint/suspicious/noExplicitAny: intentional\n  body: () => MaybePromise<any>;\n  env?: () => MaybePromise<Env | undefined>;\n  headers: (key: string) => MaybePromise<string | null | undefined>;\n\n  method: () => MaybePromise<string>;\n  queryString?: (\n    key: string,\n    url: URL,\n  ) => MaybePromise<string | null | undefined>;\n  url: () => MaybePromise<URL>;\n\n  /**\n   * The `transformResponse` function receives the output of the Inngest SDK and\n   * can decide how to package up that information to appropriately return the\n   * information to Inngest.\n   *\n   * Mostly, this is taking the given parameters and returning a new `Response`.\n   *\n   * The function is passed an {@link ActionResponse}, an object containing a\n   * `status` code, a `headers` object, and a stringified `body`. This ensures\n   * you can appropriately handle the response, including use of any required\n   * parameters such as `res` in Express-/Connect-like frameworks.\n   */\n  transformResponse: (res: ActionResponse<string>) => Output;\n\n  /**\n   * The `transformStreamingResponse` function, if defined, declares that this\n   * handler supports streaming responses back to Inngest. This is useful for\n   * functions that are expected to take a long time, as edge streaming can\n   * often circumvent restrictive request timeouts and other limitations.\n   *\n   * If your handler does not support streaming, do not define this function.\n   *\n   * It receives the output of the Inngest SDK and can decide how to package\n   * up that information to appropriately return the information in a stream\n   * to Inngest.\n   *\n   * Mostly, this is taking the given parameters and returning a new `Response`.\n   *\n   * The function is passed an {@link ActionResponse}, an object containing a\n   * `status` code, a `headers` object, and `body`, a `ReadableStream`. This\n   * ensures you can appropriately handle the response, including use of any\n   * required parameters such as `res` in Express-/Connect-like frameworks.\n   */\n  transformStreamingResponse?: (\n    res: ActionResponse<ReadableStream>,\n  ) => StreamOutput;\n\n  /**\n   * TODO Needed to give folks a chance to wrap arguments if they need to in\n   * order to extract the request body so that it can be sent back to Inngest\n   * during either sync or async calls.\n   *\n   * This is because usually they do not interact directly with e.g. the\n   * `Response` object, but with sync mode they do, so we need to provide hooks\n   * to let us access the body.\n   */\n  experimentalTransformSyncRequest?: (\n    ...args: unknown[]\n  ) => MaybePromise<unknown>;\n\n  /**\n   * TODO Needed to give folks a chance to transform the response from their own\n   * code to an Inngestish response. This is only needed so that sync mode can\n   * checkpoint the response if we've gone through the entire run with no\n   * interruptions.\n   *\n   * Because of its location when being specified, we have scoped access to the\n   * `reqArgs` (e.g. `req` and `res`), so we don't need to pass them here.\n   */\n  experimentalTransformSyncResponse?: (\n    data: unknown,\n  ) => MaybePromise<Omit<ActionResponse, \"version\">>;\n};\n\n/**\n * The response from the Inngest SDK before it is transformed in to a\n * framework-compatible response by an {@link InngestCommHandler} instance.\n */\nexport interface ActionResponse<\n  TBody extends string | ReadableStream = string,\n> {\n  /**\n   * The HTTP status code to return.\n   */\n  status: number;\n\n  /**\n   * The headers to return in the response.\n   */\n  headers: Record<string, string>;\n\n  /**\n   * A stringified body to return.\n   */\n  body: TBody;\n\n  /**\n   * The version of the execution engine that was used to run this action.\n   *\n   * If the action didn't use the execution engine (for example, a GET request\n   * as a health check) or would have but errored before reaching it, this will\n   * be `undefined`.\n   *\n   * If the version should be entirely omitted from the response (for example,\n   * when sending preliminary headers when streaming), this will be `null`.\n   */\n  version: ExecutionVersion | null | undefined;\n}\n\n/**\n * A version of {@link HandlerResponse} where each function is safely\n * promisified and requires a reason for each access.\n *\n * This enables us to provide accurate errors for each access without having to\n * wrap every access in a try/catch.\n */\nexport type ActionHandlerResponseWithErrors = {\n  [K in keyof HandlerResponse]: NonNullable<HandlerResponse[K]> extends (\n    ...args: infer Args\n  ) => infer R\n    ? R extends MaybePromise<infer PR>\n      ? (errMessage: string, ...args: Args) => Promise<PR>\n      : (errMessage: string, ...args: Args) => Promise<R>\n    : HandlerResponse[K];\n};\n\n/**\n * A version of {@link ActionHandlerResponseWithErrors} that includes helper\n * functions that provide sensible defaults on top of the direct access given\n * from the bare response.\n */\nexport interface HandlerResponseWithErrors\n  extends ActionHandlerResponseWithErrors {\n  /**\n   * Fetch a query string value from the request. If no `querystring` action has\n   * been provided by the `serve()` handler, this will fall back to using the\n   * provided URL present in the request to parse the query string from instead.\n   */\n  queryStringWithDefaults: (\n    reason: string,\n    key: string,\n  ) => Promise<string | undefined>;\n}\n"],"mappings":"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"}