@willbooster/wb 18.0.1 → 19.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 +8 -11
- package/bin/dotenv.js +27 -57
- package/bin/runArgs.js +1 -2
- package/dist/index.js +37 -37
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,8 +23,8 @@ Commands:
|
|
|
23
23
|
image
|
|
24
24
|
wb prisma Run database commands [aliases: db]
|
|
25
25
|
wb retry [command] [args...] Retry the given command until it succeeds
|
|
26
|
-
wb setup Setup development environment.
|
|
27
|
-
|
|
26
|
+
wb setup Setup development environment. Environment
|
|
27
|
+
variables are not loaded.
|
|
28
28
|
wb setup-private-packages Materialize private git and registry
|
|
29
29
|
dependencies for Docker builds (installed
|
|
30
30
|
registry packages satisfying an exact version
|
|
@@ -35,22 +35,19 @@ Commands:
|
|
|
35
35
|
wb test [targets...] Test project. If you pass no arguments, it will
|
|
36
36
|
run all tests.
|
|
37
37
|
wb test-on-ci Test project on CI with no options.
|
|
38
|
-
wb typecheck Run type checking.
|
|
39
|
-
|
|
38
|
+
wb typecheck Run type checking. Environment variables are not
|
|
39
|
+
loaded.
|
|
40
|
+
wb tc Run type checking. Environment variables are not
|
|
41
|
+
loaded.
|
|
40
42
|
|
|
41
43
|
Options:
|
|
42
|
-
--env
|
|
43
|
-
|
|
44
|
-
`.env`, `.env.<environment>`, `.env.local` and
|
|
45
|
-
`.env.<environment>.local`). Preferred over
|
|
44
|
+
--cascade-env Environment (fnox profile / mise env) to load
|
|
45
|
+
environment variables for. Preferred over
|
|
46
46
|
`cascade-node-env` and `auto-cascade-env`. [string]
|
|
47
47
|
--cascade-node-env Same with --cascade-env=<NODE_ENV || "development">.
|
|
48
48
|
Preferred over `auto-cascade-env`. [boolean]
|
|
49
49
|
--auto-cascade-env Same with --cascade-env=<WB_ENV || NODE_ENV ||
|
|
50
50
|
"development">. [boolean] [default: true]
|
|
51
|
-
--include-root-env Include .env files in root directory if the project is
|
|
52
|
-
in a monorepo and --env option is not used.
|
|
53
|
-
[boolean] [default: true]
|
|
54
51
|
-v, --verbose Whether to show verbose information [boolean]
|
|
55
52
|
-w, --working-dir A working directory [string]
|
|
56
53
|
-d, --dry-run, --dry Whether to skip actual command execution [boolean]
|
package/bin/dotenv.js
CHANGED
|
@@ -2,7 +2,6 @@ import childProcess from 'node:child_process';
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
|
|
5
|
-
import { config } from 'dotenv';
|
|
6
5
|
import { expand } from 'dotenv-expand';
|
|
7
6
|
|
|
8
7
|
const shutdownSignals = new Set(['SIGINT', 'SIGTERM', 'SIGQUIT']);
|
|
@@ -90,46 +89,27 @@ function readAndApplyEnvironmentVariables(cwd) {
|
|
|
90
89
|
// The mode is FORCED only when WB_ENV is explicitly exported; it drives the forced-mode override
|
|
91
90
|
// below and the validation at the end.
|
|
92
91
|
const mode = process.env.WB_ENV;
|
|
93
|
-
//
|
|
94
|
-
// 'development'`) so a repo keeping dev-only secrets in
|
|
95
|
-
// when WB_ENV is unset instead of only the base
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
// the wrong files.
|
|
99
|
-
// - fnoxCascade picks the fnox `--profile` and gates the WB_ENV check below. It additionally honors
|
|
100
|
-
// an explicit FNOX_PROFILE, because fnox honors it and `wb dotenv` without WB_ENV is documented
|
|
101
|
-
// to as well.
|
|
102
|
-
const envCascade = mode || process.env.NODE_ENV || 'development';
|
|
92
|
+
// The fnox `--profile` selector, defaulting to development like wb's main loader (`WB_ENV ||
|
|
93
|
+
// NODE_ENV || 'development'`) so a repo keeping dev-only secrets in
|
|
94
|
+
// `[profiles.development.secrets]` loads them when WB_ENV is unset instead of only the base
|
|
95
|
+
// table. It additionally honors an explicit FNOX_PROFILE, because fnox honors it and
|
|
96
|
+
// `wb dotenv` without WB_ENV is documented to as well.
|
|
103
97
|
const fnoxCascade = mode || process.env.FNOX_PROFILE || process.env.NODE_ENV || 'development';
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
: {};
|
|
108
|
-
// Mirror the shared cascade's precedence: .env.<c>.local > .env.local > .env.<c> > .env (c = envCascade).
|
|
109
|
-
const dotenvVars = {
|
|
110
|
-
...readEnvFile(path.join(cwd, '.env')),
|
|
111
|
-
...readEnvFile(path.join(cwd, `.env.${envCascade}`)),
|
|
112
|
-
...readEnvFile(path.join(cwd, '.env.local')),
|
|
113
|
-
...readEnvFile(path.join(cwd, `.env.${envCascade}.local`)),
|
|
114
|
-
};
|
|
115
|
-
// WB_ENV in process.env means the mode is explicitly forced, so values from the mode's own
|
|
116
|
-
// sources (.env.<mode>[.local] and the fnox profile) win over variables inherited from the
|
|
117
|
-
// parent shell — except on CI, where injected env vars must keep overriding committed files
|
|
98
|
+
// WB_ENV in process.env means the mode is explicitly forced, so values from the mode's own fnox
|
|
99
|
+
// profile win over variables inherited from the parent shell — except on CI, where injected env
|
|
100
|
+
// vars must keep overriding committed values
|
|
118
101
|
// (see https://github.com/WillBooster/shared/issues/930).
|
|
119
102
|
const modeFileOverridesProcessEnv = !!mode && !isCI(process.env.CI);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const parsed = { ...fnoxVars, ...dotenvVars };
|
|
123
|
-
// Expand ${...} references against exported variables whose FILE value loses to the shell
|
|
103
|
+
const parsed = readFnoxEnvironmentVariables(cwd, fnoxCascade, modeFileOverridesProcessEnv);
|
|
104
|
+
// Expand ${...} references against exported variables whose fnox value loses to the shell
|
|
124
105
|
// (mirroring readEnvironmentVariables' effective-value semantics): a reference must resolve to
|
|
125
|
-
// the value the child will actually see
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
!(key in process.env) || (modeFileOverridesProcessEnv && (key in modeVars || key in fnoxVars));
|
|
106
|
+
// the value the child will actually see. readFnoxEnvironmentVariables returns a
|
|
107
|
+
// process.env-shadowed key only when the forced profile overrides it, so every parsed key's own
|
|
108
|
+
// value wins and is excluded from the reference set.
|
|
129
109
|
const referenceEnv = {};
|
|
130
110
|
for (const [key, value] of Object.entries(process.env)) {
|
|
131
111
|
// Escape dollar signs so exported values substitute literally (pa$word stays pa$word).
|
|
132
|
-
if (value !== undefined && !(key in parsed
|
|
112
|
+
if (value !== undefined && !(key in parsed)) {
|
|
133
113
|
referenceEnv[key] = value.replaceAll('$', String.raw`\$`);
|
|
134
114
|
}
|
|
135
115
|
}
|
|
@@ -139,33 +119,27 @@ function readAndApplyEnvironmentVariables(cwd) {
|
|
|
139
119
|
process.env[key] = value;
|
|
140
120
|
continue;
|
|
141
121
|
}
|
|
142
|
-
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
122
|
+
if (process.env[key] === value) continue;
|
|
123
|
+
// A process.env-shadowed key reaches here only when the forced profile overrides it (see
|
|
124
|
+
// readFnoxEnvironmentVariables); on CI such keys are never returned, so no branch is needed.
|
|
146
125
|
if (modeFileOverridesProcessEnv) {
|
|
147
126
|
console.warn(
|
|
148
127
|
`Warning: ${key} in the "${mode}" mode's env sources overrides the value inherited from the parent environment because WB_ENV is explicitly set.`
|
|
149
128
|
);
|
|
150
129
|
process.env[key] = value;
|
|
151
130
|
}
|
|
152
|
-
// On CI, inherited variables intentionally win; no warning is emitted.
|
|
153
131
|
}
|
|
154
|
-
// Validate only AFTER applying the sources, so a WB_SKIP_ENV_CHECK defined in an env
|
|
155
|
-
// honored: both the captured exported mode (it selected the
|
|
132
|
+
// Validate only AFTER applying the sources, so a WB_SKIP_ENV_CHECK defined in an env SOURCE is
|
|
133
|
+
// honored: both the captured exported mode (it selected the profile) and the FINAL value the
|
|
156
134
|
// child will see.
|
|
157
135
|
validateStandardWbEnv(mode, 'the exported variable');
|
|
158
136
|
validateStandardWbEnv(process.env.WB_ENV, 'the env source or the exported variable');
|
|
159
|
-
// The selected environment is what an env source silently resolving WB_ENV to a DIFFERENT value
|
|
160
|
-
// agree with, else the child runs labeled one environment while carrying another's secrets.
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
// `WB_ENV=production`), comparing against the selected cascade rather than just the forced `mode`.
|
|
166
|
-
// Only a STANDARD cascade is enforced (mirroring Project.completeAndValidateWbEnv): a custom suffix
|
|
167
|
-
// such as `NODE_ENV=qa` legitimately selects `.env.qa` while WB_ENV stays a standard mode.
|
|
168
|
-
const expectedCascade = hasProjectFnoxConfig(cwd) ? fnoxCascade : envCascade;
|
|
137
|
+
// The selected environment is what an env source silently resolving WB_ENV to a DIFFERENT value
|
|
138
|
+
// must agree with, else the child runs labeled one environment while carrying another's secrets.
|
|
139
|
+
// Only a STANDARD cascade is enforced (mirroring Project.completeAndValidateWbEnv): a custom
|
|
140
|
+
// selector such as `NODE_ENV=qa` legitimately selects the `qa` profile while WB_ENV stays a
|
|
141
|
+
// standard mode.
|
|
142
|
+
const expectedCascade = fnoxCascade;
|
|
169
143
|
if (
|
|
170
144
|
process.env.WB_ENV &&
|
|
171
145
|
['development', 'test', 'staging', 'production'].includes(expectedCascade) &&
|
|
@@ -182,7 +156,7 @@ function readAndApplyEnvironmentVariables(cwd) {
|
|
|
182
156
|
}
|
|
183
157
|
|
|
184
158
|
// Mirrors readFnoxEnvironmentVariables in @willbooster/shared-lib-node for this startup fast path.
|
|
185
|
-
function readFnoxEnvironmentVariables(cwd, cascade,
|
|
159
|
+
function readFnoxEnvironmentVariables(cwd, cascade, modeFileOverridesProcessEnv) {
|
|
186
160
|
if (!hasProjectFnoxConfig(cwd)) return {};
|
|
187
161
|
|
|
188
162
|
const secrets = runFnoxExport(cwd, cascade, { quiet: false });
|
|
@@ -200,7 +174,7 @@ function readFnoxEnvironmentVariables(cwd, cascade, currentEnvVars, modeFileOver
|
|
|
200
174
|
|
|
201
175
|
const envVars = {};
|
|
202
176
|
for (const [key, value] of Object.entries(secrets)) {
|
|
203
|
-
if (typeof value !== 'string'
|
|
177
|
+
if (typeof value !== 'string') continue;
|
|
204
178
|
if (key in process.env) {
|
|
205
179
|
const baseSecrets = modeFileOverridesProcessEnv && cascade ? getBaseSecrets() : undefined;
|
|
206
180
|
const overridesProcessEnv = baseSecrets !== undefined && baseSecrets[key] !== value;
|
|
@@ -267,10 +241,6 @@ function hasProjectFnoxConfig(cwd) {
|
|
|
267
241
|
}
|
|
268
242
|
}
|
|
269
243
|
|
|
270
|
-
function readEnvFile(filePath) {
|
|
271
|
-
return config({ path: path.resolve(filePath), processEnv: {}, quiet: true }).parsed ?? {};
|
|
272
|
-
}
|
|
273
|
-
|
|
274
244
|
function removeNpmAndYarnEnvironmentVariables(envVars) {
|
|
275
245
|
if (envVars.PATH && envVars.BERRY_BIN_FOLDER) {
|
|
276
246
|
envVars.PATH = envVars.PATH.replace(`${envVars.BERRY_BIN_FOLDER}:`, '')
|
package/bin/runArgs.js
CHANGED
|
@@ -6,13 +6,12 @@ const booleanOptionNames = new Set([
|
|
|
6
6
|
'd',
|
|
7
7
|
'help',
|
|
8
8
|
'h',
|
|
9
|
-
'include-root-env',
|
|
10
9
|
'quiet-env',
|
|
11
10
|
'verbose',
|
|
12
11
|
'v',
|
|
13
12
|
'version',
|
|
14
13
|
]);
|
|
15
|
-
const valueOptionNames = new Set(['cascade-env', '
|
|
14
|
+
const valueOptionNames = new Set(['cascade-env', 'working-dir', 'w']);
|
|
16
15
|
const boundaryMarkerEnvName = 'WB_INTERNAL_RUN_BOUNDARY_MARKER';
|
|
17
16
|
|
|
18
17
|
export function protectRunScriptArgs(argv) {
|