@hominis/fireforge 0.37.0 → 0.39.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/CHANGELOG.md +33 -0
- package/README.md +1 -1
- package/dist/src/commands/build.js +13 -8
- package/dist/src/commands/config.js +1 -0
- package/dist/src/commands/discard.js +75 -50
- package/dist/src/commands/download.js +5 -2
- package/dist/src/commands/export-flow.d.ts +6 -2
- package/dist/src/commands/export-flow.js +17 -11
- package/dist/src/commands/export-placement-gate.js +4 -6
- package/dist/src/commands/export-placement-policy.d.ts +11 -3
- package/dist/src/commands/export-placement-policy.js +32 -29
- package/dist/src/commands/export-shared.js +17 -2
- package/dist/src/commands/export.js +5 -5
- package/dist/src/commands/furnace/index.js +23 -18
- package/dist/src/commands/import.js +5 -0
- package/dist/src/commands/lint-per-patch.js +15 -5
- package/dist/src/commands/lint.js +1 -1
- package/dist/src/commands/patch/lint-ignore.js +20 -1
- package/dist/src/commands/patch/move-files-create.d.ts +19 -0
- package/dist/src/commands/patch/move-files-create.js +116 -0
- package/dist/src/commands/patch/move-files-into.d.ts +47 -0
- package/dist/src/commands/patch/move-files-into.js +245 -0
- package/dist/src/commands/patch/move-files.d.ts +3 -1
- package/dist/src/commands/patch/move-files.js +74 -15
- package/dist/src/commands/patch/rename.js +4 -1
- package/dist/src/commands/patch/split.d.ts +11 -1
- package/dist/src/commands/patch/split.js +6 -5
- package/dist/src/commands/re-export-scan.d.ts +17 -0
- package/dist/src/commands/re-export-scan.js +51 -0
- package/dist/src/commands/re-export.js +17 -6
- package/dist/src/commands/reset.js +5 -0
- package/dist/src/commands/source.js +28 -3
- package/dist/src/commands/status-output.d.ts +9 -0
- package/dist/src/commands/status-output.js +33 -1
- package/dist/src/commands/status.js +17 -3
- package/dist/src/commands/test-diagnose.d.ts +1 -1
- package/dist/src/commands/test-diagnose.js +9 -3
- package/dist/src/commands/test-modes.d.ts +21 -0
- package/dist/src/commands/test-modes.js +42 -0
- package/dist/src/commands/test-register.js +6 -5
- package/dist/src/commands/test-run.d.ts +2 -0
- package/dist/src/commands/test-run.js +8 -2
- package/dist/src/commands/test-stale-gate.d.ts +44 -0
- package/dist/src/commands/test-stale-gate.js +81 -0
- package/dist/src/commands/test.js +52 -81
- package/dist/src/core/build-audit.d.ts +12 -0
- package/dist/src/core/build-audit.js +14 -0
- package/dist/src/core/build-baseline-types.d.ts +41 -0
- package/dist/src/core/build-baseline.d.ts +6 -1
- package/dist/src/core/build-baseline.js +48 -7
- package/dist/src/core/build-prepare.d.ts +9 -0
- package/dist/src/core/build-prepare.js +24 -0
- package/dist/src/core/config-paths.d.ts +1 -1
- package/dist/src/core/config-paths.js +1 -0
- package/dist/src/core/config-validate.js +14 -1
- package/dist/src/core/discard-baseline.d.ts +60 -0
- package/dist/src/core/discard-baseline.js +232 -0
- package/dist/src/core/engine-session-lock.d.ts +10 -1
- package/dist/src/core/engine-session-lock.js +28 -2
- package/dist/src/core/file-lock.d.ts +33 -0
- package/dist/src/core/file-lock.js +32 -6
- package/dist/src/core/firefox-archive.d.ts +2 -1
- package/dist/src/core/firefox-archive.js +32 -8
- package/dist/src/core/firefox.d.ts +8 -3
- package/dist/src/core/firefox.js +11 -6
- package/dist/src/core/furnace-validate-helpers.js +28 -1
- package/dist/src/core/license-headers.d.ts +24 -0
- package/dist/src/core/license-headers.js +103 -1
- package/dist/src/core/patch-export.d.ts +10 -1
- package/dist/src/core/patch-export.js +12 -2
- package/dist/src/core/patch-lint-checkjs.d.ts +6 -1
- package/dist/src/core/patch-lint-checkjs.js +30 -14
- package/dist/src/core/patch-lint-cross.d.ts +9 -1
- package/dist/src/core/patch-lint-cross.js +69 -9
- package/dist/src/core/patch-lint-mozbuild.d.ts +18 -0
- package/dist/src/core/patch-lint-mozbuild.js +104 -0
- package/dist/src/core/patch-lint.d.ts +3 -0
- package/dist/src/core/patch-lint.js +29 -8
- package/dist/src/core/patch-policy.d.ts +14 -1
- package/dist/src/core/patch-policy.js +13 -2
- package/dist/src/core/status-classify.d.ts +11 -2
- package/dist/src/core/status-classify.js +49 -25
- package/dist/src/core/test-harness-crash.d.ts +10 -0
- package/dist/src/core/test-harness-crash.js +16 -0
- package/dist/src/core/test-stale-check.d.ts +56 -1
- package/dist/src/core/test-stale-check.js +114 -4
- package/dist/src/core/token-manager.js +39 -2
- package/dist/src/core/token-variant.d.ts +7 -0
- package/dist/src/core/token-variant.js +9 -0
- package/dist/src/core/typecheck-shim.d.ts +13 -0
- package/dist/src/core/typecheck-shim.js +17 -2
- package/dist/src/core/typecheck.js +14 -3
- package/dist/src/types/commands/options.d.ts +69 -3
- package/dist/src/types/config.d.ts +22 -0
- package/dist/src/utils/options.d.ts +20 -0
- package/dist/src/utils/options.js +39 -0
- package/dist/src/utils/validation.d.ts +5 -0
- package/dist/src/utils/validation.js +7 -0
- package/package.json +3 -3
|
@@ -107,6 +107,15 @@ function findVariantBlockInsertionPoint(lines) {
|
|
|
107
107
|
}
|
|
108
108
|
return lines.length;
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* True when a top-level `:root<variant>` block exists in `lines`. Used by
|
|
112
|
+
* the override path to write theme-attribute blocks only when the scaffold
|
|
113
|
+
* already declares them — `insertVariantDeclaration` would otherwise create
|
|
114
|
+
* the block, which is only wanted for the explicit `--variant` flow.
|
|
115
|
+
*/
|
|
116
|
+
export function variantBlockExists(lines, variant) {
|
|
117
|
+
return findVariantBlock(lines, variant) !== null;
|
|
118
|
+
}
|
|
110
119
|
/** True when the `:root<variant>` block already declares `tokenName`. */
|
|
111
120
|
export function variantBlockHasToken(lines, variant, tokenName) {
|
|
112
121
|
const block = findVariantBlock(lines, variant);
|
|
@@ -24,6 +24,19 @@ export declare const SHIM_FILENAME = "__fireforge_firefox_globals.d.ts";
|
|
|
24
24
|
* reason the operator couldn't infer from the docs.
|
|
25
25
|
*/
|
|
26
26
|
export declare const SUPPRESSED_DIAGNOSTIC_CODES: ReadonlySet<number>;
|
|
27
|
+
/**
|
|
28
|
+
* Undefined-free-identifier codes, split out of
|
|
29
|
+
* {@link SUPPRESSED_DIAGNOSTIC_CODES} (FORGE F12). Unconditional
|
|
30
|
+
* suppression let a module reference a name with no import or declaration
|
|
31
|
+
* anywhere and still typecheck with 0 errors — the failure then surfaced
|
|
32
|
+
* as a runtime `ReferenceError`. Both flows now report these at a
|
|
33
|
+
* configurable severity (default `'warning'`: visible without breaking
|
|
34
|
+
* gates; genuine shim gaps are silenced by adding the global to
|
|
35
|
+
* `extraShim`, or per-run via the `'off'` setting).
|
|
36
|
+
*/
|
|
37
|
+
export declare const UNDEFINED_IDENTIFIER_CODES: ReadonlySet<number>;
|
|
38
|
+
/** Hint appended to reported undefined-identifier diagnostics. */
|
|
39
|
+
export declare const UNDEFINED_IDENTIFIER_HINT: string;
|
|
27
40
|
/**
|
|
28
41
|
* Result of {@link composeShimSource}: the source body to feed into
|
|
29
42
|
* the TS host plus a flag indicating whether the user-supplied extra
|
|
@@ -146,11 +146,26 @@ export const SUPPRESSED_DIAGNOSTIC_CODES = new Set([
|
|
|
146
146
|
2306, // File '{0}' is not a module.
|
|
147
147
|
2305, // Module '{0}' has no exported member '{1}'.
|
|
148
148
|
2792, // Cannot find module '{0}'. Did you mean to set the 'moduleResolution' option...
|
|
149
|
-
2304, // Cannot find name '{0}'. (for globals we missed in the shim)
|
|
150
|
-
2552, // Cannot find name '{0}'. Did you mean '{1}'?
|
|
151
149
|
2580, // Cannot find name '{0}'. Do you need to install type definitions...
|
|
152
150
|
7016, // Could not find a declaration file for module '{0}'.
|
|
153
151
|
]);
|
|
152
|
+
/**
|
|
153
|
+
* Undefined-free-identifier codes, split out of
|
|
154
|
+
* {@link SUPPRESSED_DIAGNOSTIC_CODES} (FORGE F12). Unconditional
|
|
155
|
+
* suppression let a module reference a name with no import or declaration
|
|
156
|
+
* anywhere and still typecheck with 0 errors — the failure then surfaced
|
|
157
|
+
* as a runtime `ReferenceError`. Both flows now report these at a
|
|
158
|
+
* configurable severity (default `'warning'`: visible without breaking
|
|
159
|
+
* gates; genuine shim gaps are silenced by adding the global to
|
|
160
|
+
* `extraShim`, or per-run via the `'off'` setting).
|
|
161
|
+
*/
|
|
162
|
+
export const UNDEFINED_IDENTIFIER_CODES = new Set([
|
|
163
|
+
2304, // Cannot find name '{0}'.
|
|
164
|
+
2552, // Cannot find name '{0}'. Did you mean '{1}'?
|
|
165
|
+
]);
|
|
166
|
+
/** Hint appended to reported undefined-identifier diagnostics. */
|
|
167
|
+
export const UNDEFINED_IDENTIFIER_HINT = '(undefined identifier — import or declare it, add the global to the extra shim, ' +
|
|
168
|
+
'or tune the "undefinedIdentifiers" setting)';
|
|
154
169
|
/** Matches a lone triple-slash `/// <reference path="…" />` directive line. */
|
|
155
170
|
const TRIPLE_SLASH_REFERENCE = /^\s*\/\/\/\s*<reference\s+path\s*=\s*["']([^"']+)["']\s*\/?>\s*$/;
|
|
156
171
|
/**
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
import { dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
22
22
|
import { pathExists } from '../utils/fs.js';
|
|
23
23
|
import { verbose } from '../utils/logger.js';
|
|
24
|
-
import { composeShimSource, SHIM_FILENAME, SUPPRESSED_DIAGNOSTIC_CODES } from './typecheck-shim.js';
|
|
24
|
+
import { composeShimSource, SHIM_FILENAME, SUPPRESSED_DIAGNOSTIC_CODES, UNDEFINED_IDENTIFIER_CODES, UNDEFINED_IDENTIFIER_HINT, } from './typecheck-shim.js';
|
|
25
25
|
/**
|
|
26
26
|
* Sentinel string surfaced as a `TypecheckIssue.message` when the
|
|
27
27
|
* project's jsconfig sets `checkJs: false`. Exported so tests can
|
|
@@ -131,7 +131,7 @@ export async function runTypecheck(projectRoot, cfg) {
|
|
|
131
131
|
});
|
|
132
132
|
continue;
|
|
133
133
|
}
|
|
134
|
-
results.push(await runTypecheckForProject(ts, projectRoot, projectPath, shimSource));
|
|
134
|
+
results.push(await runTypecheckForProject(ts, projectRoot, projectPath, shimSource, cfg.undefinedIdentifiers ?? 'warning'));
|
|
135
135
|
}
|
|
136
136
|
return results;
|
|
137
137
|
}
|
|
@@ -149,7 +149,7 @@ function resolveProjectExtraShim(cfg, projectPath) {
|
|
|
149
149
|
return cfg.extraShim;
|
|
150
150
|
}
|
|
151
151
|
/** Runs typecheck for a single jsconfig path, isolating its failures. */
|
|
152
|
-
async function runTypecheckForProject(ts, projectRoot, projectPath, shimSource) {
|
|
152
|
+
async function runTypecheckForProject(ts, projectRoot, projectPath, shimSource, undefinedIdentifiers = 'warning') {
|
|
153
153
|
const absConfig = resolve(projectRoot, projectPath);
|
|
154
154
|
if (!(await pathExists(absConfig))) {
|
|
155
155
|
return {
|
|
@@ -268,6 +268,17 @@ async function runTypecheckForProject(ts, projectRoot, projectPath, shimSource)
|
|
|
268
268
|
// can't act on them and they would clutter CI logs.
|
|
269
269
|
if (diag.file?.fileName === shimPath)
|
|
270
270
|
continue;
|
|
271
|
+
if (UNDEFINED_IDENTIFIER_CODES.has(diag.code)) {
|
|
272
|
+
if (undefinedIdentifiers === 'off')
|
|
273
|
+
continue;
|
|
274
|
+
const issue = diagnosticToIssue(ts, diag, absConfig, projectPath);
|
|
275
|
+
issues.push({
|
|
276
|
+
...issue,
|
|
277
|
+
category: undefinedIdentifiers,
|
|
278
|
+
message: `${issue.message} ${UNDEFINED_IDENTIFIER_HINT}`,
|
|
279
|
+
});
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
271
282
|
issues.push(diagnosticToIssue(ts, diag, absConfig, projectPath));
|
|
272
283
|
}
|
|
273
284
|
verbose(`typecheck: ${projectPath} — analyzed ${String(parsed.fileNames.length)} file(s), found ${String(issues.length)} issue(s)`);
|
|
@@ -43,6 +43,10 @@ export interface SourceSetOptions {
|
|
|
43
43
|
sha256?: string;
|
|
44
44
|
/** Clear any existing pinned SHA-256 */
|
|
45
45
|
clearSha256?: boolean;
|
|
46
|
+
/** Optional release-candidate build directory (e.g. "build2") */
|
|
47
|
+
candidate?: string;
|
|
48
|
+
/** Clear any existing release-candidate build directory */
|
|
49
|
+
clearCandidate?: boolean;
|
|
46
50
|
}
|
|
47
51
|
/**
|
|
48
52
|
* Options for the build command.
|
|
@@ -62,6 +66,12 @@ export interface BuildOptions {
|
|
|
62
66
|
* for any mismatch the rewriter cannot prove safe.
|
|
63
67
|
*/
|
|
64
68
|
rewriteMozinfo?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Parsed `--wait-lock [seconds]` value (`true` for the bare flag, meaning
|
|
71
|
+
* 60). Consumed at the CLI layer to bound the engine-session-lock wait;
|
|
72
|
+
* the command implementation ignores it.
|
|
73
|
+
*/
|
|
74
|
+
waitLock?: number | boolean;
|
|
65
75
|
}
|
|
66
76
|
/**
|
|
67
77
|
* Options for the export command.
|
|
@@ -112,6 +122,12 @@ export interface ExportOptions {
|
|
|
112
122
|
* another patch, because the resulting queue fails `verify` immediately.
|
|
113
123
|
*/
|
|
114
124
|
allowOverlap?: boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Parsed `--wait-lock [seconds]` value (`true` for the bare flag, meaning
|
|
127
|
+
* 60). Consumed at the CLI layer to bound the engine-session-lock wait;
|
|
128
|
+
* the command implementation ignores it.
|
|
129
|
+
*/
|
|
130
|
+
waitLock?: number | boolean;
|
|
115
131
|
/**
|
|
116
132
|
* Force a tier override on the new patch's `PatchMetadata.tier`. Only
|
|
117
133
|
* `"branding"` is currently recognised — Commander rejects other values
|
|
@@ -144,6 +160,12 @@ export interface ResetOptions {
|
|
|
144
160
|
* Options for the discard command.
|
|
145
161
|
*/
|
|
146
162
|
export interface DiscardOptions {
|
|
163
|
+
/**
|
|
164
|
+
* Restore to pristine upstream (HEAD) instead of the patch-applied
|
|
165
|
+
* baseline; deletes patch-created files (the pre-0.39.0 semantics —
|
|
166
|
+
* FORGE F1).
|
|
167
|
+
*/
|
|
168
|
+
toUpstream?: boolean;
|
|
147
169
|
/** Show what would be discarded without doing it */
|
|
148
170
|
dryRun?: boolean;
|
|
149
171
|
/** Skip confirmation prompt */
|
|
@@ -251,6 +273,12 @@ export interface ReExportOptions {
|
|
|
251
273
|
* patch to also suppress X").
|
|
252
274
|
*/
|
|
253
275
|
lintIgnore?: string[];
|
|
276
|
+
/**
|
|
277
|
+
* Parsed `--wait-lock [seconds]` value (`true` for the bare flag, meaning
|
|
278
|
+
* 60). Consumed at the CLI layer to bound the engine-session-lock wait;
|
|
279
|
+
* the command implementation ignores it.
|
|
280
|
+
*/
|
|
281
|
+
waitLock?: number | boolean;
|
|
254
282
|
}
|
|
255
283
|
/**
|
|
256
284
|
* Options for the `fireforge patch tier` subcommand. Sets or clears the
|
|
@@ -350,13 +378,31 @@ export interface PatchSplitOptions {
|
|
|
350
378
|
skipLint?: boolean;
|
|
351
379
|
}
|
|
352
380
|
/**
|
|
353
|
-
* Options for the
|
|
354
|
-
*
|
|
355
|
-
* `re-export --files` commands needed to perform it.
|
|
381
|
+
* Options for the `fireforge patch move-files` subcommand. Without
|
|
382
|
+
* `--create` it is preview-only: it validates an ownership transfer and
|
|
383
|
+
* prints the explicit `re-export --files` commands needed to perform it.
|
|
384
|
+
* With `--create --order <n>` the target patch is created at that order
|
|
385
|
+
* and the files move into it as one split-style transaction.
|
|
356
386
|
*/
|
|
357
387
|
export interface PatchMoveFilesOptions {
|
|
358
388
|
/** File paths relative to engine/ to move from the source patch to the target patch. */
|
|
359
389
|
file?: string[];
|
|
390
|
+
/** Create the target patch (transactional bootstrap of a split). Requires `order`. */
|
|
391
|
+
create?: boolean;
|
|
392
|
+
/** Exact sparse order for the created patch. Only valid with `create`. */
|
|
393
|
+
order?: number;
|
|
394
|
+
/** Category for the created patch; defaults to the source patch's. */
|
|
395
|
+
category?: string;
|
|
396
|
+
/** Description for the created patch. */
|
|
397
|
+
description?: string;
|
|
398
|
+
/** Preview the create+move without writing. */
|
|
399
|
+
dryRun?: boolean;
|
|
400
|
+
/** Skip interactive confirmation (required for non-TTY). */
|
|
401
|
+
yes?: boolean;
|
|
402
|
+
/** Bypass projected-lint refusals. */
|
|
403
|
+
forceUnsafe?: boolean;
|
|
404
|
+
/** Skip per-patch lint of the projected bodies. */
|
|
405
|
+
skipLint?: boolean;
|
|
360
406
|
}
|
|
361
407
|
/**
|
|
362
408
|
* Options for the rebase command.
|
|
@@ -457,6 +503,14 @@ export interface TestOptions {
|
|
|
457
503
|
killStaleMarionette?: boolean;
|
|
458
504
|
/** Permit tests against packageable engine edits newer than the last successful build. */
|
|
459
505
|
allowStaleBuild?: boolean;
|
|
506
|
+
/**
|
|
507
|
+
* Permit tests despite `components.conf` changes that only a full
|
|
508
|
+
* `fireforge build` compiles into the StaticComponents table — the
|
|
509
|
+
* packaged child process will resolve the OLD table. For operators who
|
|
510
|
+
* rebuilt out-of-band and accept the risk; distinct from
|
|
511
|
+
* `allowStaleBuild`, which only accepts stale packaged content.
|
|
512
|
+
*/
|
|
513
|
+
allowStaleComponents?: boolean;
|
|
460
514
|
/** Run the configured short harness canary. `true` means use `fireforge.json`'s test.canaryPath. */
|
|
461
515
|
canary?: string | boolean;
|
|
462
516
|
/**
|
|
@@ -487,6 +541,12 @@ export interface TestOptions {
|
|
|
487
541
|
* checkers that consume a sample artifact after the run.
|
|
488
542
|
*/
|
|
489
543
|
perfSamples?: string;
|
|
544
|
+
/**
|
|
545
|
+
* Parsed `--wait-lock [seconds]` value (`true` for the bare flag, meaning
|
|
546
|
+
* 60). Consumed at the CLI layer to bound the engine-session-lock wait;
|
|
547
|
+
* the command implementation ignores it.
|
|
548
|
+
*/
|
|
549
|
+
waitLock?: number | boolean;
|
|
490
550
|
}
|
|
491
551
|
/**
|
|
492
552
|
* Options for the furnace apply command.
|
|
@@ -741,6 +801,12 @@ export interface StatusOptions {
|
|
|
741
801
|
* patch as an ownership conflict.
|
|
742
802
|
*/
|
|
743
803
|
ownership?: boolean;
|
|
804
|
+
/**
|
|
805
|
+
* Print the recorded test-packaging coverage of the last build baseline
|
|
806
|
+
* (scope, timestamp, recording invocation) and exit. Read-only — the
|
|
807
|
+
* counterpart to the out-of-coverage test refusal (FORGE F11).
|
|
808
|
+
*/
|
|
809
|
+
testCoverage?: boolean;
|
|
744
810
|
/** Output machine-readable JSON instead of human-readable text. */
|
|
745
811
|
json?: boolean;
|
|
746
812
|
}
|
|
@@ -12,6 +12,13 @@ export interface FirefoxConfig {
|
|
|
12
12
|
product: FirefoxProduct;
|
|
13
13
|
/** Optional pinned SHA-256 for the resolved source archive */
|
|
14
14
|
sha256?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Optional release-candidate build directory (e.g. "build2"). When set,
|
|
17
|
+
* the source archive resolves under
|
|
18
|
+
* `pub/<product>/candidates/<version>-candidates/<candidate>/` instead of
|
|
19
|
+
* `pub/<product>/releases/<version>/`, for pre-release verification.
|
|
20
|
+
*/
|
|
21
|
+
candidate?: string;
|
|
15
22
|
}
|
|
16
23
|
/**
|
|
17
24
|
* Supported project license SPDX identifiers.
|
|
@@ -174,6 +181,14 @@ export interface TypecheckConfig {
|
|
|
174
181
|
* mismatch). A narrowed project sets `null` here to stay clean.
|
|
175
182
|
*/
|
|
176
183
|
projectOverrides?: Record<string, string | null>;
|
|
184
|
+
/**
|
|
185
|
+
* How to report undefined free identifiers (TS2304/TS2552). These were
|
|
186
|
+
* historically suppressed as shim-gap noise, which also hid genuine
|
|
187
|
+
* missing imports until they crashed at runtime (FORGE F12). Default
|
|
188
|
+
* `'warning'`: visible without failing the gate. `'error'` makes them
|
|
189
|
+
* blocking; `'off'` restores the historical suppression.
|
|
190
|
+
*/
|
|
191
|
+
undefinedIdentifiers?: PatchLintSeverityGate;
|
|
177
192
|
}
|
|
178
193
|
/**
|
|
179
194
|
* Wire command configuration.
|
|
@@ -255,6 +270,13 @@ export interface PatchLintConfig {
|
|
|
255
270
|
* 'off'.
|
|
256
271
|
*/
|
|
257
272
|
chromeScriptJsDoc?: PatchLintSeverityGate;
|
|
273
|
+
/**
|
|
274
|
+
* How the checkJs pass reports undefined free identifiers
|
|
275
|
+
* (TS2304/TS2552). Same semantics as `typecheck.undefinedIdentifiers`
|
|
276
|
+
* (FORGE F12); the two flows share the suppression policy so a patch
|
|
277
|
+
* cannot pass one and fail the other. Default: 'warning'.
|
|
278
|
+
*/
|
|
279
|
+
undefinedIdentifiers?: PatchLintSeverityGate;
|
|
258
280
|
}
|
|
259
281
|
/**
|
|
260
282
|
* Build mode for mach.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
export declare function pickDefined<T extends Record<string, unknown>>(obj: T): {
|
|
7
7
|
[K in keyof T]+?: Exclude<T[K], undefined>;
|
|
8
8
|
};
|
|
9
|
+
import type { Command } from 'commander';
|
|
9
10
|
/**
|
|
10
11
|
* Wraps an option-argument parser so its failures surface through
|
|
11
12
|
* commander's own invalid-argument channel.
|
|
@@ -21,3 +22,22 @@ export declare function pickDefined<T extends Record<string, unknown>>(obj: T):
|
|
|
21
22
|
* helper (or throw commander's InvalidArgumentError directly).
|
|
22
23
|
*/
|
|
23
24
|
export declare function commanderArgParser<T>(parse: (raw: string) => T): (raw: string) => T;
|
|
25
|
+
/**
|
|
26
|
+
* Resolves the parsed `--wait-lock [seconds]` option value into a wait budget
|
|
27
|
+
* in seconds for `withEngineSessionLock`:
|
|
28
|
+
* - absent (`undefined`) → `undefined` (legacy ~1 s fail-fast),
|
|
29
|
+
* - bare flag (`true`) → {@link DEFAULT_WAIT_LOCK_SECONDS},
|
|
30
|
+
* - explicit value → integer validated into 1..3600.
|
|
31
|
+
*
|
|
32
|
+
* Accepts the raw string too, so it doubles as the option's arg parser (wrap
|
|
33
|
+
* with {@link commanderArgParser} so failures surface through commander's
|
|
34
|
+
* invalid-argument channel).
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveWaitLockSeconds(value: string | number | boolean | undefined): number | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Registers the shared `--wait-lock [seconds]` flag on an engine-mutating
|
|
39
|
+
* command. The parsed option value is `true` for the bare flag or a validated
|
|
40
|
+
* integer; feed it through {@link resolveWaitLockSeconds} at the call site to
|
|
41
|
+
* obtain the `waitLockSeconds` for `withEngineSessionLock`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function addWaitLockOption(command: Command): Command;
|
|
@@ -14,6 +14,7 @@ export function pickDefined(obj) {
|
|
|
14
14
|
return result;
|
|
15
15
|
}
|
|
16
16
|
import { InvalidArgumentError as CommanderInvalidArgumentError } from 'commander';
|
|
17
|
+
import { GeneralError } from '../errors/base.js';
|
|
17
18
|
/**
|
|
18
19
|
* Wraps an option-argument parser so its failures surface through
|
|
19
20
|
* commander's own invalid-argument channel.
|
|
@@ -38,3 +39,41 @@ export function commanderArgParser(parse) {
|
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
41
|
}
|
|
42
|
+
/** Wait budget applied when `--wait-lock` is passed without a value. */
|
|
43
|
+
const DEFAULT_WAIT_LOCK_SECONDS = 60;
|
|
44
|
+
/**
|
|
45
|
+
* Resolves the parsed `--wait-lock [seconds]` option value into a wait budget
|
|
46
|
+
* in seconds for `withEngineSessionLock`:
|
|
47
|
+
* - absent (`undefined`) → `undefined` (legacy ~1 s fail-fast),
|
|
48
|
+
* - bare flag (`true`) → {@link DEFAULT_WAIT_LOCK_SECONDS},
|
|
49
|
+
* - explicit value → integer validated into 1..3600.
|
|
50
|
+
*
|
|
51
|
+
* Accepts the raw string too, so it doubles as the option's arg parser (wrap
|
|
52
|
+
* with {@link commanderArgParser} so failures surface through commander's
|
|
53
|
+
* invalid-argument channel).
|
|
54
|
+
*/
|
|
55
|
+
export function resolveWaitLockSeconds(value) {
|
|
56
|
+
if (value === undefined || value === false) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
if (value === true) {
|
|
60
|
+
return DEFAULT_WAIT_LOCK_SECONDS;
|
|
61
|
+
}
|
|
62
|
+
if (typeof value === 'number') {
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
const n = Number.parseInt(value, 10);
|
|
66
|
+
if (!Number.isFinite(n) || n < 1 || n > 3600) {
|
|
67
|
+
throw new GeneralError(`--wait-lock must be an integer in 1..3600 (got "${value}")`);
|
|
68
|
+
}
|
|
69
|
+
return n;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Registers the shared `--wait-lock [seconds]` flag on an engine-mutating
|
|
73
|
+
* command. The parsed option value is `true` for the bare flag or a validated
|
|
74
|
+
* integer; feed it through {@link resolveWaitLockSeconds} at the call site to
|
|
75
|
+
* obtain the `waitLockSeconds` for `withEngineSessionLock`.
|
|
76
|
+
*/
|
|
77
|
+
export function addWaitLockOption(command) {
|
|
78
|
+
return command.option('--wait-lock [seconds]', 'Wait up to this many seconds (default 60) for another FireForge engine-mutating command to release the engine lock, instead of failing immediately', commanderArgParser((raw) => resolveWaitLockSeconds(raw)));
|
|
79
|
+
}
|
|
@@ -57,6 +57,11 @@ export declare function isArray(value: unknown): value is unknown[];
|
|
|
57
57
|
* Accepts formats like "140.9.0", "140.9.1", "140.9.0esr", "147.0b1"
|
|
58
58
|
*/
|
|
59
59
|
export declare function isValidFirefoxVersion(version: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Validates a release-candidate build directory name.
|
|
62
|
+
* Accepts formats like "build1", "build2", "build12" (no leading zero).
|
|
63
|
+
*/
|
|
64
|
+
export declare function isValidFirefoxCandidate(candidate: string): boolean;
|
|
60
65
|
/**
|
|
61
66
|
* Validates a Firefox product string.
|
|
62
67
|
* Accepts: firefox, firefox-esr, firefox-beta, firefox-devedition
|
|
@@ -87,6 +87,13 @@ export function isValidFirefoxVersion(version) {
|
|
|
87
87
|
// Beta: 147.0b1, 147.0b2
|
|
88
88
|
return /^[1-9]\d{0,2}\.\d+(?:b[1-9]\d*|\.\d+(?:esr)?|esr)?$/.test(version);
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Validates a release-candidate build directory name.
|
|
92
|
+
* Accepts formats like "build1", "build2", "build12" (no leading zero).
|
|
93
|
+
*/
|
|
94
|
+
export function isValidFirefoxCandidate(candidate) {
|
|
95
|
+
return /^build[1-9]\d{0,3}$/.test(candidate);
|
|
96
|
+
}
|
|
90
97
|
/**
|
|
91
98
|
* Validates a Firefox product string.
|
|
92
99
|
* Accepts: firefox, firefox-esr, firefox-beta, firefox-devedition
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hominis/fireforge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.39.0",
|
|
4
4
|
"description": "FireForge — a build tool for customizing Firefox",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -73,9 +73,9 @@
|
|
|
73
73
|
"eslint-plugin-simple-import-sort": "^13.0.0",
|
|
74
74
|
"fast-check": "^4.6.0",
|
|
75
75
|
"husky": "^9.1.7",
|
|
76
|
-
"knip": "6.
|
|
76
|
+
"knip": "6.26.0",
|
|
77
77
|
"lint-staged": "^17.0.4",
|
|
78
|
-
"prettier": "3.9.
|
|
78
|
+
"prettier": "3.9.5",
|
|
79
79
|
"tsx": "^4.7.0",
|
|
80
80
|
"typescript": "~6.0.0",
|
|
81
81
|
"typescript-eslint": "^8.0.0",
|