UNPKG

@skyra/env-utilities

Version:

Functional utilities for reading and parsing environmental variables

1 lines 14.7 kB
{"version":3,"sources":["../../src/lib/env-loader.ts","../../src/lib/utils.ts","../../src/lib/setup.ts","../../src/setup.ts"],"names":["resolve","fileURLToPath","basename","expand","config"],"mappings":"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","file":"setup.cjs","sourcesContent":["import { config, type DotenvConfigOptions, type DotenvConfigOutput, type DotenvParseOutput } from 'dotenv';\nimport { expand } from 'dotenv-expand';\nimport { basename, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport interface EnvLoaderOptions extends Omit<DotenvConfigOptions, 'path'> {\n\t/**\n\t * You may specify a custom environment if `NODE_ENV` isn't sufficient.\n\t */\n\tenv?: string;\n\t/**\n\t * You may specify a required prefix for your dotenv variables (ex. `APP_`).\n\t */\n\tprefix?: string;\n\t/**\n\t * Specify a custom path if your file containing environment variables is located elsewhere.\n\t * Can also be an array of strings, specifying multiple paths.\n\t *\n\t * @default `path.resolve(process.cwd(), '.env')`\n\t *\n\t * @example with CJS\n\t * ```typescript\n\t * require('@skyra/env-utilities').setup({ path: '/custom/path/to/.env' })\n\t * ```\n\t * @example with ESM\n\t * ```typescript\n\t * import { setup } from '@skyra/env-utilities';\n\t *\n\t * const envFile = new URL('../.env', import.meta.url);\n\t * setup({ path: envFile })\n\t * ```\n\t */\n\tpath?: string | URL;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nconst packageVersion: string = '2.0.1';\n\nexport function loadEnvFiles(options?: EnvLoaderOptions): DotenvConfigOutput {\n\tconst log = options?.debug\n\t\t? (message: string) => console.debug(`[@skyra/env-utilities@${packageVersion}][DEBUG] ${message}`)\n\t\t: (_: string) => undefined;\n\n\t/**\n\t * @see {@linkplain https://github.com/facebook/create-react-app/blob/d960b9e38c062584ff6cfb1a70e1512509a966e7/packages/react-scripts/config/env.js#L18-L23}\n\t */\n\tif (!process.env.NODE_ENV) {\n\t\tthrow new Error('The NODE_ENV environment variable is required but was not specified.');\n\t}\n\n\tconst env = options?.env || process.env.NODE_ENV;\n\tconst dotenvPath = options?.path || resolve(process.cwd(), '.env');\n\n\t/**\n\t * @see {@linkplain https://github.com/facebook/create-react-app/blob/d960b9e38c062584ff6cfb1a70e1512509a966e7/packages/react-scripts/config/env.js#L25-L34}\n\t */\n\tconst dotenvFiles = [`${dotenvPath}.${env}.local`, `${dotenvPath}.${env}`, dotenvPath];\n\n\tif (process.env.NODE_ENV !== 'test') {\n\t\tdotenvFiles.splice(1, 0, `${dotenvPath}.local`);\n\t}\n\n\t/**\n\t * @see {@linkplain https://github.com/facebook/create-react-app/blob/d960b9e38c062584ff6cfb1a70e1512509a966e7/packages/react-scripts/config/env.js#L36-L49}\n\t */\n\tlet parsed: DotenvParseOutput = {};\n\n\tfor (const dotenvFile of dotenvFiles) {\n\t\tconst dotenvFileString = typeof dotenvFile === 'string' ? dotenvFile : fileURLToPath(dotenvFile);\n\n\t\tlog(`loading \\`${basename(dotenvFileString)}\\``);\n\n\t\tconst result = expand(\n\t\t\tconfig({\n\t\t\t\tdebug: options?.debug,\n\t\t\t\tencoding: options?.encoding,\n\t\t\t\tpath: dotenvFile\n\t\t\t})\n\t\t);\n\n\t\tif (result.error) {\n\t\t\tif ((result.error as FSError).code === 'ENOENT') {\n\t\t\t\tlog(`\\`${basename(dotenvFileString)}\\` file not found`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthrow result.error;\n\t\t}\n\n\t\tparsed = { ...result.parsed, ...parsed };\n\t}\n\n\t/**\n\t * @see {@linkplain https://github.com/facebook/create-react-app/blob/d960b9e38c062584ff6cfb1a70e1512509a966e7/packages/react-scripts/config/env.js#L72-L89}\n\t */\n\tif (options?.prefix) {\n\t\tconst prefixRegExp = new RegExp(`^${options.prefix}`, 'i');\n\t\tparsed = Object.keys(parsed)\n\t\t\t.filter((key) => {\n\t\t\t\tconst match = prefixRegExp.test(key);\n\t\t\t\tlog(`Prefix for key \\`${key}\\` ${match ? 'matches' : 'does not match'} \\`${options.prefix}\\``);\n\t\t\t\treturn match;\n\t\t\t})\n\t\t\t.reduce<DotenvParseOutput>((obj, key) => {\n\t\t\t\tobj[key] = parsed[key];\n\t\t\t\treturn obj;\n\t\t\t}, {});\n\t}\n\n\treturn {\n\t\tparsed\n\t};\n}\n\ninterface FSError extends Error {\n\tcode: string;\n}\n","import type { Env, EnvAny, EnvArray, EnvBoolean, EnvInteger, EnvNumber, EnvString } from './types';\n\nexport function envParseInteger(key: EnvInteger, defaultValue?: number): number;\nexport function envParseInteger(key: EnvInteger, defaultValue: number | null): number | null;\nexport function envParseInteger(key: EnvInteger, defaultValue?: number | null): number | null {\n\tconst value = process.env[key];\n\tif (!value) {\n\t\tif (defaultValue === undefined) throw new ReferenceError(`[ENV] ${key} - The key must be an integer, but is empty or undefined.`);\n\t\treturn defaultValue;\n\t}\n\n\tconst integer = Number(value);\n\tif (Number.isInteger(integer)) return integer;\n\tthrow new TypeError(`[ENV] ${key} - The key must be an integer, but received '${value}'.`);\n}\n\nexport function envParseNumber(key: EnvNumber, defaultValue?: number): number;\nexport function envParseNumber(key: EnvNumber, defaultValue: number | null): number | null;\nexport function envParseNumber(key: EnvNumber, defaultValue?: number | null): number | null {\n\tconst value = process.env[key];\n\tif (!value) {\n\t\tif (defaultValue === undefined) throw new ReferenceError(`[ENV] ${key} - The key must be a number, but is empty or undefined.`);\n\t\treturn defaultValue;\n\t}\n\n\tconst integer = Number(value);\n\tif (!Number.isNaN(integer)) return integer;\n\tthrow new TypeError(`[ENV] ${key} - The key must be a number, but received '${value}'.`);\n}\n\nexport function envParseBoolean(key: EnvBoolean, defaultValue?: boolean): boolean;\nexport function envParseBoolean(key: EnvBoolean, defaultValue: boolean | null): boolean | null;\nexport function envParseBoolean(key: EnvBoolean, defaultValue?: boolean | null): boolean | null {\n\tconst value = process.env[key];\n\tif (!value) {\n\t\tif (defaultValue === undefined) throw new ReferenceError(`[ENV] ${key} - The key must be a boolean, but is empty or undefined.`);\n\t\treturn defaultValue;\n\t}\n\n\tif (value.length === 4 && value.toLowerCase() === 'true') return true;\n\tif (value.length === 5 && value.toLowerCase() === 'false') return false;\n\tthrow new TypeError(`[ENV] ${key} - The key must be a boolean, but received '${value}'.`);\n}\n\nexport function envParseString<K extends EnvString>(key: K, defaultValue?: Env[K]): NonNullable<Env[K]>;\nexport function envParseString<K extends EnvString>(key: K, defaultValue: Env[K] | null): NonNullable<Env[K]> | null;\nexport function envParseString<K extends EnvString>(key: K, defaultValue?: Env[K] | null): NonNullable<Env[K]> | null {\n\tconst value = process.env[key];\n\tif (!value) {\n\t\tif (defaultValue === undefined) throw new ReferenceError(`[ENV] ${key} - The key must be a string, but is empty or undefined.`);\n\t\treturn defaultValue!;\n\t}\n\n\treturn value!;\n}\n\nexport function envParseArray(key: EnvArray, defaultValue?: string[]): string[];\nexport function envParseArray(key: EnvArray, defaultValue: string[] | null): string[] | null;\nexport function envParseArray(key: EnvArray, defaultValue?: string[] | null): string[] | null {\n\tconst value = process.env[key];\n\tif (!value) {\n\t\tif (defaultValue === undefined) throw new ReferenceError(`[ENV] ${key} - The key must be an array, but is empty or undefined.`);\n\t\treturn defaultValue;\n\t}\n\n\treturn value.split(' ');\n}\n\n/**\n * Checks if the value of the specified environment variable is null.\n * @param key - The name of the environment variable.\n * @returns Whether the value of the specified environment variable is:\n * - The string `\"0\"`\n * - The string `\"null\"`, case insensitive\n */\nexport function envIsNull(key: EnvAny): boolean {\n\tconst value = process.env[key];\n\treturn typeof value === 'string' && (value === '0' || (value.length === 4 && value.toLowerCase() === 'null'));\n}\n\n/**\n * Checks if the value of the specified environment variable is undefined.\n * @param key - The name of the environment variable.\n * @returns Whether the value of the specified environment variable is:\n * - `undefined`\n * - An empty string (`\"\"`)\n */\nexport function envIsUndefined(key: EnvAny): boolean {\n\tconst value = process.env[key];\n\treturn value === undefined || value.length === 0;\n}\n\n/**\n * Checks if the value of the specified environment variable is nullish.\n * @param key - The name of the environment variable.\n * @returns Whether the value of the specified environment variable is:\n * - `undefined`\n * - An empty string (`\"\"`)\n * - The string `\"0\"`\n * - The string `\"null\"`, case insensitive\n */\nexport function envIsNullish(key: EnvAny): boolean {\n\treturn envIsUndefined(key) || envIsNull(key);\n}\n\n/**\n * Checks if any of the specified environment variables is defined.\n * @param key - The name of the environment variable.\n * @returns Whether the value of any of the specified environment variables is a non-empty string\n */\nexport function envIsDefined(...keys: readonly EnvAny[]): boolean {\n\treturn keys.every((key) => !envIsUndefined(key));\n}\n","import type { DotenvConfigOutput } from 'dotenv';\nimport { fileURLToPath } from 'node:url';\nimport { loadEnvFiles, type EnvLoaderOptions } from './env-loader';\nimport { envIsDefined, envParseBoolean } from './utils';\n\nexport function setup(pathOrOptions?: string | URL | EnvSetupOptions): DotenvConfigOutput {\n\t// Unless explicitly defined, set NODE_ENV as development:\n\tprocess.env.NODE_ENV ??= 'development';\n\n\tlet options: EnvLoaderOptions;\n\tif (typeof pathOrOptions === 'undefined') {\n\t\toptions = {};\n\t} else if (typeof pathOrOptions === 'string') {\n\t\toptions = { path: pathOrOptions };\n\t} else if (typeof pathOrOptions === 'object') {\n\t\tif (pathOrOptions instanceof URL) {\n\t\t\toptions = { path: fileURLToPath(pathOrOptions) };\n\t\t} else {\n\t\t\tconst { path, ...rest } = pathOrOptions;\n\t\t\toptions = { path: typeof path === 'undefined' ? path : typeof path === 'string' ? path : fileURLToPath(path), ...rest };\n\t\t}\n\t} else {\n\t\tthrow new TypeError('Expected undefined, string, URL, or EnvSetupOptions');\n\t}\n\n\treturn loadEnvFiles({\n\t\tdebug: envIsDefined('DOTENV_DEBUG') ? envParseBoolean('DOTENV_DEBUG') : undefined,\n\t\tencoding: process.env.DOTENV_ENCODING,\n\t\tenv: process.env.DOTENV_ENV,\n\t\tpath: process.env.DOTENV_PATH,\n\t\tprefix: process.env.DOTENV_PREFIX,\n\t\t...options\n\t});\n}\n\nexport interface EnvSetupOptions extends Omit<EnvLoaderOptions, 'path'> {\n\t/**\n\t * You may specify a custom path if your file containing environment variables is located elsewhere.\n\t */\n\tpath?: string | URL;\n}\n\nexport type EnvSetupResult = DotenvConfigOutput;\n","import { setup } from './index';\n\nsetup();\n"]}