@fiberplane/hono-otel
Version:
Hono middleware to forward OpenTelemetry traces to a local instance of @fiberplane/studio
83 lines (82 loc) • 2.77 kB
JavaScript
/**
* In Hono-node environments, env vars are not available on the `env` object that's passed to `app.fetch`.
* This helper will also check process.env and Deno.env.toObject() and fallback to that if the env var is not present on the `env` object.
*
* If multiple keys are provided, the first key that exists will be returned.
*/
export function getFromEnv(honoEnv, key) {
const env = getPlatformSafeEnv(honoEnv);
if (typeof env !== "object" || env === null) {
return null;
}
const envRecord = env;
// Handle single string key
if (typeof key === "string") {
return envRecord?.[key] ?? null;
}
// Handle array of keys with precedence
for (const k of key) {
const value = envRecord?.[k];
if (value) {
return value;
}
}
return null;
}
/**
* Return `process.env` if we're in Node.js, `Deno.env.toObject()` if we're in Deno, otherwise `honoEnv`
*
* In the case of Deno, we merge the `Deno.env.toObject()` with the `honoEnv` object.
*
* Used to get the env object for accessing and recording env vars.
* This exists because environment variables are accessed differently across runtimes.
*
* @param honoEnv - The env object from the `app.fetch` method.
* @returns - Environment variables from the appropriate runtime source
*/
export function getPlatformSafeEnv(honoEnv) {
const hasProcessEnv = runtimeHasProcessEnv();
const hasDenoEnv = runtimeHasDenoEnv();
const isRunningInHonoNode = isHonoNodeEnv(honoEnv);
if (hasProcessEnv && isRunningInHonoNode) {
return process.env;
}
if (hasDenoEnv) {
const denoEnv = globalThis?.Deno?.env?.toObject?.();
return {
...(denoEnv ?? {}),
...(typeof honoEnv === "object" && honoEnv !== null ? honoEnv : {}),
};
}
return honoEnv;
}
function runtimeHasProcessEnv() {
if (typeof process !== "undefined" && typeof process.env !== "undefined") {
return true;
}
return false;
}
function runtimeHasDenoEnv() {
try {
const denoGlobal = globalThis.Deno;
return typeof denoGlobal?.env?.toObject === "function";
}
catch {
return false;
}
}
/**
* Helper to determine if the env is coming from a Hono node environment.
*
* In Node.js, the `env` passed to `app.fetch` is an object with keys "incoming" and "outgoing",
* one of which has circular references. We don't want to serialize this.
*/
function isHonoNodeEnv(env) {
if (typeof env !== "object" || env === null) {
return false;
}
const envKeys = Object.keys(env).map((key) => key.toLowerCase());
return (envKeys.length === 2 &&
envKeys.includes("incoming") &&
envKeys.includes("outgoing"));
}