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.

193 lines (191 loc) • 6.83 kB
import { __require } from "../_virtual/rolldown_runtime.js"; import { envKeys, headerKeys } from "./consts.js"; import { version } from "../version.js"; //#region src/helpers/env.ts function checkModeConfiguration({ internalLogger, mode, signingKey }) { if (mode === "cloud" && !signingKey) { internalLogger.error(`In cloud mode but no signing key found. For local dev, set the INNGEST_DEV=1 env var. For production, set the ${envKeys.InngestSigningKey} env var`); return false; } return true; } const normalizeUrl = (urlString, scheme = "http://") => { if (urlString === "undefined") throw new Error("URL undefined"); if (urlString.includes("://")) return urlString; return `${scheme}${urlString}`; }; /** * getEnvironmentName returns the suspected branch name for this environment by * searching through a set of common environment variables. * * This could be used to determine if we're on a branch deploy or not, though it * should be noted that we don't know if this is the default branch or not. */ const getEnvironmentName = (env = allProcessEnv()) => { /** * Order is important; more than one of these env vars may be set, so ensure * that we check the most specific, most reliable env vars first. */ return env[envKeys.InngestEnvironment] || env[envKeys.BranchName] || env[envKeys.VercelBranch] || env[envKeys.NetlifyBranch] || env[envKeys.CloudflarePagesBranch] || env[envKeys.RenderBranch] || env[envKeys.RailwayBranch]; }; const processEnv = (key) => { return allProcessEnv()[key]; }; /** * allProcessEnv returns the current process environment variables, or an empty * object if they cannot be read, making sure we support environments other than * Node such as Deno, too. * * Using this ensures we don't dangerously access `process.env` in environments * where it may not be defined, such as Deno or the browser. */ const allProcessEnv = () => { try { if (process.env) return process.env; } catch (_err) {} try { const env = Deno.env.toObject(); if (env) return env; } catch (_err) {} try { const env = Netlify.env.toObject(); if (env) return env; } catch (_err) {} return {}; }; /** * Generate a standardised set of headers based on input and environment * variables. * * */ const inngestHeaders = (opts) => { const sdkVersion = `inngest-js:v${version}`; const headers = { "Content-Type": "application/json", "User-Agent": sdkVersion, [headerKeys.SdkVersion]: sdkVersion }; if (opts?.framework) headers[headerKeys.Framework] = opts.framework; if (opts?.expectedServerKind) headers[headerKeys.InngestExpectedServerKind] = opts.expectedServerKind; const env = { ...allProcessEnv(), ...opts?.env }; const inngestEnv = opts?.inngestEnv || getEnvironmentName(env); if (inngestEnv) headers[headerKeys.Environment] = inngestEnv; const platform = getPlatformName(env); if (platform) headers[headerKeys.Platform] = platform; return { ...headers, ...opts?.client?.["headers"], ...opts?.extras }; }; /** * A set of checks that, given an environment, will return `true` if the current * environment is running on the platform with the given name. */ const platformChecks = { vercel: (env) => env[envKeys.IsVercel] === "1" || typeof EdgeRuntime === "string", netlify: (env) => env[envKeys.IsNetlify] === "true", "cloudflare-pages": (env) => env[envKeys.IsCloudflarePages] === "1", render: (env) => env[envKeys.IsRender] === "true", railway: (env) => Boolean(env[envKeys.RailwayEnvironment]) }; const getPlatformName = (env) => { return Object.keys(platformChecks).find((key) => { return platformChecks[key](env); }); }; /** * A unique symbol used to mark a custom fetch implementation. We wrap the * implementations to provide some extra control when handling errors. */ const CUSTOM_FETCH_MARKER = Symbol("Custom fetch implementation"); /** * Given a potential fetch function, return the fetch function to use based on * this and the environment. */ const getFetch = (logger, givenFetch) => { /** * If we've explicitly been given a fetch function, use that. */ if (givenFetch) { if (CUSTOM_FETCH_MARKER in givenFetch) return givenFetch; /** * We wrap the given fetch function to provide some extra control when * handling errors. */ const customFetch = async (...args) => { try { return await givenFetch(...args); } catch (err) { /** * Capture warnings that are not simple fetch failures and highlight * them for the user. * * We also use this opportunity to log the causing error, as code higher * up the stack will likely abstract this. */ if (!(err instanceof Error) || !err.message?.startsWith("fetch failed")) logger.error({ err }, "A request failed when using a custom fetch implementation; this may be a misconfiguration. Make sure that your fetch client is correctly bound to the global scope."); throw err; } }; /** * Mark the custom fetch implementation so that we can identify it later, in * addition to adding some runtime properties to it to make it seem as much * like the original fetch as possible. */ Object.defineProperties(customFetch, { [CUSTOM_FETCH_MARKER]: {}, name: { value: givenFetch.name }, length: { value: givenFetch.length } }); return customFetch; } /** * Browser or Node 18+ */ try { if (typeof globalThis !== "undefined" && "fetch" in globalThis) return fetch.bind(globalThis); } catch (_err) {} /** * Existing polyfilled fetch */ if (typeof fetch !== "undefined") return fetch; /** * Environments where fetch cannot be found and must be polyfilled */ return __require("cross-fetch"); }; /** * If `Response` isn't included in this environment, it's probably an earlier * Node env that isn't already polyfilling. This function returns either the * native `Response` or a polyfilled one. */ const getResponse = () => { if (typeof Response !== "undefined") return Response; return __require("cross-fetch").Response; }; /** * Given an unknown value, try to parse it as a `boolean`. Useful for parsing * environment variables that could be a selection of different values such as * `"true"`, `"1"`. * * If the value could not be confidently parsed as a `boolean` or was seen to be * `undefined`, this function returns `undefined`. */ const parseAsBoolean = (value) => { if (typeof value === "boolean") return value; if (typeof value === "number") return Boolean(value); if (typeof value === "string") { const trimmed = value.trim().toLowerCase(); if (trimmed === "undefined") return; if (["true", "1"].includes(trimmed)) return true; if (["false", "0"].includes(trimmed)) return false; } }; //#endregion export { allProcessEnv, checkModeConfiguration, getEnvironmentName, getFetch, getPlatformName, getResponse, inngestHeaders, normalizeUrl, parseAsBoolean, processEnv }; //# sourceMappingURL=env.js.map