inngest 3.43.1 → 3.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/components/Fetch.js +5 -5
- package/components/Fetch.js.map +1 -1
- package/components/InngestCommHandler.cjs +4 -2
- package/components/InngestCommHandler.cjs.map +1 -1
- package/components/InngestCommHandler.d.cts.map +1 -1
- package/components/InngestCommHandler.d.ts.map +1 -1
- package/components/InngestCommHandler.js +6 -4
- package/components/InngestCommHandler.js.map +1 -1
- package/components/InngestFunctionReference.cjs +13 -2
- package/components/InngestFunctionReference.cjs.map +1 -1
- package/components/InngestFunctionReference.d.cts +5 -0
- package/components/InngestFunctionReference.d.cts.map +1 -1
- package/components/InngestFunctionReference.d.ts +5 -0
- package/components/InngestFunctionReference.d.ts.map +1 -1
- package/components/InngestFunctionReference.js +7 -1
- package/components/InngestFunctionReference.js.map +1 -1
- package/components/connect/buffer.js +2 -2
- package/components/connect/buffer.js.map +1 -1
- package/components/connect/index.js +2 -2
- package/components/connect/index.js.map +1 -1
- package/components/execution/InngestExecution.js +2 -2
- package/components/execution/InngestExecution.js.map +1 -1
- package/components/execution/otel/middleware.js +9 -9
- package/components/execution/otel/middleware.js.map +1 -1
- package/components/execution/otel/processor.js +9 -9
- package/components/execution/otel/processor.js.map +1 -1
- package/components/execution/v1.cjs +30 -15
- package/components/execution/v1.cjs.map +1 -1
- package/components/execution/v1.d.cts.map +1 -1
- package/components/execution/v1.d.ts.map +1 -1
- package/components/execution/v1.js +30 -15
- package/components/execution/v1.js.map +1 -1
- package/components/execution/v2.cjs +30 -15
- package/components/execution/v2.cjs.map +1 -1
- package/components/execution/v2.d.cts.map +1 -1
- package/components/execution/v2.d.ts.map +1 -1
- package/components/execution/v2.js +30 -15
- package/components/execution/v2.js.map +1 -1
- package/helpers/functions.cjs +2 -0
- package/helpers/functions.cjs.map +1 -1
- package/helpers/functions.js +2 -0
- package/helpers/functions.js.map +1 -1
- package/helpers/validators/index.d.cts +4 -4
- package/helpers/validators/index.d.cts.map +1 -1
- package/helpers/validators/index.d.ts +4 -4
- package/helpers/validators/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/types.cjs +1 -0
- package/types.cjs.map +1 -1
- package/types.d.cts +5 -0
- package/types.d.cts.map +1 -1
- package/types.d.ts +5 -0
- package/types.d.ts.map +1 -1
- package/types.js +1 -0
- package/types.js.map +1 -1
- package/version.cjs +1 -1
- package/version.cjs.map +1 -1
- package/version.d.cts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# inngest
|
|
2
2
|
|
|
3
|
+
## 3.44.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1102](https://github.com/inngest/inngest-js/pull/1102) [`6507c0cd`](https://github.com/inngest/inngest-js/commit/6507c0cdc792ef905b06481f69b4e7fe8ad75fe7) Thanks [@jpwilliams](https://github.com/jpwilliams)! - Add `InngestFunctionReference.Like` for comparing referenced functions across versions
|
|
8
|
+
|
|
9
|
+
- [#1102](https://github.com/inngest/inngest-js/pull/1102) [`6507c0cd`](https://github.com/inngest/inngest-js/commit/6507c0cdc792ef905b06481f69b4e7fe8ad75fe7) Thanks [@jpwilliams](https://github.com/jpwilliams)! - Add Standard Schema to `referenceFunction()`
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#1075](https://github.com/inngest/inngest-js/pull/1075) [`1cf1e525`](https://github.com/inngest/inngest-js/commit/1cf1e525a90186af0bbb6024198259d0e9006adc) Thanks [@Linell](https://github.com/Linell)! - Add support for the `StepFailed` opcode, which is used to signify that a function has failed in a permanent way and should not be retried.
|
|
14
|
+
|
|
3
15
|
## 3.43.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/components/Fetch.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { getAsyncCtx } from "./execution/als.js";
|
|
2
2
|
import { gatewaySymbol } from "./InngestStepTools.js";
|
|
3
|
-
import
|
|
3
|
+
import debug from "debug";
|
|
4
4
|
|
|
5
5
|
//#region src/components/Fetch.ts
|
|
6
6
|
const globalFetch = globalThis.fetch;
|
|
7
|
-
const debug =
|
|
7
|
+
const debug$1 = debug("inngest:fetch");
|
|
8
8
|
const createFetchShim = () => {
|
|
9
9
|
let stepFetch;
|
|
10
10
|
const fetch$1 = async (input, init) => {
|
|
11
11
|
const ctx = await getAsyncCtx();
|
|
12
12
|
if (!ctx) {
|
|
13
13
|
if (!stepFetch.fallback) throw new Error("step.fetch() called outside of a function and had no fallback set");
|
|
14
|
-
debug("step.fetch() called outside of a function; falling back to global fetch");
|
|
14
|
+
debug$1("step.fetch() called outside of a function; falling back to global fetch");
|
|
15
15
|
return stepFetch.fallback(input, init);
|
|
16
16
|
}
|
|
17
17
|
if (ctx.executingStep) {
|
|
18
18
|
if (!stepFetch.fallback) throw new Error(`step.fetch() called inside step "${ctx.executingStep.id}" and had no fallback set`);
|
|
19
|
-
debug(`step.fetch() called inside step "${ctx.executingStep.id}"; falling back to global fetch`);
|
|
19
|
+
debug$1(`step.fetch() called inside step "${ctx.executingStep.id}"; falling back to global fetch`);
|
|
20
20
|
return stepFetch.fallback(input, init);
|
|
21
21
|
}
|
|
22
22
|
const targetUrl = new URL(input instanceof Request ? input.url : input.toString());
|
|
23
|
-
debug("step.fetch() shimming request to", targetUrl.hostname);
|
|
23
|
+
debug$1("step.fetch() shimming request to", targetUrl.hostname);
|
|
24
24
|
const jsonRes = await ctx.ctx.step[gatewaySymbol](`step.fetch: ${targetUrl.hostname}`, input, init);
|
|
25
25
|
return new Response(jsonRes.body, {
|
|
26
26
|
headers: jsonRes.headers,
|
package/components/Fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Fetch.js","names":["stepFetch: StepFetch","fetch: Fetch","optionsRef: StepFetch.Options","extras: StepFetch.Extras","fetch"],"sources":["../../src/components/Fetch.ts"],"sourcesContent":["import Debug from \"debug\";\nimport type { Simplify } from \"../helpers/types.ts\";\nimport { getAsyncCtx } from \"./execution/als.ts\";\nimport { gatewaySymbol, type InternalStepTools } from \"./InngestStepTools.ts\";\n\nconst globalFetch = globalThis.fetch;\ntype Fetch = typeof globalFetch;\n\nexport type StepFetch = Fetch &\n Simplify<\n {\n config: (options: StepFetch.Options) => StepFetch;\n } & Readonly<StepFetch.Options>\n >;\n\nexport namespace StepFetch {\n export interface Options {\n fallback?: Fetch | undefined;\n }\n\n export interface Extras extends Options {\n config: (options: Options) => StepFetch;\n }\n}\n\nconst debug = Debug(\"inngest:fetch\");\n\nconst createFetchShim = (): StepFetch => {\n // biome-ignore lint/style/useConst: need this to allow fns to be defined\n let stepFetch: StepFetch;\n\n const fetch: Fetch = async (input, init) => {\n const ctx = await getAsyncCtx();\n if (!ctx) {\n // Not in a function run\n if (!stepFetch.fallback) {\n // TODO Tell the user how to solve\n throw new Error(\n \"step.fetch() called outside of a function and had no fallback set\",\n );\n }\n\n debug(\n \"step.fetch() called outside of a function; falling back to global fetch\",\n );\n\n return stepFetch.fallback(input, init);\n }\n\n // In a function run\n if (ctx.executingStep) {\n // Inside a step\n if (!stepFetch.fallback) {\n // TODO Tell the user how to solve\n throw new Error(\n `step.fetch() called inside step \"${ctx.executingStep.id}\" and had no fallback set`,\n );\n }\n\n debug(\n `step.fetch() called inside step \"${ctx.executingStep.id}\"; falling back to global fetch`,\n );\n\n return stepFetch.fallback(input, init);\n }\n\n const targetUrl = new URL(\n input instanceof Request ? input.url : input.toString(),\n );\n\n debug(\"step.fetch() shimming request to\", targetUrl.hostname);\n\n // Purposefully do not try/cacth this; if it throws then we treat that as a\n // regular `fetch()` throw, which also would not return a `Response`.\n const jsonRes = await (ctx.ctx.step as InternalStepTools)[gatewaySymbol](\n `step.fetch: ${targetUrl.hostname}`,\n input,\n init,\n );\n\n return new Response(jsonRes.body, {\n headers: jsonRes.headers,\n status: jsonRes.status,\n });\n };\n\n const optionsRef: StepFetch.Options = {\n fallback: globalFetch,\n };\n\n const extras: StepFetch.Extras = {\n config: (options) => {\n Object.assign(optionsRef, options);\n Object.assign(stepFetch, optionsRef);\n\n return stepFetch;\n },\n ...optionsRef,\n };\n\n stepFetch = Object.assign(fetch, extras);\n\n return stepFetch;\n};\n\n/**\n * `fetch` is a Fetch API-compatible function that can be used to make any HTTP\n * code durable if it's called within an Inngest function.\n *\n * It will gracefully fall back to the global `fetch` if called outside of this\n * context, and a custom fallback can be set using the `config` method.\n *\n * @example Basic usage\n * ```ts\n * import { fetch } from \"inngest\";\n *\n * const api = new MyProductApi({ fetch });\n * ```\n *\n * @example Setting a custom fallback\n * ```ts\n * import { fetch } from \"inngest\";\n *\n * const api = new MyProductApi({\n * fetch: fetch.config({ fallback: myCustomFetch }),\n * });\n * ```\n *\n * @example Do not allow fallback\n * ```ts\n * import { fetch } from \"inngest\";\n *\n * const api = new MyProductApi({\n * fetch: fetch.config({ fallback: undefined }),\n * });\n * ```\n */\nexport const fetch = createFetchShim();\n"],"mappings":";;;;;AAKA,MAAM,cAAc,WAAW;AAoB/B,
|
|
1
|
+
{"version":3,"file":"Fetch.js","names":["debug","Debug","stepFetch: StepFetch","fetch: Fetch","optionsRef: StepFetch.Options","extras: StepFetch.Extras","fetch"],"sources":["../../src/components/Fetch.ts"],"sourcesContent":["import Debug from \"debug\";\nimport type { Simplify } from \"../helpers/types.ts\";\nimport { getAsyncCtx } from \"./execution/als.ts\";\nimport { gatewaySymbol, type InternalStepTools } from \"./InngestStepTools.ts\";\n\nconst globalFetch = globalThis.fetch;\ntype Fetch = typeof globalFetch;\n\nexport type StepFetch = Fetch &\n Simplify<\n {\n config: (options: StepFetch.Options) => StepFetch;\n } & Readonly<StepFetch.Options>\n >;\n\nexport namespace StepFetch {\n export interface Options {\n fallback?: Fetch | undefined;\n }\n\n export interface Extras extends Options {\n config: (options: Options) => StepFetch;\n }\n}\n\nconst debug = Debug(\"inngest:fetch\");\n\nconst createFetchShim = (): StepFetch => {\n // biome-ignore lint/style/useConst: need this to allow fns to be defined\n let stepFetch: StepFetch;\n\n const fetch: Fetch = async (input, init) => {\n const ctx = await getAsyncCtx();\n if (!ctx) {\n // Not in a function run\n if (!stepFetch.fallback) {\n // TODO Tell the user how to solve\n throw new Error(\n \"step.fetch() called outside of a function and had no fallback set\",\n );\n }\n\n debug(\n \"step.fetch() called outside of a function; falling back to global fetch\",\n );\n\n return stepFetch.fallback(input, init);\n }\n\n // In a function run\n if (ctx.executingStep) {\n // Inside a step\n if (!stepFetch.fallback) {\n // TODO Tell the user how to solve\n throw new Error(\n `step.fetch() called inside step \"${ctx.executingStep.id}\" and had no fallback set`,\n );\n }\n\n debug(\n `step.fetch() called inside step \"${ctx.executingStep.id}\"; falling back to global fetch`,\n );\n\n return stepFetch.fallback(input, init);\n }\n\n const targetUrl = new URL(\n input instanceof Request ? input.url : input.toString(),\n );\n\n debug(\"step.fetch() shimming request to\", targetUrl.hostname);\n\n // Purposefully do not try/cacth this; if it throws then we treat that as a\n // regular `fetch()` throw, which also would not return a `Response`.\n const jsonRes = await (ctx.ctx.step as InternalStepTools)[gatewaySymbol](\n `step.fetch: ${targetUrl.hostname}`,\n input,\n init,\n );\n\n return new Response(jsonRes.body, {\n headers: jsonRes.headers,\n status: jsonRes.status,\n });\n };\n\n const optionsRef: StepFetch.Options = {\n fallback: globalFetch,\n };\n\n const extras: StepFetch.Extras = {\n config: (options) => {\n Object.assign(optionsRef, options);\n Object.assign(stepFetch, optionsRef);\n\n return stepFetch;\n },\n ...optionsRef,\n };\n\n stepFetch = Object.assign(fetch, extras);\n\n return stepFetch;\n};\n\n/**\n * `fetch` is a Fetch API-compatible function that can be used to make any HTTP\n * code durable if it's called within an Inngest function.\n *\n * It will gracefully fall back to the global `fetch` if called outside of this\n * context, and a custom fallback can be set using the `config` method.\n *\n * @example Basic usage\n * ```ts\n * import { fetch } from \"inngest\";\n *\n * const api = new MyProductApi({ fetch });\n * ```\n *\n * @example Setting a custom fallback\n * ```ts\n * import { fetch } from \"inngest\";\n *\n * const api = new MyProductApi({\n * fetch: fetch.config({ fallback: myCustomFetch }),\n * });\n * ```\n *\n * @example Do not allow fallback\n * ```ts\n * import { fetch } from \"inngest\";\n *\n * const api = new MyProductApi({\n * fetch: fetch.config({ fallback: undefined }),\n * });\n * ```\n */\nexport const fetch = createFetchShim();\n"],"mappings":";;;;;AAKA,MAAM,cAAc,WAAW;AAoB/B,MAAMA,UAAQC,MAAM,gBAAgB;AAEpC,MAAM,wBAAmC;CAEvC,IAAIC;CAEJ,MAAMC,UAAe,OAAO,OAAO,SAAS;EAC1C,MAAM,MAAM,MAAM,aAAa;AAC/B,MAAI,CAAC,KAAK;AAER,OAAI,CAAC,UAAU,SAEb,OAAM,IAAI,MACR,oEACD;AAGH,WACE,0EACD;AAED,UAAO,UAAU,SAAS,OAAO,KAAK;;AAIxC,MAAI,IAAI,eAAe;AAErB,OAAI,CAAC,UAAU,SAEb,OAAM,IAAI,MACR,oCAAoC,IAAI,cAAc,GAAG,2BAC1D;AAGH,WACE,oCAAoC,IAAI,cAAc,GAAG,iCAC1D;AAED,UAAO,UAAU,SAAS,OAAO,KAAK;;EAGxC,MAAM,YAAY,IAAI,IACpB,iBAAiB,UAAU,MAAM,MAAM,MAAM,UAAU,CACxD;AAED,UAAM,oCAAoC,UAAU,SAAS;EAI7D,MAAM,UAAU,MAAO,IAAI,IAAI,KAA2B,eACxD,eAAe,UAAU,YACzB,OACA,KACD;AAED,SAAO,IAAI,SAAS,QAAQ,MAAM;GAChC,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GACjB,CAAC;;CAGJ,MAAMC,aAAgC,EACpC,UAAU,aACX;CAED,MAAMC,SAA2B;EAC/B,SAAS,YAAY;AACnB,UAAO,OAAO,YAAY,QAAQ;AAClC,UAAO,OAAO,WAAW,WAAW;AAEpC,UAAO;;EAET,GAAG;EACJ;AAED,aAAY,OAAO,OAAOC,SAAO,OAAO;AAExC,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,MAAa,QAAQ,iBAAiB"}
|
|
@@ -852,7 +852,8 @@ var InngestCommHandler = class {
|
|
|
852
852
|
event,
|
|
853
853
|
events,
|
|
854
854
|
runId: ctx?.run_id || "",
|
|
855
|
-
attempt: ctx?.attempt ?? 0
|
|
855
|
+
attempt: ctx?.attempt ?? 0,
|
|
856
|
+
maxAttempts: ctx?.max_attempts
|
|
856
857
|
},
|
|
857
858
|
stepState,
|
|
858
859
|
requestedRunStep: stepId === "step" ? void 0 : stepId || void 0,
|
|
@@ -890,7 +891,8 @@ var InngestCommHandler = class {
|
|
|
890
891
|
event,
|
|
891
892
|
events,
|
|
892
893
|
runId: ctx?.run_id || "",
|
|
893
|
-
attempt: ctx?.attempt ?? 0
|
|
894
|
+
attempt: ctx?.attempt ?? 0,
|
|
895
|
+
maxAttempts: ctx?.max_attempts
|
|
894
896
|
},
|
|
895
897
|
stepState,
|
|
896
898
|
requestedRunStep: stepId === "step" ? void 0 : stepId || void 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InngestCommHandler.cjs","names":["z","allProcessEnv","logPrefix","acc","envKeys","defaultLogLevel: typeof this.logLevel","logLevels","debugPrefix","defaultStreamingOption: typeof this.streaming","getFetch","defaultInngestApiBaseUrl","defaultInngestEventBaseUrl","dummyEventKey","hashEventKey","hashSigningKey","queryKeys","platformSupportsStreaming","ServerTiming","rethrowError","actions: HandlerResponseWithErrors","args","runAsPromise","headerKeys","inngestHeaders","getMode","Mode","method","headers: Record<string, string>","PREFERRED_EXECUTION_VERSION","signature: string | undefined","stringify","serializeError","signature","createStream","actionRes","probe","enumFromValue","probeEnum","undefinedToNull","result","deployId","parseAsBoolean","syncKind","inBandSyncRequestBodySchema","parseFnData","version","ExecutionVersion","fetchAllFnData","data","functionConfigSchema","body: InBandRegisterRequest","getPlatformName","introspection:\n | UnauthenticatedIntrospection\n | AuthenticatedIntrospection","res: globalThis.Response","devServerHost","devServerAvailable","devServerUrl","fetchWithAuthFallback","err: unknown","data: z.input<typeof registerResSchema>","status: number","error: string","skipped: boolean","modified: boolean","signDataWithKey","logLevels: LogLevel[]","#verifySignature"],"sources":["../../src/components/InngestCommHandler.ts"],"sourcesContent":["import debug from \"debug\";\nimport { z } from \"zod/v3\";\nimport {\n debugPrefix,\n defaultInngestApiBaseUrl,\n defaultInngestEventBaseUrl,\n dummyEventKey,\n ExecutionVersion,\n envKeys,\n headerKeys,\n logPrefix,\n probe as probeEnum,\n queryKeys,\n syncKind,\n} from \"../helpers/consts.ts\";\nimport { devServerAvailable, devServerUrl } from \"../helpers/devserver.ts\";\nimport { enumFromValue } from \"../helpers/enum.ts\";\nimport {\n allProcessEnv,\n devServerHost,\n type Env,\n getFetch,\n getMode,\n getPlatformName,\n inngestHeaders,\n Mode,\n parseAsBoolean,\n platformSupportsStreaming,\n} from \"../helpers/env.ts\";\nimport { rethrowError, serializeError } from \"../helpers/errors.ts\";\nimport {\n type FnData,\n fetchAllFnData,\n parseFnData,\n undefinedToNull,\n} from \"../helpers/functions.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 { hashEventKey, hashSigningKey, stringify } from \"../helpers/strings.ts\";\nimport type { MaybePromise } from \"../helpers/types.ts\";\nimport {\n type AuthenticatedIntrospection,\n type EventPayload,\n type FunctionConfig,\n functionConfigSchema,\n type InBandRegisterRequest,\n inBandSyncRequestBodySchema,\n type LogLevel,\n logLevels,\n type OutgoingOp,\n type RegisterOptions,\n type RegisterRequest,\n type SupportedFrameworkName,\n type UnauthenticatedIntrospection,\n} from \"../types.ts\";\nimport { version } from \"../version.ts\";\nimport {\n type ExecutionResult,\n type ExecutionResultHandler,\n type ExecutionResultHandlers,\n type InngestExecutionOptions,\n PREFERRED_EXECUTION_VERSION,\n} from \"./execution/InngestExecution.ts\";\nimport type { Inngest } from \"./Inngest.ts\";\nimport type {\n CreateExecutionOptions,\n InngestFunction,\n} from \"./InngestFunction.ts\";\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\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\ninterface InngestCommHandlerOptions<\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Input extends any[] = any[],\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Output = any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\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/**\n * Capturing the global type of fetch so that we can reliably access it below.\n */\ntype FetchT = typeof fetch;\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: <explanation>\n Input extends any[] = any[],\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Output = any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n StreamOutput = any,\n> {\n /**\n * The ID 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 public readonly id: string;\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 signing key used to validate requests from Inngest. This is\n * intentionally mutable so that we can pick up the signing key from the\n * environment during execution if needed.\n */\n protected signingKey: string | undefined;\n\n /**\n * The same as signingKey, except used as a fallback when auth fails using the\n * primary signing key.\n */\n protected signingKeyFallback: string | undefined;\n\n /**\n * A property that can be set to indicate whether we believe we are in\n * production mode.\n *\n * Should be set every time a request is received.\n */\n protected _mode: Mode | undefined;\n\n /**\n * The localized `fetch` implementation used by this handler.\n */\n private readonly fetch: FetchT;\n\n /**\n * The host 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 hostname 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 _serveHost: 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 `serveHost`.\n */\n private readonly _servePath: string | undefined;\n\n /**\n * The minimum level to log from the Inngest serve handler.\n */\n protected readonly logLevel: LogLevel;\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<\n string,\n { fn: InngestFunction.Any; onFailure: boolean }\n > = {};\n\n private env: Env = allProcessEnv();\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 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 *\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\n if (options.id) {\n console.warn(\n `${logPrefix} The \\`id\\` serve option is deprecated and will be removed in v4`,\n );\n }\n this.id = options.id || this.client.id;\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: <explanation>\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) as InngestFunction.Any[];\n\n if (this.rawFns.length !== options.functions.length) {\n // TODO PrettyError\n console.warn(\n `Some functions passed to serve() are undefined and misconfigured. Please check your imports.`,\n );\n }\n\n this.fns = this.rawFns.reduce<\n Record<string, { fn: InngestFunction.Any; onFailure: boolean }>\n >((acc, fn) => {\n const configs = fn[\"getConfig\"]({\n baseUrl: new URL(\"https://example.com\"),\n appPrefix: this.id,\n });\n\n const fns = configs.reduce((acc, { id }, index) => {\n return { ...acc, [id]: { fn, onFailure: Boolean(index) } };\n }, {});\n\n // biome-ignore lint/complexity/noForEach: <explanation>\n configs.forEach(({ id }) => {\n if (acc[id]) {\n // TODO PrettyError\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\n return {\n ...acc,\n ...fns,\n };\n }, {});\n\n this.inngestRegisterUrl = new URL(\"/fn/register\", this.apiBaseUrl);\n\n this.signingKey = options.signingKey;\n this.signingKeyFallback = options.signingKeyFallback;\n this._serveHost = options.serveHost || this.env[envKeys.InngestServeHost];\n this._servePath = options.servePath || this.env[envKeys.InngestServePath];\n\n this.skipSignatureValidation = options.skipSignatureValidation || false;\n\n const defaultLogLevel: typeof this.logLevel = \"info\";\n this.logLevel = z\n .enum(logLevels)\n .default(defaultLogLevel)\n .catch((ctx) => {\n this.log(\n \"warn\",\n `Unknown log level passed: ${String(\n ctx.input,\n )}; defaulting to ${defaultLogLevel}`,\n );\n\n return defaultLogLevel;\n })\n .parse(options.logLevel || this.env[envKeys.InngestLogLevel]);\n\n if (this.logLevel === \"debug\") {\n /**\n * `debug` is an old library; sometimes its runtime detection doesn't work\n * for newer pairings of framework/runtime.\n *\n * One silly symptom of this is that `Debug()` returns an anonymous\n * function with no extra properties instead of a `Debugger` instance if\n * the wrong code is consumed following a bad detection. This results in\n * the following `.enable()` call failing, so we just try carefully to\n * enable it here.\n */\n if (debug.enable && typeof debug.enable === \"function\") {\n debug.enable(`${debugPrefix}:*`);\n }\n }\n\n const defaultStreamingOption: typeof this.streaming = false;\n this.streaming = z\n .union([z.enum([\"allow\", \"force\"]), z.literal(false)])\n .default(defaultStreamingOption)\n .catch((ctx) => {\n this.log(\n \"warn\",\n `Unknown streaming option passed: ${String(\n ctx.input,\n )}; defaulting to ${String(defaultStreamingOption)}`,\n );\n\n return defaultStreamingOption;\n })\n .parse(options.streaming || this.env[envKeys.InngestStreaming]);\n\n this.fetch = options.fetch ? getFetch(options.fetch) : this.client[\"fetch\"];\n }\n\n /**\n * Get the API base URL for the Inngest API.\n *\n * This is a getter to encourage checking the environment for the API base URL\n * each time it's accessed, as it may change during execution.\n */\n protected get apiBaseUrl(): string {\n return (\n this._options.baseUrl ||\n this.env[envKeys.InngestApiBaseUrl] ||\n this.env[envKeys.InngestBaseUrl] ||\n this.client.apiBaseUrl ||\n defaultInngestApiBaseUrl\n );\n }\n\n /**\n * Get the event API base URL for the Inngest API.\n *\n * This is a getter to encourage checking the environment for the event API\n * base URL each time it's accessed, as it may change during execution.\n */\n protected get eventApiBaseUrl(): string {\n return (\n this._options.baseUrl ||\n this.env[envKeys.InngestEventApiBaseUrl] ||\n this.env[envKeys.InngestBaseUrl] ||\n this.client.eventBaseUrl ||\n defaultInngestEventBaseUrl\n );\n }\n\n /**\n * The host 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 hostname 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 serveHost(): string | undefined {\n return this._serveHost || this.env[envKeys.InngestServeHost];\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 `serveHost`.\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\"] || this.client[\"eventKey\"] === dummyEventKey) {\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.signingKey) {\n return undefined;\n }\n return hashSigningKey(this.signingKey);\n }\n\n private get hashedSigningKeyFallback(): string | undefined {\n if (!this.signingKeyFallback) {\n return undefined;\n }\n return hashSigningKey(this.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 // We must be able to stream responses to continue.\n if (!actions.transformStreamingResponse) {\n return false;\n }\n\n // If the user has forced streaming, we should always stream.\n if (this.streaming === \"force\") {\n return true;\n }\n\n // If the user has allowed streaming, we should stream if the platform\n // supports it.\n return (\n this.streaming === \"allow\" &&\n platformSupportsStreaming(\n this.frameworkName as SupportedFrameworkName,\n this.env,\n )\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(): (...args: Input) => Promise<Awaited<Output>> {\n const handler = async (...args: Input) => {\n const timer = new ServerTiming();\n\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 =\n Object.entries(rawActions).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 = () =>\n (value as (...args: unknown[]) => unknown)(...args);\n\n return runAsPromise(fn)\n .catch(rethrowError(errMessage))\n .catch((err) => {\n this.log(\"error\", err);\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 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 this.env = {\n ...allProcessEnv(),\n ...env,\n };\n\n const getInngestHeaders = (): 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\n const assumedMode = getMode({ env: this.env, client: this.client });\n\n if (assumedMode.isExplicit) {\n this._mode = assumedMode;\n } else {\n const serveIsProd = await actions.isProduction?.(\n \"starting to handle request\",\n );\n if (typeof serveIsProd === \"boolean\") {\n this._mode = new Mode({\n type: serveIsProd ? \"cloud\" : \"dev\",\n isExplicit: false,\n });\n } else {\n this._mode = assumedMode;\n }\n }\n\n this.upsertKeysFromEnv();\n\n const methodP = actions.method(\"starting to handle request\");\n\n const headerPromises = [\n headerKeys.TraceParent,\n headerKeys.TraceState,\n ].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 contentLength = await actions\n .headers(\"checking signature for request\", headerKeys.ContentLength)\n .then((value) => {\n if (!value) {\n return undefined;\n }\n return Number.parseInt(value, 10);\n });\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((method) => {\n if (method === \"POST\" || method === \"PUT\") {\n if (!contentLength) {\n // Return empty string because req.json() will throw an error.\n return \"\";\n }\n\n return actions.body(\n `checking body for request signing as method is ${method}`,\n );\n }\n\n return \"\";\n }),\n ]);\n\n const signatureValidation = this.validateSignature(signature, body);\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 actionRes = timer.wrap(\"action\", () =>\n this.handleAction({\n actions,\n timer,\n getInngestHeaders,\n reqArgs: args,\n signatureValidation,\n\n body,\n method,\n headers: headersToForwardP,\n }),\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 ...getInngestHeaders(),\n ...(await headersToForwardP),\n ...res.headers,\n ...(res.version === null\n ? {}\n : {\n [headerKeys.RequestVersion]: (\n res.version ?? PREFERRED_EXECUTION_VERSION\n ).toString(),\n }),\n };\n\n let signature: string | undefined;\n\n try {\n signature = await signatureValidation.then((result) => {\n if (!result.success || !result.keyUsed) {\n return undefined;\n }\n\n return 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 if (await this.shouldStream(actions)) {\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 actionRes.then((res) => {\n return finalize(prepareActionRes(res));\n });\n\n return timer.wrap(\"res\", () => {\n return actions.transformStreamingResponse?.(\n \"starting streaming response\",\n {\n status: 201,\n headers: getInngestHeaders(),\n body: stream,\n version: null,\n },\n );\n });\n }\n }\n\n return timer.wrap(\"res\", async () => {\n return actionRes.then(prepareActionRes).then((actionRes) => {\n return actions.transformResponse(\"sending back response\", actionRes);\n });\n });\n };\n\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 // biome-ignore lint/correctness/noUnusedPrivateClassMembers: used in the SDK\n private get mode(): Mode | undefined {\n return this._mode;\n }\n\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: used in the SDK\n private set mode(m) {\n this._mode = m;\n\n if (m) {\n this.client[\"mode\"] = m;\n }\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 getInngestHeaders,\n reqArgs,\n signatureValidation,\n body,\n method,\n headers,\n }: {\n actions: HandlerResponseWithErrors;\n timer: ServerTiming;\n getInngestHeaders: () => Record<string, string>;\n reqArgs: unknown[];\n signatureValidation: ReturnType<InngestCommHandler[\"validateSignature\"]>;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n body: any;\n method: string;\n headers: Promise<Record<string, string>>;\n }): Promise<ActionResponse> {\n // This is when the request body is completely missing; it does not\n // include an empty body. This commonly happens when the HTTP framework\n // doesn't have body parsing middleware.\n const isMissingBody = body === undefined;\n\n try {\n let url = await actions.url(\"starting to handle request\");\n\n if (method === \"POST\") {\n if (isMissingBody) {\n this.log(\n \"error\",\n \"Missing body when executing, 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 executing, possibly due to missing request body middleware\",\n ),\n ),\n ),\n version: undefined,\n };\n }\n\n const validationResult = await signatureValidation;\n if (!validationResult.success) {\n return {\n status: 401,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: stringify(serializeError(validationResult.err)),\n version: undefined,\n };\n }\n\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 const fnId = await actions.queryStringWithDefaults(\n \"processing run request\",\n queryKeys.FnId,\n );\n if (!fnId) {\n // TODO PrettyError\n throw new Error(\"No function ID found in request\");\n }\n\n const stepId =\n (await actions.queryStringWithDefaults(\n \"processing run request\",\n queryKeys.StepId,\n )) || null;\n\n const { version, result } = this.runStep({\n functionId: fnId,\n data: body,\n stepId,\n timer,\n reqArgs,\n headers: await headers,\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 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 return {\n status: 500,\n headers: {\n \"Content-Type\": \"application/json\",\n [headerKeys.NoRetry]: \"false\",\n },\n body: stringify({\n error: `Could not find step \"${\n result.step.displayName || result.step.id\n }\" to run; timed out`,\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 };\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.log(\"error\", \"Error handling execution result\", err);\n throw err;\n }\n }\n\n // TODO: This feels hacky, so we should probably make it not hacky.\n const env = getInngestHeaders()[headerKeys.Environment] ?? null;\n\n if (method === \"GET\") {\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.log(\n \"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 getInngestHeaders,\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 return {\n status: 405,\n body: JSON.stringify({\n message: \"No action found; request was likely not POST, PUT, or GET\",\n mode: this._mode,\n }),\n headers: {},\n version: undefined,\n };\n }\n\n protected runStep({\n functionId,\n stepId,\n data,\n timer,\n reqArgs,\n headers,\n }: {\n functionId: string;\n stepId: string | null;\n data: unknown;\n timer: ServerTiming;\n reqArgs: unknown[];\n headers: Record<string, string>;\n }): { version: ExecutionVersion; result: Promise<ExecutionResult> } {\n const fn = this.fns[functionId];\n if (!fn) {\n // TODO PrettyError\n throw new Error(`Could not find function with ID \"${functionId}\"`);\n }\n\n const immediateFnData = parseFnData(data);\n let { version } = immediateFnData;\n\n // Handle opting in to optimized parallelism in v3.\n if (\n version === ExecutionVersion.V1 &&\n fn.fn[\"shouldOptimizeParallelism\"]?.()\n ) {\n version = ExecutionVersion.V2;\n }\n\n const result = runAsPromise(async () => {\n const anyFnData = await fetchAllFnData({\n data: immediateFnData,\n api: this.client[\"inngestApi\"],\n version,\n });\n if (!anyFnData.ok) {\n throw new Error(anyFnData.error);\n }\n\n type ExecutionStarter<V> = (\n fnData: V extends ExecutionVersion\n ? Extract<FnData, { version: V }>\n : FnData,\n ) => MaybePromise<CreateExecutionOptions>;\n\n type GenericExecutionStarters = Record<\n ExecutionVersion,\n ExecutionStarter<unknown>\n >;\n\n type ExecutionStarters = {\n [V in ExecutionVersion]: ExecutionStarter<V>;\n };\n\n const executionStarters = ((s: ExecutionStarters) =>\n s as GenericExecutionStarters)({\n [ExecutionVersion.V0]: ({ event, events, steps, ctx, version }) => {\n const stepState = Object.entries(steps ?? {}).reduce<\n InngestExecutionOptions[\"stepState\"]\n >((acc, [id, data]) => {\n return {\n ...acc,\n\n [id]: { id, data },\n };\n }, {});\n\n return {\n version,\n partialOptions: {\n client: this.client,\n runId: ctx?.run_id || \"\",\n data: {\n event: event as EventPayload,\n events: events as [EventPayload, ...EventPayload[]],\n runId: ctx?.run_id || \"\",\n attempt: ctx?.attempt ?? 0,\n },\n stepState,\n requestedRunStep:\n stepId === \"step\" ? undefined : stepId || undefined,\n timer,\n isFailureHandler: fn.onFailure,\n stepCompletionOrder: ctx?.stack?.stack ?? [],\n reqArgs,\n headers,\n },\n };\n },\n [ExecutionVersion.V1]: ({ event, events, steps, ctx, version }) => {\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 return {\n version,\n partialOptions: {\n client: this.client,\n runId: ctx?.run_id || \"\",\n data: {\n event: event as EventPayload,\n events: events as [EventPayload, ...EventPayload[]],\n runId: ctx?.run_id || \"\",\n attempt: ctx?.attempt ?? 0,\n },\n stepState,\n requestedRunStep:\n stepId === \"step\" ? undefined : stepId || undefined,\n timer,\n isFailureHandler: fn.onFailure,\n disableImmediateExecution: ctx?.disable_immediate_execution,\n stepCompletionOrder: ctx?.stack?.stack ?? [],\n reqArgs,\n headers,\n },\n };\n },\n [ExecutionVersion.V2]: ({ event, events, steps, ctx, version }) => {\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 return {\n version,\n partialOptions: {\n client: this.client,\n runId: ctx?.run_id || \"\",\n data: {\n event: event as EventPayload,\n events: events as [EventPayload, ...EventPayload[]],\n runId: ctx?.run_id || \"\",\n attempt: ctx?.attempt ?? 0,\n },\n stepState,\n requestedRunStep:\n stepId === \"step\" ? undefined : stepId || undefined,\n timer,\n isFailureHandler: fn.onFailure,\n disableImmediateExecution: ctx?.disable_immediate_execution,\n stepCompletionOrder: ctx?.stack?.stack ?? [],\n reqArgs,\n headers,\n },\n };\n },\n });\n\n const executionOptions = await executionStarters[version](\n anyFnData.value,\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 = Object.values(this.rawFns).reduce<FunctionConfig[]>(\n (acc, fn) => [\n ...acc,\n ...fn[\"getConfig\"]({ baseUrl: url, appPrefix: this.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.log(\n \"warn\",\n `Config invalid for function \"${config.id}\" : ${errors}`,\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 `serveHost` 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 serveHost = this.serveHost || this.env[envKeys.InngestServeHost];\n const servePath = this.servePath || this.env[envKeys.InngestServePath];\n\n if (servePath) {\n ret.pathname = servePath;\n }\n\n if (serveHost) {\n ret = new URL(ret.pathname + ret.search, serveHost);\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.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.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 ...allProcessEnv(),\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 (introspectionBody.authentication_succeeded) {\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._mode) {\n throw new Error(\"No mode set; cannot introspect without mode\");\n }\n\n let introspection:\n | UnauthenticatedIntrospection\n | AuthenticatedIntrospection = {\n authentication_succeeded: null,\n extra: {\n is_mode_explicit: this._mode.isExplicit,\n },\n has_event_key: this.client[\"eventKeySet\"](),\n has_signing_key: Boolean(this.signingKey),\n function_count: registerBody.functions.length,\n mode: this._mode.type,\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._mode.type === \"cloud\") {\n try {\n const validationResult = await signatureValidation;\n if (!validationResult.success) {\n throw new Error(\"Signature validation failed\");\n }\n\n introspection = {\n ...introspection,\n authentication_succeeded: true,\n api_origin: this.apiBaseUrl,\n app_id: this.id,\n capabilities: {\n trust_probe: \"v1\",\n connect: \"v1\",\n },\n env,\n event_api_origin: this.eventApiBaseUrl,\n event_key_hash: this.hashedEventKey ?? null,\n extra: {\n ...introspection.extra,\n is_streaming: await this.shouldStream(actions),\n },\n framework: this.frameworkName,\n sdk_language: \"js\",\n sdk_version: version,\n serve_origin: this.serveHost ?? null,\n serve_path: this.servePath ?? null,\n signing_key_fallback_hash: this.hashedSigningKeyFallback ?? null,\n signing_key_hash: this.hashedSigningKey ?? null,\n } satisfies AuthenticatedIntrospection;\n } catch {\n // Swallow signature validation error since we'll just return the\n // unauthenticated introspection\n introspection = {\n ...introspection,\n authentication_succeeded: false,\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: () => 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 // Whenever we register, we check to see if the dev server is up. This\n // is a noop and returns false in production. Clone the URL object to avoid\n // mutating the property between requests.\n let registerURL = new URL(this.inngestRegisterUrl.href);\n\n const inferredDevMode =\n this._mode && this._mode.isInferred && this._mode.isDev;\n\n if (inferredDevMode) {\n const host = devServerHost(this.env);\n const hasDevServer = await devServerAvailable(host, this.fetch);\n if (hasDevServer) {\n registerURL = devServerUrl(host, \"/fn/register\");\n }\n } else if (this._mode?.explicitDevUrl) {\n registerURL = devServerUrl(\n this._mode.explicitDevUrl.href,\n \"/fn/register\",\n );\n }\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.fetch,\n url: registerURL.href,\n options: {\n method: \"POST\",\n body: stringify(body),\n headers: {\n ...getHeaders(),\n [headerKeys.InngestSyncKind]: syncKind.OutOfBand,\n },\n redirect: \"follow\",\n },\n });\n } catch (err: unknown) {\n this.log(\"error\", err);\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.log(\"warn\", \"Couldn't unpack register response:\", err);\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.log(\"warn\", \"Invalid register response schema:\", err);\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.log(\n \"debug\",\n \"registered inngest functions:\",\n res.status,\n res.statusText,\n data,\n );\n }\n\n return { status, message: error, modified };\n }\n\n /**\n * Given an environment, upsert any missing keys. This is useful in\n * situations where environment variables are passed directly to handlers or\n * are otherwise difficult to access during initialization.\n */\n private upsertKeysFromEnv() {\n if (this.env[envKeys.InngestSigningKey]) {\n if (!this.signingKey) {\n this.signingKey = String(this.env[envKeys.InngestSigningKey]);\n }\n\n this.client[\"inngestApi\"].setSigningKey(this.signingKey);\n }\n\n if (this.env[envKeys.InngestSigningKeyFallback]) {\n if (!this.signingKeyFallback) {\n this.signingKeyFallback = String(\n this.env[envKeys.InngestSigningKeyFallback],\n );\n }\n\n this.client[\"inngestApi\"].setSigningKeyFallback(this.signingKeyFallback);\n }\n\n if (!this.client[\"eventKeySet\"]() && this.env[envKeys.InngestEventKey]) {\n this.client.setEventKey(String(this.env[envKeys.InngestEventKey]));\n }\n\n // v2 -> v3 migration warnings\n if (this.env[envKeys.InngestDevServerUrl]) {\n this.log(\n \"warn\",\n `Use of ${envKeys.InngestDevServerUrl} has been deprecated in v3; please use ${envKeys.InngestBaseUrl} instead. See https://www.inngest.com/docs/sdk/migration`,\n );\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._mode && !this._mode.isCloud) {\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.signingKey) {\n // TODO PrettyError\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/secrets`,\n );\n }\n\n // If we're here, we're in production; lack of a req signature is an error.\n if (!sig) {\n // TODO PrettyError\n throw new Error(`No ${headerKeys.Signature} provided`);\n }\n\n // Validate the signature\n return {\n success: true,\n keyUsed: new RequestSignature(sig).verifySignature({\n body,\n allowExpiredSignatures: this.allowExpiredSignatures,\n signingKey: this.signingKey,\n signingKeyFallback: this.signingKeyFallback,\n }),\n };\n } catch (err) {\n return { success: false, err: err as Error };\n }\n }\n\n protected getResponseSignature(key: string, body: string): string {\n const now = Date.now();\n const mac = signDataWithKey(body, key, now.toString());\n\n return `t=${now}&s=${mac}`;\n }\n\n /**\n * Log to stdout/stderr if the log level is set to include the given level.\n * The default log level is `\"info\"`.\n *\n * This is an abstraction over `console.log` and will try to use the correct\n * method for the given log level. For example, `log(\"error\", \"foo\")` will\n * call `console.error(\"foo\")`.\n */\n protected log(level: LogLevel, ...args: unknown[]) {\n const logLevels: LogLevel[] = [\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"fatal\",\n \"silent\",\n ];\n\n const logLevelSetting = logLevels.indexOf(this.logLevel);\n const currentLevel = logLevels.indexOf(level);\n\n if (currentLevel >= logLevelSetting) {\n let logger = console.log;\n\n if (Object.hasOwn(console, level)) {\n logger = console[level as keyof typeof console] as typeof logger;\n }\n\n logger(`${logPrefix} ${level as string} -`, ...args);\n }\n }\n}\n\nclass 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 // TODO PrettyError\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 delta =\n Date.now() - new Date(Number.parseInt(this.timestamp) * 1000).valueOf();\n return delta > 1000 * 60 * 5;\n }\n\n #verifySignature({\n body,\n signingKey,\n allowExpiredSignatures,\n }: {\n body: unknown;\n signingKey: string;\n allowExpiredSignatures: boolean;\n }): void {\n if (this.hasExpired(allowExpiredSignatures)) {\n // TODO PrettyError\n throw new Error(\"Signature has expired\");\n }\n\n const mac = signDataWithKey(body, signingKey, this.timestamp);\n if (mac !== this.signature) {\n // TODO PrettyError\n throw new Error(\"Invalid signature\");\n }\n }\n\n public verifySignature({\n body,\n signingKey,\n signingKeyFallback,\n allowExpiredSignatures,\n }: {\n body: unknown;\n signingKey: string;\n signingKeyFallback: string | undefined;\n allowExpiredSignatures: boolean;\n }): string {\n try {\n this.#verifySignature({ body, signingKey, allowExpiredSignatures });\n\n return signingKey;\n } catch (err) {\n if (!signingKeyFallback) {\n throw err;\n }\n\n this.#verifySignature({\n body,\n signingKey: signingKeyFallback,\n allowExpiredSignatures,\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: <explanation>\n Input extends any[] = any[],\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Output = any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n StreamOutput = any,\n> = (...args: Input) => HandlerResponse<Output, StreamOutput>;\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type HandlerResponse<Output = any, StreamOutput = any> = {\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n body: () => MaybePromise<any>;\n env?: () => MaybePromise<Env | undefined>;\n headers: (key: string) => MaybePromise<string | null | undefined>;\n\n /**\n * Whether the current environment is production. This is used to determine\n * some functionality like whether to connect to the dev server or whether to\n * show debug logging.\n *\n * If this is not provided--or is provided and returns `undefined`--we'll try\n * to automatically detect whether we're in production by checking various\n * environment variables.\n */\n isProduction?: () => MaybePromise<boolean | undefined>;\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/**\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":";;;;;;;;;;;;;;;;;;;;;;;;AA2KA,MAAM,oBAAoBA,SAAE,OAAO;CACjC,QAAQA,SAAE,QAAQ,CAAC,QAAQ,IAAI;CAC/B,SAASA,SAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,MAAM;CAC9C,UAAUA,SAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,MAAM;CAC/C,OAAOA,SAAE,QAAQ,CAAC,QAAQ,0BAA0B;CACrD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CF,IAAa,qBAAb,MAOE;;;;;;CAMA,AAAgB;;;;CAKhB,AAAgB;;;;CAKhB,AAAiB;;;;;CAMjB,AAAmB;;;;;;CAOnB,AAAU;;;;;CAMV,AAAU;;;;;;;CAQV,AAAU;;;;CAKV,AAAiB;;;;;;;;;;;;;;;;CAiBjB,AAAiB;;;;;;;;;;;;;;;;CAiBjB,AAAiB;;;;CAKjB,AAAmB;CAEnB,AAAmB;;;;;CAMnB,AAAiB;CAEjB,AAAiB;;;;;CAMjB,AAAiB,MAGb,EAAE;CAEN,AAAQ,MAAWC,2BAAe;CAElC,AAAQ;CAER,AAAiB;CAMjB,AAAiB;CAEjB,YAAY,SAAiE;AAE3E,OAAK,WAAW;;;;;;;;AAShB,MAAI,OAAO,OAAO,SAAS,WAAW,CACpC,OAAM,IAAI,MACR,GAAGC,yBAAU,yPACd;AAGH,OAAK,gBAAgB,QAAQ;AAC7B,OAAK,SAAS,QAAQ;AAEtB,MAAI,QAAQ,GACV,SAAQ,KACN,GAAGA,yBAAU,kEACd;AAEH,OAAK,KAAK,QAAQ,MAAM,KAAK,OAAO;AAEpC,OAAK,UAAU,QAAQ;;;;;AAMvB,OAAK,yBAAyB,QAE5B,UAAU,MAAM,gCACjB;AAGD,OAAK,SAAS,QAAQ,UAAU,OAAO,QAAQ;AAE/C,MAAI,KAAK,OAAO,WAAW,QAAQ,UAAU,OAE3C,SAAQ,KACN,gGACD;AAGH,OAAK,MAAM,KAAK,OAAO,QAEpB,KAAK,OAAO;GACb,MAAM,UAAU,GAAG,aAAa;IAC9B,SAAS,IAAI,IAAI,sBAAsB;IACvC,WAAW,KAAK;IACjB,CAAC;GAEF,MAAM,MAAM,QAAQ,QAAQ,OAAK,EAAE,MAAM,UAAU;AACjD,WAAO;KAAE,GAAGC;MAAM,KAAK;MAAE;MAAI,WAAW,QAAQ,MAAM;MAAE;KAAE;MACzD,EAAE,CAAC;AAGN,WAAQ,SAAS,EAAE,SAAS;AAC1B,QAAI,IAAI,IAEN,OAAM,IAAI,MACR,0BAA0B,GAAG,kFAC9B;KAEH;AAEF,UAAO;IACL,GAAG;IACH,GAAG;IACJ;KACA,EAAE,CAAC;AAEN,OAAK,qBAAqB,IAAI,IAAI,gBAAgB,KAAK,WAAW;AAElE,OAAK,aAAa,QAAQ;AAC1B,OAAK,qBAAqB,QAAQ;AAClC,OAAK,aAAa,QAAQ,aAAa,KAAK,IAAIC,uBAAQ;AACxD,OAAK,aAAa,QAAQ,aAAa,KAAK,IAAIA,uBAAQ;AAExD,OAAK,0BAA0B,QAAQ,2BAA2B;EAElE,MAAMC,kBAAwC;AAC9C,OAAK,WAAWL,SACb,KAAKM,wBAAU,CACf,QAAQ,gBAAgB,CACxB,OAAO,QAAQ;AACd,QAAK,IACH,QACA,6BAA6B,OAC3B,IAAI,MACL,CAAC,kBAAkB,kBACrB;AAED,UAAO;IACP,CACD,MAAM,QAAQ,YAAY,KAAK,IAAIF,uBAAQ,iBAAiB;AAE/D,MAAI,KAAK,aAAa,SAWpB;;;;;;;;;;;OAAI,cAAM,UAAU,OAAO,cAAM,WAAW,WAC1C,eAAM,OAAO,GAAGG,2BAAY,IAAI;;EAIpC,MAAMC,yBAAgD;AACtD,OAAK,YAAYR,SACd,MAAM,CAACA,SAAE,KAAK,CAAC,SAAS,QAAQ,CAAC,EAAEA,SAAE,QAAQ,MAAM,CAAC,CAAC,CACrD,QAAQ,uBAAuB,CAC/B,OAAO,QAAQ;AACd,QAAK,IACH,QACA,oCAAoC,OAClC,IAAI,MACL,CAAC,kBAAkB,OAAO,uBAAuB,GACnD;AAED,UAAO;IACP,CACD,MAAM,QAAQ,aAAa,KAAK,IAAII,uBAAQ,kBAAkB;AAEjE,OAAK,QAAQ,QAAQ,QAAQK,qBAAS,QAAQ,MAAM,GAAG,KAAK,OAAO;;;;;;;;CASrE,IAAc,aAAqB;AACjC,SACE,KAAK,SAAS,WACd,KAAK,IAAIL,uBAAQ,sBACjB,KAAK,IAAIA,uBAAQ,mBACjB,KAAK,OAAO,cACZM;;;;;;;;CAUJ,IAAc,kBAA0B;AACtC,SACE,KAAK,SAAS,WACd,KAAK,IAAIN,uBAAQ,2BACjB,KAAK,IAAIA,uBAAQ,mBACjB,KAAK,OAAO,gBACZO;;;;;;;;;;;;;;;;;CAmBJ,IAAc,YAAgC;AAC5C,SAAO,KAAK,cAAc,KAAK,IAAIP,uBAAQ;;;;;;;;;;;;;;;;;;;;CAqB7C,IAAc,YAAgC;AAC5C,SAAO,KAAK,cAAc,KAAK,IAAIA,uBAAQ;;CAG7C,IAAY,iBAAqC;AAC/C,MAAI,CAAC,KAAK,OAAO,eAAe,KAAK,OAAO,gBAAgBQ,6BAC1D;AAEF,SAAOC,6BAAa,KAAK,OAAO,YAAY;;CAK9C,IAAY,mBAAuC;AACjD,MAAI,CAAC,KAAK,WACR;AAEF,SAAOC,+BAAe,KAAK,WAAW;;CAGxC,IAAY,2BAA+C;AACzD,MAAI,CAAC,KAAK,mBACR;AAEF,SAAOA,+BAAe,KAAK,mBAAmB;;;;;;;CAQhD,MAAc,aACZ,SACkB;AAKlB,MAJiB,MAAM,QAAQ,wBAC7B,qBACAC,yBAAU,MACX,KACgB,OACf,QAAO;AAIT,MAAI,CAAC,QAAQ,2BACX,QAAO;AAIT,MAAI,KAAK,cAAc,QACrB,QAAO;AAKT,SACE,KAAK,cAAc,WACnBC,sCACE,KAAK,eACL,KAAK,IACN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCL,AAAO,gBAA8D;EACnE,MAAM,UAAU,OAAO,GAAG,SAAgB;GACxC,MAAM,QAAQ,IAAIC,mCAAc;;;;;GAMhC,MAAM,UAAU,KAAK,KAAK,SAAS;GACnC,MAAM,kBACJ,OAAO,YAAY,YACnB,YAAY,QACZ,qBAAqB,WACrB,OAAO,QAAQ,uBAAuB,YACtC,QAAQ,uBAAuB,OAC3B,QAAQ,qBACR,EAAE;;;;;GAMR,MAAM,aAAa;IACjB,GAAI,MAAM,MACP,KAAK,iBAAiB,KAAK,QAAQ,GAAG,KAAK,CAAC,CAC5C,MAAMC,4BAAa,8BAA8B,CAAC;IACrD,GAAG;IACJ;;;;;GA2CD,MAAMC,UAAqC;IACzC,GAjCA,OAAO,QAAQ,WAAW,CAAC,QAAQ,KAAK,CAAC,KAAK,WAAW;AACvD,SAAI,OAAO,UAAU,WACnB,QAAO;AAGT,YAAO;MACL,GAAG;OACF,OAAO,QAAgB,GAAGC,WAAoB;OAC7C,MAAM,aAAa,CACjB,oBAAoB,IAAI,wBACxB,OACD,CACE,OAAO,QAAQ,CACf,KAAK,SAAS;OAEjB,MAAM,WACH,MAA0C,GAAGA,OAAK;AAErD,cAAOC,8BAAa,GAAG,CACpB,MAAMH,4BAAa,WAAW,CAAC,CAC/B,OAAO,QAAQ;AACd,aAAK,IAAI,SAAS,IAAI;AACtB,cAAM;SACN;;MAEP;OACA,EAAE,CAAoC;IAQzC,yBAAyB,OACvB,QACA,QACgC;KAChC,MAAM,MAAM,MAAM,QAAQ,IAAI,OAAO;AAOrC,YAJG,MAAM,QAAQ,cAAc,QAAQ,KAAK,IAAI,IAC9C,IAAI,aAAa,IAAI,IAAI,IACzB;;IAIJ,GAAG;IACJ;GAED,MAAM,CAAC,KAAK,sBAAsB,MAAM,QAAQ,IAAI,CAClD,QAAQ,MAAM,6BAA6B,EAC3C,QAAQ,QACN,iCACAI,0BAAW,kBACZ,CACF,CAAC;AAKF,QAAK,MAAM;IACT,GAAGrB,2BAAe;IAClB,GAAG;IACJ;GAED,MAAM,0BACJsB,2BAAe;IACb,KAAK,KAAK;IACV,WAAW,KAAK;IAChB,QAAQ,KAAK;IACb,oBAAoB,sBAAsB;IAC1C,QAAQ,EACN,iBAAiB,MAAM,WAAW,EACnC;IACF,CAAC;GAEJ,MAAM,cAAcC,oBAAQ;IAAE,KAAK,KAAK;IAAK,QAAQ,KAAK;IAAQ,CAAC;AAEnE,OAAI,YAAY,WACd,MAAK,QAAQ;QACR;IACL,MAAM,cAAc,MAAM,QAAQ,eAChC,6BACD;AACD,QAAI,OAAO,gBAAgB,UACzB,MAAK,QAAQ,IAAIC,iBAAK;KACpB,MAAM,cAAc,UAAU;KAC9B,YAAY;KACb,CAAC;QAEF,MAAK,QAAQ;;AAIjB,QAAK,mBAAmB;GAExB,MAAM,UAAU,QAAQ,OAAO,6BAA6B;GAE5D,MAAM,iBAAiB,CACrBH,0BAAW,aACXA,0BAAW,WACZ,CAAC,IAAI,OAAO,WAAW;IACtB,MAAM,QAAQ,MAAM,QAAQ,QAC1B,YAAY,OAAO,kBACnB,OACD;AAED,WAAO;KAAE;KAAQ;KAAO;KACxB;GAEF,MAAM,gBAAgB,MAAM,QACzB,QAAQ,kCAAkCA,0BAAW,cAAc,CACnE,MAAM,UAAU;AACf,QAAI,CAAC,MACH;AAEF,WAAO,OAAO,SAAS,OAAO,GAAG;KACjC;GAEJ,MAAM,CAAC,WAAW,QAAQ,QAAQ,MAAM,QAAQ,IAAI;IAClD,QACG,QAAQ,kCAAkCA,0BAAW,UAAU,CAC/D,MAAM,oBAAoB;AACzB,YAAO,mBAAmB;MAC1B;IACJ;IACA,QAAQ,MAAM,aAAW;AACvB,SAAII,aAAW,UAAUA,aAAW,OAAO;AACzC,UAAI,CAAC,cAEH,QAAO;AAGT,aAAO,QAAQ,KACb,kDAAkDA,WACnD;;AAGH,YAAO;MACP;IACH,CAAC;GAEF,MAAM,sBAAsB,KAAK,kBAAkB,WAAW,KAAK;GAEnE,MAAM,oBAAoB,QAAQ,IAAI,eAAe,CAAC,MACnD,mBAAmB;AAClB,WAAO,eAAe,QACnB,KAAK,EAAE,QAAQ,YAAY;AAC1B,SAAI,MACF,KAAI,UAAU;AAGhB,YAAO;OAET,EAAE,CACH;KAEJ;GAED,MAAM,YAAY,MAAM,KAAK,gBAC3B,KAAK,aAAa;IAChB;IACA;IACA;IACA,SAAS;IACT;IAEA;IACA;IACA,SAAS;IACV,CAAC,CACH;;;;;;;;GASD,MAAM,mBAAmB,OACvB,QAC4B;IAC5B,MAAMC,UAAkC;KACtC,GAAG,mBAAmB;KACtB,GAAI,MAAM;KACV,GAAG,IAAI;KACP,GAAI,IAAI,YAAY,OAChB,EAAE,GACF,GACGL,0BAAW,kBACV,IAAI,WAAWM,sDACf,UAAU,EACb;KACN;IAED,IAAIC;AAEJ,QAAI;AACF,mBAAY,MAAM,oBAAoB,MAAM,WAAW;AACrD,UAAI,CAAC,OAAO,WAAW,CAAC,OAAO,QAC7B;AAGF,aAAO,KAAK,qBAAqB,OAAO,SAAS,IAAI,KAAK;OAC1D;aACK,KAAK;AAEZ,YAAO;MACL,GAAG;MACH;MACA,MAAMC,0BAAUC,8BAAe,IAAI,CAAC;MACpC,QAAQ;MACT;;AAGH,QAAIC,YACF,SAAQV,0BAAW,aAAaU;AAGlC,WAAO;KACL,GAAG;KACH;KACD;;AAGH,OAAI,MAAM,KAAK,aAAa,QAAQ,EAGlC;QAFe,MAAM,QAAQ,OAAO,8BAA8B,KAEnD,QAAQ;KACrB,MAAM,EAAE,QAAQ,aAAa,MAAMC,6BAAc;;;;;AAMjD,KAAK,UAAU,MAAM,QAAQ;AAC3B,aAAO,SAAS,iBAAiB,IAAI,CAAC;OACtC;AAEF,YAAO,MAAM,KAAK,aAAa;AAC7B,aAAO,QAAQ,6BACb,+BACA;OACE,QAAQ;OACR,SAAS,mBAAmB;OAC5B,MAAM;OACN,SAAS;OACV,CACF;OACD;;;AAIN,UAAO,MAAM,KAAK,OAAO,YAAY;AACnC,WAAO,UAAU,KAAK,iBAAiB,CAAC,MAAM,gBAAc;AAC1D,YAAO,QAAQ,kBAAkB,yBAAyBC,YAAU;MACpE;KACF;;;;;;;;;;;;;;;AAgBJ,SAAO,iBAAiB,SAAS;GAC/B,MAAM,EACJ,OAAO,kBACR;GACD,QAAQ,EACN,OAAO,KAAK,QAAQ,QACrB;GACF,CAAC;AAEF,SAAO;;CAIT,IAAY,OAAyB;AACnC,SAAO,KAAK;;CAId,IAAY,KAAK,GAAG;AAClB,OAAK,QAAQ;AAEb,MAAI,EACF,MAAK,OAAO,UAAU;;;;;;;;;;;;;CAe1B,MAAc,aAAa,EACzB,SACA,OACA,mBACA,SACA,qBACA,MACA,QACA,WAW0B;EAI1B,MAAM,gBAAgB,SAAS;AAE/B,MAAI;GACF,IAAI,MAAM,MAAM,QAAQ,IAAI,6BAA6B;AAEzD,OAAI,WAAW,QAAQ;AACrB,QAAI,eAAe;AACjB,UAAK,IACH,SACA,+EACD;AAED,YAAO;MACL,QAAQ;MACR,SAAS,EACP,gBAAgB,oBACjB;MACD,MAAMJ,0BACJC,8CACE,IAAI,MACF,uFACD,CACF,CACF;MACD,SAAS;MACV;;IAGH,MAAM,mBAAmB,MAAM;AAC/B,QAAI,CAAC,iBAAiB,QACpB,QAAO;KACL,QAAQ;KACR,SAAS,EACP,gBAAgB,oBACjB;KACD,MAAMD,0BAAUC,8BAAe,iBAAiB,IAAI,CAAC;KACrD,SAAS;KACV;IAGH,MAAM,WAAW,MAAM,QAAQ,wBAC7B,qBACAhB,yBAAU,MACX;AACD,QAAI,UAAU;KACZ,MAAMoB,UAAQC,2BAAcC,sBAAW,SAAS;AAChD,SAAI,CAACF,QAGH,QAAO;MACL,QAAQ;MACR,SAAS,EACP,gBAAgB,oBACjB;MACD,MAAML,0BACJC,8CAAe,IAAI,MAAM,kBAAkB,SAAS,GAAG,CAAC,CACzD;MACD,SAAS;MACV;AAkBH,YAXI,GACDM,qBAAU,eAAe;MACxB,QAAQ;MACR,SAAS,EACP,gBAAgB,oBACjB;MACD,MAAM;MACN,SAAS;MACV,GACF,CAEmBF,UAAQ;;IAG9B,MAAM,OAAO,MAAM,QAAQ,wBACzB,0BACApB,yBAAU,KACX;AACD,QAAI,CAAC,KAEH,OAAM,IAAI,MAAM,kCAAkC;IAGpD,MAAM,SACH,MAAM,QAAQ,wBACb,0BACAA,yBAAU,OACX,IAAK;IAER,MAAM,EAAE,oBAAS,WAAW,KAAK,QAAQ;KACvC,YAAY;KACZ,MAAM;KACN;KACA;KACA;KACA,SAAS,MAAM;KAChB,CAAC;IACF,MAAM,aAAa,MAAM;;;;;IAMzB,MAAM,yBAAyB,OAAmB;AAChD,QAAG,OAAOuB,kCAAgB,GAAG,KAAK;AAClC,YAAO;;IA6ET,MAAM,UA1E0D;KAC9D,sBAAsB,aAAW;AAC/B,aAAO;OACL,QAAQC,SAAO,YAAY,MAAM;OACjC,SAAS;QACP,gBAAgB;SACfjB,0BAAW,UAAUiB,SAAO,YAAY,UAAU;QACnD,GAAI,OAAOA,SAAO,cAAc,WAC5B,GAAGjB,0BAAW,aAAaiB,SAAO,WAAW,GAC7C,EAAE;QACP;OACD,MAAMT,0BAAUQ,kCAAgBC,SAAO,MAAM,CAAC;OAC9C;OACD;;KAEH,sBAAsB,aAAW;AAC/B,aAAO;OACL,QAAQ;OACR,SAAS,EACP,gBAAgB,oBACjB;OACD,MAAMT,0BAAUQ,kCAAgBC,SAAO,KAAK,CAAC;OAC7C;OACD;;KAEH,mBAAmB,aAAW;AAC5B,aAAO;OACL,QAAQ;OACR,SAAS;QACP,gBAAgB;SACfjB,0BAAW,UAAU;QACvB;OACD,MAAMQ,0BAAU,EACd,OAAO,wBACLS,SAAO,KAAK,eAAeA,SAAO,KAAK,GACxC,sBACF,CAAC;OACF;OACD;;KAEH,aAAa,aAAW;MACtB,MAAM,OAAO,sBAAsBA,SAAO,KAAK;AAE/C,aAAO;OACL,QAAQ;OACR,SAAS;QACP,gBAAgB;QAChB,GAAI,OAAOA,SAAO,cAAc,cAC5B;UACGjB,0BAAW,UAAUiB,SAAO,YAAY,UAAU;SACnD,GAAI,OAAOA,SAAO,cAAc,WAC5B,GAAGjB,0BAAW,aAAaiB,SAAO,WAAW,GAC7C,EAAE;SACP,GACD,EAAE;QACP;OACD,MAAMT,0BAAU,CAAC,KAAK,CAAC;OACvB;OACD;;KAEH,gBAAgB,aAAW;MACzB,MAAM,QAAQS,SAAO,MAAM,IAAI,sBAAsB;AAErD,aAAO;OACL,QAAQ;OACR,SAAS,EACP,gBAAgB,oBACjB;OACD,MAAMT,0BAAU,MAAM;OACtB;OACD;;KAEJ,CAGC,WAAW;AAGb,QAAI;AACF,YAAO,MAAM,QAAQ,WAAW;aACzB,KAAK;AACZ,UAAK,IAAI,SAAS,mCAAmC,IAAI;AACzD,WAAM;;;GAKV,MAAM,MAAM,mBAAmB,CAACR,0BAAW,gBAAgB;AAE3D,OAAI,WAAW,MACb,QAAO;IACL,QAAQ;IACR,MAAMQ,0BACJ,MAAM,KAAK,kBAAkB;KAC3B;KACA;KACA;KACA;KACD,CAAC,CACH;IACD,SAAS,EACP,gBAAgB,oBACjB;IACD,SAAS;IACV;AAGH,OAAI,WAAW,OAAO;IACpB,MAAM,CAAC,UAAU,uBAAuB,MAAM,QAAQ,IAAI,CACxD,QACG,wBACC,iCACAf,yBAAU,SACX,CACA,MAAM,eAAa;AAClB,YAAOyB,eAAa,cAAc,SAAYA;MAC9C,EAEJ,QAAQ,QACNC,2BAAe,KAAK,IAAIrC,uBAAQ,wBAAwB,CACzD,CACE,MAAM,oBAAoB;AACzB,SAAI,oBAAoB,UAAa,CAAC,gBACpC,QAAOsC,wBAAS;AAGlB,YAAO,QAAQ,QACb,iCACApB,0BAAW,gBACZ;MACD,CACD,MAAM,SAAS;AACd,YAAO,SAASoB,wBAAS;MACzB,CACL,CAAC;AAEF,QAAI,qBAAqB;AACvB,SAAI,eAAe;AACjB,WAAK,IACH,SACA,6EACD;AAED,aAAO;OACL,QAAQ;OACR,SAAS,EACP,gBAAgB,oBACjB;OACD,MAAMZ,0BACJC,8CACE,IAAI,MACF,qFACD,CACF,CACF;OACD,SAAS;OACV;;AAQH,SAAI,EAFa,MAAM,qBAET,QACZ,QAAO;MACL,QAAQ;MACR,MAAMD,0BAAU,EACd,MAAM,2BACP,CAAC;MACF,SAAS,EACP,gBAAgB,oBACjB;MACD,SAAS;MACV;KAGH,MAAM,MAAMa,0CAA4B,UAAU,KAAK;AACvD,SAAI,CAAC,IAAI,QACP,QAAO;MACL,QAAQ;MACR,MAAMb,0BAAU;OACd,MAAM;OACN,SAAS,IAAI,MAAM;OACpB,CAAC;MACF,SAAS,EACP,gBAAgB,oBACjB;MACD,SAAS;MACV;AAKH,WAAM,KAAK,OAAO,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC;KAGxC,MAAM,WAAW,MAAM,KAAK,mBAAmB;MAC7C;MACA;MACA;MACA;MACA;MACD,CAAC;AAEF,YAAO;MACL,QAAQ;MACR,MAAMA,0BAAU,SAAS;MACzB,SAAS;OACP,gBAAgB;QACfR,0BAAW,kBAAkBoB,wBAAS;OACxC;MACD,SAAS;MACV;;IAIH,MAAM,EAAE,QAAQ,SAAS,aAAa,MAAM,KAAK,SAC/C,KAAK,OAAO,IAAI,EAChB,UACA,kBACD;AAED,WAAO;KACL;KACA,MAAMZ,0BAAU;MAAE;MAAS;MAAU,CAAC;KACtC,SAAS;MACP,gBAAgB;OACfR,0BAAW,kBAAkBoB,wBAAS;MACxC;KACD,SAAS;KACV;;WAEI,KAAK;AACZ,UAAO;IACL,QAAQ;IACR,MAAMZ,0BAAU;KACd,MAAM;KACN,GAAGC,8BAAe,IAAa;KAChC,CAAC;IACF,SAAS,EACP,gBAAgB,oBACjB;IACD,SAAS;IACV;;AAGH,SAAO;GACL,QAAQ;GACR,MAAM,KAAK,UAAU;IACnB,SAAS;IACT,MAAM,KAAK;IACZ,CAAC;GACF,SAAS,EAAE;GACX,SAAS;GACV;;CAGH,AAAU,QAAQ,EAChB,YACA,QACA,MACA,OACA,SACA,WAQkE;EAClE,MAAM,KAAK,KAAK,IAAI;AACpB,MAAI,CAAC,GAEH,OAAM,IAAI,MAAM,oCAAoC,WAAW,GAAG;EAGpE,MAAM,kBAAkBa,8BAAY,KAAK;EACzC,IAAI,EAAE,uBAAY;AAGlB,MACEC,cAAYC,gCAAiB,MAC7B,GAAG,GAAG,gCAAgC,CAEtC,aAAUA,gCAAiB;EAG7B,MAAM,SAASzB,8BAAa,YAAY;GACtC,MAAM,YAAY,MAAM0B,iCAAe;IACrC,MAAM;IACN,KAAK,KAAK,OAAO;IACjB;IACD,CAAC;AACF,OAAI,CAAC,UAAU,GACb,OAAM,IAAI,MAAM,UAAU,MAAM;GAmIlC,MAAM,mBAAmB,QAjHG,MAC1B,GAA+B;KAC9BD,gCAAiB,MAAM,EAAE,OAAO,QAAQ,OAAO,KAAK,yBAAc;KACjE,MAAM,YAAY,OAAO,QAAQ,SAAS,EAAE,CAAC,CAAC,QAE3C,KAAK,CAAC,IAAIE,YAAU;AACrB,aAAO;OACL,GAAG;QAEF,KAAK;QAAE;QAAI;QAAM;OACnB;QACA,EAAE,CAAC;AAEN,YAAO;MACL;MACA,gBAAgB;OACd,QAAQ,KAAK;OACb,OAAO,KAAK,UAAU;OACtB,MAAM;QACG;QACC;QACR,OAAO,KAAK,UAAU;QACtB,SAAS,KAAK,WAAW;QAC1B;OACD;OACA,kBACE,WAAW,SAAS,SAAY,UAAU;OAC5C;OACA,kBAAkB,GAAG;OACrB,qBAAqB,KAAK,OAAO,SAAS,EAAE;OAC5C;OACA;OACD;MACF;;KAEFF,gCAAiB,MAAM,EAAE,OAAO,QAAQ,OAAO,KAAK,yBAAc;KACjE,MAAM,YAAY,OAAO,QAAQ,SAAS,EAAE,CAAC,CAAC,QAE3C,KAAK,CAAC,IAAIP,cAAY;AACvB,aAAO;OACL,GAAG;QACF,KACCA,SAAO,SAAS,SACZ;QAAE;QAAI,MAAMA,SAAO;QAAM,GACzBA,SAAO,SAAS,UACd;QAAE;QAAI,OAAOA,SAAO;QAAO,GAC3B;QAAE;QAAI,OAAOA,SAAO;QAAO;OACpC;QACA,EAAE,CAAC;AAEN,YAAO;MACL;MACA,gBAAgB;OACd,QAAQ,KAAK;OACb,OAAO,KAAK,UAAU;OACtB,MAAM;QACG;QACC;QACR,OAAO,KAAK,UAAU;QACtB,SAAS,KAAK,WAAW;QAC1B;OACD;OACA,kBACE,WAAW,SAAS,SAAY,UAAU;OAC5C;OACA,kBAAkB,GAAG;OACrB,2BAA2B,KAAK;OAChC,qBAAqB,KAAK,OAAO,SAAS,EAAE;OAC5C;OACA;OACD;MACF;;KAEFO,gCAAiB,MAAM,EAAE,OAAO,QAAQ,OAAO,KAAK,yBAAc;KACjE,MAAM,YAAY,OAAO,QAAQ,SAAS,EAAE,CAAC,CAAC,QAE3C,KAAK,CAAC,IAAIP,cAAY;AACvB,aAAO;OACL,GAAG;QACF,KACCA,SAAO,SAAS,SACZ;QAAE;QAAI,MAAMA,SAAO;QAAM,GACzBA,SAAO,SAAS,UACd;QAAE;QAAI,OAAOA,SAAO;QAAO,GAC3B;QAAE;QAAI,OAAOA,SAAO;QAAO;OACpC;QACA,EAAE,CAAC;AAEN,YAAO;MACL;MACA,gBAAgB;OACd,QAAQ,KAAK;OACb,OAAO,KAAK,UAAU;OACtB,MAAM;QACG;QACC;QACR,OAAO,KAAK,UAAU;QACtB,SAAS,KAAK,WAAW;QAC1B;OACD;OACA,kBACE,WAAW,SAAS,SAAY,UAAU;OAC5C;OACA,kBAAkB,GAAG;OACrB,2BAA2B,KAAK;OAChC,qBAAqB,KAAK,OAAO,SAAS,EAAE;OAC5C;OACA;OACD;MACF;;IAEJ,CAAC,CAE+CM,WAC/C,UAAU,MACX;AAED,UAAO,GAAG,GAAG,mBAAmB,iBAAiB,CAAC,OAAO;IACzD;AAEF,SAAO;GAAE;GAAS;GAAQ;;CAG5B,AAAU,QAAQ,KAA4B;EAC5C,MAAM,UAAU,OAAO,OAAO,KAAK,OAAO,CAAC,QACxC,KAAK,OAAO,CACX,GAAG,KACH,GAAG,GAAG,aAAa;GAAE,SAAS;GAAK,WAAW,KAAK;GAAI,CAAC,CACzD,EACD,EAAE,CACH;AAED,OAAK,MAAM,UAAU,SAAS;GAC5B,MAAM,QAAQI,mCAAqB,UAAU,OAAO;AACpD,OAAI,CAAC,MAAM,SAAS;IAClB,MAAM,SAAS,MAAM,MAAM,OAAO,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK;AAEtE,SAAK,IACH,QACA,gCAAgC,OAAO,GAAG,MAAM,SACjD;;;AAIL,SAAO;;;;;;;;CAST,AAAU,OAAO,KAAe;EAC9B,IAAI,MAAM,IAAI,IAAI,IAAI;EAEtB,MAAM,YAAY,KAAK,aAAa,KAAK,IAAI7C,uBAAQ;EACrD,MAAM,YAAY,KAAK,aAAa,KAAK,IAAIA,uBAAQ;AAErD,MAAI,UACF,KAAI,WAAW;AAGjB,MAAI,UACF,OAAM,IAAI,IAAI,IAAI,WAAW,IAAI,QAAQ,UAAU;AAGrD,SAAO;;CAGT,AAAU,aAAa,EACrB,KACA,YASkB;AAiBlB,SAhB8B;GAC5B,KAAK,IAAI;GACT,YAAY;GACZ,WAAW,KAAK;GAChB,SAAS,KAAK;GACd,WAAW,KAAK,QAAQ,IAAI;GAC5B,KAAK,OAAOyC;GACZ,GAAG;GACH,UAAU,YAAY;GACtB,cAAc;IACZ,aAAa;IACb,SAAS;IACV;GACD,YAAY,KAAK,OAAO;GACzB;;CAKH,MAAgB,mBAAmB,EACjC,SACA,UACA,KACA,qBACA,OAciC;EACjC,MAAM,eAAe,KAAK,aAAa;GAAE;GAAU;GAAK,CAAC;EACzD,MAAM,oBAAoB,MAAM,KAAK,kBAAkB;GACrD;GACA;GACA;GACA;GACD,CAAC;EAEF,MAAMK,OAA8B;GAClC,QAAQ,KAAK;GACb,YAAY,KAAK,OAAO;GACxB,cAAc,aAAa;GAC3B;GACA,WAAW,aAAa;GACxB,WAAW,aAAa;GACxB,YAAY;GACZ,UAAUC,4BAAgB;IACxB,GAAGlD,2BAAe;IAClB,GAAG,KAAK;IACT,CAAC;GACF,YAAY;GACZ,cAAc;GACd,aAAa;GACb,KAAK,aAAa;GAClB,KAAK,aAAa;GACnB;AAED,MAAI,kBAAkB,0BAA0B;AAC9C,QAAK,eAAe,kBAAkB;AACtC,QAAK,cAAc,kBAAkB;;AAGvC,SAAO;;CAGT,MAAgB,kBAAkB,EAChC,SACA,KACA,qBACA,OAMqE;EACrE,MAAM,eAAe,KAAK,aAAa;GACrC,KAAK,KAAK,OAAO,IAAI;GACrB,UAAU;GACX,CAAC;AAEF,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,8CAA8C;EAGhE,IAAImD,gBAE6B;GAC/B,0BAA0B;GAC1B,OAAO,EACL,kBAAkB,KAAK,MAAM,YAC9B;GACD,eAAe,KAAK,OAAO,gBAAgB;GAC3C,iBAAiB,QAAQ,KAAK,WAAW;GACzC,gBAAgB,aAAa,UAAU;GACvC,MAAM,KAAK,MAAM;GACjB,gBAAgB;GACjB;AAID,MAAI,KAAK,MAAM,SAAS,QACtB,KAAI;AAEF,OAAI,EADqB,MAAM,qBACT,QACpB,OAAM,IAAI,MAAM,8BAA8B;AAGhD,mBAAgB;IACd,GAAG;IACH,0BAA0B;IAC1B,YAAY,KAAK;IACjB,QAAQ,KAAK;IACb,cAAc;KACZ,aAAa;KACb,SAAS;KACV;IACD;IACA,kBAAkB,KAAK;IACvB,gBAAgB,KAAK,kBAAkB;IACvC,OAAO;KACL,GAAG,cAAc;KACjB,cAAc,MAAM,KAAK,aAAa,QAAQ;KAC/C;IACD,WAAW,KAAK;IAChB,cAAc;IACd,aAAaP;IACb,cAAc,KAAK,aAAa;IAChC,YAAY,KAAK,aAAa;IAC9B,2BAA2B,KAAK,4BAA4B;IAC5D,kBAAkB,KAAK,oBAAoB;IAC5C;UACK;AAGN,mBAAgB;IACd,GAAG;IACH,0BAA0B;IAC3B;;AAIL,SAAO;;CAGT,MAAgB,SACd,KACA,UACA,YACiE;EACjE,MAAM,OAAO,KAAK,aAAa;GAAE;GAAK;GAAU,CAAC;EAEjD,IAAIQ;EAKJ,IAAI,cAAc,IAAI,IAAI,KAAK,mBAAmB,KAAK;AAKvD,MAFE,KAAK,SAAS,KAAK,MAAM,cAAc,KAAK,MAAM,OAE/B;GACnB,MAAM,OAAOC,0BAAc,KAAK,IAAI;AAEpC,OADqB,MAAMC,qCAAmB,MAAM,KAAK,MAAM,CAE7D,eAAcC,+BAAa,MAAM,eAAe;aAEzC,KAAK,OAAO,eACrB,eAAcA,+BACZ,KAAK,MAAM,eAAe,MAC1B,eACD;AAGH,MAAI,SACF,aAAY,aAAa,IAAIzC,yBAAU,UAAU,SAAS;AAG5D,MAAI;AACF,SAAM,MAAM0C,kCAAsB;IAChC,WAAW,KAAK;IAChB,mBAAmB,KAAK;IACxB,OAAO,KAAK;IACZ,KAAK,YAAY;IACjB,SAAS;KACP,QAAQ;KACR,MAAM3B,0BAAU,KAAK;KACrB,SAAS;MACP,GAAG,YAAY;OACdR,0BAAW,kBAAkBoB,wBAAS;MACxC;KACD,UAAU;KACX;IACF,CAAC;WACKgB,KAAc;AACrB,QAAK,IAAI,SAAS,IAAI;AAEtB,UAAO;IACL,QAAQ;IACR,SAAS,qBACP,eAAe,QAAQ,KAAK,IAAI,YAAY;IAE9C,UAAU;IACX;;EAGH,MAAM,MAAM,MAAM,IAAI,MAAM;EAE5B,IAAIC,OAA0C,EAAE;AAEhD,MAAI;AACF,UAAO,KAAK,MAAM,IAAI;WACf,KAAK;AACZ,QAAK,IAAI,QAAQ,sCAAsC,IAAI;GAE3D,IAAI,UAAU;AACd,OAAI,eAAe,MACjB,YAAW,KAAK,IAAI;AAEtB,cAAW,kBAAkB,IAAI;AAEjC,UAAO;IACL,QAAQ;IACR;IACA,UAAU;IACX;;EAGH,IAAIC;EACJ,IAAIC;EACJ,IAAIC;EACJ,IAAIC;AACJ,MAAI;AACF,IAAC,CAAE,QAAQ,OAAO,SAAS,YAAa,kBAAkB,MAAM,KAAK;WAC9D,KAAK;AACZ,QAAK,IAAI,QAAQ,qCAAqC,IAAI;GAE1D,IAAI,UAAU;AACd,OAAI,eAAe,MACjB,YAAW,KAAK,IAAI;AAEtB,cAAW,kBAAkB,IAAI;AAEjC,UAAO;IACL,QAAQ;IACR;IACA,UAAU;IACX;;AAQH,MAAI,CAAC,QACH,MAAK,IACH,SACA,iCACA,IAAI,QACJ,IAAI,YACJ,KACD;AAGH,SAAO;GAAE;GAAQ,SAAS;GAAO;GAAU;;;;;;;CAQ7C,AAAQ,oBAAoB;AAC1B,MAAI,KAAK,IAAI3D,uBAAQ,oBAAoB;AACvC,OAAI,CAAC,KAAK,WACR,MAAK,aAAa,OAAO,KAAK,IAAIA,uBAAQ,mBAAmB;AAG/D,QAAK,OAAO,cAAc,cAAc,KAAK,WAAW;;AAG1D,MAAI,KAAK,IAAIA,uBAAQ,4BAA4B;AAC/C,OAAI,CAAC,KAAK,mBACR,MAAK,qBAAqB,OACxB,KAAK,IAAIA,uBAAQ,2BAClB;AAGH,QAAK,OAAO,cAAc,sBAAsB,KAAK,mBAAmB;;AAG1E,MAAI,CAAC,KAAK,OAAO,gBAAgB,IAAI,KAAK,IAAIA,uBAAQ,iBACpD,MAAK,OAAO,YAAY,OAAO,KAAK,IAAIA,uBAAQ,iBAAiB,CAAC;AAIpE,MAAI,KAAK,IAAIA,uBAAQ,qBACnB,MAAK,IACH,QACA,UAAUA,uBAAQ,oBAAoB,yCAAyCA,uBAAQ,eAAe,0DACvG;;;;;;CASL,MAAgB,kBACd,KACA,MAGA;AACA,MAAI;AAEF,OAAI,KAAK,wBACP,QAAO;IAAE,SAAS;IAAM,SAAS;IAAI;AAMvC,OAAI,KAAK,SAAS,CAAC,KAAK,MAAM,QAC5B,QAAO;IAAE,SAAS;IAAM,SAAS;IAAI;AAIvC,OAAI,CAAC,KAAK,WAER,OAAM,IAAI,MACR,6CAA6CA,uBAAQ,kBAAkB,6DACxE;AAIH,OAAI,CAAC,IAEH,OAAM,IAAI,MAAM,MAAMkB,0BAAW,UAAU,WAAW;AAIxD,UAAO;IACL,SAAS;IACT,SAAS,IAAI,iBAAiB,IAAI,CAAC,gBAAgB;KACjD;KACA,wBAAwB,KAAK;KAC7B,YAAY,KAAK;KACjB,oBAAoB,KAAK;KAC1B,CAAC;IACH;WACM,KAAK;AACZ,UAAO;IAAE,SAAS;IAAY;IAAc;;;CAIhD,AAAU,qBAAqB,KAAa,MAAsB;EAChE,MAAM,MAAM,KAAK,KAAK;EACtB,MAAM,MAAM0C,4BAAgB,MAAM,KAAK,IAAI,UAAU,CAAC;AAEtD,SAAO,KAAK,IAAI,KAAK;;;;;;;;;;CAWvB,AAAU,IAAI,OAAiB,GAAG,MAAiB;EACjD,MAAMC,cAAwB;GAC5B;GACA;GACA;GACA;GACA;GACA;GACD;EAED,MAAM,kBAAkB3D,YAAU,QAAQ,KAAK,SAAS;AAGxD,MAFqBA,YAAU,QAAQ,MAAM,IAEzB,iBAAiB;GACnC,IAAI,SAAS,QAAQ;AAErB,OAAI,OAAO,OAAO,SAAS,MAAM,CAC/B,UAAS,QAAQ;AAGnB,UAAO,GAAGJ,yBAAU,GAAG,MAAgB,KAAK,GAAG,KAAK;;;;AAK1D,IAAM,mBAAN,MAAuB;CACrB,AAAO;CACP,AAAO;CAEP,YAAY,KAAa;EACvB,MAAM,SAAS,IAAI,gBAAgB,IAAI;AACvC,OAAK,YAAY,OAAO,IAAI,IAAI,IAAI;AACpC,OAAK,YAAY,OAAO,IAAI,IAAI,IAAI;AAEpC,MAAI,CAAC,KAAK,aAAa,CAAC,KAAK,UAE3B,OAAM,IAAI,MAAM,WAAWoB,0BAAW,UAAU,WAAW;;CAI/D,AAAQ,WAAW,wBAAkC;AACnD,MAAI,uBACF,QAAO;AAKT,SADE,KAAK,KAAK,oBAAG,IAAI,KAAK,OAAO,SAAS,KAAK,UAAU,GAAG,IAAK,EAAC,SAAS,GAC1D,MAAO,KAAK;;CAG7B,iBAAiB,EACf,MACA,YACA,0BAKO;AACP,MAAI,KAAK,WAAW,uBAAuB,CAEzC,OAAM,IAAI,MAAM,wBAAwB;AAI1C,MADY0C,4BAAgB,MAAM,YAAY,KAAK,UAAU,KACjD,KAAK,UAEf,OAAM,IAAI,MAAM,oBAAoB;;CAIxC,AAAO,gBAAgB,EACrB,MACA,YACA,oBACA,0BAMS;AACT,MAAI;AACF,SAAKE,gBAAiB;IAAE;IAAM;IAAY;IAAwB,CAAC;AAEnE,UAAO;WACA,KAAK;AACZ,OAAI,CAAC,mBACH,OAAM;AAGR,SAAKA,gBAAiB;IACpB;IACA,YAAY;IACZ;IACD,CAAC;AAEF,UAAO"}
|
|
1
|
+
{"version":3,"file":"InngestCommHandler.cjs","names":["z","allProcessEnv","logPrefix","acc","envKeys","defaultLogLevel: typeof this.logLevel","logLevels","debugPrefix","defaultStreamingOption: typeof this.streaming","getFetch","defaultInngestApiBaseUrl","defaultInngestEventBaseUrl","dummyEventKey","hashEventKey","hashSigningKey","queryKeys","platformSupportsStreaming","ServerTiming","rethrowError","actions: HandlerResponseWithErrors","args","runAsPromise","headerKeys","inngestHeaders","getMode","Mode","method","headers: Record<string, string>","PREFERRED_EXECUTION_VERSION","signature: string | undefined","stringify","serializeError","signature","createStream","actionRes","probe","enumFromValue","probeEnum","undefinedToNull","result","deployId","parseAsBoolean","syncKind","inBandSyncRequestBodySchema","parseFnData","version","ExecutionVersion","fetchAllFnData","data","functionConfigSchema","body: InBandRegisterRequest","getPlatformName","introspection:\n | UnauthenticatedIntrospection\n | AuthenticatedIntrospection","res: globalThis.Response","devServerHost","devServerAvailable","devServerUrl","fetchWithAuthFallback","err: unknown","data: z.input<typeof registerResSchema>","status: number","error: string","skipped: boolean","modified: boolean","signDataWithKey","logLevels: LogLevel[]","#verifySignature"],"sources":["../../src/components/InngestCommHandler.ts"],"sourcesContent":["import debug from \"debug\";\nimport { z } from \"zod/v3\";\nimport {\n debugPrefix,\n defaultInngestApiBaseUrl,\n defaultInngestEventBaseUrl,\n dummyEventKey,\n ExecutionVersion,\n envKeys,\n headerKeys,\n logPrefix,\n probe as probeEnum,\n queryKeys,\n syncKind,\n} from \"../helpers/consts.ts\";\nimport { devServerAvailable, devServerUrl } from \"../helpers/devserver.ts\";\nimport { enumFromValue } from \"../helpers/enum.ts\";\nimport {\n allProcessEnv,\n devServerHost,\n type Env,\n getFetch,\n getMode,\n getPlatformName,\n inngestHeaders,\n Mode,\n parseAsBoolean,\n platformSupportsStreaming,\n} from \"../helpers/env.ts\";\nimport { rethrowError, serializeError } from \"../helpers/errors.ts\";\nimport {\n type FnData,\n fetchAllFnData,\n parseFnData,\n undefinedToNull,\n} from \"../helpers/functions.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 { hashEventKey, hashSigningKey, stringify } from \"../helpers/strings.ts\";\nimport type { MaybePromise } from \"../helpers/types.ts\";\nimport {\n type AuthenticatedIntrospection,\n type EventPayload,\n type FunctionConfig,\n functionConfigSchema,\n type InBandRegisterRequest,\n inBandSyncRequestBodySchema,\n type LogLevel,\n logLevels,\n type OutgoingOp,\n type RegisterOptions,\n type RegisterRequest,\n type SupportedFrameworkName,\n type UnauthenticatedIntrospection,\n} from \"../types.ts\";\nimport { version } from \"../version.ts\";\nimport {\n type ExecutionResult,\n type ExecutionResultHandler,\n type ExecutionResultHandlers,\n type InngestExecutionOptions,\n PREFERRED_EXECUTION_VERSION,\n} from \"./execution/InngestExecution.ts\";\nimport type { Inngest } from \"./Inngest.ts\";\nimport type {\n CreateExecutionOptions,\n InngestFunction,\n} from \"./InngestFunction.ts\";\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\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\ninterface InngestCommHandlerOptions<\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Input extends any[] = any[],\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Output = any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\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/**\n * Capturing the global type of fetch so that we can reliably access it below.\n */\ntype FetchT = typeof fetch;\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: <explanation>\n Input extends any[] = any[],\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Output = any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n StreamOutput = any,\n> {\n /**\n * The ID 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 public readonly id: string;\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 signing key used to validate requests from Inngest. This is\n * intentionally mutable so that we can pick up the signing key from the\n * environment during execution if needed.\n */\n protected signingKey: string | undefined;\n\n /**\n * The same as signingKey, except used as a fallback when auth fails using the\n * primary signing key.\n */\n protected signingKeyFallback: string | undefined;\n\n /**\n * A property that can be set to indicate whether we believe we are in\n * production mode.\n *\n * Should be set every time a request is received.\n */\n protected _mode: Mode | undefined;\n\n /**\n * The localized `fetch` implementation used by this handler.\n */\n private readonly fetch: FetchT;\n\n /**\n * The host 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 hostname 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 _serveHost: 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 `serveHost`.\n */\n private readonly _servePath: string | undefined;\n\n /**\n * The minimum level to log from the Inngest serve handler.\n */\n protected readonly logLevel: LogLevel;\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<\n string,\n { fn: InngestFunction.Any; onFailure: boolean }\n > = {};\n\n private env: Env = allProcessEnv();\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 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 *\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\n if (options.id) {\n console.warn(\n `${logPrefix} The \\`id\\` serve option is deprecated and will be removed in v4`,\n );\n }\n this.id = options.id || this.client.id;\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: <explanation>\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) as InngestFunction.Any[];\n\n if (this.rawFns.length !== options.functions.length) {\n // TODO PrettyError\n console.warn(\n `Some functions passed to serve() are undefined and misconfigured. Please check your imports.`,\n );\n }\n\n this.fns = this.rawFns.reduce<\n Record<string, { fn: InngestFunction.Any; onFailure: boolean }>\n >((acc, fn) => {\n const configs = fn[\"getConfig\"]({\n baseUrl: new URL(\"https://example.com\"),\n appPrefix: this.id,\n });\n\n const fns = configs.reduce((acc, { id }, index) => {\n return { ...acc, [id]: { fn, onFailure: Boolean(index) } };\n }, {});\n\n // biome-ignore lint/complexity/noForEach: <explanation>\n configs.forEach(({ id }) => {\n if (acc[id]) {\n // TODO PrettyError\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\n return {\n ...acc,\n ...fns,\n };\n }, {});\n\n this.inngestRegisterUrl = new URL(\"/fn/register\", this.apiBaseUrl);\n\n this.signingKey = options.signingKey;\n this.signingKeyFallback = options.signingKeyFallback;\n this._serveHost = options.serveHost || this.env[envKeys.InngestServeHost];\n this._servePath = options.servePath || this.env[envKeys.InngestServePath];\n\n this.skipSignatureValidation = options.skipSignatureValidation || false;\n\n const defaultLogLevel: typeof this.logLevel = \"info\";\n this.logLevel = z\n .enum(logLevels)\n .default(defaultLogLevel)\n .catch((ctx) => {\n this.log(\n \"warn\",\n `Unknown log level passed: ${String(\n ctx.input,\n )}; defaulting to ${defaultLogLevel}`,\n );\n\n return defaultLogLevel;\n })\n .parse(options.logLevel || this.env[envKeys.InngestLogLevel]);\n\n if (this.logLevel === \"debug\") {\n /**\n * `debug` is an old library; sometimes its runtime detection doesn't work\n * for newer pairings of framework/runtime.\n *\n * One silly symptom of this is that `Debug()` returns an anonymous\n * function with no extra properties instead of a `Debugger` instance if\n * the wrong code is consumed following a bad detection. This results in\n * the following `.enable()` call failing, so we just try carefully to\n * enable it here.\n */\n if (debug.enable && typeof debug.enable === \"function\") {\n debug.enable(`${debugPrefix}:*`);\n }\n }\n\n const defaultStreamingOption: typeof this.streaming = false;\n this.streaming = z\n .union([z.enum([\"allow\", \"force\"]), z.literal(false)])\n .default(defaultStreamingOption)\n .catch((ctx) => {\n this.log(\n \"warn\",\n `Unknown streaming option passed: ${String(\n ctx.input,\n )}; defaulting to ${String(defaultStreamingOption)}`,\n );\n\n return defaultStreamingOption;\n })\n .parse(options.streaming || this.env[envKeys.InngestStreaming]);\n\n this.fetch = options.fetch ? getFetch(options.fetch) : this.client[\"fetch\"];\n }\n\n /**\n * Get the API base URL for the Inngest API.\n *\n * This is a getter to encourage checking the environment for the API base URL\n * each time it's accessed, as it may change during execution.\n */\n protected get apiBaseUrl(): string {\n return (\n this._options.baseUrl ||\n this.env[envKeys.InngestApiBaseUrl] ||\n this.env[envKeys.InngestBaseUrl] ||\n this.client.apiBaseUrl ||\n defaultInngestApiBaseUrl\n );\n }\n\n /**\n * Get the event API base URL for the Inngest API.\n *\n * This is a getter to encourage checking the environment for the event API\n * base URL each time it's accessed, as it may change during execution.\n */\n protected get eventApiBaseUrl(): string {\n return (\n this._options.baseUrl ||\n this.env[envKeys.InngestEventApiBaseUrl] ||\n this.env[envKeys.InngestBaseUrl] ||\n this.client.eventBaseUrl ||\n defaultInngestEventBaseUrl\n );\n }\n\n /**\n * The host 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 hostname 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 serveHost(): string | undefined {\n return this._serveHost || this.env[envKeys.InngestServeHost];\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 `serveHost`.\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\"] || this.client[\"eventKey\"] === dummyEventKey) {\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.signingKey) {\n return undefined;\n }\n return hashSigningKey(this.signingKey);\n }\n\n private get hashedSigningKeyFallback(): string | undefined {\n if (!this.signingKeyFallback) {\n return undefined;\n }\n return hashSigningKey(this.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 // We must be able to stream responses to continue.\n if (!actions.transformStreamingResponse) {\n return false;\n }\n\n // If the user has forced streaming, we should always stream.\n if (this.streaming === \"force\") {\n return true;\n }\n\n // If the user has allowed streaming, we should stream if the platform\n // supports it.\n return (\n this.streaming === \"allow\" &&\n platformSupportsStreaming(\n this.frameworkName as SupportedFrameworkName,\n this.env,\n )\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(): (...args: Input) => Promise<Awaited<Output>> {\n const handler = async (...args: Input) => {\n const timer = new ServerTiming();\n\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 =\n Object.entries(rawActions).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 = () =>\n (value as (...args: unknown[]) => unknown)(...args);\n\n return runAsPromise(fn)\n .catch(rethrowError(errMessage))\n .catch((err) => {\n this.log(\"error\", err);\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 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 this.env = {\n ...allProcessEnv(),\n ...env,\n };\n\n const getInngestHeaders = (): 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\n const assumedMode = getMode({ env: this.env, client: this.client });\n\n if (assumedMode.isExplicit) {\n this._mode = assumedMode;\n } else {\n const serveIsProd = await actions.isProduction?.(\n \"starting to handle request\",\n );\n if (typeof serveIsProd === \"boolean\") {\n this._mode = new Mode({\n type: serveIsProd ? \"cloud\" : \"dev\",\n isExplicit: false,\n });\n } else {\n this._mode = assumedMode;\n }\n }\n\n this.upsertKeysFromEnv();\n\n const methodP = actions.method(\"starting to handle request\");\n\n const headerPromises = [\n headerKeys.TraceParent,\n headerKeys.TraceState,\n ].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 contentLength = await actions\n .headers(\"checking signature for request\", headerKeys.ContentLength)\n .then((value) => {\n if (!value) {\n return undefined;\n }\n return Number.parseInt(value, 10);\n });\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((method) => {\n if (method === \"POST\" || method === \"PUT\") {\n if (!contentLength) {\n // Return empty string because req.json() will throw an error.\n return \"\";\n }\n\n return actions.body(\n `checking body for request signing as method is ${method}`,\n );\n }\n\n return \"\";\n }),\n ]);\n\n const signatureValidation = this.validateSignature(signature, body);\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 actionRes = timer.wrap(\"action\", () =>\n this.handleAction({\n actions,\n timer,\n getInngestHeaders,\n reqArgs: args,\n signatureValidation,\n\n body,\n method,\n headers: headersToForwardP,\n }),\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 ...getInngestHeaders(),\n ...(await headersToForwardP),\n ...res.headers,\n ...(res.version === null\n ? {}\n : {\n [headerKeys.RequestVersion]: (\n res.version ?? PREFERRED_EXECUTION_VERSION\n ).toString(),\n }),\n };\n\n let signature: string | undefined;\n\n try {\n signature = await signatureValidation.then((result) => {\n if (!result.success || !result.keyUsed) {\n return undefined;\n }\n\n return 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 if (await this.shouldStream(actions)) {\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 actionRes.then((res) => {\n return finalize(prepareActionRes(res));\n });\n\n return timer.wrap(\"res\", () => {\n return actions.transformStreamingResponse?.(\n \"starting streaming response\",\n {\n status: 201,\n headers: getInngestHeaders(),\n body: stream,\n version: null,\n },\n );\n });\n }\n }\n\n return timer.wrap(\"res\", async () => {\n return actionRes.then(prepareActionRes).then((actionRes) => {\n return actions.transformResponse(\"sending back response\", actionRes);\n });\n });\n };\n\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 // biome-ignore lint/correctness/noUnusedPrivateClassMembers: used in the SDK\n private get mode(): Mode | undefined {\n return this._mode;\n }\n\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: used in the SDK\n private set mode(m) {\n this._mode = m;\n\n if (m) {\n this.client[\"mode\"] = m;\n }\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 getInngestHeaders,\n reqArgs,\n signatureValidation,\n body,\n method,\n headers,\n }: {\n actions: HandlerResponseWithErrors;\n timer: ServerTiming;\n getInngestHeaders: () => Record<string, string>;\n reqArgs: unknown[];\n signatureValidation: ReturnType<InngestCommHandler[\"validateSignature\"]>;\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n body: any;\n method: string;\n headers: Promise<Record<string, string>>;\n }): Promise<ActionResponse> {\n // This is when the request body is completely missing; it does not\n // include an empty body. This commonly happens when the HTTP framework\n // doesn't have body parsing middleware.\n const isMissingBody = body === undefined;\n\n try {\n let url = await actions.url(\"starting to handle request\");\n\n if (method === \"POST\") {\n if (isMissingBody) {\n this.log(\n \"error\",\n \"Missing body when executing, 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 executing, possibly due to missing request body middleware\",\n ),\n ),\n ),\n version: undefined,\n };\n }\n\n const validationResult = await signatureValidation;\n if (!validationResult.success) {\n return {\n status: 401,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: stringify(serializeError(validationResult.err)),\n version: undefined,\n };\n }\n\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 const fnId = await actions.queryStringWithDefaults(\n \"processing run request\",\n queryKeys.FnId,\n );\n if (!fnId) {\n // TODO PrettyError\n throw new Error(\"No function ID found in request\");\n }\n\n const stepId =\n (await actions.queryStringWithDefaults(\n \"processing run request\",\n queryKeys.StepId,\n )) || null;\n\n const { version, result } = this.runStep({\n functionId: fnId,\n data: body,\n stepId,\n timer,\n reqArgs,\n headers: await headers,\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 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 return {\n status: 500,\n headers: {\n \"Content-Type\": \"application/json\",\n [headerKeys.NoRetry]: \"false\",\n },\n body: stringify({\n error: `Could not find step \"${\n result.step.displayName || result.step.id\n }\" to run; timed out`,\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 };\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.log(\"error\", \"Error handling execution result\", err);\n throw err;\n }\n }\n\n // TODO: This feels hacky, so we should probably make it not hacky.\n const env = getInngestHeaders()[headerKeys.Environment] ?? null;\n\n if (method === \"GET\") {\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.log(\n \"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 getInngestHeaders,\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 return {\n status: 405,\n body: JSON.stringify({\n message: \"No action found; request was likely not POST, PUT, or GET\",\n mode: this._mode,\n }),\n headers: {},\n version: undefined,\n };\n }\n\n protected runStep({\n functionId,\n stepId,\n data,\n timer,\n reqArgs,\n headers,\n }: {\n functionId: string;\n stepId: string | null;\n data: unknown;\n timer: ServerTiming;\n reqArgs: unknown[];\n headers: Record<string, string>;\n }): { version: ExecutionVersion; result: Promise<ExecutionResult> } {\n const fn = this.fns[functionId];\n if (!fn) {\n // TODO PrettyError\n throw new Error(`Could not find function with ID \"${functionId}\"`);\n }\n\n const immediateFnData = parseFnData(data);\n let { version } = immediateFnData;\n\n // Handle opting in to optimized parallelism in v3.\n if (\n version === ExecutionVersion.V1 &&\n fn.fn[\"shouldOptimizeParallelism\"]?.()\n ) {\n version = ExecutionVersion.V2;\n }\n\n const result = runAsPromise(async () => {\n const anyFnData = await fetchAllFnData({\n data: immediateFnData,\n api: this.client[\"inngestApi\"],\n version,\n });\n if (!anyFnData.ok) {\n throw new Error(anyFnData.error);\n }\n\n type ExecutionStarter<V> = (\n fnData: V extends ExecutionVersion\n ? Extract<FnData, { version: V }>\n : FnData,\n ) => MaybePromise<CreateExecutionOptions>;\n\n type GenericExecutionStarters = Record<\n ExecutionVersion,\n ExecutionStarter<unknown>\n >;\n\n type ExecutionStarters = {\n [V in ExecutionVersion]: ExecutionStarter<V>;\n };\n\n const executionStarters = ((s: ExecutionStarters) =>\n s as GenericExecutionStarters)({\n [ExecutionVersion.V0]: ({ event, events, steps, ctx, version }) => {\n const stepState = Object.entries(steps ?? {}).reduce<\n InngestExecutionOptions[\"stepState\"]\n >((acc, [id, data]) => {\n return {\n ...acc,\n\n [id]: { id, data },\n };\n }, {});\n\n return {\n version,\n partialOptions: {\n client: this.client,\n runId: ctx?.run_id || \"\",\n data: {\n event: event as EventPayload,\n events: events as [EventPayload, ...EventPayload[]],\n runId: ctx?.run_id || \"\",\n attempt: ctx?.attempt ?? 0,\n },\n stepState,\n requestedRunStep:\n stepId === \"step\" ? undefined : stepId || undefined,\n timer,\n isFailureHandler: fn.onFailure,\n stepCompletionOrder: ctx?.stack?.stack ?? [],\n reqArgs,\n headers,\n },\n };\n },\n [ExecutionVersion.V1]: ({ event, events, steps, ctx, version }) => {\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 return {\n version,\n partialOptions: {\n client: this.client,\n runId: ctx?.run_id || \"\",\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 },\n stepState,\n requestedRunStep:\n stepId === \"step\" ? undefined : stepId || undefined,\n timer,\n isFailureHandler: fn.onFailure,\n disableImmediateExecution: ctx?.disable_immediate_execution,\n stepCompletionOrder: ctx?.stack?.stack ?? [],\n reqArgs,\n headers,\n },\n };\n },\n [ExecutionVersion.V2]: ({ event, events, steps, ctx, version }) => {\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 return {\n version,\n partialOptions: {\n client: this.client,\n runId: ctx?.run_id || \"\",\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 },\n stepState,\n requestedRunStep:\n stepId === \"step\" ? undefined : stepId || undefined,\n timer,\n isFailureHandler: fn.onFailure,\n disableImmediateExecution: ctx?.disable_immediate_execution,\n stepCompletionOrder: ctx?.stack?.stack ?? [],\n reqArgs,\n headers,\n },\n };\n },\n });\n\n const executionOptions = await executionStarters[version](\n anyFnData.value,\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 = Object.values(this.rawFns).reduce<FunctionConfig[]>(\n (acc, fn) => [\n ...acc,\n ...fn[\"getConfig\"]({ baseUrl: url, appPrefix: this.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.log(\n \"warn\",\n `Config invalid for function \"${config.id}\" : ${errors}`,\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 `serveHost` 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 serveHost = this.serveHost || this.env[envKeys.InngestServeHost];\n const servePath = this.servePath || this.env[envKeys.InngestServePath];\n\n if (servePath) {\n ret.pathname = servePath;\n }\n\n if (serveHost) {\n ret = new URL(ret.pathname + ret.search, serveHost);\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.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.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 ...allProcessEnv(),\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 (introspectionBody.authentication_succeeded) {\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._mode) {\n throw new Error(\"No mode set; cannot introspect without mode\");\n }\n\n let introspection:\n | UnauthenticatedIntrospection\n | AuthenticatedIntrospection = {\n authentication_succeeded: null,\n extra: {\n is_mode_explicit: this._mode.isExplicit,\n },\n has_event_key: this.client[\"eventKeySet\"](),\n has_signing_key: Boolean(this.signingKey),\n function_count: registerBody.functions.length,\n mode: this._mode.type,\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._mode.type === \"cloud\") {\n try {\n const validationResult = await signatureValidation;\n if (!validationResult.success) {\n throw new Error(\"Signature validation failed\");\n }\n\n introspection = {\n ...introspection,\n authentication_succeeded: true,\n api_origin: this.apiBaseUrl,\n app_id: this.id,\n capabilities: {\n trust_probe: \"v1\",\n connect: \"v1\",\n },\n env,\n event_api_origin: this.eventApiBaseUrl,\n event_key_hash: this.hashedEventKey ?? null,\n extra: {\n ...introspection.extra,\n is_streaming: await this.shouldStream(actions),\n },\n framework: this.frameworkName,\n sdk_language: \"js\",\n sdk_version: version,\n serve_origin: this.serveHost ?? null,\n serve_path: this.servePath ?? null,\n signing_key_fallback_hash: this.hashedSigningKeyFallback ?? null,\n signing_key_hash: this.hashedSigningKey ?? null,\n } satisfies AuthenticatedIntrospection;\n } catch {\n // Swallow signature validation error since we'll just return the\n // unauthenticated introspection\n introspection = {\n ...introspection,\n authentication_succeeded: false,\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: () => 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 // Whenever we register, we check to see if the dev server is up. This\n // is a noop and returns false in production. Clone the URL object to avoid\n // mutating the property between requests.\n let registerURL = new URL(this.inngestRegisterUrl.href);\n\n const inferredDevMode =\n this._mode && this._mode.isInferred && this._mode.isDev;\n\n if (inferredDevMode) {\n const host = devServerHost(this.env);\n const hasDevServer = await devServerAvailable(host, this.fetch);\n if (hasDevServer) {\n registerURL = devServerUrl(host, \"/fn/register\");\n }\n } else if (this._mode?.explicitDevUrl) {\n registerURL = devServerUrl(\n this._mode.explicitDevUrl.href,\n \"/fn/register\",\n );\n }\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.fetch,\n url: registerURL.href,\n options: {\n method: \"POST\",\n body: stringify(body),\n headers: {\n ...getHeaders(),\n [headerKeys.InngestSyncKind]: syncKind.OutOfBand,\n },\n redirect: \"follow\",\n },\n });\n } catch (err: unknown) {\n this.log(\"error\", err);\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.log(\"warn\", \"Couldn't unpack register response:\", err);\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.log(\"warn\", \"Invalid register response schema:\", err);\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.log(\n \"debug\",\n \"registered inngest functions:\",\n res.status,\n res.statusText,\n data,\n );\n }\n\n return { status, message: error, modified };\n }\n\n /**\n * Given an environment, upsert any missing keys. This is useful in\n * situations where environment variables are passed directly to handlers or\n * are otherwise difficult to access during initialization.\n */\n private upsertKeysFromEnv() {\n if (this.env[envKeys.InngestSigningKey]) {\n if (!this.signingKey) {\n this.signingKey = String(this.env[envKeys.InngestSigningKey]);\n }\n\n this.client[\"inngestApi\"].setSigningKey(this.signingKey);\n }\n\n if (this.env[envKeys.InngestSigningKeyFallback]) {\n if (!this.signingKeyFallback) {\n this.signingKeyFallback = String(\n this.env[envKeys.InngestSigningKeyFallback],\n );\n }\n\n this.client[\"inngestApi\"].setSigningKeyFallback(this.signingKeyFallback);\n }\n\n if (!this.client[\"eventKeySet\"]() && this.env[envKeys.InngestEventKey]) {\n this.client.setEventKey(String(this.env[envKeys.InngestEventKey]));\n }\n\n // v2 -> v3 migration warnings\n if (this.env[envKeys.InngestDevServerUrl]) {\n this.log(\n \"warn\",\n `Use of ${envKeys.InngestDevServerUrl} has been deprecated in v3; please use ${envKeys.InngestBaseUrl} instead. See https://www.inngest.com/docs/sdk/migration`,\n );\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._mode && !this._mode.isCloud) {\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.signingKey) {\n // TODO PrettyError\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/secrets`,\n );\n }\n\n // If we're here, we're in production; lack of a req signature is an error.\n if (!sig) {\n // TODO PrettyError\n throw new Error(`No ${headerKeys.Signature} provided`);\n }\n\n // Validate the signature\n return {\n success: true,\n keyUsed: new RequestSignature(sig).verifySignature({\n body,\n allowExpiredSignatures: this.allowExpiredSignatures,\n signingKey: this.signingKey,\n signingKeyFallback: this.signingKeyFallback,\n }),\n };\n } catch (err) {\n return { success: false, err: err as Error };\n }\n }\n\n protected getResponseSignature(key: string, body: string): string {\n const now = Date.now();\n const mac = signDataWithKey(body, key, now.toString());\n\n return `t=${now}&s=${mac}`;\n }\n\n /**\n * Log to stdout/stderr if the log level is set to include the given level.\n * The default log level is `\"info\"`.\n *\n * This is an abstraction over `console.log` and will try to use the correct\n * method for the given log level. For example, `log(\"error\", \"foo\")` will\n * call `console.error(\"foo\")`.\n */\n protected log(level: LogLevel, ...args: unknown[]) {\n const logLevels: LogLevel[] = [\n \"debug\",\n \"info\",\n \"warn\",\n \"error\",\n \"fatal\",\n \"silent\",\n ];\n\n const logLevelSetting = logLevels.indexOf(this.logLevel);\n const currentLevel = logLevels.indexOf(level);\n\n if (currentLevel >= logLevelSetting) {\n let logger = console.log;\n\n if (Object.hasOwn(console, level)) {\n logger = console[level as keyof typeof console] as typeof logger;\n }\n\n logger(`${logPrefix} ${level as string} -`, ...args);\n }\n }\n}\n\nclass 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 // TODO PrettyError\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 delta =\n Date.now() - new Date(Number.parseInt(this.timestamp) * 1000).valueOf();\n return delta > 1000 * 60 * 5;\n }\n\n #verifySignature({\n body,\n signingKey,\n allowExpiredSignatures,\n }: {\n body: unknown;\n signingKey: string;\n allowExpiredSignatures: boolean;\n }): void {\n if (this.hasExpired(allowExpiredSignatures)) {\n // TODO PrettyError\n throw new Error(\"Signature has expired\");\n }\n\n const mac = signDataWithKey(body, signingKey, this.timestamp);\n if (mac !== this.signature) {\n // TODO PrettyError\n throw new Error(\"Invalid signature\");\n }\n }\n\n public verifySignature({\n body,\n signingKey,\n signingKeyFallback,\n allowExpiredSignatures,\n }: {\n body: unknown;\n signingKey: string;\n signingKeyFallback: string | undefined;\n allowExpiredSignatures: boolean;\n }): string {\n try {\n this.#verifySignature({ body, signingKey, allowExpiredSignatures });\n\n return signingKey;\n } catch (err) {\n if (!signingKeyFallback) {\n throw err;\n }\n\n this.#verifySignature({\n body,\n signingKey: signingKeyFallback,\n allowExpiredSignatures,\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: <explanation>\n Input extends any[] = any[],\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n Output = any,\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n StreamOutput = any,\n> = (...args: Input) => HandlerResponse<Output, StreamOutput>;\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type HandlerResponse<Output = any, StreamOutput = any> = {\n // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n body: () => MaybePromise<any>;\n env?: () => MaybePromise<Env | undefined>;\n headers: (key: string) => MaybePromise<string | null | undefined>;\n\n /**\n * Whether the current environment is production. This is used to determine\n * some functionality like whether to connect to the dev server or whether to\n * show debug logging.\n *\n * If this is not provided--or is provided and returns `undefined`--we'll try\n * to automatically detect whether we're in production by checking various\n * environment variables.\n */\n isProduction?: () => MaybePromise<boolean | undefined>;\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/**\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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InngestCommHandler.d.cts","names":[],"sources":["../../src/components/InngestCommHandler.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AA6EA;;;;AAA6C,UAA5B,mBAAA,SAA4B,eAAA,CAAA;EAAe;AAkB3D;;QA6BS,EA3CA,OAAA,CAAQ,IA2CA;;;;WAkCgB,EAAA,SAxEZ,eAAA,CAAgB,IAwEJ,EAAA;;UA7DxB,yBA6NsB,CAAA,cAAA,GAAA,EAAA,GAAA,GAAA,EAAA,EAAA,SAAA,GAAA,EAAA,eAAA,GAAA,CAAA,SAtNtB,eAsNsB,CAAA;;;;;;;;eA6Uc,EAAA,MAAA;;;;;;;;;;;QAsvBH,EArwCjC,OAAA,CAAQ,IAqwCyB;;;;
|
|
1
|
+
{"version":3,"file":"InngestCommHandler.d.cts","names":[],"sources":["../../src/components/InngestCommHandler.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AA6EA;;;;AAA6C,UAA5B,mBAAA,SAA4B,eAAA,CAAA;EAAe;AAkB3D;;QA6BS,EA3CA,OAAA,CAAQ,IA2CA;;;;WAkCgB,EAAA,SAxEZ,eAAA,CAAgB,IAwEJ,EAAA;;UA7DxB,yBA6NsB,CAAA,cAAA,GAAA,EAAA,GAAA,GAAA,EAAA,EAAA,SAAA,GAAA,EAAA,eAAA,GAAA,CAAA,SAtNtB,eAsNsB,CAAA;;;;;;;;eA6Uc,EAAA,MAAA;;;;;;;;;;;QAsvBH,EArwCjC,OAAA,CAAQ,IAqwCyB;;;;WAsMb,EAAA,SAt8CR,eAAA,CAAgB,IAs8CR,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA0LR,EAnmDX,OAmmDW,CAnmDH,KAmmDG,EAnmDI,MAmmDJ,EAnmDY,YAmmDZ,CAAA;yBACjB,CAAA,EAAA,OAAA;;;;;AA2UL;;;;;;;AAUA;;;;;;;;;;;;;;;;;;AAiEA;;;;;;;AAsCA;;;;;;;;;AAKuD,cAr+D1C,kBAq+D0C,CAAA,cAAA,GAAA,EAAA,GAAA,GAAA,EAAA,EAAA,SAAA,GAAA,EAAA,eAAA,GAAA,CAAA,CAAA;;;;;;WAEjC,EAAA,EAAA,MAAA;EAAC;AAQvB;;WAUO,OAAA,EAv+DoB,OAu+DpB;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAv8DY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BA4CY;gCAEC;;;;;;;;;;;;;;;;uBA+BT,0BAA0B,OAAO,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA8S5B,UAAU,QAAQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;WAmvBnD;;aAEE;;aACI;YAA0B,QAAQ;;yBAwK1B,MAAM;;;;;;;wBA8BP,MAAM;;;;;SAqBrB;;;;;;MAOH;;;;;;;;aA2BO;;;;;;;yBASY,WAAW;SAE3B;MACH,QAAQ;;;;;;;aA0CD;;yBAEY,WAAW;SAC3B;MACH,QAAQ,+BAA+B;0BAuEpC,4DAEa,yBACjB;;;;;;;;;;;;;;;uEAqKA;;;;;SAC2D;;;;;;;;;;;uBA2DzC;;;;;;KA0GX,mFAOE,UAAU,gBAAgB,QAAQ;KAGpC;cAEE;cACA,aAAa;4BACC;;;;;;;;;;uBAWL;gBACP;mCAGP,QACF;aACM,aAAa;;;;;;;;;;;;;2BAcC,2BAA2B;;;;;;;;;;;;;;;;;;;;qCAsB7C,eAAe,oBACjB;;;;;;UAOU,sCACQ;;;;;;;;WAUd;;;;QAKH;;;;;;;;;;;WAYG;;;;;;;;;KAUC,+BAAA,iBACE,kBAAkB,YAAY,gBAAgB,iDAGtD,UAAU,uDACsB,SAAS,QAAQ,oCACjB,SAAS,QAAQ,KACjD,gBAAgB;;;;;;UAQL,yBAAA,SACP;;;;;;4DASH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InngestCommHandler.d.ts","names":[],"sources":["../../src/components/InngestCommHandler.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AA6EA;;;;AAA6C,UAA5B,mBAAA,SAA4B,eAAA,CAAA;EAAe;AAkB3D;;QA6BS,EA3CA,OAAA,CAAQ,IA2CA;;;;WAkCgB,EAAA,SAxEZ,eAAA,CAAgB,IAwEJ,EAAA;;UA7DxB,yBA6NsB,CAAA,cAAA,GAAA,EAAA,GAAA,GAAA,EAAA,EAAA,SAAA,GAAA,EAAA,eAAA,GAAA,CAAA,SAtNtB,eAsNsB,CAAA;;;;;;;;eA6Uc,EAAA,MAAA;;;;;;;;;;;QAsvBH,EArwCjC,OAAA,CAAQ,IAqwCyB;;;;
|
|
1
|
+
{"version":3,"file":"InngestCommHandler.d.ts","names":[],"sources":["../../src/components/InngestCommHandler.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AA6EA;;;;AAA6C,UAA5B,mBAAA,SAA4B,eAAA,CAAA;EAAe;AAkB3D;;QA6BS,EA3CA,OAAA,CAAQ,IA2CA;;;;WAkCgB,EAAA,SAxEZ,eAAA,CAAgB,IAwEJ,EAAA;;UA7DxB,yBA6NsB,CAAA,cAAA,GAAA,EAAA,GAAA,GAAA,EAAA,EAAA,SAAA,GAAA,EAAA,eAAA,GAAA,CAAA,SAtNtB,eAsNsB,CAAA;;;;;;;;eA6Uc,EAAA,MAAA;;;;;;;;;;;QAsvBH,EArwCjC,OAAA,CAAQ,IAqwCyB;;;;WAsMb,EAAA,SAt8CR,eAAA,CAAgB,IAs8CR,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA0LR,EAnmDX,OAmmDW,CAnmDH,KAmmDG,EAnmDI,MAmmDJ,EAnmDY,YAmmDZ,CAAA;yBACjB,CAAA,EAAA,OAAA;;;;;AA2UL;;;;;;;AAUA;;;;;;;;;;;;;;;;;;AAiEA;;;;;;;AAsCA;;;;;;;;;AAKuD,cAr+D1C,kBAq+D0C,CAAA,cAAA,GAAA,EAAA,GAAA,GAAA,EAAA,EAAA,SAAA,GAAA,EAAA,eAAA,GAAA,CAAA,CAAA;;;;;;WAEjC,EAAA,EAAA,MAAA;EAAC;AAQvB;;WAUO,OAAA,EAv+DoB,OAu+DpB;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAv8DY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BA4CY;gCAEC;;;;;;;;;;;;;;;;uBA+BT,0BAA0B,OAAO,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BA8S5B,UAAU,QAAQ,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;WAmvBnD;;aAEE;;aACI;YAA0B,QAAQ;;yBAwK1B,MAAM;;;;;;;wBA8BP,MAAM;;;;;SAqBrB;;;;;;MAOH;;;;;;;;aA2BO;;;;;;;yBASY,WAAW;SAE3B;MACH,QAAQ;;;;;;;aA0CD;;yBAEY,WAAW;SAC3B;MACH,QAAQ,+BAA+B;0BAuEpC,4DAEa,yBACjB;;;;;;;;;;;;;;;uEAqKA;;;;;SAC2D;;;;;;;;;;;uBA2DzC;;;;;;KA0GX,mFAOE,UAAU,gBAAgB,QAAQ;KAGpC;cAEE;cACA,aAAa;4BACC;;;;;;;;;;uBAWL;gBACP;mCAGP,QACF;aACM,aAAa;;;;;;;;;;;;;2BAcC,2BAA2B;;;;;;;;;;;;;;;;;;;;qCAsB7C,eAAe,oBACjB;;;;;;UAOU,sCACQ;;;;;;;;WAUd;;;;QAKH;;;;;;;;;;;WAYG;;;;;;;;;KAUC,+BAAA,iBACE,kBAAkB,YAAY,gBAAgB,iDAGtD,UAAU,uDACsB,SAAS,QAAQ,oCACjB,SAAS,QAAQ,KACjD,gBAAgB;;;;;;UAQL,yBAAA,SACP;;;;;;4DASH"}
|