@karmaniverous/get-dotenv 7.0.6 → 7.0.8

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.
Files changed (51) hide show
  1. package/dist/chunks/{createCli-BkHLeYXL.mjs → createCli-CUPiFVdZ.mjs} +27 -10
  2. package/dist/chunks/index-CNXekCQC.mjs +96 -0
  3. package/dist/chunks/{index-Dd6S1nZ-.mjs → index-DnG3N6yj.mjs} +6 -6
  4. package/dist/chunks/{loader-V1vbmtyw.mjs → loader-C3DtD6HB.mjs} +4 -2
  5. package/dist/chunks/{readDotenvCascade-Dgx4SC1p.mjs → readDotenvCascade-CfFPgLCp.mjs} +52 -21
  6. package/dist/chunks/{readMergedOptions-CraAnYdB.mjs → readMergedOptions-BT1C87_u.mjs} +53 -13
  7. package/dist/chunks/{resolveCliOptions-BMBkWDYJ.mjs → resolveCliOptions-BbfouWSK.mjs} +1 -1
  8. package/dist/chunks/{spawnEnv-CKgnHGpr.mjs → spawnEnv-DvisqPiU.mjs} +28 -3
  9. package/dist/chunks/{types-BthqmnDr.mjs → types-BkQxnyZK.mjs} +1 -1
  10. package/dist/cli.d.ts +29 -8
  11. package/dist/cli.mjs +11 -15
  12. package/dist/cliHost.d.ts +29 -8
  13. package/dist/cliHost.mjs +6 -6
  14. package/dist/config.d.ts +1 -1
  15. package/dist/config.mjs +1 -1
  16. package/dist/env-overlay.d.ts +13 -9
  17. package/dist/env-overlay.mjs +2 -2
  18. package/dist/getdotenv.cli.mjs +11 -15
  19. package/dist/index.d.ts +30 -9
  20. package/dist/index.mjs +31 -23
  21. package/dist/plugins-aws.d.ts +12 -1
  22. package/dist/plugins-aws.mjs +8 -7
  23. package/dist/plugins-batch.d.ts +28 -1
  24. package/dist/plugins-batch.mjs +202 -68
  25. package/dist/plugins-cmd.d.ts +12 -1
  26. package/dist/plugins-cmd.mjs +6 -6
  27. package/dist/plugins-init.d.ts +12 -1
  28. package/dist/plugins-init.mjs +3 -3
  29. package/dist/plugins.d.ts +14 -1
  30. package/dist/plugins.mjs +10 -14
  31. package/package.json +40 -40
  32. package/schema/getdotenv.config.schema.json +207 -0
  33. package/dist/chunks/AwsRestJsonProtocol-4m7HHwvS.mjs +0 -1026
  34. package/dist/chunks/externalDataInterceptor-DyDNbv-D.mjs +0 -19
  35. package/dist/chunks/getSSOTokenFromFile-CkYcEieD.mjs +0 -22
  36. package/dist/chunks/index-B35hOhgq.mjs +0 -669
  37. package/dist/chunks/index-B3fM_U6F.mjs +0 -349
  38. package/dist/chunks/index-B_yJRqty.mjs +0 -541
  39. package/dist/chunks/index-BuxEK_Z4.mjs +0 -12529
  40. package/dist/chunks/index-C58EanKv.mjs +0 -383
  41. package/dist/chunks/index-CjWZ4uNg.mjs +0 -103
  42. package/dist/chunks/index-CsI5JuIM.mjs +0 -188
  43. package/dist/chunks/index-D-a5vkZL.mjs +0 -82
  44. package/dist/chunks/index-D6iVe1wh.mjs +0 -946
  45. package/dist/chunks/index-Dl8qC51H.mjs +0 -290
  46. package/dist/chunks/index-FT37CtcF.mjs +0 -31
  47. package/dist/chunks/index-QkVZTs6l.mjs +0 -519
  48. package/dist/chunks/loadSso-DF7GLUZf.mjs +0 -488
  49. package/dist/chunks/package-DbbYaehr.mjs +0 -5
  50. package/dist/chunks/parseKnownFiles-BZNrX_JE.mjs +0 -23
  51. package/dist/chunks/sdk-stream-mixin-BL49AxZx.mjs +0 -307
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
- export { c as createCli } from './chunks/createCli-BkHLeYXL.mjs';
1
+ export { c as createCli } from './chunks/createCli-CUPiFVdZ.mjs';
2
2
  import 'zod';
3
3
  import 'path';
4
- import './chunks/loader-V1vbmtyw.mjs';
4
+ import './chunks/loader-C3DtD6HB.mjs';
5
5
  import 'fs-extra';
6
6
  import 'package-directory';
7
7
  import 'url';
@@ -13,27 +13,23 @@ import './chunks/loadModuleDefault-Dj8B3Stt.mjs';
13
13
  import 'crypto';
14
14
  import '@commander-js/extra-typings';
15
15
  import 'nanoid';
16
- import './chunks/readMergedOptions-CraAnYdB.mjs';
17
- import './chunks/readDotenvCascade-Dgx4SC1p.mjs';
16
+ import './chunks/readMergedOptions-BT1C87_u.mjs';
17
+ import './chunks/readDotenvCascade-CfFPgLCp.mjs';
18
18
  import 'dotenv';
19
19
  import 'execa';
20
20
  import './chunks/helpConfig-CGejgwWW.mjs';
21
- import './chunks/resolveCliOptions-BMBkWDYJ.mjs';
21
+ import './chunks/resolveCliOptions-BbfouWSK.mjs';
22
22
  import './chunks/validate-CDl0rE6k.mjs';
23
23
  import './plugins-aws.mjs';
24
- import './chunks/spawnEnv-CKgnHGpr.mjs';
25
- import './chunks/index-BuxEK_Z4.mjs';
26
- import 'node:os';
27
- import 'node:fs/promises';
28
- import 'node:stream';
29
- import 'node:crypto';
30
- import 'node:fs';
31
- import 'node:https';
32
- import 'node:process';
24
+ import './chunks/spawnEnv-DvisqPiU.mjs';
25
+ import './chunks/index-CNXekCQC.mjs';
26
+ import '@aws-sdk/client-sts';
33
27
  import './plugins-batch.mjs';
34
28
  import './chunks/invoke-DuRPU1oC.mjs';
35
29
  import 'globby';
36
- import './chunks/index-Dd6S1nZ-.mjs';
30
+ import 'os';
31
+ import './chunks/index-DnG3N6yj.mjs';
37
32
  import './plugins-init.mjs';
33
+ import 'node:process';
38
34
  import 'readline/promises';
39
35
  import 'node:url';
package/dist/cliHost.d.ts CHANGED
@@ -287,7 +287,7 @@ interface RootOptionsShape {
287
287
  */
288
288
  trace?: boolean | string[];
289
289
  /** Paths to search for dotenv files (space-delimited string or array). */
290
- paths?: string;
290
+ paths?: string | string[];
291
291
  /** Delimiter for paths string (default: space). */
292
292
  pathsDelimiter?: string;
293
293
  /** Regex pattern for paths delimiter. */
@@ -384,7 +384,7 @@ type ProcessEnv = Record<string, string | undefined>;
384
384
  * and the selected environment (if any), and returns either a string to set
385
385
  * or `undefined` to unset/skip the variable.
386
386
  */
387
- type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | undefined;
387
+ type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | null | undefined;
388
388
  /**
389
389
  * A map of dynamic variable definitions.
390
390
  * Keys are variable names; values are either literal strings or functions.
@@ -480,6 +480,12 @@ interface ResolveAndLoadOptions {
480
480
  * @default true
481
481
  */
482
482
  runAfterResolve?: boolean;
483
+ /**
484
+ * Name of the invoked subcommand (plugin namespace). When provided,
485
+ * only the matching plugin subtree runs afterResolve hooks.
486
+ * When omitted, all plugins run afterResolve (backward compatibility).
487
+ */
488
+ invokedSubcommand?: string;
483
489
  }
484
490
  /**
485
491
  * Structural public interface for the host exposed to plugins.
@@ -573,6 +579,11 @@ interface GetDotenvCliPlugin<TOptions extends GetDotenvOptions = GetDotenvOption
573
579
  * After the dotenv context is resolved, initialize any clients/secrets
574
580
  * or attach per-plugin state under ctx.plugins (by convention).
575
581
  * Runs parent → children (pre-order).
582
+ *
583
+ * **Scoping**: When the host provides an invoked subcommand filter,
584
+ * afterResolve only fires for plugins whose namespace matches the
585
+ * invoked command path. A plugin's afterResolve should never produce
586
+ * side effects for commands outside its subtree.
576
587
  */
577
588
  afterResolve?: (cli: GetDotenvCliPublic<TOptions, TArgs, TOpts, TGlobal>, ctx: GetDotenvCliCtx<TOptions>) => void | Promise<void>;
578
589
  /** Zod schema for this plugin's config slice (from config.plugins[…]). */
@@ -812,10 +823,14 @@ declare class GetDotenvCli<TOptions extends GetDotenvOptions = GetDotenvOptions,
812
823
  * Resolve options (strict) and compute dotenv context.
813
824
  * Stores the context on the instance under a symbol.
814
825
  *
815
- * Options:
816
- * - opts.runAfterResolve (default true): when false, skips running plugin
817
- * afterResolve hooks. Useful for top-level help rendering to avoid
818
- * long-running side-effects while still evaluating dynamic help text.
826
+ * @param customOptions - Partial options to overlay for this invocation.
827
+ * @param opts - Optional resolver behavior switches.
828
+ * - `runAfterResolve` (default `true`): when false, skips running plugin
829
+ * afterResolve hooks. Useful for top-level help rendering to avoid
830
+ * long-running side-effects while still evaluating dynamic help text.
831
+ * - `invokedSubcommand`: when provided, only the plugin subtree whose
832
+ * namespace matches this name runs afterResolve hooks. When omitted,
833
+ * all plugins run afterResolve (backward compatibility).
819
834
  */
820
835
  resolveAndLoad(customOptions?: Partial<TOptions>, opts?: ResolveAndLoadOptions): Promise<GetDotenvCliCtx<TOptions>>;
821
836
  /**
@@ -887,9 +902,15 @@ declare class GetDotenvCli<TOptions extends GetDotenvOptions = GetDotenvOptions,
887
902
  */
888
903
  install(): Promise<void>;
889
904
  /**
890
- * Run afterResolve hooks for all plugins (parent → children).
905
+ * Run afterResolve hooks for registered plugins (parent → children).
906
+ * When {@link commandPath} is provided, only the matching branch of the
907
+ * plugin tree runs; otherwise all plugins run (backward compatibility).
908
+ *
909
+ * The path is walked segment-by-segment against the plugin tree.
910
+ * Intermediate matches run their own afterResolve hook.
911
+ * The deepest match runs afterResolve for itself and all its descendants.
891
912
  */
892
- private _runAfterResolve;
913
+ _runAfterResolve(ctx: GetDotenvCliCtx<TOptions>, commandPath?: string[]): Promise<void>;
893
914
  }
894
915
 
895
916
  /** src/cliHost/getRootCommand.ts
package/dist/cliHost.mjs CHANGED
@@ -1,12 +1,12 @@
1
- export { G as GetDotenvCli, g as definePlugin, r as readMergedOptions } from './chunks/readMergedOptions-CraAnYdB.mjs';
2
- export { b as buildSpawnEnv, r as resolveCommand, a as resolveShell, c as runCommand, d as runCommandResult, s as shouldCapture } from './chunks/spawnEnv-CKgnHGpr.mjs';
3
- export { b as baseGetDotenvCliOptions, r as resolveCliOptions } from './chunks/resolveCliOptions-BMBkWDYJ.mjs';
4
- export { d as defineScripts, g as groupPlugins } from './chunks/types-BthqmnDr.mjs';
1
+ export { G as GetDotenvCli, d as definePlugin, r as readMergedOptions } from './chunks/readMergedOptions-BT1C87_u.mjs';
2
+ export { b as buildSpawnEnv, r as resolveCommand, a as resolveShell, c as runCommand, d as runCommandResult, s as shouldCapture } from './chunks/spawnEnv-DvisqPiU.mjs';
3
+ export { b as baseGetDotenvCliOptions, r as resolveCliOptions } from './chunks/resolveCliOptions-BbfouWSK.mjs';
4
+ export { d as defineScripts, g as groupPlugins } from './chunks/types-BkQxnyZK.mjs';
5
5
  export { t as toHelpConfig } from './chunks/helpConfig-CGejgwWW.mjs';
6
6
  export { c as composeNestedEnv, m as maybePreserveNodeEvalArgv, s as stripOne } from './chunks/invoke-DuRPU1oC.mjs';
7
7
  export { z } from 'zod';
8
8
  import '@commander-js/extra-typings';
9
- import './chunks/readDotenvCascade-Dgx4SC1p.mjs';
9
+ import './chunks/readDotenvCascade-CfFPgLCp.mjs';
10
10
  import 'fs-extra';
11
11
  import 'radash';
12
12
  import 'node:buffer';
@@ -17,7 +17,7 @@ import 'path';
17
17
  import 'url';
18
18
  import 'dotenv';
19
19
  import 'nanoid';
20
- import './chunks/loader-V1vbmtyw.mjs';
20
+ import './chunks/loader-C3DtD6HB.mjs';
21
21
  import 'package-directory';
22
22
  import 'yaml';
23
23
  import 'execa';
package/dist/config.d.ts CHANGED
@@ -69,7 +69,7 @@ interface RootOptionsShape {
69
69
  */
70
70
  trace?: boolean | string[];
71
71
  /** Paths to search for dotenv files (space-delimited string or array). */
72
- paths?: string;
72
+ paths?: string | string[];
73
73
  /** Delimiter for paths string (default: space). */
74
74
  pathsDelimiter?: string;
75
75
  /** Regex pattern for paths delimiter. */
package/dist/config.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { d as discoverConfigFiles, l as loadConfigFile, r as resolveGetDotenvConfigSources, t as toFileUrl } from './chunks/loader-V1vbmtyw.mjs';
1
+ export { d as discoverConfigFiles, l as loadConfigFile, r as resolveGetDotenvConfigSources, t as toFileUrl } from './chunks/loader-C3DtD6HB.mjs';
2
2
  export { v as validateEnvAgainstSources } from './chunks/validate-CDl0rE6k.mjs';
3
3
  import 'fs-extra';
4
4
  import 'package-directory';
@@ -69,7 +69,7 @@ interface RootOptionsShape {
69
69
  */
70
70
  trace?: boolean | string[];
71
71
  /** Paths to search for dotenv files (space-delimited string or array). */
72
- paths?: string;
72
+ paths?: string | string[];
73
73
  /** Delimiter for paths string (default: space). */
74
74
  pathsDelimiter?: string;
75
75
  /** Regex pattern for paths delimiter. */
@@ -165,7 +165,7 @@ type ProcessEnv = Record<string, string | undefined>;
165
165
  * and the selected environment (if any), and returns either a string to set
166
166
  * or `undefined` to unset/skip the variable.
167
167
  */
168
- type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | undefined;
168
+ type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | null | undefined;
169
169
  /**
170
170
  * A map of dynamic variable definitions.
171
171
  * Keys are variable names; values are either literal strings or functions.
@@ -318,15 +318,17 @@ declare function pushDotenvProvenance(prov: DotenvProvenance, key: string, entry
318
318
 
319
319
  /**
320
320
  * Apply a dynamic map to the target progressively.
321
- * - Functions receive (target, env) and may return string | undefined.
322
- * - Literals are assigned directly (including undefined).
321
+ * - Functions receive (target, env) and may return string | null | undefined.
322
+ * - string set the key to that value.
323
+ * - undefined → no-op, leave existing value unchanged.
324
+ * - null → delete the key from the target.
323
325
  *
324
326
  * @param target - Mutable target environment to assign into.
325
327
  * @param map - Dynamic map to apply (functions and/or literal values).
326
328
  * @param env - Selected environment name (if any) passed through to dynamic functions.
327
- * @returns Nothing.
329
+ * @returns Set of keys that were deleted (value was null).
328
330
  */
329
- declare function applyDynamicMap(target: ProcessEnv, map?: GetDotenvDynamic, env?: string): void;
331
+ declare function applyDynamicMap(target: ProcessEnv, map?: GetDotenvDynamic, env?: string): Set<string>;
330
332
  /**
331
333
  * Load a default-export dynamic map from a JS/TS file (without applying it).
332
334
  *
@@ -357,12 +359,14 @@ declare function loadDynamicModuleDefault(absPath: string, cacheDirName: string)
357
359
  * @param prov - Provenance map to append into.
358
360
  * @param meta - Dynamic provenance metadata (source tier and optional dynamicPath).
359
361
  *
362
+ * @returns Set of keys that were deleted (value was null).
363
+ *
360
364
  * @public
361
365
  */
362
366
  declare function applyDynamicMapWithProvenance(target: ProcessEnv, map: GetDotenvDynamic | undefined, env: string | undefined, prov: DotenvProvenance, meta: {
363
367
  dynamicSource: DotenvDynamicSource;
364
368
  dynamicPath?: string;
365
- }): void;
369
+ }): Set<string>;
366
370
  /**
367
371
  * Load a default-export dynamic map from a JS/TS file and apply it.
368
372
  * Uses util/loadModuleDefault for robust TS handling (direct import, esbuild,
@@ -376,9 +380,9 @@ declare function applyDynamicMapWithProvenance(target: ProcessEnv, map: GetDoten
376
380
  * @param absPath - Absolute path to the dynamic module file.
377
381
  * @param env - Selected environment name (if any).
378
382
  * @param cacheDirName - Cache subdirectory under `.tsbuild/` for compiled artifacts.
379
- * @returns A `Promise\<void\>` which resolves after the module (if present) has been applied.
383
+ * @returns A `Promise\<Set\<string\>\>` resolving to the set of deleted keys.
380
384
  */
381
- declare function loadAndApplyDynamic(target: ProcessEnv, absPath: string, env: string | undefined, cacheDirName: string): Promise<void>;
385
+ declare function loadAndApplyDynamic(target: ProcessEnv, absPath: string, env: string | undefined, cacheDirName: string): Promise<Set<string>>;
382
386
 
383
387
  /**
384
388
  * Configuration sources for environment overlay.
@@ -1,5 +1,5 @@
1
- import { e as dotenvExpandAll } from './chunks/readDotenvCascade-Dgx4SC1p.mjs';
2
- export { a as applyDynamicMap, b as applyDynamicMapWithProvenance, c as createDotenvProvenance, l as loadAndApplyDynamic, g as loadDynamicModuleDefault, o as overlayEnvWithProvenance, p as pushDotenvProvenance, h as readDotenvCascadeWithProvenance } from './chunks/readDotenvCascade-Dgx4SC1p.mjs';
1
+ import { d as dotenvExpandAll } from './chunks/readDotenvCascade-CfFPgLCp.mjs';
2
+ export { a as applyDynamicMap, b as applyDynamicMapWithProvenance, c as createDotenvProvenance, l as loadAndApplyDynamic, e as loadDynamicModuleDefault, o as overlayEnvWithProvenance, p as pushDotenvProvenance, r as readDotenvCascadeWithProvenance } from './chunks/readDotenvCascade-CfFPgLCp.mjs';
3
3
  import 'fs-extra';
4
4
  import 'node:path';
5
5
  import 'radash';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { c as createCli } from './chunks/createCli-BkHLeYXL.mjs';
2
+ import { c as createCli } from './chunks/createCli-CUPiFVdZ.mjs';
3
3
  import 'zod';
4
4
  import 'path';
5
- import './chunks/loader-V1vbmtyw.mjs';
5
+ import './chunks/loader-C3DtD6HB.mjs';
6
6
  import 'fs-extra';
7
7
  import 'package-directory';
8
8
  import 'url';
@@ -14,28 +14,24 @@ import './chunks/loadModuleDefault-Dj8B3Stt.mjs';
14
14
  import 'crypto';
15
15
  import '@commander-js/extra-typings';
16
16
  import 'nanoid';
17
- import './chunks/readMergedOptions-CraAnYdB.mjs';
18
- import './chunks/readDotenvCascade-Dgx4SC1p.mjs';
17
+ import './chunks/readMergedOptions-BT1C87_u.mjs';
18
+ import './chunks/readDotenvCascade-CfFPgLCp.mjs';
19
19
  import 'dotenv';
20
20
  import 'execa';
21
21
  import './chunks/helpConfig-CGejgwWW.mjs';
22
- import './chunks/resolveCliOptions-BMBkWDYJ.mjs';
22
+ import './chunks/resolveCliOptions-BbfouWSK.mjs';
23
23
  import './chunks/validate-CDl0rE6k.mjs';
24
24
  import './plugins-aws.mjs';
25
- import './chunks/spawnEnv-CKgnHGpr.mjs';
26
- import './chunks/index-BuxEK_Z4.mjs';
27
- import 'node:os';
28
- import 'node:fs/promises';
29
- import 'node:stream';
30
- import 'node:crypto';
31
- import 'node:fs';
32
- import 'node:https';
33
- import 'node:process';
25
+ import './chunks/spawnEnv-DvisqPiU.mjs';
26
+ import './chunks/index-CNXekCQC.mjs';
27
+ import '@aws-sdk/client-sts';
34
28
  import './plugins-batch.mjs';
35
29
  import './chunks/invoke-DuRPU1oC.mjs';
36
30
  import 'globby';
37
- import './chunks/index-Dd6S1nZ-.mjs';
31
+ import 'os';
32
+ import './chunks/index-DnG3N6yj.mjs';
38
33
  import './plugins-init.mjs';
34
+ import 'node:process';
39
35
  import 'readline/promises';
40
36
  import 'node:url';
41
37
 
package/dist/index.d.ts CHANGED
@@ -286,7 +286,7 @@ interface RootOptionsShape {
286
286
  */
287
287
  trace?: boolean | string[];
288
288
  /** Paths to search for dotenv files (space-delimited string or array). */
289
- paths?: string;
289
+ paths?: string | string[];
290
290
  /** Delimiter for paths string (default: space). */
291
291
  pathsDelimiter?: string;
292
292
  /** Regex pattern for paths delimiter. */
@@ -398,7 +398,7 @@ type RootOptionsShapeCompat = Omit<RootOptionsShape, 'vars' | 'paths'> & {
398
398
  * and the selected environment (if any), and returns either a string to set
399
399
  * or `undefined` to unset/skip the variable.
400
400
  */
401
- type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | undefined;
401
+ type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | null | undefined;
402
402
  /**
403
403
  * A map of dynamic variable definitions.
404
404
  * Keys are variable names; values are either literal strings or functions.
@@ -433,7 +433,7 @@ type GetDotenvOptions = Omit<z.output<typeof getDotenvOptionsSchemaResolved>, 'l
433
433
  * Vars-aware dynamic helpers (compile-time DX).
434
434
  * DynamicFn: receive the current expanded variables and optional env.
435
435
  */
436
- type DynamicFn<Vars extends ProcessEnv> = (vars: Vars, env?: string) => string | undefined;
436
+ type DynamicFn<Vars extends ProcessEnv> = (vars: Vars, env?: string) => string | null | undefined;
437
437
  /**
438
438
  * Vars-aware dynamic map type used by {@link defineDynamic} and JS/TS configs.
439
439
  *
@@ -632,6 +632,12 @@ interface ResolveAndLoadOptions {
632
632
  * @default true
633
633
  */
634
634
  runAfterResolve?: boolean;
635
+ /**
636
+ * Name of the invoked subcommand (plugin namespace). When provided,
637
+ * only the matching plugin subtree runs afterResolve hooks.
638
+ * When omitted, all plugins run afterResolve (backward compatibility).
639
+ */
640
+ invokedSubcommand?: string;
635
641
  }
636
642
  /**
637
643
  * Structural public interface for the host exposed to plugins.
@@ -725,6 +731,11 @@ interface GetDotenvCliPlugin<TOptions extends GetDotenvOptions = GetDotenvOption
725
731
  * After the dotenv context is resolved, initialize any clients/secrets
726
732
  * or attach per-plugin state under ctx.plugins (by convention).
727
733
  * Runs parent → children (pre-order).
734
+ *
735
+ * **Scoping**: When the host provides an invoked subcommand filter,
736
+ * afterResolve only fires for plugins whose namespace matches the
737
+ * invoked command path. A plugin's afterResolve should never produce
738
+ * side effects for commands outside its subtree.
728
739
  */
729
740
  afterResolve?: (cli: GetDotenvCliPublic<TOptions, TArgs, TOpts, TGlobal>, ctx: GetDotenvCliCtx<TOptions>) => void | Promise<void>;
730
741
  /** Zod schema for this plugin's config slice (from config.plugins[…]). */
@@ -861,10 +872,14 @@ declare class GetDotenvCli<TOptions extends GetDotenvOptions = GetDotenvOptions,
861
872
  * Resolve options (strict) and compute dotenv context.
862
873
  * Stores the context on the instance under a symbol.
863
874
  *
864
- * Options:
865
- * - opts.runAfterResolve (default true): when false, skips running plugin
866
- * afterResolve hooks. Useful for top-level help rendering to avoid
867
- * long-running side-effects while still evaluating dynamic help text.
875
+ * @param customOptions - Partial options to overlay for this invocation.
876
+ * @param opts - Optional resolver behavior switches.
877
+ * - `runAfterResolve` (default `true`): when false, skips running plugin
878
+ * afterResolve hooks. Useful for top-level help rendering to avoid
879
+ * long-running side-effects while still evaluating dynamic help text.
880
+ * - `invokedSubcommand`: when provided, only the plugin subtree whose
881
+ * namespace matches this name runs afterResolve hooks. When omitted,
882
+ * all plugins run afterResolve (backward compatibility).
868
883
  */
869
884
  resolveAndLoad(customOptions?: Partial<TOptions>, opts?: ResolveAndLoadOptions): Promise<GetDotenvCliCtx<TOptions>>;
870
885
  /**
@@ -936,9 +951,15 @@ declare class GetDotenvCli<TOptions extends GetDotenvOptions = GetDotenvOptions,
936
951
  */
937
952
  install(): Promise<void>;
938
953
  /**
939
- * Run afterResolve hooks for all plugins (parent → children).
954
+ * Run afterResolve hooks for registered plugins (parent → children).
955
+ * When {@link commandPath} is provided, only the matching branch of the
956
+ * plugin tree runs; otherwise all plugins run (backward compatibility).
957
+ *
958
+ * The path is walked segment-by-segment against the plugin tree.
959
+ * Intermediate matches run their own afterResolve hook.
960
+ * The deepest match runs afterResolve for itself and all its descendants.
940
961
  */
941
- private _runAfterResolve;
962
+ _runAfterResolve(ctx: GetDotenvCliCtx<TOptions>, commandPath?: string[]): Promise<void>;
942
963
  }
943
964
 
944
965
  /**
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- export { c as createCli } from './chunks/createCli-BkHLeYXL.mjs';
2
- import { j as resolveGetDotenvOptions, w as writeDotenvFile } from './chunks/readMergedOptions-CraAnYdB.mjs';
3
- export { G as GetDotenvCli, a as assertLogger, c as baseRootOptionDefaults, d as defaultsDeep, e as defineDynamic, f as defineGetDotenvConfig, g as definePlugin, h as getDotenvCliOptions2Options, i as interpolateDeep, r as readMergedOptions } from './chunks/readMergedOptions-CraAnYdB.mjs';
4
- export { b as buildSpawnEnv, s as shouldCapture, t as tokenize } from './chunks/spawnEnv-CKgnHGpr.mjs';
5
- export { d as defineScripts, g as groupPlugins } from './chunks/types-BthqmnDr.mjs';
1
+ export { c as createCli } from './chunks/createCli-CUPiFVdZ.mjs';
2
+ import { e as resolveGetDotenvOptions, w as writeDotenvFile } from './chunks/readMergedOptions-BT1C87_u.mjs';
3
+ export { G as GetDotenvCli, f as assertLogger, b as baseRootOptionDefaults, a as defaultsDeep, h as defineDynamic, i as defineGetDotenvConfig, d as definePlugin, g as getDotenvCliOptions2Options, j as interpolateDeep, r as readMergedOptions } from './chunks/readMergedOptions-BT1C87_u.mjs';
4
+ export { b as buildSpawnEnv, s as shouldCapture, t as tokenize } from './chunks/spawnEnv-DvisqPiU.mjs';
5
+ export { d as defineScripts, g as groupPlugins } from './chunks/types-BkQxnyZK.mjs';
6
6
  import { omit, pick } from 'radash';
7
7
  import { Buffer } from 'node:buffer';
8
8
  export { l as loadModuleDefault } from './chunks/loadModuleDefault-Dj8B3Stt.mjs';
@@ -10,35 +10,31 @@ import { InvalidArgumentError } from '@commander-js/extra-typings';
10
10
  import 'zod';
11
11
  import { nanoid } from 'nanoid';
12
12
  import path$1 from 'path';
13
- import { a as redactObject, m as maybeWarnEntropy } from './chunks/index-Dd6S1nZ-.mjs';
14
- export { r as redactDisplay, t as traceChildEnv } from './chunks/index-Dd6S1nZ-.mjs';
15
- import { r as readDotenv, e as dotenvExpandAll, a as applyDynamicMap, l as loadAndApplyDynamic } from './chunks/readDotenvCascade-Dgx4SC1p.mjs';
16
- export { d as dotenvExpand, f as dotenvExpandFromProcessEnv } from './chunks/readDotenvCascade-Dgx4SC1p.mjs';
13
+ import { r as redactObject, m as maybeWarnEntropy } from './chunks/index-DnG3N6yj.mjs';
14
+ export { a as redactDisplay, t as traceChildEnv } from './chunks/index-DnG3N6yj.mjs';
15
+ import { g as readDotenv, d as dotenvExpandAll, a as applyDynamicMap, l as loadAndApplyDynamic } from './chunks/readDotenvCascade-CfFPgLCp.mjs';
16
+ export { h as dotenvExpand, f as dotenvExpandFromProcessEnv } from './chunks/readDotenvCascade-CfFPgLCp.mjs';
17
17
  import fs from 'fs-extra';
18
18
  import path from 'node:path';
19
19
  import 'crypto';
20
20
  import 'url';
21
21
  import 'dotenv';
22
- import './chunks/loader-V1vbmtyw.mjs';
22
+ import './chunks/loader-C3DtD6HB.mjs';
23
23
  import 'package-directory';
24
24
  import 'yaml';
25
25
  import 'execa';
26
26
  import './chunks/helpConfig-CGejgwWW.mjs';
27
- import './chunks/resolveCliOptions-BMBkWDYJ.mjs';
27
+ import './chunks/resolveCliOptions-BbfouWSK.mjs';
28
28
  import './chunks/validate-CDl0rE6k.mjs';
29
29
  import './plugins-aws.mjs';
30
- import './chunks/index-BuxEK_Z4.mjs';
31
- import 'node:os';
32
- import 'node:fs/promises';
33
- import 'node:stream';
34
- import 'node:crypto';
35
- import 'node:fs';
36
- import 'node:https';
37
- import 'node:process';
30
+ import './chunks/index-CNXekCQC.mjs';
31
+ import '@aws-sdk/client-sts';
38
32
  import './plugins-batch.mjs';
39
33
  import './chunks/invoke-DuRPU1oC.mjs';
40
34
  import 'globby';
35
+ import 'os';
41
36
  import './plugins-init.mjs';
37
+ import 'node:process';
42
38
  import 'readline/promises';
43
39
  import 'node:url';
44
40
 
@@ -927,11 +923,13 @@ async function getDotenv(options = {}) {
927
923
  ...(outputPath ? { [outputKey]: outputPath } : {}),
928
924
  }, { progressive: true });
929
925
  // Process dynamic variables. Programmatic option takes precedence over path.
926
+ const deletedKeys = new Set();
930
927
  if (!excludeDynamic) {
931
928
  // A2 precedence: programmatic dynamic < dynamicPath (dynamicPath wins when present)
932
929
  if (options.dynamic && Object.keys(options.dynamic).length > 0) {
933
930
  try {
934
- applyDynamicMap(dotenv, options.dynamic, env ?? defaultEnv);
931
+ for (const k of applyDynamicMap(dotenv, options.dynamic, env ?? defaultEnv))
932
+ deletedKeys.add(k);
935
933
  }
936
934
  catch {
937
935
  throw new Error(`Unable to evaluate dynamic variables.`);
@@ -940,7 +938,8 @@ async function getDotenv(options = {}) {
940
938
  // dynamicPath is evaluated even when programmatic `dynamic` is present.
941
939
  if (dynamicPath) {
942
940
  const absDynamicPath = path$1.resolve(dynamicPath);
943
- await loadAndApplyDynamic(dotenv, absDynamicPath, env ?? defaultEnv, 'getdotenv-dynamic');
941
+ for (const k of await loadAndApplyDynamic(dotenv, absDynamicPath, env ?? defaultEnv, 'getdotenv-dynamic'))
942
+ deletedKeys.add(k);
944
943
  }
945
944
  }
946
945
  // Write output file.
@@ -989,8 +988,17 @@ async function getDotenv(options = {}) {
989
988
  }
990
989
  }
991
990
  // Load process.env.
992
- if (loadProcess)
993
- Object.assign(process.env, resultDotenv);
991
+ if (loadProcess) {
992
+ for (const key of deletedKeys) {
993
+ Reflect.deleteProperty(process.env, key);
994
+ }
995
+ for (const [key, value] of Object.entries(resultDotenv)) {
996
+ if (value === undefined)
997
+ Reflect.deleteProperty(process.env, key);
998
+ else
999
+ process.env[key] = value;
1000
+ }
1001
+ }
994
1002
  return resultDotenv;
995
1003
  }
996
1004
 
@@ -272,7 +272,7 @@ type ProcessEnv = Record<string, string | undefined>;
272
272
  * and the selected environment (if any), and returns either a string to set
273
273
  * or `undefined` to unset/skip the variable.
274
274
  */
275
- type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | undefined;
275
+ type GetDotenvDynamicFunction = (vars: ProcessEnv, env: string | undefined) => string | null | undefined;
276
276
  /**
277
277
  * A map of dynamic variable definitions.
278
278
  * Keys are variable names; values are either literal strings or functions.
@@ -358,6 +358,12 @@ interface ResolveAndLoadOptions {
358
358
  * @default true
359
359
  */
360
360
  runAfterResolve?: boolean;
361
+ /**
362
+ * Name of the invoked subcommand (plugin namespace). When provided,
363
+ * only the matching plugin subtree runs afterResolve hooks.
364
+ * When omitted, all plugins run afterResolve (backward compatibility).
365
+ */
366
+ invokedSubcommand?: string;
361
367
  }
362
368
  /**
363
369
  * Structural public interface for the host exposed to plugins.
@@ -451,6 +457,11 @@ interface GetDotenvCliPlugin<TOptions extends GetDotenvOptions = GetDotenvOption
451
457
  * After the dotenv context is resolved, initialize any clients/secrets
452
458
  * or attach per-plugin state under ctx.plugins (by convention).
453
459
  * Runs parent → children (pre-order).
460
+ *
461
+ * **Scoping**: When the host provides an invoked subcommand filter,
462
+ * afterResolve only fires for plugins whose namespace matches the
463
+ * invoked command path. A plugin's afterResolve should never produce
464
+ * side effects for commands outside its subtree.
454
465
  */
455
466
  afterResolve?: (cli: GetDotenvCliPublic<TOptions, TArgs, TOpts, TGlobal>, ctx: GetDotenvCliCtx<TOptions>) => void | Promise<void>;
456
467
  /** Zod schema for this plugin's config slice (from config.plugins[…]). */
@@ -1,4 +1,4 @@
1
- import { r as readMergedOptions, g as definePlugin } from './chunks/readMergedOptions-CraAnYdB.mjs';
1
+ import { r as readMergedOptions, d as definePlugin } from './chunks/readMergedOptions-BT1C87_u.mjs';
2
2
  import 'execa';
3
3
  import { isObject } from 'radash';
4
4
  import 'node:buffer';
@@ -10,12 +10,12 @@ import 'url';
10
10
  import '@commander-js/extra-typings';
11
11
  import 'nanoid';
12
12
  import 'dotenv';
13
- import './chunks/loader-V1vbmtyw.mjs';
13
+ import './chunks/loader-C3DtD6HB.mjs';
14
14
  import 'package-directory';
15
15
  import 'yaml';
16
16
  import { z } from 'zod';
17
- import { c as runCommand, d as runCommandResult, s as shouldCapture, a as resolveShell, b as buildSpawnEnv } from './chunks/spawnEnv-CKgnHGpr.mjs';
18
- import './chunks/readDotenvCascade-Dgx4SC1p.mjs';
17
+ import { c as runCommand, d as runCommandResult, s as shouldCapture, a as resolveShell, b as buildSpawnEnv } from './chunks/spawnEnv-DvisqPiU.mjs';
18
+ import './chunks/readDotenvCascade-CfFPgLCp.mjs';
19
19
  import './chunks/loadModuleDefault-Dj8B3Stt.mjs';
20
20
 
21
21
  /**
@@ -329,12 +329,13 @@ const resolveAwsContext = async ({ dotenv, cfg, }) => {
329
329
  };
330
330
 
331
331
  /**
332
- * Create the AWS plugin `afterResolve` hook.
332
+ * Create the AWS plugin afterResolve hook.
333
333
  *
334
- * This runs once per invocation after the host resolves dotenv context.
334
+ * This runs after the host resolves dotenv context, but only when the aws
335
+ * plugin (or a child of it) is in the invoked command path.
335
336
  *
336
337
  * @param plugin - The AWS plugin instance.
337
- * @returns An `afterResolve` hook function suitable for assigning to `plugin.afterResolve`.
338
+ * @returns An afterResolve hook function suitable for assigning to plugin.afterResolve.
338
339
  *
339
340
  * @internal
340
341
  */