UNPKG

inngest

Version:

Official SDK for Inngest.com. Inngest is the reliability layer for modern applications. Inngest combines durable execution, events, and queues into a zero-infra platform with built-in observability.

162 lines (160 loc) 6.06 kB
import { headerKeys, queryKeys } from "../../helpers/consts.js"; import { version } from "../../version.js"; import { getEnvironmentName } from "../../helpers/env.js"; import { DefaultMaxRuntime } from "../../types.js"; import { PREFERRED_ASYNC_EXECUTION_VERSION } from "../execution/InngestExecution.js"; import { parseFnData } from "../../helpers/functions.js"; import { hashSigningKey } from "../../helpers/strings.js"; import { internalLoggerSymbol } from "../Inngest.js"; import { InngestCommHandler } from "../InngestCommHandler.js"; import { SDKResponse, SDKResponseStatus } from "../../proto/src/components/connect/protobuf/connect.js"; import { parseTraceCtx } from "./util.js"; //#region src/components/connect/config.ts /** * Connection configuration preparation. * * Encapsulates signing key hashing, function config building, * InngestCommHandler creation, and connection data assembly — everything * needed before handing off to a connection strategy. */ const InngestBranchEnvironmentSigningKeyPrefix = "signkey-branch-"; /** * Collect per-app client + functions from ConnectApp definitions. */ function collectFunctions(apps) { const result = {}; for (const app of apps) { const client = app.client; if (result[client.id]) throw new Error(`Duplicate app id: ${client.id}`); result[client.id] = { client: app.client, functions: app.functions ?? client.funcs }; } return result; } /** * Prepare all connection configuration: signing keys, function configs, * connection data, and request handlers. */ function prepareConnectionConfig(apps, inngest) { const envName = inngest.env ?? getEnvironmentName(); const hashedSigningKey = inngest.signingKey ? hashSigningKey(inngest.signingKey) : void 0; if (inngest.signingKey && inngest.signingKey.startsWith(InngestBranchEnvironmentSigningKeyPrefix) && !envName) throw new Error("Environment is required when using branch environment signing keys"); const hashedFallbackKey = inngest.signingKeyFallback ? hashSigningKey(inngest.signingKeyFallback) : void 0; const capabilities = { trust_probe: "v1", connect: "v1" }; const functions = collectFunctions(apps); const functionConfigs = {}; for (const [appId, { client, functions: fns }] of Object.entries(functions)) functionConfigs[appId] = { client, functions: fns.flatMap((f) => f["getConfig"]({ baseUrl: new URL("wss://connect"), appPrefix: client.id, isConnect: true })) }; inngest[internalLoggerSymbol].debug({ functionSlugs: Object.entries(functionConfigs).map(([appId, { functions: fns }]) => { return JSON.stringify({ appId, functions: fns.map((f) => ({ id: f.id, stepUrls: Object.values(f.steps).map((s) => s.runtime["url"]) })) }); }) }, "Prepared sync data"); const connectionData = { manualReadinessAck: true, marshaledCapabilities: JSON.stringify(capabilities), apps: Object.entries(functionConfigs).map(([appId, { client, functions: fns }]) => ({ appName: appId, appVersion: client.appVersion, functions: new TextEncoder().encode(JSON.stringify(fns)) })) }; const requestHandlers = {}; for (const [appId, { client, functions: fns }] of Object.entries(functions)) { const inngestCommHandler = new InngestCommHandler({ client, functions: fns, frameworkName: "connect", defaultMaxRuntime: DefaultMaxRuntime.connect, skipSignatureValidation: true, handler: (msg) => { const asString = new TextDecoder().decode(msg.requestPayload); const parsed = parseFnData(JSON.parse(asString), void 0, inngest[internalLoggerSymbol]); const userTraceCtx = parseTraceCtx(msg.userTraceCtx); return { body() { return parsed; }, method() { return "POST"; }, headers(key) { switch (key) { case headerKeys.ContentLength.toString(): return asString.length.toString(); case headerKeys.InngestExpectedServerKind.toString(): return "connect"; case headerKeys.RequestVersion.toString(): return parsed.version.toString(); case headerKeys.RequestId.toString(): return msg.requestId; case headerKeys.InngestJobId.toString(): return msg.jobId; case headerKeys.Signature.toString(): return null; case headerKeys.TraceParent.toString(): return userTraceCtx?.traceParent ?? null; case headerKeys.TraceState.toString(): return userTraceCtx?.traceState ?? null; default: return null; } }, transformResponse({ body, headers, status }) { let sdkResponseStatus = SDKResponseStatus.DONE; switch (status) { case 200: sdkResponseStatus = SDKResponseStatus.DONE; break; case 206: sdkResponseStatus = SDKResponseStatus.NOT_COMPLETED; break; case 500: sdkResponseStatus = SDKResponseStatus.ERROR; break; } return SDKResponse.create({ requestId: msg.requestId, accountId: msg.accountId, envId: msg.envId, appId: msg.appId, status: sdkResponseStatus, body: new TextEncoder().encode(body), noRetry: headers[headerKeys.NoRetry] === "true", retryAfter: headers[headerKeys.RetryAfter], sdkVersion: `inngest-js:v${version}`, requestVersion: parseInt(headers[headerKeys.RequestVersion] ?? PREFERRED_ASYNC_EXECUTION_VERSION.toString(), 10), systemTraceCtx: msg.systemTraceCtx, userTraceCtx: msg.userTraceCtx, runId: msg.runId }); }, url() { const baseUrl = new URL("http://connect.inngest.com"); baseUrl.searchParams.set(queryKeys.FnId, msg.functionSlug); if (msg.stepId) baseUrl.searchParams.set(queryKeys.StepId, msg.stepId); return baseUrl; } }; } }); if (!inngestCommHandler.checkModeConfiguration()) throw new Error("Signing key is required"); requestHandlers[appId] = inngestCommHandler.createHandler(); } return { hashedSigningKey, hashedFallbackKey, envName, connectionData, requestHandlers }; } //#endregion export { prepareConnectionConfig }; //# sourceMappingURL=config.js.map