@karmaniverous/get-dotenv 4.5.2 → 5.0.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.
Files changed (49) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +369 -215
  3. package/dist/cliHost.cjs +1078 -0
  4. package/dist/cliHost.d.cts +193 -0
  5. package/dist/cliHost.d.mts +193 -0
  6. package/dist/cliHost.d.ts +193 -0
  7. package/dist/cliHost.mjs +1074 -0
  8. package/dist/config.cjs +247 -0
  9. package/dist/config.d.cts +53 -0
  10. package/dist/config.d.mts +53 -0
  11. package/dist/config.d.ts +53 -0
  12. package/dist/config.mjs +242 -0
  13. package/dist/env-overlay.cjs +163 -0
  14. package/dist/env-overlay.d.cts +50 -0
  15. package/dist/env-overlay.d.mts +50 -0
  16. package/dist/env-overlay.d.ts +50 -0
  17. package/dist/env-overlay.mjs +161 -0
  18. package/dist/getdotenv.cli.mjs +2817 -40874
  19. package/dist/index.cjs +1482 -40965
  20. package/dist/index.d.cts +206 -67
  21. package/dist/index.d.mts +206 -67
  22. package/dist/index.d.ts +206 -67
  23. package/dist/index.mjs +1454 -40939
  24. package/dist/plugins-aws.cjs +618 -0
  25. package/dist/plugins-aws.d.cts +178 -0
  26. package/dist/plugins-aws.d.mts +178 -0
  27. package/dist/plugins-aws.d.ts +178 -0
  28. package/dist/plugins-aws.mjs +616 -0
  29. package/dist/plugins-batch.cjs +569 -0
  30. package/dist/plugins-batch.d.cts +200 -0
  31. package/dist/plugins-batch.d.mts +200 -0
  32. package/dist/plugins-batch.d.ts +200 -0
  33. package/dist/plugins-batch.mjs +567 -0
  34. package/dist/plugins-init.cjs +282 -0
  35. package/dist/plugins-init.d.cts +182 -0
  36. package/dist/plugins-init.d.mts +182 -0
  37. package/dist/plugins-init.d.ts +182 -0
  38. package/dist/plugins-init.mjs +280 -0
  39. package/getdotenv.config.json +19 -0
  40. package/package.json +228 -139
  41. package/templates/cli/ts/index.ts +9 -0
  42. package/templates/cli/ts/plugins/hello.ts +17 -0
  43. package/templates/config/js/getdotenv.config.js +15 -0
  44. package/templates/config/json/local/getdotenv.config.local.json +7 -0
  45. package/templates/config/json/public/getdotenv.config.json +12 -0
  46. package/templates/config/public/getdotenv.config.json +13 -0
  47. package/templates/config/ts/getdotenv.config.ts +16 -0
  48. package/templates/config/yaml/local/getdotenv.config.local.yaml +7 -0
  49. package/templates/config/yaml/public/getdotenv.config.yaml +10 -0
@@ -0,0 +1,163 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Dotenv expansion utilities.
5
+ *
6
+ * This module implements recursive expansion of environment-variable
7
+ * references in strings and records. It supports both whitespace and
8
+ * bracket syntaxes with optional defaults:
9
+ *
10
+ * - Whitespace: `$VAR[:default]`
11
+ * - Bracketed: `${VAR[:default]}`
12
+ *
13
+ * Escaped dollar signs (`\$`) are preserved.
14
+ * Unknown variables resolve to empty string unless a default is provided.
15
+ */
16
+ /**
17
+ * Like String.prototype.search but returns the last index.
18
+ * @internal
19
+ */
20
+ const searchLast = (str, rgx) => {
21
+ const matches = Array.from(str.matchAll(rgx));
22
+ return matches.length > 0 ? (matches.slice(-1)[0]?.index ?? -1) : -1;
23
+ };
24
+ const replaceMatch = (value, match, ref) => {
25
+ /**
26
+ * @internal
27
+ */
28
+ const group = match[0];
29
+ const key = match[1];
30
+ const defaultValue = match[2];
31
+ if (!key)
32
+ return value;
33
+ const replacement = value.replace(group, ref[key] ?? defaultValue ?? '');
34
+ return interpolate(replacement, ref);
35
+ };
36
+ const interpolate = (value = '', ref = {}) => {
37
+ /**
38
+ * @internal
39
+ */
40
+ // if value is falsy, return it as is
41
+ if (!value)
42
+ return value;
43
+ // get position of last unescaped dollar sign
44
+ const lastUnescapedDollarSignIndex = searchLast(value, /(?!(?<=\\))\$/g);
45
+ // return value if none found
46
+ if (lastUnescapedDollarSignIndex === -1)
47
+ return value;
48
+ // evaluate the value tail
49
+ const tail = value.slice(lastUnescapedDollarSignIndex);
50
+ // find whitespace pattern: $KEY:DEFAULT
51
+ const whitespacePattern = /^\$([\w]+)(?::([^\s]*))?/;
52
+ const whitespaceMatch = whitespacePattern.exec(tail);
53
+ if (whitespaceMatch != null)
54
+ return replaceMatch(value, whitespaceMatch, ref);
55
+ else {
56
+ // find bracket pattern: ${KEY:DEFAULT}
57
+ const bracketPattern = /^\${([\w]+)(?::([^}]*))?}/;
58
+ const bracketMatch = bracketPattern.exec(tail);
59
+ if (bracketMatch != null)
60
+ return replaceMatch(value, bracketMatch, ref);
61
+ }
62
+ return value;
63
+ };
64
+ /**
65
+ * Recursively expands environment variables in a string. Variables may be
66
+ * presented with optional default as `$VAR[:default]` or `${VAR[:default]}`.
67
+ * Unknown variables will expand to an empty string.
68
+ *
69
+ * @param value - The string to expand.
70
+ * @param ref - The reference object to use for variable expansion.
71
+ * @returns The expanded string.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * process.env.FOO = 'bar';
76
+ * dotenvExpand('Hello $FOO'); // "Hello bar"
77
+ * dotenvExpand('Hello $BAZ:world'); // "Hello world"
78
+ * ```
79
+ *
80
+ * @remarks
81
+ * The expansion is recursive. If a referenced variable itself contains
82
+ * references, those will also be expanded until a stable value is reached.
83
+ * Escaped references (e.g. `\$FOO`) are preserved as literals.
84
+ */
85
+ const dotenvExpand = (value, ref = process.env) => {
86
+ const result = interpolate(value, ref);
87
+ return result ? result.replace(/\\\$/g, '$') : undefined;
88
+ };
89
+ /**
90
+ * Recursively expands environment variables in the values of a JSON object.
91
+ * Variables may be presented with optional default as `$VAR[:default]` or
92
+ * `${VAR[:default]}`. Unknown variables will expand to an empty string.
93
+ *
94
+ * @param values - The values object to expand.
95
+ * @param options - Expansion options.
96
+ * @returns The value object with expanded string values.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * process.env.FOO = 'bar';
101
+ * dotenvExpandAll({ A: '$FOO', B: 'x${FOO}y' });
102
+ * // => { A: "bar", B: "xbary" }
103
+ * ```
104
+ *
105
+ * @remarks
106
+ * Options:
107
+ * - ref: The reference object to use for expansion (defaults to process.env).
108
+ * - progressive: Whether to progressively add expanded values to the set of
109
+ * reference keys.
110
+ *
111
+ * When `progressive` is true, each expanded key becomes available for
112
+ * subsequent expansions in the same object (left-to-right by object key order).
113
+ */
114
+ const dotenvExpandAll = (values = {}, options = {}) => Object.keys(values).reduce((acc, key) => {
115
+ const { ref = process.env, progressive = false } = options;
116
+ acc[key] = dotenvExpand(values[key], {
117
+ ...ref,
118
+ ...(progressive ? acc : {}),
119
+ });
120
+ return acc;
121
+ }, {});
122
+
123
+ const applyKv = (current, kv) => {
124
+ if (!kv || Object.keys(kv).length === 0)
125
+ return current;
126
+ const expanded = dotenvExpandAll(kv, { ref: current, progressive: true });
127
+ return { ...current, ...expanded };
128
+ };
129
+ const applyConfigSlice = (current, cfg, env) => {
130
+ if (!cfg)
131
+ return current;
132
+ // kind axis: global then env (env overrides global)
133
+ const afterGlobal = applyKv(current, cfg.vars);
134
+ const envKv = env && cfg.envVars ? cfg.envVars[env] : undefined;
135
+ return applyKv(afterGlobal, envKv);
136
+ };
137
+ /**
138
+ * Overlay config-provided values onto a base ProcessEnv using precedence axes:
139
+ * - kind: env \> global
140
+ * - privacy: local \> public
141
+ * - source: project \> packaged \> base
142
+ *
143
+ * Programmatic explicit vars (if provided) override all config slices.
144
+ * Progressive expansion is applied within each slice.
145
+ */
146
+ const overlayEnv = ({ base, env, configs, programmaticVars, }) => {
147
+ let current = { ...base };
148
+ // Source: packaged (public -> local)
149
+ current = applyConfigSlice(current, configs.packaged, env);
150
+ // Packaged "local" is not expected by policy; if present, honor it.
151
+ // We do not have a separate object for packaged.local in sources, keep as-is.
152
+ // Source: project (public -> local)
153
+ current = applyConfigSlice(current, configs.project?.public, env);
154
+ current = applyConfigSlice(current, configs.project?.local, env);
155
+ // Programmatic explicit vars (top of static tier)
156
+ if (programmaticVars) {
157
+ const toApply = Object.fromEntries(Object.entries(programmaticVars).filter(([_k, v]) => typeof v === 'string'));
158
+ current = applyKv(current, toApply);
159
+ }
160
+ return current;
161
+ };
162
+
163
+ exports.overlayEnv = overlayEnv;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * A minimal representation of an environment key/value mapping.
3
+ * Values may be `undefined` to represent "unset".
4
+ */
5
+ type ProcessEnv = Record<string, string | undefined>;
6
+
7
+ type Scripts = Record<string, string | {
8
+ cmd: string;
9
+ shell?: string | boolean;
10
+ }>;
11
+
12
+ type GetDotenvConfigResolved = {
13
+ dotenvToken?: string;
14
+ privateToken?: string;
15
+ paths?: string[];
16
+ loadProcess?: boolean;
17
+ log?: boolean;
18
+ shell?: string | boolean;
19
+ scripts?: Scripts;
20
+ vars?: Record<string, string>;
21
+ envVars?: Record<string, Record<string, string>>;
22
+ dynamic?: unknown;
23
+ plugins?: Record<string, unknown>;
24
+ };
25
+
26
+ type OverlayConfigSources = {
27
+ packaged?: GetDotenvConfigResolved;
28
+ project?: {
29
+ public?: GetDotenvConfigResolved;
30
+ local?: GetDotenvConfigResolved;
31
+ };
32
+ };
33
+ /**
34
+ * Overlay config-provided values onto a base ProcessEnv using precedence axes:
35
+ * - kind: env \> global
36
+ * - privacy: local \> public
37
+ * - source: project \> packaged \> base
38
+ *
39
+ * Programmatic explicit vars (if provided) override all config slices.
40
+ * Progressive expansion is applied within each slice.
41
+ */
42
+ declare const overlayEnv: ({ base, env, configs, programmaticVars, }: {
43
+ base: ProcessEnv;
44
+ env: string | undefined;
45
+ configs: OverlayConfigSources;
46
+ programmaticVars?: ProcessEnv;
47
+ }) => ProcessEnv;
48
+
49
+ export { overlayEnv };
50
+ export type { OverlayConfigSources };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * A minimal representation of an environment key/value mapping.
3
+ * Values may be `undefined` to represent "unset".
4
+ */
5
+ type ProcessEnv = Record<string, string | undefined>;
6
+
7
+ type Scripts = Record<string, string | {
8
+ cmd: string;
9
+ shell?: string | boolean;
10
+ }>;
11
+
12
+ type GetDotenvConfigResolved = {
13
+ dotenvToken?: string;
14
+ privateToken?: string;
15
+ paths?: string[];
16
+ loadProcess?: boolean;
17
+ log?: boolean;
18
+ shell?: string | boolean;
19
+ scripts?: Scripts;
20
+ vars?: Record<string, string>;
21
+ envVars?: Record<string, Record<string, string>>;
22
+ dynamic?: unknown;
23
+ plugins?: Record<string, unknown>;
24
+ };
25
+
26
+ type OverlayConfigSources = {
27
+ packaged?: GetDotenvConfigResolved;
28
+ project?: {
29
+ public?: GetDotenvConfigResolved;
30
+ local?: GetDotenvConfigResolved;
31
+ };
32
+ };
33
+ /**
34
+ * Overlay config-provided values onto a base ProcessEnv using precedence axes:
35
+ * - kind: env \> global
36
+ * - privacy: local \> public
37
+ * - source: project \> packaged \> base
38
+ *
39
+ * Programmatic explicit vars (if provided) override all config slices.
40
+ * Progressive expansion is applied within each slice.
41
+ */
42
+ declare const overlayEnv: ({ base, env, configs, programmaticVars, }: {
43
+ base: ProcessEnv;
44
+ env: string | undefined;
45
+ configs: OverlayConfigSources;
46
+ programmaticVars?: ProcessEnv;
47
+ }) => ProcessEnv;
48
+
49
+ export { overlayEnv };
50
+ export type { OverlayConfigSources };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * A minimal representation of an environment key/value mapping.
3
+ * Values may be `undefined` to represent "unset".
4
+ */
5
+ type ProcessEnv = Record<string, string | undefined>;
6
+
7
+ type Scripts = Record<string, string | {
8
+ cmd: string;
9
+ shell?: string | boolean;
10
+ }>;
11
+
12
+ type GetDotenvConfigResolved = {
13
+ dotenvToken?: string;
14
+ privateToken?: string;
15
+ paths?: string[];
16
+ loadProcess?: boolean;
17
+ log?: boolean;
18
+ shell?: string | boolean;
19
+ scripts?: Scripts;
20
+ vars?: Record<string, string>;
21
+ envVars?: Record<string, Record<string, string>>;
22
+ dynamic?: unknown;
23
+ plugins?: Record<string, unknown>;
24
+ };
25
+
26
+ type OverlayConfigSources = {
27
+ packaged?: GetDotenvConfigResolved;
28
+ project?: {
29
+ public?: GetDotenvConfigResolved;
30
+ local?: GetDotenvConfigResolved;
31
+ };
32
+ };
33
+ /**
34
+ * Overlay config-provided values onto a base ProcessEnv using precedence axes:
35
+ * - kind: env \> global
36
+ * - privacy: local \> public
37
+ * - source: project \> packaged \> base
38
+ *
39
+ * Programmatic explicit vars (if provided) override all config slices.
40
+ * Progressive expansion is applied within each slice.
41
+ */
42
+ declare const overlayEnv: ({ base, env, configs, programmaticVars, }: {
43
+ base: ProcessEnv;
44
+ env: string | undefined;
45
+ configs: OverlayConfigSources;
46
+ programmaticVars?: ProcessEnv;
47
+ }) => ProcessEnv;
48
+
49
+ export { overlayEnv };
50
+ export type { OverlayConfigSources };
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Dotenv expansion utilities.
3
+ *
4
+ * This module implements recursive expansion of environment-variable
5
+ * references in strings and records. It supports both whitespace and
6
+ * bracket syntaxes with optional defaults:
7
+ *
8
+ * - Whitespace: `$VAR[:default]`
9
+ * - Bracketed: `${VAR[:default]}`
10
+ *
11
+ * Escaped dollar signs (`\$`) are preserved.
12
+ * Unknown variables resolve to empty string unless a default is provided.
13
+ */
14
+ /**
15
+ * Like String.prototype.search but returns the last index.
16
+ * @internal
17
+ */
18
+ const searchLast = (str, rgx) => {
19
+ const matches = Array.from(str.matchAll(rgx));
20
+ return matches.length > 0 ? (matches.slice(-1)[0]?.index ?? -1) : -1;
21
+ };
22
+ const replaceMatch = (value, match, ref) => {
23
+ /**
24
+ * @internal
25
+ */
26
+ const group = match[0];
27
+ const key = match[1];
28
+ const defaultValue = match[2];
29
+ if (!key)
30
+ return value;
31
+ const replacement = value.replace(group, ref[key] ?? defaultValue ?? '');
32
+ return interpolate(replacement, ref);
33
+ };
34
+ const interpolate = (value = '', ref = {}) => {
35
+ /**
36
+ * @internal
37
+ */
38
+ // if value is falsy, return it as is
39
+ if (!value)
40
+ return value;
41
+ // get position of last unescaped dollar sign
42
+ const lastUnescapedDollarSignIndex = searchLast(value, /(?!(?<=\\))\$/g);
43
+ // return value if none found
44
+ if (lastUnescapedDollarSignIndex === -1)
45
+ return value;
46
+ // evaluate the value tail
47
+ const tail = value.slice(lastUnescapedDollarSignIndex);
48
+ // find whitespace pattern: $KEY:DEFAULT
49
+ const whitespacePattern = /^\$([\w]+)(?::([^\s]*))?/;
50
+ const whitespaceMatch = whitespacePattern.exec(tail);
51
+ if (whitespaceMatch != null)
52
+ return replaceMatch(value, whitespaceMatch, ref);
53
+ else {
54
+ // find bracket pattern: ${KEY:DEFAULT}
55
+ const bracketPattern = /^\${([\w]+)(?::([^}]*))?}/;
56
+ const bracketMatch = bracketPattern.exec(tail);
57
+ if (bracketMatch != null)
58
+ return replaceMatch(value, bracketMatch, ref);
59
+ }
60
+ return value;
61
+ };
62
+ /**
63
+ * Recursively expands environment variables in a string. Variables may be
64
+ * presented with optional default as `$VAR[:default]` or `${VAR[:default]}`.
65
+ * Unknown variables will expand to an empty string.
66
+ *
67
+ * @param value - The string to expand.
68
+ * @param ref - The reference object to use for variable expansion.
69
+ * @returns The expanded string.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * process.env.FOO = 'bar';
74
+ * dotenvExpand('Hello $FOO'); // "Hello bar"
75
+ * dotenvExpand('Hello $BAZ:world'); // "Hello world"
76
+ * ```
77
+ *
78
+ * @remarks
79
+ * The expansion is recursive. If a referenced variable itself contains
80
+ * references, those will also be expanded until a stable value is reached.
81
+ * Escaped references (e.g. `\$FOO`) are preserved as literals.
82
+ */
83
+ const dotenvExpand = (value, ref = process.env) => {
84
+ const result = interpolate(value, ref);
85
+ return result ? result.replace(/\\\$/g, '$') : undefined;
86
+ };
87
+ /**
88
+ * Recursively expands environment variables in the values of a JSON object.
89
+ * Variables may be presented with optional default as `$VAR[:default]` or
90
+ * `${VAR[:default]}`. Unknown variables will expand to an empty string.
91
+ *
92
+ * @param values - The values object to expand.
93
+ * @param options - Expansion options.
94
+ * @returns The value object with expanded string values.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * process.env.FOO = 'bar';
99
+ * dotenvExpandAll({ A: '$FOO', B: 'x${FOO}y' });
100
+ * // => { A: "bar", B: "xbary" }
101
+ * ```
102
+ *
103
+ * @remarks
104
+ * Options:
105
+ * - ref: The reference object to use for expansion (defaults to process.env).
106
+ * - progressive: Whether to progressively add expanded values to the set of
107
+ * reference keys.
108
+ *
109
+ * When `progressive` is true, each expanded key becomes available for
110
+ * subsequent expansions in the same object (left-to-right by object key order).
111
+ */
112
+ const dotenvExpandAll = (values = {}, options = {}) => Object.keys(values).reduce((acc, key) => {
113
+ const { ref = process.env, progressive = false } = options;
114
+ acc[key] = dotenvExpand(values[key], {
115
+ ...ref,
116
+ ...(progressive ? acc : {}),
117
+ });
118
+ return acc;
119
+ }, {});
120
+
121
+ const applyKv = (current, kv) => {
122
+ if (!kv || Object.keys(kv).length === 0)
123
+ return current;
124
+ const expanded = dotenvExpandAll(kv, { ref: current, progressive: true });
125
+ return { ...current, ...expanded };
126
+ };
127
+ const applyConfigSlice = (current, cfg, env) => {
128
+ if (!cfg)
129
+ return current;
130
+ // kind axis: global then env (env overrides global)
131
+ const afterGlobal = applyKv(current, cfg.vars);
132
+ const envKv = env && cfg.envVars ? cfg.envVars[env] : undefined;
133
+ return applyKv(afterGlobal, envKv);
134
+ };
135
+ /**
136
+ * Overlay config-provided values onto a base ProcessEnv using precedence axes:
137
+ * - kind: env \> global
138
+ * - privacy: local \> public
139
+ * - source: project \> packaged \> base
140
+ *
141
+ * Programmatic explicit vars (if provided) override all config slices.
142
+ * Progressive expansion is applied within each slice.
143
+ */
144
+ const overlayEnv = ({ base, env, configs, programmaticVars, }) => {
145
+ let current = { ...base };
146
+ // Source: packaged (public -> local)
147
+ current = applyConfigSlice(current, configs.packaged, env);
148
+ // Packaged "local" is not expected by policy; if present, honor it.
149
+ // We do not have a separate object for packaged.local in sources, keep as-is.
150
+ // Source: project (public -> local)
151
+ current = applyConfigSlice(current, configs.project?.public, env);
152
+ current = applyConfigSlice(current, configs.project?.local, env);
153
+ // Programmatic explicit vars (top of static tier)
154
+ if (programmaticVars) {
155
+ const toApply = Object.fromEntries(Object.entries(programmaticVars).filter(([_k, v]) => typeof v === 'string'));
156
+ current = applyKv(current, toApply);
157
+ }
158
+ return current;
159
+ };
160
+
161
+ export { overlayEnv };