diff --git a/README.md b/README.md index b258fde..a869836 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ making it ideal for cross-platform development. multiple runtimes. - **Validation:** Ensures environment variables are valid before usage. - **Error handling:** Provides clear error messages for unsupported runtimes or validation failures. -- **Optional environmental file loading:** Supports loading variables from custom .env files _(experimental)_ +- **Optional environmental file loading:** Supports loading variables from custom .env(or other filename if supplied) + files. ## Installation @@ -104,6 +105,13 @@ function isPositiveNumber(value: string): boolean { const timeout = validateAndGetEnv("TIMEOUT", isPositiveNumber); ``` +To automatically load environment variables at the start of the application. This only works for .env-files but is +customizable in the main setup function setupEnv() instead if different behavior is desired. + +```javascript +import "@cross/env/load.ts"; +``` + ## Configuration (optional) For more advanced use cases you can configure the behaviour of the library. The library defaults to showing console @@ -114,7 +122,7 @@ await setupEnv({ throwErrors: true, logWarnings: false, dotEnv: { - enabled: true, + enabled: false, path: ".env.local", allowQuotes: true, enableExpansion: true, diff --git a/deno.jsonc b/deno.jsonc index 7f4d742..fe37c4a 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,6 +1,6 @@ { "name": "@cross/env", - "version": "0.2.5", + "version": "0.2.6", "exports": "./mod.ts", "tasks": { diff --git a/lib/filehandler.ts b/lib/filehandler.ts index 21700ef..b657e21 100644 --- a/lib/filehandler.ts +++ b/lib/filehandler.ts @@ -7,7 +7,6 @@ import { readFile } from "node:fs/promises"; * * @param {Runtimes} currentRuntime - The current runtime environment. * @param {EnvOptions} options - setup options. - * @param {boolean} failSilentlyOnError - supress errors and warnings while reading file. * @returns {Record} A object of parsed environment variables. * @throws {UnsupportedEnvironmentError} If the runtime is unsupported and the 'throwErrors' flag is set. * @throws {FileReadError} If there's an error reading the .env file and the 'throwErrors' flag is set. @@ -15,7 +14,6 @@ import { readFile } from "node:fs/promises"; export async function loadEnvFile( currentRuntime: string, options: EnvOptions, - failSilentlyOnError: boolean, ): Promise> { const filePath = options.dotEnv?.path ? options.dotEnv.path : ".env"; let fileContent = ""; @@ -40,13 +38,11 @@ export async function loadEnvFile( break; } } catch (err) { - if (!failSilentlyOnError) { - if (options.throwErrors) { - throw new FileReadError(err.message); - } - if (options.logWarnings) { - console.warn(err.message); - } + if (options.throwErrors) { + throw new FileReadError(err.message); + } + if (options.logWarnings) { + console.warn(err.message); } } diff --git a/load.ts b/load.ts new file mode 100644 index 0000000..6d472fc --- /dev/null +++ b/load.ts @@ -0,0 +1,23 @@ +/** + * Automatically loads environment variables at the start of the application. + * + * By default, this script enables the loading of `.env` files, merging their values + * with the existing environment variables. This behavior is customizable in the + * main setup function if different behavior is desired. + * + * @module load + */ + +import { setupEnv } from "./mod.ts"; + +// Invoke the setupEnv function with default options for automatic environment variable loading. +// The `dotEnv` option is enabled by default to automatically load variables from a `.env` file. +try { + await setupEnv({ + dotEnv: { + enabled: true, + }, + }); +} catch (error) { + console.error("Failed to load environment variables:", error); +} diff --git a/mod.ts b/mod.ts index 527ec61..7756f01 100644 --- a/mod.ts +++ b/mod.ts @@ -30,7 +30,7 @@ const defaultOptions: EnvOptions = { throwErrors: false, // Errors are not thrown by default logWarnings: true, // Warnings are logged to the console by default dotEnv: { - enabled: true, // .env file loading enabled by default + enabled: false, // .env file loading disabled by default path: ".env", // Standard .env file location allowQuotes: true, // Allow quotes by default enableExpansion: true, // Enable variable expansion by default @@ -47,28 +47,25 @@ let logWarnings = defaultOptions.logWarnings; * @param {EnvOptions} options - setup options. */ export async function setupEnv(options?: EnvOptions) { - if (options) { - const mergedOptions = simpleMerge({}, defaultOptions, options); + const mergedOptions = simpleMerge(defaultOptions, options || {}); - throwErrors = mergedOptions.throwErrors!; - logWarnings = mergedOptions.logWarnings!; + throwErrors = mergedOptions?.throwErrors || defaultOptions.throwErrors; + logWarnings = mergedOptions?.logWarnings || defaultOptions.logWarnings; - if (mergedOptions.dotEnv?.enabled) { - const failSilentlyOnError = options.dotEnv?.enabled ? false : true; - const currentRuntime = getCurrentRuntime(); - const envVars = await loadEnvFile(currentRuntime, mergedOptions, failSilentlyOnError); + if (mergedOptions?.dotEnv?.enabled) { + const currentRuntime = getCurrentRuntime(); + const envVars = await loadEnvFile(currentRuntime, mergedOptions); - switch (currentRuntime) { - case "deno": - Object.entries(envVars).forEach(([key, value]) => Deno.env.set(key, value)); - break; - case "bun": - Object.entries(envVars).forEach(([key, value]) => Bun.env[key] = value); - break; - case "node": - Object.entries(envVars).forEach(([key, value]) => process.env[key] = value); - break; - } + switch (currentRuntime) { + case "deno": + Object.entries(envVars).forEach(([key, value]) => Deno.env.set(key, value)); + break; + case "bun": + Object.entries(envVars).forEach(([key, value]) => Bun.env[key] = value); + break; + case "node": + Object.entries(envVars).forEach(([key, value]) => process.env[key] = value); + break; } } }