@karmaniverous/get-dotenv 5.0.0-1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,14 +1,12 @@
1
- # get-dotenv
2
-
3
- ## Requirements
4
-
5
- - Node.js >= 20 (this repository pins 22.19.0 for CI/reproducibility)
1
+ > **_Load, expand, and compose environment variables from a deterministic dotenv cascade, then execute commands under that context. Use `get-dotenv` as a library, a CLI, or a plugin-first host to build dotenv-aware tooling with cross‑platform shell control, CI‑friendly capture, and clear diagnostics._**
6
2
 
7
- ## API Reference
8
- Generated API documentation is hosted at:
9
- - https://docs.karmanivero.us/get-dotenv
3
+ # get-dotenv
10
4
 
11
- The site is built with TypeDoc from the source code in this repository.
5
+ [![npm version](https://img.shields.io/npm/v/@karmaniverous/get-dotenv.svg)](https://www.npmjs.com/package/@karmaniverous/get-dotenv)
6
+ ![Node Current](https://img.shields.io/node/v/@karmaniverous/get-dotenv) <!-- TYPEDOC_EXCLUDE -->
7
+ [![docs](https://img.shields.io/badge/docs-website-blue)](https://docs.karmanivero.us/get-dotenv)
8
+ [![changelog](https://img.shields.io/badge/changelog-latest-blue.svg)](https://github.com/karmaniverous/get-dotenv/tree/main/CHANGELOG.md)<!-- /TYPEDOC_EXCLUDE -->
9
+ [![license](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](https://github.com/karmaniverous/get-dotenv/tree/main/LICENSE.md)
12
10
 
13
11
  Load environment variables with a cascade of environment-aware dotenv files. You can:
14
12
 
@@ -44,6 +42,18 @@ You can always use `getdotenv` directly on the command line, but its REAL power
44
42
 
45
43
  When you plug your own [`commander`](https://www.npmjs.com/package/commander) CLI commands into the `getdotenv` base, they will execute within all of the environmental context created above!
46
44
 
45
+ ## Requirements
46
+
47
+ - Node.js >= 20 (this repository pins 22.19.0 for CI/reproducibility)
48
+
49
+ ## API Reference
50
+
51
+ Generated API documentation is hosted at:
52
+
53
+ - https://docs.karmanivero.us/get-dotenv
54
+
55
+ The site is built with TypeDoc from the source code in this repository.
56
+
47
57
  ## Testing
48
58
 
49
59
  This project uses Vitest with the V8 coverage provider. Run:
@@ -60,8 +70,7 @@ npm install @karmaniverous/get-dotenv
60
70
 
61
71
  ## Scaffold
62
72
 
63
- You can scaffold config files and a host-based CLI skeleton using the built-in
64
- init command. Templates are shipped with the package and copied verbatim.
73
+ You can scaffold config files and a host-based CLI skeleton using the built-in init command. Templates are shipped with the package and copied verbatim.
65
74
 
66
75
  Examples:
67
76
 
@@ -83,20 +92,13 @@ npx getdotenv init ./apps/toolbox \
83
92
 
84
93
  Collision flow (when a destination file exists):
85
94
 
86
- - Interactive prompt: [o]verwrite, [e]xample, [s]kip, or their “all” variants
87
- [O]/[E]/[S].
88
- - Non-interactive detection:
89
- - Treated as `--yes` (Skip All) unless `--force` is provided (Overwrite All).
90
- - Considered non-interactive when stdin or stdout is not a TTY OR when a
91
- CI-like environment variable is present (`CI`, `GITHUB_ACTIONS`,
92
- `BUILDKITE`, `TEAMCITY_VERSION`, `TF_BUILD`).
93
- - Precedence:
94
- - `--force` > `--yes` > auto-detect (non-interactive => Skip All).
95
+ - Interactive prompt: [o]verwrite, [e]xample, [s]kip, or their “all” variants [O]/[E]/[S].
96
+ - Non-interactive detection: Treated as `--yes` (Skip All) unless `--force` is provided (Overwrite All). Considered non-interactive when stdin or stdout is not a TTY OR when a CI-like environment variable is present (`CI`, `GITHUB_ACTIONS`, `BUILDKITE`, `TEAMCITY_VERSION`, `TF_BUILD`).
97
+ - Precedence: `--force` > `--yes` > auto-detect (non-interactive => Skip All).
95
98
  - Options overview:
96
99
  - `--config-format <json|yaml|js|ts>`
97
100
  - `--with-local` to generate `.local` alongside public config (JSON/YAML)
98
- - `--cli-name <string>` for token substitution (`__CLI_NAME__`) in the CLI
99
- skeleton
101
+ - `--cli-name <string>` for token substitution (`__CLI_NAME__`) in the CLI skeleton
100
102
  - `--force` to overwrite all; `--yes` to skip all
101
103
 
102
104
  Notes:
@@ -106,14 +108,15 @@ Notes:
106
108
 
107
109
  ## Usage
108
110
 
109
- ````js
111
+ ```js
110
112
  import { getDotenv } from '@karmaniverous/get-dotenv';
111
113
 
112
- const dotenv = await getDotenv(options);```
114
+ const dotenv = await getDotenv(options);
115
+ ```
113
116
 
114
117
  Options can be passed programmatically or set in a `getdotenv.config.json` file in your project root directory. The same file also sets default options for the `getdotenv` CLI or any child CLI you spawn from it.
115
118
 
116
- See the [child CLI example repo](https://github.com/karmaniverous/get-dotenv-child#configuration) for an extensiive discussion of the various config options and how & where to set them.
119
+ See the [child CLI example repo](https://github.com/karmaniverous/get-dotenv-child#configuration) for an extensive discussion of the various config options and how & where to set them.
117
120
 
118
121
  ## Dynamic Processing
119
122
 
@@ -126,10 +129,10 @@ export default {
126
129
  SOME_DYNAMIC_VARIABLE: (dotenv) => someLogic(dotenv),
127
130
  ANOTHER_DYNAMIC_VARIABLE: (dotenv) =>
128
131
  someOtherLogic(dotenv.SOME_DYNAMIC_VARIABLE),
129
- ONE_MORE_TIME: ({ DESTRUCTRED_VARIABLE, ANOTHER_DYNAMIC_VARIABLE }) =>
130
- DESTRUCTRED_VARIABLE + ANOTHER_DYNAMIC_VARIABLE,
132
+ ONE_MORE_TIME: ({ DESTRUCTURED_VARIABLE, ANOTHER_DYNAMIC_VARIABLE }) =>
133
+ DESTRUCTURED_VARIABLE + ANOTHER_DYNAMIC_VARIABLE,
131
134
  };
132
- ````
135
+ ```
133
136
 
134
137
  If the value corresponding to a key is a function, it will be executed with the current state of `dotenv` as its single argument and the result applied back to the `dotenv` object. Otherwise, the value will just be applied back to `dotenv`. (Although if you're going to do that then you might as well just create a public global variable in the first place.)
135
138
 
@@ -146,9 +149,7 @@ export default {
146
149
  };
147
150
  ```
148
151
 
149
- If `esbuild` is not installed and a direct import fails, get-dotenv attempts a
150
- simple fallback for single-file `.ts` modules without imports; otherwise it will
151
- throw with clear guidance to install `esbuild`.
152
+ If `esbuild` is not installed and a direct import fails, get-dotenv attempts a simple fallback for single-file `.ts` modules without imports; otherwise it will throw with clear guidance to install `esbuild`.
152
153
 
153
154
  Programmatic users can skip files entirely and pass dynamic variables directly:
154
155
 
@@ -175,8 +176,7 @@ Notes:
175
176
  - Install `esbuild` (`npm i -D esbuild`).
176
177
 
177
178
  - “Unable to load dynamic TypeScript file …”:
178
- - Install `esbuild`. A simple transpile fallback exists only for trivial
179
- single-file modules; any imports in `dynamic.ts` require `esbuild` bundling.
179
+ - Install `esbuild`. A simple transpile fallback exists only for trivial single-file modules; any imports in `dynamic.ts` require `esbuild` bundling.
180
180
 
181
181
  ## Command Line Interface
182
182
 
@@ -218,7 +218,8 @@ You can also use `getdotenv` from the command line:
218
218
  # --dynamic-path <string> dynamic variables path (.js or .ts; .ts is auto-compiled when esbuild is available, otherwise precompile)
219
219
  # --paths <string> dotenv-expanded delimited list of paths to dotenv directory (default: "./")
220
220
  # --paths-delimiter <string> paths delimiter string (default: " ")
221
- # --paths-delimiter-pattern <string> paths delimiter regex pattern# --private-token <string> dotenv-expanded token indicating private variables (default: "local")
221
+ # --paths-delimiter-pattern <string> paths delimiter regex pattern
222
+ # --private-token <string> dotenv-expanded token indicating private variables (default: "local")
222
223
  # --vars-delimiter <string> vars delimiter string (default: " ")
223
224
  # --vars-delimiter-pattern <string> vars delimiter regex pattern
224
225
  # --vars-assignor <string> vars assignment operator string (default: "=")
@@ -277,7 +278,7 @@ Note that `batch` executes its commands in sequence, rather than in parallel!
277
278
 
278
279
  To understand why, imagine running `npm install` in a dozen repos from the same command line. The visual feedback would be impossible to follow, and if something broke you'd have a really hard time figuring out why.
279
280
 
280
- Instead, everything runs in sequence, and you get a clear record of exactly what heppened and where. Also worth noting that many complex processes are resource hogs: you would not _want_ to run a dozen Serverless deployments at once!
281
+ Instead, everything runs in sequence, and you get a clear record of exactly what happened and where. Also worth noting that many complex processes are resource hogs: you would not _want_ to run a dozen Serverless deployments at once!
281
282
 
282
283
  Meanwhile, [this issue](https://github.com/karmaniverous/get-dotenv/issues/7) documents the parallel-processing option requirement. Feel free to submit a PR!
283
284
 
@@ -285,9 +286,7 @@ Meanwhile, [this issue](https://github.com/karmaniverous/get-dotenv/issues/7) do
285
286
 
286
287
  ### Authoring npm scripts and the `-c`/`--cmd` alias
287
288
 
288
- When you run commands via `npm run`, flags after `--` are forwarded to your script
289
- and may be applied to the inner shell command instead of `getdotenv` unless you
290
- structure your script carefully.
289
+ When you run commands via `npm run`, flags after `--` are forwarded to your script and may be applied to the inner shell command instead of `getdotenv` unless you structure your script carefully.
291
290
 
292
291
  - Anti-pattern:
293
292
 
@@ -301,22 +300,17 @@ structure your script carefully.
301
300
  ```json
302
301
  { "scripts": { "script": "getdotenv -c 'echo $APP_SETTING'" } }
303
302
  ```
304
- Now `npm run script -- -e dev` applies `-e` to `getdotenv`, which loads and expands
305
- variables before executing the inner command.
303
+ Now `npm run script -- -e dev` applies `-e` to `getdotenv`, which loads and expands variables before executing the inner command.
306
304
 
307
305
  Notes:
308
306
 
309
307
  - `-c`/`--cmd` is an alias of the `cmd` subcommand; do not use both in a single invocation.
310
- - On POSIX shells, prefer single quotes to prevent the outer shell from expanding `$VAR`
311
- before Node sees it. On PowerShell, single quotes are also literal.
312
- - Script-level shell overrides (`scripts[name].shell`) still take precedence over the global
313
- `--shell`.
308
+ - On POSIX shells, prefer single quotes to prevent the outer shell from expanding `$VAR` before Node sees it. On PowerShell, single quotes are also literal.
309
+ - Script-level shell overrides (`scripts[name].shell`) still take precedence over the global `--shell`.
314
310
 
315
311
  Important:
316
312
 
317
- - When using the parent alias `--cmd` with a Node eval payload, quote the entire
318
- payload as a single token so Commander does not treat `-e/--eval` as
319
- getdotenv’s `-e, --env` flag.
313
+ - When using the parent alias `--cmd` with a Node eval payload, quote the entire payload as a single token so Commander does not treat `-e/--eval` as getdotenv’s `-e, --env` flag.
320
314
  - POSIX example:
321
315
  ```
322
316
  getdotenv --cmd 'node -e "console.log(process.env.APP_SETTING ?? \"\")"'
@@ -325,23 +319,19 @@ Important:
325
319
  ```
326
320
  getdotenv --cmd 'node -e "console.log(process.env.APP_SETTING ?? \"\")"'
327
321
  ```
328
- - If you do not need to pass additional parent flags after the command, you can
329
- prefer the subcommand form instead:
322
+ - If you do not need to pass additional parent flags after the command, you can prefer the subcommand form instead:
330
323
  ```
331
324
  getdotenv --shell-off cmd node -e "console.log(process.env.APP_SETTING ?? '')"
332
325
  ```
333
326
 
334
327
  Diagnostics and CI capture:
335
328
 
336
- - To capture child stdout/stderr deterministically (e.g., in CI), either set
337
- the environment variable `GETDOTENV_STDIO=pipe` or pass `--capture`. Outputs
338
- are buffered and re-emitted after completion.
329
+ - To capture child stdout/stderr deterministically (e.g., in CI), either set the environment variable `GETDOTENV_STDIO=pipe` or pass `--capture`. Outputs are buffered and re-emitted after completion.
339
330
  - For debugging environment composition, use:
340
331
  ```
341
332
  getdotenv --trace [keys...] cmd node -e "0"
342
333
  ```
343
- When provided without keys, `--trace` emits a concise origin line for every
344
- key (parent | dotenv | unset) to stderr before the child process launches.
334
+ When provided without keys, `--trace` emits a concise origin line for every key (parent | dotenv | unset) to stderr before the child process launches.
345
335
 
346
336
  ---
347
337
 
@@ -349,21 +339,17 @@ Diagnostics and CI capture:
349
339
 
350
340
  - [Cascade and precedence](./guides/cascade.md)
351
341
  - [Shell execution behavior and quoting](./guides/shell.md)
342
+ - [Config files and overlays](./guides/config.md)
343
+ - [Plugin-first host and plugins](./guides/plugins.md)
352
344
 
353
345
  The guides are also included in the [hosted API docs](https://docs.karmanivero.us/get-dotenv).
354
346
 
355
- ---
356
-
357
347
  ## Generated CLI
358
348
 
359
- This package still supports generating a standalone CLI for your projects.
360
- For most use cases we recommend the new plugin-first host because it resolves
361
- dotenv context once per invocation, supports composable plugins, and provides
362
- better subprocess control and diagnostics. If you prefer a thin, fixed
363
- command surface with defaults baked into config, the generated CLI can be a
364
- good fit.
349
+ This package still supports generating a standalone CLI for your projects. For most use cases we recommend the new plugin-first host because it resolves dotenv context once per invocation, supports composable plugins, and provides better subprocess control and diagnostics. If you prefer a thin, fixed command surface with defaults baked into config, the generated CLI can be a good fit.
350
+
351
+ See the [Generated CLI guide](https://docs.karmanivero.us/get-dotenv/guides/generated-cli) for details
365
352
 
366
- See the Generated CLI guide for details:
367
- https://docs.karmanivero.us/get-dotenv/guides/generated-cli
353
+ ---
368
354
 
369
355
  See more great templates & tools on [my GitHub Profile](https://github.com/karmaniverous)!
package/dist/index.cjs CHANGED
@@ -498,7 +498,8 @@ const cmdCommand$1 = new commander.Command()
498
498
  .description('execute command, conflicts with --command option (default subcommand)')
499
499
  .enablePositionalOptions()
500
500
  .passThroughOptions()
501
- .action(async (_options, thisCommand) => {
501
+ .argument('[command...]')
502
+ .action(async (commandParts, _options, thisCommand) => {
502
503
  if (!thisCommand.parent)
503
504
  throw new Error(`unable to resolve parent command`);
504
505
  if (!thisCommand.parent.parent)
@@ -511,7 +512,12 @@ const cmdCommand$1 = new commander.Command()
511
512
  const pkgCwd = !!raw.pkgCwd;
512
513
  const rootPath = typeof raw.rootPath === 'string' ? raw.rootPath : './';
513
514
  // Execute command.
514
- const command = thisCommand.args.join(' ');
515
+ const args = Array.isArray(commandParts) ? commandParts : [];
516
+ // When no positional tokens are provided (e.g., option form `-c/--command`),
517
+ // the preSubcommand hook handles execution. Avoid a duplicate call here.
518
+ if (args.length === 0)
519
+ return;
520
+ const command = args.map(String).join(' ');
515
521
  await execShellCommandBatch({
516
522
  command: resolveCommand(getDotenvCliOptions.scripts, command),
517
523
  getDotenvCliOptions,
@@ -578,8 +584,9 @@ const cmdCommand = new commander.Command()
578
584
  .configureHelp({ showGlobalOptions: true })
579
585
  .enablePositionalOptions()
580
586
  .passThroughOptions()
581
- .action(async (_options, thisCommand) => {
582
- const args = thisCommand.args;
587
+ .argument('[command...]')
588
+ .action(async (commandParts, _options, thisCommand) => {
589
+ const args = Array.isArray(commandParts) ? commandParts : [];
583
590
  if (args.length === 0)
584
591
  return;
585
592
  if (!thisCommand.parent)
package/dist/index.mjs CHANGED
@@ -495,7 +495,8 @@ const cmdCommand$1 = new Command()
495
495
  .description('execute command, conflicts with --command option (default subcommand)')
496
496
  .enablePositionalOptions()
497
497
  .passThroughOptions()
498
- .action(async (_options, thisCommand) => {
498
+ .argument('[command...]')
499
+ .action(async (commandParts, _options, thisCommand) => {
499
500
  if (!thisCommand.parent)
500
501
  throw new Error(`unable to resolve parent command`);
501
502
  if (!thisCommand.parent.parent)
@@ -508,7 +509,12 @@ const cmdCommand$1 = new Command()
508
509
  const pkgCwd = !!raw.pkgCwd;
509
510
  const rootPath = typeof raw.rootPath === 'string' ? raw.rootPath : './';
510
511
  // Execute command.
511
- const command = thisCommand.args.join(' ');
512
+ const args = Array.isArray(commandParts) ? commandParts : [];
513
+ // When no positional tokens are provided (e.g., option form `-c/--command`),
514
+ // the preSubcommand hook handles execution. Avoid a duplicate call here.
515
+ if (args.length === 0)
516
+ return;
517
+ const command = args.map(String).join(' ');
512
518
  await execShellCommandBatch({
513
519
  command: resolveCommand(getDotenvCliOptions.scripts, command),
514
520
  getDotenvCliOptions,
@@ -575,8 +581,9 @@ const cmdCommand = new Command()
575
581
  .configureHelp({ showGlobalOptions: true })
576
582
  .enablePositionalOptions()
577
583
  .passThroughOptions()
578
- .action(async (_options, thisCommand) => {
579
- const args = thisCommand.args;
584
+ .argument('[command...]')
585
+ .action(async (commandParts, _options, thisCommand) => {
586
+ const args = Array.isArray(commandParts) ? commandParts : [];
580
587
  if (args.length === 0)
581
588
  return;
582
589
  if (!thisCommand.parent)
package/package.json CHANGED
@@ -224,5 +224,5 @@
224
224
  },
225
225
  "type": "module",
226
226
  "types": "dist/index.d.ts",
227
- "version": "5.0.0-1"
227
+ "version": "5.0.0"
228
228
  }