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
JavaScript
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