@willbooster/wb 21.6.0 → 21.7.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 +7 -2
- package/bin/dotenv.js +34 -16
- package/dist/index.js +39 -39
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -13,12 +13,16 @@ wb <command>
|
|
|
13
13
|
|
|
14
14
|
Commands:
|
|
15
15
|
wb buildIfNeeded Build code if changes are detected
|
|
16
|
-
wb kill-port
|
|
17
|
-
|
|
16
|
+
wb kill-port <ports..> Kill the processes listening on the given TCP
|
|
17
|
+
ports
|
|
18
|
+
wb kill-port-if-non-ci Kill the process on the PORT environment
|
|
19
|
+
variable (or the auto-selection preferred port)
|
|
20
|
+
if non-CI.
|
|
18
21
|
wb lint [files...] Lint code
|
|
19
22
|
wb maintenance <action> Start or stop a lightweight maintenance page
|
|
20
23
|
server.
|
|
21
24
|
Example: wb maintenance start
|
|
25
|
+
wb open-cli <target> Open a URL or file in its default application
|
|
22
26
|
wb optimizeForDockerBuild Optimize configuration when building a Docker
|
|
23
27
|
image
|
|
24
28
|
wb prisma Run database commands [aliases: db]
|
|
@@ -39,6 +43,7 @@ Commands:
|
|
|
39
43
|
loaded.
|
|
40
44
|
wb tc Run type checking. Environment variables are not
|
|
41
45
|
loaded.
|
|
46
|
+
wb wait-on <resource> Wait for an HTTP(S) URL or TCP port
|
|
42
47
|
|
|
43
48
|
Options:
|
|
44
49
|
--cascade-env Environment (fnox profile / mise env) to load
|
package/bin/dotenv.js
CHANGED
|
@@ -161,25 +161,34 @@ function readFnoxEnvironmentVariables(cwd, cascade, modeFileOverridesProcessEnv)
|
|
|
161
161
|
|
|
162
162
|
const secrets = runFnoxExport(cwd, cascade, { quiet: false });
|
|
163
163
|
if (!secrets) return {};
|
|
164
|
-
// A key is profile-specific (and may override process.env off CI)
|
|
165
|
-
//
|
|
166
|
-
//
|
|
164
|
+
// A key's value is profile-specific (and may override process.env off CI) under EITHER
|
|
165
|
+
// criterion: the `--no-defaults` export — the profile's own table without the base `[secrets]`
|
|
166
|
+
// — contains it, or its value differs from the base export's (which alone covers a base entry
|
|
167
|
+
// interpolating a profile-overridden key). Both exports run lazily, only when a process.env
|
|
168
|
+
// collision needs adjudicating, and a failing export disables its own criterion. Because the
|
|
169
|
+
// profile-only export omits the base table, fnox rejects a profile default referencing a base
|
|
170
|
+
// secret (forbidden by the repository rules); the warning names the rule.
|
|
171
|
+
let cachedProfileKeys = false;
|
|
172
|
+
const getProfileKeys = () => {
|
|
173
|
+
if (cachedProfileKeys === false) {
|
|
174
|
+
const profileSecrets = runFnoxExport(cwd, cascade, { quiet: false, profileOnly: true });
|
|
175
|
+
cachedProfileKeys = profileSecrets && new Set(Object.keys(profileSecrets));
|
|
176
|
+
}
|
|
177
|
+
return cachedProfileKeys;
|
|
178
|
+
};
|
|
167
179
|
let cachedBaseSecrets = false;
|
|
168
|
-
const
|
|
180
|
+
const overridesProcessEnv = (key, value) => {
|
|
181
|
+
if (getProfileKeys()?.has(key)) return true;
|
|
169
182
|
if (cachedBaseSecrets === false) {
|
|
170
183
|
cachedBaseSecrets = runFnoxExport(cwd, undefined, { quiet: true, ignoreProfileEnvVar: true });
|
|
171
184
|
}
|
|
172
|
-
return cachedBaseSecrets;
|
|
185
|
+
return cachedBaseSecrets !== undefined && cachedBaseSecrets[key] !== value;
|
|
173
186
|
};
|
|
174
187
|
|
|
175
188
|
const envVars = {};
|
|
176
189
|
for (const [key, value] of Object.entries(secrets)) {
|
|
177
190
|
if (typeof value !== 'string') continue;
|
|
178
|
-
if (key in process.env)
|
|
179
|
-
const baseSecrets = modeFileOverridesProcessEnv && cascade ? getBaseSecrets() : undefined;
|
|
180
|
-
const overridesProcessEnv = baseSecrets !== undefined && baseSecrets[key] !== value;
|
|
181
|
-
if (!overridesProcessEnv) continue;
|
|
182
|
-
}
|
|
191
|
+
if (key in process.env && !(modeFileOverridesProcessEnv && cascade && overridesProcessEnv(key, value))) continue;
|
|
183
192
|
envVars[key] = value;
|
|
184
193
|
}
|
|
185
194
|
return envVars;
|
|
@@ -189,15 +198,18 @@ function runFnoxExport(cwd, cascade, options) {
|
|
|
189
198
|
// `--if-missing error`: fnox otherwise exits 0 and silently omits secrets it fails to resolve.
|
|
190
199
|
// `--non-interactive`: prompts or browser auth flows would hang forever because stdin is ignored.
|
|
191
200
|
const args = ['export', '--format', 'json', '--no-color', '--if-missing', 'error', '--non-interactive'];
|
|
192
|
-
const env = { ...process.env };
|
|
193
201
|
if (cascade) {
|
|
194
202
|
args.push('--profile', cascade);
|
|
195
203
|
}
|
|
204
|
+
if (options.profileOnly) {
|
|
205
|
+
// Omit the base `[secrets]` table so the export's key set is exactly the profile's own
|
|
206
|
+
// declarations, giving per-key provenance regardless of whether the values coincide.
|
|
207
|
+
args.push('--no-defaults');
|
|
208
|
+
}
|
|
209
|
+
const env = { ...process.env };
|
|
196
210
|
if (options.ignoreProfileEnvVar) {
|
|
197
|
-
// Without `--profile`, fnox falls back to FNOX_PROFILE; the base-adjudication export must
|
|
198
|
-
//
|
|
199
|
-
// it. A PRIMARY export still honors FNOX_PROFILE: it either stays profile-less (fnox reads the
|
|
200
|
-
// variable) or folds it into the `--profile` it passes (see wb dotenv's cascade).
|
|
211
|
+
// Without `--profile`, fnox falls back to FNOX_PROFILE; the base-adjudication export must read
|
|
212
|
+
// the BASE secrets, so the inherited profile selection is cleared for it — and only for it.
|
|
201
213
|
delete env.FNOX_PROFILE;
|
|
202
214
|
}
|
|
203
215
|
const result = childProcess.spawnSync('fnox', args, {
|
|
@@ -207,9 +219,15 @@ function runFnoxExport(cwd, cascade, options) {
|
|
|
207
219
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
208
220
|
});
|
|
209
221
|
if (result.error || result.status !== 0 || !result.stdout?.trim()) {
|
|
222
|
+
// The profile-only export reports what its failure costs plus its likeliest cause, and always
|
|
223
|
+
// quotes fnox's own error because other causes (e.g. a fnox too old for `--no-defaults`) look
|
|
224
|
+
// identical from here.
|
|
210
225
|
if (!options.quiet) {
|
|
226
|
+
const reason = result.error?.message || result.stderr?.trim() || `fnox exited with status ${result.status}`;
|
|
211
227
|
console.warn(
|
|
212
|
-
|
|
228
|
+
options.profileOnly
|
|
229
|
+
? `Failed to read the "${cascade}" fnox profile's own secrets, so its values equal to the base values do not override the inherited environment variables. Make the defaults in [profiles.${cascade}.secrets] independent of the base [secrets] table. ${reason}`
|
|
230
|
+
: `Failed to read fnox secrets: ${reason}`
|
|
213
231
|
);
|
|
214
232
|
}
|
|
215
233
|
return;
|