dynenv 1.3.2 → 1.4.2

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
@@ -2,12 +2,12 @@
2
2
 
3
3
  Dynamically loads environment variables from modules and then spawns a child process with them
4
4
 
5
- It's like [dotenv](https://github.com/motdotla/dotenv), but instead of .env files, you require modules!
5
+ It's like [dotenv](https://github.com/motdotla/dotenv), but instead of .env files, you require modules!
6
6
 
7
7
  ## Usage
8
8
 
9
9
  Add `dynenv` as a dev dependency using your particular package manager:
10
- ```json
10
+ ```sh
11
11
  npm install dynenv --save-dev
12
12
  yarn add dynenv --dev
13
13
  ```
package/index.js CHANGED
@@ -1,80 +1,9 @@
1
1
  #!/usr/bin/env node
2
- const spawn = require('cross-spawn');
3
- const { readdir } = require('fs');
4
- const { join, resolve, sep } = require('path');
2
+ import { parseArgs } from './lib/parseArgs.js';
3
+ import { requireFiles } from './lib/requireFiles.js';
4
+ import { spawnNextCommand } from './lib/spawnNextCommand.js';
5
5
 
6
- parseArgs()
7
- .then(state => requireFiles(state))
8
- .then(state => process.exitCode = spawnNextCommand(state).status)
6
+ parseArgs(process.argv.slice(2))
7
+ .then(state => requireFiles(state, process.env))
8
+ .then(state => process.exitCode = spawnNextCommand(state).status)
9
9
  ;
10
-
11
- async function parseArgs() {
12
- const args = process.argv.slice(2);
13
- const barrier = args.indexOf('--');
14
- if (-1 === barrier) {
15
- const modules = await listDirectory('./node_modules/');
16
- for (const parentDirectory of modules.filter(m => m.indexOf(`${sep}@`) >= 0)) {
17
- modules.push(...await listDirectory(parentDirectory));
18
- }
19
- const filesToRequire = [];
20
- for (const module of modules) {
21
- const packageJSON = safeRequire(resolve(module, 'package.json'));
22
- if (packageJSON && packageJSON.dynenv) {
23
- filesToRequire.push(resolve(module, packageJSON.dynenv));
24
- }
25
- }
26
- return {
27
- filesToRequire,
28
- nextCommand: args[0],
29
- nextCommandArgs: args.slice(1),
30
- };
31
- }
32
- else {
33
- return {
34
- filesToRequire: args.slice(0, barrier),
35
- nextCommand: args[barrier + 1],
36
- nextCommandArgs: args.slice(barrier + 2),
37
- };
38
- }
39
- }
40
-
41
- function listDirectory(ref) {
42
- return new Promise((resolve, reject) => {
43
- readdir(ref, (err, results) => err
44
- ? reject(err)
45
- : resolve(results.map(result => join(ref, result))),
46
- );
47
- });
48
- }
49
-
50
- async function requireFiles(state) {
51
- state.env = Object.assign({}, process.env);
52
- for (const fileToRequire of state.filesToRequire) {
53
- const exports = safeRequire(fileToRequire.startsWith('./')
54
- ? resolve(fileToRequire)
55
- : fileToRequire);
56
- const newEnv = typeof exports === 'function'
57
- ? await exports()
58
- : exports;
59
- if (newEnv) {
60
- Object.assign(state.env, newEnv);
61
- }
62
- }
63
- return state;
64
- }
65
-
66
- function safeRequire(ref) {
67
- try {
68
- return require(ref);
69
- }
70
- catch (err) {
71
- return null;
72
- }
73
- }
74
-
75
- function spawnNextCommand({ nextCommand, nextCommandArgs, env }) {
76
- return spawn.sync(nextCommand, nextCommandArgs, {
77
- stdio: 'inherit',
78
- env,
79
- });
80
- }
@@ -0,0 +1,11 @@
1
+ import { readdir } from 'fs';
2
+ import { join } from 'path';
3
+
4
+ export function listDirectory(ref) {
5
+ return new Promise((resolve, reject) => {
6
+ readdir(ref, (err, results) => err
7
+ ? reject(err)
8
+ : resolve(results.map(result => join(ref, result))),
9
+ );
10
+ });
11
+ }
@@ -0,0 +1,32 @@
1
+ import { resolve, sep } from 'path';
2
+ import { listDirectory } from './listDirectory.js';
3
+ import { safeRequire } from './safeRequire.js';
4
+
5
+ export async function parseArgs(args) {
6
+ const barrier = args.indexOf('--');
7
+ if (-1 === barrier) {
8
+ const modules = await listDirectory('./node_modules/');
9
+ for (const parentDirectory of modules.filter(m => m.indexOf(`${sep}@`) >= 0)) {
10
+ modules.push(...await listDirectory(parentDirectory));
11
+ }
12
+ const filesToRequire = [];
13
+ for (const module of modules) {
14
+ const packageJSON = safeRequire(resolve(module, 'package.json'));
15
+ if (packageJSON && packageJSON.dynenv) {
16
+ filesToRequire.push(resolve(module, packageJSON.dynenv));
17
+ }
18
+ }
19
+ return {
20
+ filesToRequire,
21
+ nextCommand: args[0],
22
+ nextCommandArgs: args.slice(1),
23
+ };
24
+ }
25
+ else {
26
+ return {
27
+ filesToRequire: args.slice(0, barrier),
28
+ nextCommand: args[barrier + 1],
29
+ nextCommandArgs: args.slice(barrier + 2),
30
+ };
31
+ }
32
+ }
@@ -0,0 +1,18 @@
1
+ import { resolve } from 'path';
2
+ import { safeRequire } from './safeRequire.js';
3
+
4
+ export async function requireFiles(state, initialEnv) {
5
+ state.env = Object.assign({}, initialEnv);
6
+ for (const fileToRequire of state.filesToRequire) {
7
+ const exports = safeRequire(fileToRequire.startsWith('./')
8
+ ? resolve(fileToRequire)
9
+ : fileToRequire);
10
+ const newEnv = typeof exports === 'function'
11
+ ? await exports()
12
+ : exports;
13
+ if (newEnv) {
14
+ Object.assign(state.env, newEnv);
15
+ }
16
+ }
17
+ return state;
18
+ }
@@ -0,0 +1,14 @@
1
+ import { createRequire } from 'module';
2
+
3
+ // Create a CommonJS-compatible require that works from ESM context
4
+ const requireCompat = createRequire(import.meta.url);
5
+
6
+ export function safeRequire(ref) {
7
+ try {
8
+ return requireCompat(ref);
9
+ }
10
+ catch (err) {
11
+ console.error(err);
12
+ return null;
13
+ }
14
+ }
@@ -0,0 +1,8 @@
1
+ import { sync } from 'cross-spawn';
2
+
3
+ export function spawnNextCommand({ nextCommand, nextCommandArgs, env }) {
4
+ return sync(nextCommand, nextCommandArgs, {
5
+ stdio: 'inherit',
6
+ env,
7
+ });
8
+ }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.2",
2
+ "version": "1.4.2",
3
3
  "name": "dynenv",
4
4
  "description": "Dynamically loads environment variables from modules and then spawns a child process with them",
5
5
  "author": "Dawson Toth",
@@ -7,33 +7,40 @@
7
7
  "dotenv"
8
8
  ],
9
9
  "homepage": ".",
10
- "license": "",
10
+ "type": "module",
11
+ "license": "ISC",
12
+ "publishConfig": {
13
+ "registry": "https://registry.npmjs.org/",
14
+ "tag": "latest",
15
+ "provenance": true
16
+ },
11
17
  "repository": "github:dawsontoth/dynenv",
12
18
  "main": "index.js",
13
19
  "bin": {
14
20
  "dynenv": "./index.js"
15
21
  },
16
- "scripts": {},
22
+ "scripts": {
23
+ "test": "vitest",
24
+ "test:ci": "vitest run",
25
+ "test:coverage": "vitest run --coverage",
26
+ "lint": "eslint .",
27
+ "lint:fix": "eslint . --fix"
28
+ },
17
29
  "dependencies": {
18
30
  "cross-spawn": "^7.0.3"
19
31
  },
20
32
  "devDependencies": {
33
+ "@eslint/js": "^9.39.1",
34
+ "@semantic-release/commit-analyzer": "^13.0.1",
21
35
  "@semantic-release/git": "^10.0.1",
22
- "semantic-release": "^23.0.0"
23
- },
24
- "plugins": [
25
- "@semantic-release/commit-analyzer",
26
- "@semantic-release/release-notes-generator",
27
- [
28
- "@semantic-release/git",
29
- {
30
- "assets": [
31
- "dist/**/*.{js,css}",
32
- "docs",
33
- "package.json"
34
- ],
35
- "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
36
- }
37
- ]
38
- ]
36
+ "@semantic-release/github": "^12.0.2",
37
+ "@semantic-release/npm": "^13.1.1",
38
+ "@semantic-release/release-notes-generator": "^14.1.0",
39
+ "@vitest/coverage-v8": "^4.0.8",
40
+ "conventional-changelog-conventionalcommits": "^9.1.0",
41
+ "eslint": "^9.39.1",
42
+ "globals": "^16.5.0",
43
+ "semantic-release": "^25.0.2",
44
+ "vitest": "^4.0.8"
45
+ }
39
46
  }