{"_id":"better-envforge","name":"better-envforge","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"better-envforge","version":"1.0.0","description":"A fast, validated, zero-dependency environment configuration toolkit for Node.js","main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","bin":{"dot2env":"dist/cli.cjs"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs","default":"./dist/index.cjs"},"./config":{"import":"./dist/config.mjs","require":"./dist/config.cjs","default":"./dist/config.cjs"},"./config.js":{"import":"./dist/config.mjs","require":"./dist/config.cjs","default":"./dist/config.cjs"},"./package.json":"./package.json"},"scripts":{"build":"node scripts/build.js","dts-check":"tsc --project tests/types/tsconfig.json","lint":"standard","test:samples":"node samples/run-tests.js","test":"npm run build && npm run lint && npm run dts-check && tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000 && npm run test:samples","prepack":"npm run build","prepublishOnly":"npm test","prerelease":"npm test","release:check":"npm test && npm pack --dry-run"},"keywords":["dotenv","env","environment","configuration","validation","schema","variable-expansion","cli","typescript","twelve-factor"],"license":"BSD-2-Clause","sideEffects":["./dist/config.cjs","./dist/config.mjs"],"engines":{"node":">=20"},"publishConfig":{"access":"public"},"devDependencies":{"@types/node":"^20.19.0","esbuild":"^0.28.2","sinon":"^22.1.0","standard":"^17.1.2","tap":"^21.8.0","typescript":"^4.9.5"},"_id":"better-envforge@1.0.0","gitHead":"2fc7eac8ad77cbd5f7814355c7fa352dbcf3c358","_nodeVersion":"20.18.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-HrebdgYNOctfWIDvBIddENOxHtWLHwpG6T/9wPzMTT3DWpRuu+BdtEM+C0g8AgxW9kwYy9uLQ4KknRGnsALvDg==","shasum":"22e3ccf88ea5d47aaf0c2517193d8ed2a45ed489","tarball":"https://registry.npmjs.org/better-envforge/-/better-envforge-1.0.0.tgz","fileCount":13,"unpackedSize":353357,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCnfAgQn9WWpqVzYEqc5EYcs4DiFxpGxIy1yTN+Js8+KQIgCKx/znrYPWzZvBDP6UqjgaUQWUeAdUtta+nHlTIm3D8="}]},"_npmUser":{"name":"orcaoperation","email":"sowhatdowedonowlol@proton.me"},"directories":{},"maintainers":[{"name":"orcaoperation","email":"sowhatdowedonowlol@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/better-envforge_1.0.0_1789831198310_0.8562333406953144"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-19T15:19:58.173Z","1.0.0":"2026-09-19T15:19:58.499Z","modified":"2026-09-19T15:19:58.670Z"},"maintainers":[{"name":"orcaoperation","email":"sowhatdowedonowlol@proton.me"}],"description":"A fast, validated, zero-dependency environment configuration toolkit for Node.js","keywords":["dotenv","env","environment","configuration","validation","schema","variable-expansion","cli","typescript","twelve-factor"],"license":"BSD-2-Clause","readme":"# node-env-buffer\n\nFast, validated, zero-dependency environment configuration for Node.js.\n\nnode-env-buffer reads `.env` files into `process.env` or an isolated object while providing the controls production applications commonly need: safe variable expansion, required-variable checks, typed schema validation, asynchronous loading, parent-directory discovery, deterministic multi-file precedence, and a command runner.\n\nThe default parser and configuration behavior remain familiar to users of `dotenv`, while every extended feature is explicit and opt-in.\n\n## Highlights\n\n- Zero runtime dependencies\n- CommonJS and native ESM builds\n- Synchronous and asynchronous configuration APIs\n- Classic parser plus an optimized character-scanner parser\n- Ordered loading from multiple files\n- Safe variable expansion without command execution\n- Atomic required-variable checks\n- Dependency-free validation and typed coercion\n- Parent-directory file discovery for monorepos and nested applications\n- Custom target objects for isolation and testing\n- Structured load metadata and error collections\n- Production command runner with strict failure behavior\n- Built-in TypeScript declarations\n\n## Requirements\n\n- Node.js 20 or later\n\n## Installation\n\n```sh\nnpm install node-env-buffer\n```\n\n## Quick start\n\nCreate a `.env` file in the application directory:\n\n```dotenv\nAPP_NAME=payments-api\nPORT=3000\nLOG_LEVEL=info\n```\n\nLoad it before reading configuration:\n\n```js\nconst env = require('node-env-buffer')\n\nconst result = env.config()\n\nif (result.error) {\n  throw result.error\n}\n\nconsole.log(process.env.APP_NAME)\n```\n\nESM applications can use named or default imports:\n\n```js\nimport env, { config } from 'node-env-buffer'\n\nconfig()\n```\n\nFor side-effect loading before the rest of an ESM application is evaluated:\n\n```js\nimport 'node-env-buffer/config'\n```\n\n## Production configuration\n\nA production entry point can combine expansion, required keys, validation, and strict error handling:\n\n```js\nimport { config } from 'node-env-buffer'\n\nconst result = config({\n  path: ['.env.production.local', '.env.production'],\n  expand: true,\n  required: ['DATABASE_URL', 'PORT'],\n  strict: true,\n  quiet: true,\n  schema: {\n    DATABASE_URL: 'url',\n    PORT: {\n      type: 'integer',\n      min: 1,\n      max: 65535,\n      required: true\n    },\n    LOG_LEVEL: {\n      type: 'string',\n      enum: ['debug', 'info', 'warn', 'error'],\n      default: 'info'\n    }\n  }\n})\n\nconst { PORT, LOG_LEVEL } = result.validated\n```\n\nRaw values written to `process.env` remain strings. Coerced values are returned separately through `result.validated`.\n\n## Environment-file syntax\n\nnode-env-buffer supports the established `.env` syntax:\n\n```dotenv\n# Comments and blank lines are ignored.\nPLAIN=value\nEMPTY=\nSINGLE_QUOTED='literal value'\nDOUBLE_QUOTED=\"supports escaped\\nnewlines\"\nBACKTICKED=`multiline-friendly value`\nexport EXPORTED=value\nCOLON: value\nINLINE=value # comment\nHASH=\"value#inside-quotes\"\nMULTILINE=\"first line\nsecond line\"\n```\n\nKeys may contain letters, numbers, underscores, periods, and hyphens. Parsed values are strings. Existing environment values are preserved unless `override: true` is selected.\n\n## API\n\nnode-env-buffer exports eight functions:\n\n- `config()`\n- `configDotenv()`\n- `configAsync()`\n- `parse()`\n- `populate()`\n- `expand()`\n- `validate()`\n- `findUp()`\n\n### `config(options?)`\n\nReads environment files synchronously, parses and optionally expands them, validates the candidate environment, and commits values to the selected target.\n\n```js\nconst result = node-env-buffer.config({\n  path: '.env.local',\n  quiet: true\n})\n```\n\nThe result has the following shape:\n\n```ts\ninterface node-env-bufferConfigOutput<T> {\n  parsed: Record<string, string>\n  loaded: string[]\n  errors: Error[]\n  error?: Error\n  validated?: T\n}\n```\n\n`loaded` contains absolute paths for files read successfully. `errors` contains every load or processing error in encounter order. `error` is the primary error retained for conventional single-error handling.\n\n#### Configuration options\n\n| Option | Type | Default | Purpose |\n| --- | --- | --- | --- |\n| `path` | `string \\| URL \\| Array<string \\| URL>` | `<cwd>/.env` | File or ordered files to load. |\n| `cwd` | `string` | `process.cwd()` | Base directory for relative paths and discovery. |\n| `encoding` | `BufferEncoding` | `utf8` | File encoding. |\n| `processEnv` | `Record<string, string>` | `process.env` | Target object for loaded values. |\n| `override` | `boolean` | `false` | Replace existing values and let later files win. |\n| `quiet` | `boolean` | `false` | Suppress the injection summary. |\n| `debug` | `boolean` | `false` | Print diagnostic messages. |\n| `fast` | `boolean` | `false` | Select the optimized parser. |\n| `expand` | `boolean` | `false` | Expand variable references before validation. |\n| `required` | `string \\| string[]` | none | Require non-empty final values. |\n| `allowEmpty` | `boolean` | `false` | Permit required values to be empty strings. |\n| `schema` | `node-env-bufferSchema` | none | Validate and coerce the final environment. |\n| `strict` | `boolean` | `false` | Throw instead of returning processing errors. |\n| `searchUp` | `boolean \\| string` | `false` | Find `.env` or a named file in an ancestor directory. |\n| `stopDir` | `string` | filesystem root | Stop upward discovery at this directory. |\n| `secure` | `boolean` | `false` | Delegate encrypted configuration to an installed `@dotenvx/dotenvx`. |\n\n### `configAsync(options?)`\n\nProvides the same processing pipeline as `config()` but reads multiple files concurrently through the promise-based filesystem API.\n\n```js\nconst result = await node-env-buffer.configAsync({\n  path: ['.env.local', '.env'],\n  processEnv: {},\n  quiet: true\n})\n```\n\nUse `config()` during conventional process bootstrap when subsequent imports immediately depend on environment values. Use `configAsync()` when startup is already asynchronous or when several files are loaded from slower storage.\n\n### `configDotenv(options?)`\n\nRuns the local environment-file pipeline directly. `config()` normally delegates to this function, except when secure mode is enabled.\n\n### `parse(source, options?)`\n\nParses a string or `Buffer` without reading files or mutating an environment object.\n\n```js\nconst values = node-env-buffer.parse('HOST=localhost\\nPORT=3000')\n// { HOST: 'localhost', PORT: '3000' }\n```\n\nEnable the optimized scanner explicitly:\n\n```js\nconst values = node-env-buffer.parse(source, { fast: true })\n```\n\nThe scanner supports BOM-prefixed files, multiline quoted values, escaped quotes and backslashes, comments, `export` prefixes, and the same ordered duplicate-key behavior as the classic parser.\n\n### `populate(target, values, options?)`\n\nWrites values to a target object and returns only the values actually assigned.\n\n```js\nconst target = { PORT: '8080' }\n\nconst populated = node-env-buffer.populate(\n  target,\n  { PORT: '3000', HOST: 'localhost' },\n  { override: false }\n)\n\n// target:    { PORT: '8080', HOST: 'localhost' }\n// populated: { HOST: 'localhost' }\n```\n\nOwn properties are preserved by default, including properties whose value is `undefined`. Special property names are assigned safely without changing object prototypes.\n\n### `expand(values, options?)`\n\nReturns a new object with variable references expanded. It never executes commands and does not mutate its input.\n\n```dotenv\nHOST=localhost\nPORT=3000\nBASE_URL=http://${HOST}:${PORT}\nOPTIONAL=${UNSET:-fallback}\nLITERAL=\\$HOST\n```\n\nSupported expressions:\n\n| Expression | Meaning |\n| --- | --- |\n| `$NAME` | Resolve `NAME`. |\n| `${NAME}` | Resolve `NAME`. |\n| `${NAME-default}` | Use `default` when `NAME` is unset. |\n| `${NAME:-default}` | Use `default` when `NAME` is unset or empty. |\n| `\\$NAME` | Preserve `$NAME` literally. |\n\nExisting values in `processEnv` take precedence while references are resolved. Pass `override: true` to prefer local values:\n\n```js\nconst expanded = node-env-buffer.expand(values, {\n  processEnv: process.env,\n  override: true\n})\n```\n\nCircular references raise a `node-env-buffer_EXPANSION_CYCLE` error containing variable names but not their values. Shell expressions such as `$(command)` are left untouched.\n\n### `validate(values, schema)`\n\nValidates configuration and returns a new object containing the schema fields with requested coercions.\n\n```js\nconst settings = node-env-buffer.validate(process.env, {\n  APP_ENV: {\n    type: 'string',\n    enum: ['development', 'test', 'production'],\n    required: true\n  },\n  PORT: {\n    type: 'integer',\n    min: 1,\n    max: 65535,\n    default: 3000\n  },\n  ENABLE_CACHE: 'boolean',\n  CACHE_OPTIONS: 'json',\n  PUBLIC_URL: 'url'\n})\n```\n\nSupported types:\n\n| Type | Output | Accepted input |\n| --- | --- | --- |\n| `string` | `string` | Any defined value. |\n| `number` | `number` | A finite numeric value. |\n| `integer` | `number` | A safe integer. |\n| `boolean` | `boolean` | `true`, `false`, `1`, `0`, `yes`, `no`, `on`, or `off`. |\n| `json` | JSON value | Valid JSON text or an existing value. |\n| `url` | `string` | A URL accepted by the standard `URL` parser. |\n\nA schema rule can specify:\n\n```ts\ninterface node-env-bufferValidationRule {\n  type?: 'string' | 'number' | 'integer' | 'boolean' | 'json' | 'url'\n  required?: boolean\n  allowEmpty?: boolean\n  default?: unknown\n  enum?: readonly unknown[]\n  min?: number\n  max?: number\n  pattern?: RegExp | string\n  validate?: (value: unknown) => boolean | string | void\n  transform?: (value: unknown) => unknown\n}\n```\n\nA type shorthand such as `PORT: 'integer'` marks that field as required. Descriptor rules are optional unless `required: true` is set. Validation failures are collected in `error.issues`; built-in diagnostics identify keys and rules without including configuration values.\n\n### `findUp(filename?, options?)`\n\nFinds the nearest matching file from a directory toward the filesystem root:\n\n```js\nconst envPath = node-env-buffer.findUp('.env', {\n  cwd: __dirname,\n  stopDir: '/workspace'\n})\n```\n\nIt returns an absolute path or `undefined`. The equivalent configuration shortcut is:\n\n```js\nnode-env-buffer.config({ searchUp: true })\nnode-env-buffer.config({ searchUp: '.env.production' })\n```\n\n## Multi-file precedence\n\nFiles are parsed in the supplied order.\n\n```js\nnode-env-buffer.config({\n  path: ['.env.local', '.env']\n})\n```\n\nBy default:\n\n1. Values already present in the target are preserved.\n2. The first file defining a key wins.\n3. Later files add only keys that are still absent.\n\nWith `override: true`:\n\n1. File values replace values already present in the target.\n2. The last file defining a key wins.\n\nRequired checks and schema validation run against the final candidate environment before parsed values are committed. A required-key, expansion, or schema failure therefore cannot partially update the target.\n\n## Strict error handling\n\nWithout strict mode, the configuration result reports failures through `error` and `errors`, preserving compatibility with result-based startup handling:\n\n```js\nconst result = node-env-buffer.config({ path: '.env.production' })\n\nif (result.error) {\n  console.error(result.error.message)\n  process.exit(1)\n}\n```\n\nWith `strict: true`, the primary failure is thrown:\n\n```js\nnode-env-buffer.config({\n  path: '.env.production',\n  required: ['DATABASE_URL'],\n  strict: true\n})\n```\n\n## Isolated environments\n\nPassing `processEnv` avoids global mutation and is recommended for tests, build tools, and applications that maintain separate configuration contexts:\n\n```js\nconst environment = {}\n\nconst result = node-env-buffer.config({\n  path: '.env.test',\n  processEnv: environment,\n  quiet: true\n})\n```\n\n## Command-line interface\n\nRun a command with variables loaded from `.env`:\n\n```sh\nnode-env-buffer run -- node server.js\n```\n\nLoad multiple files:\n\n```sh\nnode-env-buffer run -f .env.local -f .env -- node server.js\n```\n\nRequire and expand configuration before the child starts:\n\n```sh\nnode-env-buffer run --expand --required DATABASE_URL,PORT -- node server.js\n```\n\nDiscover an ancestor file from a workspace package:\n\n```sh\nnode-env-buffer run --search-up -- npm test\n```\n\n### CLI options\n\n| Option | Purpose |\n| --- | --- |\n| `-f, --file <path>` | Load a file; repeat to load multiple files. |\n| `--cwd <path>` | Resolve files from a different directory. |\n| `--search-up[=<name>]` | Find `.env` or a named file in an ancestor directory. |\n| `--expand` | Expand variable references safely. |\n| `--required <names>` | Require comma-separated variables; repeatable. |\n| `--allow-empty` | Permit empty required values. |\n| `--override` | Replace existing environment values. |\n| `--strict` | Fail on any load or validation error. |\n| `--fast` | Use the optimized parser. |\n| `--secure` | Delegate encrypted loading to `@dotenvx/dotenvx`. |\n| `--debug` | Print diagnostics. |\n| `--quiet` | Suppress the injection summary. |\n| `-h, --help` | Show command help. |\n| `-v, --version` | Print the installed version. |\n\nThe `--` separator is required. The child process receives arguments directly and node-env-buffer propagates its exit status.\n\n## Environment-based options\n\nConfiguration defaults may be supplied with either the `node-env-buffer_CONFIG_` prefix or the legacy `DOTENV_CONFIG_` prefix. The `node-env-buffer_CONFIG_` value wins when both are present.\n\nSupported names:\n\n- `PATH`\n- `ENCODING`\n- `CWD`\n- `QUIET`\n- `DEBUG`\n- `OVERRIDE`\n- `SECURE`\n- `FAST`\n- `EXPAND`\n- `STRICT`\n- `SEARCH_UP`\n- `ALLOW_EMPTY`\n- `REQUIRED` as a comma-separated list\n\nFor example:\n\n```sh\nnode-env-buffer_CONFIG_PATH=.env.production \\\nnode-env-buffer_CONFIG_EXPAND=true \\\nnode-env-buffer_CONFIG_REQUIRED=DATABASE_URL,PORT \\\nnode server.js\n```\n\nDirect API options and CLI flags take precedence over environment defaults.\n\n## Security model\n\nnode-env-buffer treats environment files as configuration, not executable input.\n\n- Variable expansion does not execute commands.\n- Configuration values are not included in built-in validation errors.\n- Required-key and schema failures are atomic.\n- Special property names cannot alter object prototypes.\n- No network operation is performed by the core package.\n- Runtime dependencies are not installed.\n\nEnvironment files commonly contain secrets. Restrict their filesystem permissions, exclude them from source control, avoid printing parsed objects, and use the secret-management facilities of the deployment platform in production.\n\nEncrypted-value delegation is optional and requires a separately installed `@dotenvx/dotenvx` package:\n\n```sh\nnpm install @dotenvx/dotenvx\n```\n\n```js\nnode-env-buffer.config({ secure: true })\n```\n\n## TypeScript\n\nDeclarations are included with the package. Generic result types can describe validated output:\n\n```ts\nimport { config } from 'node-env-buffer'\n\ninterface Settings {\n  PORT: number\n  ENABLE_CACHE: boolean\n}\n\nconst result = config<Settings>({\n  schema: {\n    PORT: 'integer',\n    ENABLE_CACHE: 'boolean'\n  },\n  strict: true\n})\n\nresult.validated?.PORT.toFixed()\n```\n\nCompatibility type aliases beginning with `Dotenv` are retained for straightforward migration.\n\n## Migration from dotenv\n\nChange the package import:\n\n```diff\n- const dotenv = require('dotenv')\n- dotenv.config()\n+ const node-env-buffer = require('node-env-buffer')\n+ node-env-buffer.config()\n```\n\nUpdate preload imports:\n\n```diff\n- import 'dotenv/config'\n+ import 'node-env-buffer/config'\n```\n\nCore defaults remain the same: `.env` is read from the current working directory, values are strings, existing target keys are preserved, and multiple paths use first-file-wins precedence unless `override` is enabled.\n\nnode-env-buffer is an independent fork and is not the official `dotenv` distribution.\n\n## Development and verification\n\nInstall the locked development dependencies:\n\n```sh\nnpm ci\n```\n\nRun the complete pipeline:\n\n```sh\nnpm test\n```\n\nThe pipeline builds all module formats, checks JavaScript style, verifies TypeScript declarations, runs unit and integration tests, and executes the sample applications.\n\nRun sample programs directly:\n\n```sh\nnode samples/basic/test.js\nnode samples/features/test.js\n```\n\nVerify the package contents before publishing:\n\n```sh\nnpm pack --dry-run\n```\n\n## Project structure\n\n```text\nlib/          Runtime implementation and declarations\nscripts/      Reproducible build tooling\ntests/        Unit, integration, CLI, parser, and type tests\nsamples/      Executable consumer-style test programs\ndist/         Generated CommonJS, ESM, CLI, preload, and declaration files\n```\n\n## Upstream attribution\n\nnode-env-buffer is derived from [`dotenv`](https://github.com/motdotla/dotenv) and retains its BSD 2-Clause licensing terms. The fork adds independent APIs, packaging, tests, documentation, and release policy.\n\n## License\n\nBSD 2-Clause. See [LICENSE](LICENSE).\n","readmeFilename":"README.md","_rev":"1-8fcdb295a5b865101025c211eae05ed5"}