dotenv-extended 2.9.0 → 3.0.1

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,9 +1,12 @@
1
1
  # dotenv-extended
2
2
 
3
- [![Build Status](https://travis-ci.org/keithmorris/node-dotenv-extended.svg?branch=develop)](https://travis-ci.org/keithmorris/node-dotenv-extended)
4
- [![Coverage Status](https://coveralls.io/repos/github/keithmorris/node-dotenv-extended/badge.svg?branch=develop)](https://coveralls.io/github/keithmorris/node-dotenv-extended?branch=develop)
5
- [![Dependency Status](https://david-dm.org/keithmorris/node-dotenv-extended.svg)](https://david-dm.org/keithmorris/node-dotenv-extended)
3
+ Extended `.env` loading with defaults and schema validation.
6
4
 
5
+ ## Supported Node Versions
6
+
7
+ - Node `20.x`
8
+ - Node `22.x`
9
+ - Node `24.x`
7
10
 
8
11
  I've been a big fan of the [dotenv] for a quite some time (in fact, this library uses [dotenv] under the hood for the `.env` file parsing). However, while working on some bigger projects, we realized that the managing of the `.env` files became a bit of a chore. As the files changed in the development environments, it became a tedious manual process to compare and figure out what needed to be added or removed in the other environments.
9
12
 
@@ -29,7 +32,6 @@ Common configuration defaults across all environments (commited to source contro
29
32
 
30
33
  Defines a schema of what variables _should_ be defined in the combination of `.env` and `.env.defaults`. Optionally, you can have the library throw an error if all values are not configured or if there are extra values that shouldn't be there.
31
34
 
32
-
33
35
  The `.env.schema` file should only have the name of the variable and the `=` without any value:
34
36
 
35
37
  ```
@@ -49,6 +51,24 @@ I have tried to stay as compatible as possible with the [dotenv] library but the
49
51
  npm i --save dotenv-extended
50
52
  ```
51
53
 
54
+ ## Development
55
+
56
+ ```bash
57
+ npm run check
58
+ ```
59
+
60
+ `npm run check` runs linting, formatting checks, and tests.
61
+
62
+ Use individual commands only when needed:
63
+
64
+ ```bash
65
+ npm run build
66
+ npm run lint
67
+ npm run format
68
+ npm run test:unit
69
+ npm test
70
+ ```
71
+
52
72
  ## Usage
53
73
 
54
74
  As early as possible in your main script:
@@ -61,7 +81,7 @@ Or if you prefer import syntax:
61
81
 
62
82
  ```javascript
63
83
  import dotEnvExtended from 'dotenv-extended';
64
- dotEnvExtended.load();
84
+ dotEnvExtended.load();
65
85
  ```
66
86
 
67
87
  Create a `.env` file in the root directory of your project. Add environment-specific variables on new lines in the form of `NAME=VALUE`.
@@ -80,7 +100,7 @@ MONGO_PASS=dbpassword!
80
100
  ```javascript
81
101
  mongoose.connect('mongodb://' + process.env.MONGO_HOST + '/' + process.env.MONGO_DATABASE, {
82
102
  user: process.env.MONGO_USER,
83
- pass: process.env.MONGO_PASS
103
+ pass: process.env.MONGO_PASS,
84
104
  });
85
105
  ```
86
106
 
@@ -98,6 +118,8 @@ Or to specify load options:
98
118
  node -r dotenv-extended/config your_script.js dotenv_config_path=./env/.env dotenv_config_defaults=./env/.env.defaults
99
119
  ```
100
120
 
121
+ `dotenv_config_*` values are normalized to the same option names as `load()`, supporting both snake_case and kebab-case style keys.
122
+
101
123
  ### Load Environment Variables and pass to non-NodeJS script
102
124
 
103
125
  New in 2.0.0, is a feature inspired by [cross-env](https://www.npmjs.com/package/cross-env) to allow you to load environment variables from your `.env` files and then pass them into a non-NodeJS script such as a shell script. This can simplify the process of maintaining variables used in both your Node app and other scripts. To use this command line executable, you will either need to install globally with the `-g` flag, or install `dotenv-extended` in your project and reference it from your npm scripts.
@@ -142,19 +164,20 @@ Defaults are shown below:
142
164
 
143
165
  ```javascript
144
166
  require('dotenv-extended').load({
145
- encoding: 'utf8',
146
- silent: true,
147
- path: '.env',
148
- defaults: '.env.defaults',
149
- schema: '.env.schema',
150
- errorOnMissing: false,
151
- errorOnExtra: false,
152
- errorOnRegex: false,
153
- includeProcessEnv: false,
154
- assignToProcessEnv: true,
155
- overrideProcessEnv: false
167
+ encoding: 'utf8',
168
+ silent: true,
169
+ path: '.env',
170
+ defaults: '.env.defaults',
171
+ schema: '.env.schema',
172
+ errorOnMissing: false,
173
+ errorOnExtra: false,
174
+ errorOnRegex: false,
175
+ includeProcessEnv: false,
176
+ assignToProcessEnv: true,
177
+ overrideProcessEnv: false,
156
178
  });
157
179
  ```
180
+
158
181
  ### Configure via Environment Variables (New in 2.8.0)
159
182
 
160
183
  You may also set the configuration values via environment variables loaded from `process.env` shown below with defaults:
@@ -255,18 +278,18 @@ API_KEY=
255
278
  ```javascript
256
279
  const myConfig = require('dotenv-extended').load();
257
280
 
258
- myConfig.DB_HOST === process.env.DB_HOST === "localhost"
259
- myConfig.DB_USER === process.env.DB_USER === "databaseuser-local"
260
- myConfig.DB_PASS === process.env.DB_PASS === "localhost"
261
- myConfig.DB_DATABASE === process.env.DB_DATABASE === "MyAppDB"
262
- myConfig.SHARE_URL === process.env.SHARE_URL === "http://www.example.com"
281
+ (myConfig.DB_HOST === process.env.DB_HOST) === 'localhost';
282
+ (myConfig.DB_USER === process.env.DB_USER) === 'databaseuser-local';
283
+ (myConfig.DB_PASS === process.env.DB_PASS) === 'localhost';
284
+ (myConfig.DB_DATABASE === process.env.DB_DATABASE) === 'MyAppDB';
285
+ (myConfig.SHARE_URL === process.env.SHARE_URL) === 'http://www.example.com';
263
286
  ```
264
287
 
265
288
  ### Load files with `errorOnMissing`
266
289
 
267
290
  ```javascript
268
291
  const myConfig = require('dotenv-extended').load({
269
- errorOnMissing: true
292
+ errorOnMissing: true,
270
293
  });
271
294
 
272
295
  // Throws ERROR `MISSING CONFIG VALUES: API_KEY`
@@ -276,7 +299,7 @@ const myConfig = require('dotenv-extended').load({
276
299
 
277
300
  ```javascript
278
301
  const myConfig = require('dotenv-extended').load({
279
- errorOnExtra: true
302
+ errorOnExtra: true,
280
303
  });
281
304
 
282
305
  // Throws ERROR `EXTRA CONFIG VALUES: SHARE_URL`
@@ -286,7 +309,7 @@ const myConfig = require('dotenv-extended').load({
286
309
 
287
310
  ```javascript
288
311
  const myConfig = require('dotenv-extended').load({
289
- errorOnRegex: true
312
+ errorOnRegex: true,
290
313
  });
291
314
 
292
315
  // Throws ERROR `REGEX MISMATCH: DB_USER`
@@ -296,6 +319,18 @@ const myConfig = require('dotenv-extended').load({
296
319
 
297
320
  See [CONTRIBUTING.md](CONTRIBUTING.md)
298
321
 
322
+ ## Migration Notes
323
+
324
+ ### Migrating from legacy 2.x tooling
325
+
326
+ - Node `>=20` is now required.
327
+ - Build/test tooling no longer uses `gulp`, Babel, `esm`, or Mocha/NYC.
328
+ - The project now uses:
329
+ - `tsup` for build output in `lib/`
330
+ - `vitest` for tests
331
+ - modern `eslint` config and `prettier`
332
+ - Public API is kept compatible (`load`, `config`, `parse`, CLI behavior, and `dotenv-extended/config` preload entry).
333
+
299
334
  ## Change Log
300
335
 
301
336
  See [CHANGELOG.md](CHANGELOG.md)
@@ -72,7 +72,7 @@ export interface IDotenvExtendedOptions {
72
72
  errorOnRegex?: boolean;
73
73
 
74
74
  /**
75
- * Causes the library add process.env variables to error checking. The variables in process.env overrides the
75
+ * Causes the library add process.env variables to error checking. The variables in process.env overrides the
76
76
  * variables in .env and .env.defaults while checking
77
77
  *
78
78
  * @default false
package/lib/bin/cli.js ADDED
@@ -0,0 +1,224 @@
1
+ #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+
25
+ // src/index.js
26
+ var import_dotenv2 = __toESM(require("dotenv"));
27
+
28
+ // src/utils/parse-primitive.js
29
+ var parsePrimitive = (value) => {
30
+ if (value === null || typeof value === "undefined") {
31
+ return value;
32
+ }
33
+ if (typeof value === "number" || typeof value === "boolean") {
34
+ return value;
35
+ }
36
+ if (typeof value !== "string") {
37
+ return value;
38
+ }
39
+ let normalized = value.trim().replace(/(^"|"$)|(^'|'$)/g, "").toLowerCase();
40
+ if (normalized === "" || normalized === "undefined") {
41
+ return void 0;
42
+ }
43
+ if (normalized === "null") {
44
+ return null;
45
+ }
46
+ if (normalized === "nan") {
47
+ return NaN;
48
+ }
49
+ if (normalized === "true" || normalized === "1") {
50
+ return true;
51
+ }
52
+ if (normalized === "false" || normalized === "0") {
53
+ return false;
54
+ }
55
+ const numeric = Number(normalized);
56
+ if (!Number.isNaN(numeric)) {
57
+ return numeric;
58
+ }
59
+ return value;
60
+ };
61
+ var parse_primitive_default = parsePrimitive;
62
+
63
+ // src/utils/normalize-option-key.js
64
+ var normalizedWithSeparators = (key) => key.toLowerCase().replace(/[_-\s]+([a-z0-9])/g, (_, next) => next.toUpperCase());
65
+ var normalizeOptionKey = (key) => {
66
+ const trimmed = key.trim();
67
+ if (!trimmed) {
68
+ return "";
69
+ }
70
+ if (/[_-\s]/.test(trimmed)) {
71
+ return normalizedWithSeparators(trimmed);
72
+ }
73
+ if (trimmed === trimmed.toUpperCase()) {
74
+ return trimmed.toLowerCase();
75
+ }
76
+ return trimmed.charAt(0).toLowerCase() + trimmed.slice(1);
77
+ };
78
+ var normalize_option_key_default = normalizeOptionKey;
79
+
80
+ // src/utils/config-from-env.js
81
+ var getConfigFromEnv = (env) => {
82
+ let config2 = {};
83
+ Object.keys(env).forEach((key) => {
84
+ const curr = key.split("DOTENV_CONFIG_");
85
+ if (curr.length === 2 && curr[0] === "" && curr[1].length) {
86
+ config2[normalize_option_key_default(curr[1])] = parse_primitive_default(env[key]);
87
+ }
88
+ });
89
+ return config2;
90
+ };
91
+ var config_from_env_default = getConfigFromEnv;
92
+
93
+ // src/utils/load-environment-file.js
94
+ var import_fs = __toESM(require("fs"));
95
+ var import_dotenv = __toESM(require("dotenv"));
96
+ var loadEnvironmentFile = (path, encoding, silent) => {
97
+ try {
98
+ const data = import_fs.default.readFileSync(path, encoding);
99
+ return import_dotenv.default.parse(data);
100
+ } catch (err) {
101
+ if (!silent) {
102
+ console.error(err.message);
103
+ }
104
+ return {};
105
+ }
106
+ };
107
+ var load_environment_file_default = loadEnvironmentFile;
108
+
109
+ // src/index.js
110
+ var parse = import_dotenv2.default.parse.bind(import_dotenv2.default);
111
+ var config = (options) => {
112
+ let defaultsData, environmentData, defaultOptions = {
113
+ encoding: "utf8",
114
+ silent: true,
115
+ path: ".env",
116
+ defaults: ".env.defaults",
117
+ schema: ".env.schema",
118
+ errorOnMissing: false,
119
+ errorOnExtra: false,
120
+ errorOnRegex: false,
121
+ includeProcessEnv: false,
122
+ assignToProcessEnv: true,
123
+ overrideProcessEnv: false
124
+ }, processEnvOptions = config_from_env_default(process.env);
125
+ options = Object.assign({}, defaultOptions, processEnvOptions, options);
126
+ defaultsData = load_environment_file_default(options.defaults, options.encoding, options.silent);
127
+ environmentData = load_environment_file_default(options.path, options.encoding, options.silent);
128
+ let configData = Object.assign({}, defaultsData, environmentData);
129
+ const config2 = options.includeProcessEnv ? Object.assign({}, configData, process.env) : configData;
130
+ const configOnlyKeys = Object.keys(configData);
131
+ const configKeys = Object.keys(config2);
132
+ if (options.errorOnMissing || options.errorOnExtra || options.errorOnRegex) {
133
+ const schema = load_environment_file_default(options.schema, options.encoding, options.silent);
134
+ const schemaKeys = Object.keys(schema);
135
+ let missingKeys = schemaKeys.filter(function(key) {
136
+ return configKeys.indexOf(key) < 0;
137
+ });
138
+ let extraKeys = configOnlyKeys.filter(function(key) {
139
+ return schemaKeys.indexOf(key) < 0;
140
+ });
141
+ if (options.errorOnMissing && missingKeys.length) {
142
+ throw new Error("MISSING CONFIG VALUES: " + missingKeys.join(", "));
143
+ }
144
+ if (options.errorOnExtra && extraKeys.length) {
145
+ throw new Error("EXTRA CONFIG VALUES: " + extraKeys.join(", "));
146
+ }
147
+ if (options.errorOnRegex) {
148
+ const regexMismatchKeys = schemaKeys.filter(function(key) {
149
+ if (schema[key]) {
150
+ return !new RegExp(schema[key]).test(
151
+ typeof config2[key] === "string" ? config2[key] : ""
152
+ );
153
+ }
154
+ });
155
+ if (regexMismatchKeys.length) {
156
+ throw new Error("REGEX MISMATCH: " + regexMismatchKeys.join(", "));
157
+ }
158
+ }
159
+ }
160
+ if (options.includeProcessEnv && !options.overrideProcessEnv) {
161
+ for (let i = 0; i < configKeys.length; i++) {
162
+ if (typeof process.env[configKeys[i]] !== "undefined")
163
+ configData[configKeys[i]] = process.env[configKeys[i]];
164
+ }
165
+ }
166
+ if (options.assignToProcessEnv) {
167
+ if (options.overrideProcessEnv) {
168
+ Object.assign(process.env, configData);
169
+ } else {
170
+ const tmp = Object.assign({}, configData, process.env);
171
+ Object.assign(process.env, tmp);
172
+ }
173
+ }
174
+ return configData;
175
+ };
176
+
177
+ // src/utils/parse-command.js
178
+ var dotEnvFlagRegex = /^--(.+)=(.+)/;
179
+ var parseCommand = (args) => {
180
+ const config2 = {};
181
+ let command = null;
182
+ let commandArgs = [];
183
+ for (let i = 0; i < args.length; i++) {
184
+ const match = dotEnvFlagRegex.exec(args[i]);
185
+ if (match) {
186
+ config2[normalize_option_key_default(match[1])] = parse_primitive_default(match[2]);
187
+ } else {
188
+ command = args[i];
189
+ commandArgs = args.slice(i + 1);
190
+ break;
191
+ }
192
+ }
193
+ return [config2, command, commandArgs];
194
+ };
195
+ var parse_command_default = parseCommand;
196
+
197
+ // src/bin/index.js
198
+ var import_node_child_process = require("child_process");
199
+ var spawnCommand = (command, commandArgs, options) => (0, import_node_child_process.spawn)(command, commandArgs, options);
200
+ function loadAndExecute(args, dependencies = {}) {
201
+ const {
202
+ spawnCommandFn = spawnCommand,
203
+ processOn = process.on.bind(process),
204
+ processExit = process.exit
205
+ } = dependencies;
206
+ const [dotEnvConfig, command, commandArgs] = parse_command_default(args);
207
+ if (command) {
208
+ config(dotEnvConfig);
209
+ const proc = spawnCommandFn(command, commandArgs, {
210
+ stdio: "inherit",
211
+ shell: true,
212
+ env: process.env
213
+ });
214
+ processOn("SIGTERM", () => proc.kill("SIGTERM"));
215
+ processOn("SIGINT", () => proc.kill("SIGINT"));
216
+ processOn("SIGBREAK", () => proc.kill("SIGBREAK"));
217
+ processOn("SIGHUP", () => proc.kill("SIGHUP"));
218
+ proc.on("exit", processExit);
219
+ return proc;
220
+ }
221
+ }
222
+
223
+ // src/bin/cli.js
224
+ loadAndExecute(process.argv.slice(2));
package/lib/bin/index.js CHANGED
@@ -1,63 +1,239 @@
1
1
  #!/usr/bin/env node
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
2
29
 
3
- /**
4
- * Created by Keith Morris on 4/26/17.
5
- *
6
- * This bin script is inspired by and borrows heavily from CrossEnv
7
- * https://github.com/kentcdodds/cross-env
8
- */
9
- "use strict";
10
-
11
- var _ = require("..");
12
-
13
- var _parseCommand3 = _interopRequireDefault(require("../utils/parse-command"));
14
-
15
- var _crossSpawn = require("cross-spawn");
16
-
17
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
30
+ // src/bin/index.js
31
+ var bin_exports = {};
32
+ __export(bin_exports, {
33
+ loadAndExecute: () => loadAndExecute,
34
+ spawnCommand: () => spawnCommand
35
+ });
36
+ module.exports = __toCommonJS(bin_exports);
18
37
 
19
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
38
+ // src/index.js
39
+ var import_dotenv2 = __toESM(require("dotenv"));
20
40
 
21
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
41
+ // src/utils/parse-primitive.js
42
+ var parsePrimitive = (value) => {
43
+ if (value === null || typeof value === "undefined") {
44
+ return value;
45
+ }
46
+ if (typeof value === "number" || typeof value === "boolean") {
47
+ return value;
48
+ }
49
+ if (typeof value !== "string") {
50
+ return value;
51
+ }
52
+ let normalized = value.trim().replace(/(^"|"$)|(^'|'$)/g, "").toLowerCase();
53
+ if (normalized === "" || normalized === "undefined") {
54
+ return void 0;
55
+ }
56
+ if (normalized === "null") {
57
+ return null;
58
+ }
59
+ if (normalized === "nan") {
60
+ return NaN;
61
+ }
62
+ if (normalized === "true" || normalized === "1") {
63
+ return true;
64
+ }
65
+ if (normalized === "false" || normalized === "0") {
66
+ return false;
67
+ }
68
+ const numeric = Number(normalized);
69
+ if (!Number.isNaN(numeric)) {
70
+ return numeric;
71
+ }
72
+ return value;
73
+ };
74
+ var parse_primitive_default = parsePrimitive;
22
75
 
23
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
76
+ // src/utils/normalize-option-key.js
77
+ var normalizedWithSeparators = (key) => key.toLowerCase().replace(/[_-\s]+([a-z0-9])/g, (_, next) => next.toUpperCase());
78
+ var normalizeOptionKey = (key) => {
79
+ const trimmed = key.trim();
80
+ if (!trimmed) {
81
+ return "";
82
+ }
83
+ if (/[_-\s]/.test(trimmed)) {
84
+ return normalizedWithSeparators(trimmed);
85
+ }
86
+ if (trimmed === trimmed.toUpperCase()) {
87
+ return trimmed.toLowerCase();
88
+ }
89
+ return trimmed.charAt(0).toLowerCase() + trimmed.slice(1);
90
+ };
91
+ var normalize_option_key_default = normalizeOptionKey;
24
92
 
25
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
93
+ // src/utils/config-from-env.js
94
+ var getConfigFromEnv = (env) => {
95
+ let config2 = {};
96
+ Object.keys(env).forEach((key) => {
97
+ const curr = key.split("DOTENV_CONFIG_");
98
+ if (curr.length === 2 && curr[0] === "" && curr[1].length) {
99
+ config2[normalize_option_key_default(curr[1])] = parse_primitive_default(env[key]);
100
+ }
101
+ });
102
+ return config2;
103
+ };
104
+ var config_from_env_default = getConfigFromEnv;
26
105
 
27
- function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
106
+ // src/utils/load-environment-file.js
107
+ var import_fs = __toESM(require("fs"));
108
+ var import_dotenv = __toESM(require("dotenv"));
109
+ var loadEnvironmentFile = (path, encoding, silent) => {
110
+ try {
111
+ const data = import_fs.default.readFileSync(path, encoding);
112
+ return import_dotenv.default.parse(data);
113
+ } catch (err) {
114
+ if (!silent) {
115
+ console.error(err.message);
116
+ }
117
+ return {};
118
+ }
119
+ };
120
+ var load_environment_file_default = loadEnvironmentFile;
28
121
 
29
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
122
+ // src/index.js
123
+ var parse = import_dotenv2.default.parse.bind(import_dotenv2.default);
124
+ var config = (options) => {
125
+ let defaultsData, environmentData, defaultOptions = {
126
+ encoding: "utf8",
127
+ silent: true,
128
+ path: ".env",
129
+ defaults: ".env.defaults",
130
+ schema: ".env.schema",
131
+ errorOnMissing: false,
132
+ errorOnExtra: false,
133
+ errorOnRegex: false,
134
+ includeProcessEnv: false,
135
+ assignToProcessEnv: true,
136
+ overrideProcessEnv: false
137
+ }, processEnvOptions = config_from_env_default(process.env);
138
+ options = Object.assign({}, defaultOptions, processEnvOptions, options);
139
+ defaultsData = load_environment_file_default(options.defaults, options.encoding, options.silent);
140
+ environmentData = load_environment_file_default(options.path, options.encoding, options.silent);
141
+ let configData = Object.assign({}, defaultsData, environmentData);
142
+ const config2 = options.includeProcessEnv ? Object.assign({}, configData, process.env) : configData;
143
+ const configOnlyKeys = Object.keys(configData);
144
+ const configKeys = Object.keys(config2);
145
+ if (options.errorOnMissing || options.errorOnExtra || options.errorOnRegex) {
146
+ const schema = load_environment_file_default(options.schema, options.encoding, options.silent);
147
+ const schemaKeys = Object.keys(schema);
148
+ let missingKeys = schemaKeys.filter(function(key) {
149
+ return configKeys.indexOf(key) < 0;
150
+ });
151
+ let extraKeys = configOnlyKeys.filter(function(key) {
152
+ return schemaKeys.indexOf(key) < 0;
153
+ });
154
+ if (options.errorOnMissing && missingKeys.length) {
155
+ throw new Error("MISSING CONFIG VALUES: " + missingKeys.join(", "));
156
+ }
157
+ if (options.errorOnExtra && extraKeys.length) {
158
+ throw new Error("EXTRA CONFIG VALUES: " + extraKeys.join(", "));
159
+ }
160
+ if (options.errorOnRegex) {
161
+ const regexMismatchKeys = schemaKeys.filter(function(key) {
162
+ if (schema[key]) {
163
+ return !new RegExp(schema[key]).test(
164
+ typeof config2[key] === "string" ? config2[key] : ""
165
+ );
166
+ }
167
+ });
168
+ if (regexMismatchKeys.length) {
169
+ throw new Error("REGEX MISMATCH: " + regexMismatchKeys.join(", "));
170
+ }
171
+ }
172
+ }
173
+ if (options.includeProcessEnv && !options.overrideProcessEnv) {
174
+ for (let i = 0; i < configKeys.length; i++) {
175
+ if (typeof process.env[configKeys[i]] !== "undefined")
176
+ configData[configKeys[i]] = process.env[configKeys[i]];
177
+ }
178
+ }
179
+ if (options.assignToProcessEnv) {
180
+ if (options.overrideProcessEnv) {
181
+ Object.assign(process.env, configData);
182
+ } else {
183
+ const tmp = Object.assign({}, configData, process.env);
184
+ Object.assign(process.env, tmp);
185
+ }
186
+ }
187
+ return configData;
188
+ };
30
189
 
31
- function loadAndExecute(args) {
32
- var _parseCommand = (0, _parseCommand3["default"])(args),
33
- _parseCommand2 = _slicedToArray(_parseCommand, 3),
34
- dotEnvConfig = _parseCommand2[0],
35
- command = _parseCommand2[1],
36
- commandArgs = _parseCommand2[2];
190
+ // src/utils/parse-command.js
191
+ var dotEnvFlagRegex = /^--(.+)=(.+)/;
192
+ var parseCommand = (args) => {
193
+ const config2 = {};
194
+ let command = null;
195
+ let commandArgs = [];
196
+ for (let i = 0; i < args.length; i++) {
197
+ const match = dotEnvFlagRegex.exec(args[i]);
198
+ if (match) {
199
+ config2[normalize_option_key_default(match[1])] = parse_primitive_default(match[2]);
200
+ } else {
201
+ command = args[i];
202
+ commandArgs = args.slice(i + 1);
203
+ break;
204
+ }
205
+ }
206
+ return [config2, command, commandArgs];
207
+ };
208
+ var parse_command_default = parseCommand;
37
209
 
210
+ // src/bin/index.js
211
+ var import_node_child_process = require("child_process");
212
+ var spawnCommand = (command, commandArgs, options) => (0, import_node_child_process.spawn)(command, commandArgs, options);
213
+ function loadAndExecute(args, dependencies = {}) {
214
+ const {
215
+ spawnCommandFn = spawnCommand,
216
+ processOn = process.on.bind(process),
217
+ processExit = process.exit
218
+ } = dependencies;
219
+ const [dotEnvConfig, command, commandArgs] = parse_command_default(args);
38
220
  if (command) {
39
- (0, _.config)(dotEnvConfig); // mutates process.env
40
-
41
- var proc = (0, _crossSpawn.spawn)(command, commandArgs, {
42
- stdio: 'inherit',
221
+ config(dotEnvConfig);
222
+ const proc = spawnCommandFn(command, commandArgs, {
223
+ stdio: "inherit",
43
224
  shell: true,
44
225
  env: process.env
45
226
  });
46
- process.on('SIGTERM', function () {
47
- return proc.kill('SIGTERM');
48
- });
49
- process.on('SIGINT', function () {
50
- return proc.kill('SIGINT');
51
- });
52
- process.on('SIGBREAK', function () {
53
- return proc.kill('SIGBREAK');
54
- });
55
- process.on('SIGHUP', function () {
56
- return proc.kill('SIGHUP');
57
- });
58
- proc.on('exit', process.exit);
227
+ processOn("SIGTERM", () => proc.kill("SIGTERM"));
228
+ processOn("SIGINT", () => proc.kill("SIGINT"));
229
+ processOn("SIGBREAK", () => proc.kill("SIGBREAK"));
230
+ processOn("SIGHUP", () => proc.kill("SIGHUP"));
231
+ proc.on("exit", processExit);
59
232
  return proc;
60
233
  }
61
234
  }
62
-
63
- loadAndExecute(process.argv.slice(2));
235
+ // Annotate the CommonJS export names for ESM import in node:
236
+ 0 && (module.exports = {
237
+ loadAndExecute,
238
+ spawnCommand
239
+ });