@willbooster/wb 18.0.0 → 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 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. .env files are
27
- ignored.
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. .env files are ignored.
39
- wb tc Run type checking. .env files are ignored.
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 .env files to be loaded. [array]
43
- --cascade-env Environment to load cascading .env files (e.g.,
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
- // Two selectors, both defaulting to development like wb's main loader (`WB_ENV || NODE_ENV ||
94
- // 'development'`) so a repo keeping dev-only secrets in `[profiles.development.secrets]` loads them
95
- // when WB_ENV is unset instead of only the base table:
96
- // - envCascade picks the `.env.<envCascade>` files. It must NOT consult FNOX_PROFILE — that is a
97
- // fnox-only selector, and letting it redirect a legacy `.env`-only project's cascade would load
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
- // Mode-specific sources drive the forced-mode override below (only meaningful when the mode is forced).
105
- const modeVars = mode
106
- ? { ...readEnvFile(path.join(cwd, `.env.${mode}`)), ...readEnvFile(path.join(cwd, `.env.${mode}.local`)) }
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
- // fnox.toml is the committed, encrypted equivalent of .env files; local .env files still win over it.
121
- const fnoxVars = readFnoxEnvironmentVariables(cwd, fnoxCascade, dotenvVars, modeFileOverridesProcessEnv);
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, so a shell-shadowed key expands to the shell value
126
- // while a winning file/override value expands to the file value.
127
- const fileValueWins = (key) =>
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 && fileValueWins(key))) {
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
- // readFnoxEnvironmentVariables returns a process.env-shadowed key only when the forced
143
- // profile overrides it, so fnox-provided keys count as mode-specific here.
144
- if (!(key in modeVars || key in fnoxVars) || process.env[key] === value) continue;
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 FILE is
155
- // honored: both the captured exported mode (it selected the cascade) and the FINAL value 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 must
160
- // agree with, else the child runs labeled one environment while carrying another's secrets. The
161
- // expectation is `fnoxCascade` only when a fnox config participates (its profile provides WB_ENV in a
162
- // compliant repo); in a legacy `.env`-only project FNOX_PROFILE is irrelevant, so the expectation is
163
- // `envCascade`. This covers both a forced `.env.production` containing `WB_ENV=development` and the
164
- // default-development path (`.env.development`, read even when WB_ENV is unset, containing
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, currentEnvVars, modeFileOverridesProcessEnv) {
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' || key in currentEnvVars) continue;
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', 'env', 'working-dir', 'w']);
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) {