From 6631e95907f4ac163ade27568d916bce0a202cec Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 9 Aug 2023 10:40:26 +0200 Subject: [PATCH] feat: universal `env` shim --- README.md | 2 ++ src/env.ts | 39 +++++++++++++++++++++++++++++++++++++++ src/index.ts | 22 ++++++++++------------ test/index.test.ts | 2 ++ 4 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 src/env.ts diff --git a/README.md b/README.md index bab05a9..e114a44 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ const { isCI } = require('std-env') Available exports: +- `env` +- `nodeENV` - `hasTTY` - `hasWindow` - `isCI` diff --git a/src/env.ts b/src/env.ts new file mode 100644 index 0000000..ec497fd --- /dev/null +++ b/src/env.ts @@ -0,0 +1,39 @@ +const _envShim = Object.create(null); + +const _getEnv = (useShim?: boolean) => + globalThis.__env__ || + globalThis.process?.env || + (useShim ? _envShim : globalThis); + +export const env = new Proxy(_envShim, { + get(_, prop) { + const env = _getEnv(); + return env[prop as any] ?? _envShim[prop]; + }, + has(_, prop) { + const env = _getEnv(); + return prop in env || prop in _envShim; + }, + set(_, prop, value) { + const env = _getEnv(true); + env[prop as any] = value; + return true; + }, + deleteProperty(_, prop) { + if (!prop) { + return false; + } + const env = _getEnv(true); + delete env[prop as any]; + return true; + }, + ownKeys() { + const env = _getEnv(); + return Object.keys(env); + }, +}); + +export const nodeENV = + (typeof process !== "undefined" && process.env && process.env.NODE_ENV) || + env.NODE_ENV || + ""; diff --git a/src/index.ts b/src/index.ts index 1a55c63..84f6321 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,35 +1,34 @@ import { detectProvider, ProviderName } from "./providers"; +import { env, nodeENV } from "./env"; +export { env, nodeENV } from "./env"; export type { ProviderName, ProviderInfo } from "./providers"; -const processShim: typeof process = +const _process: typeof process = typeof process !== "undefined" ? process : ({} as typeof process); -const envShim = processShim.env || ({} as typeof process.env); +const envShim = _process.env || ({} as typeof process.env); const providerInfo = detectProvider(envShim); -const nodeENV = - (typeof process !== "undefined" && process.env && process.env.NODE_ENV) || ""; - /** Value of process.platform */ -export const platform = processShim.platform; +export const platform = _process.platform; /** Current provider name */ export const provider: ProviderName = providerInfo.name; /** Detect if `CI` environment variable is set or a provider CI detected */ -export const isCI = toBoolean(envShim.CI) || providerInfo.ci !== false; +export const isCI = toBoolean(env.CI) || providerInfo.ci !== false; /** Detect if stdout.TTY is available */ -export const hasTTY = toBoolean(processShim.stdout && processShim.stdout.isTTY); +export const hasTTY = toBoolean(_process.stdout && _process.stdout.isTTY); /** Detect if global `window` object is available */ export const hasWindow = typeof window !== "undefined"; /** Detect if `DEBUG` environment variable is set */ -export const isDebug = toBoolean(envShim.DEBUG); +export const isDebug = toBoolean(env.DEBUG); /** Detect if `NODE_ENV` environment variable is `test` */ -export const isTest = nodeENV === "test" || toBoolean(envShim.TEST); +export const isTest = nodeENV === "test" || toBoolean(env.TEST); /** Detect if `NODE_ENV` environment variable is `production` */ export const isProduction = nodeENV === "production"; @@ -38,8 +37,7 @@ export const isProduction = nodeENV === "production"; export const isDevelopment = nodeENV === "dev" || nodeENV === "development"; /** Detect if MINIMAL environment variable is set, running in CI or test or TTY is unavailable */ -export const isMinimal = - toBoolean(envShim.MINIMAL) || isCI || isTest || !hasTTY; +export const isMinimal = toBoolean(env.MINIMAL) || isCI || isTest || !hasTTY; /** Detect if process.platform is Windows */ export const isWindows = /^win/i.test(platform); diff --git a/test/index.test.ts b/test/index.test.ts index 86255b2..b485bbb 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -5,6 +5,8 @@ describe("std-env", () => { it("has expected exports", () => { expect(Object.keys(stdEnv)).toMatchInlineSnapshot(` [ + "env", + "nodeENV", "platform", "provider", "isCI",