@hominis/fireforge 0.50.0 → 0.52.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 +67 -0
- package/dist/build-info.json +4 -4
- package/dist/src/commands/check-report.d.ts +17 -4
- package/dist/src/commands/check-report.js +19 -6
- package/dist/src/commands/check-run.d.ts +5 -0
- package/dist/src/commands/check-run.js +9 -1
- package/dist/src/commands/check-steps.d.ts +8 -0
- package/dist/src/commands/check-steps.js +31 -6
- package/dist/src/commands/check.js +1 -1
- package/dist/src/commands/declarations-report.d.ts +43 -0
- package/dist/src/commands/declarations-report.js +76 -0
- package/dist/src/commands/export-placement-gate.js +8 -0
- package/dist/src/commands/furnace/rename-registrations.js +7 -2
- package/dist/src/commands/furnace/validate.js +26 -1
- package/dist/src/commands/lint-per-patch.js +6 -2
- package/dist/src/commands/lint-per-run-checkjs.js +2 -2
- package/dist/src/commands/lint-report.js +7 -2
- package/dist/src/commands/manifest.js +2 -0
- package/dist/src/commands/park.d.ts +22 -0
- package/dist/src/commands/park.js +232 -0
- package/dist/src/commands/patch/delete.js +11 -6
- package/dist/src/commands/patch/index.d.ts +3 -3
- package/dist/src/commands/patch/index.js +8 -4
- package/dist/src/commands/patch/lint-ignore-from.d.ts +44 -0
- package/dist/src/commands/patch/lint-ignore-from.js +142 -0
- package/dist/src/commands/patch/lint-ignore.js +39 -29
- package/dist/src/commands/patch/move-files-create.js +11 -4
- package/dist/src/commands/patch/move-files-into.js +10 -4
- package/dist/src/commands/patch/move-files.js +3 -1
- package/dist/src/commands/patch/removal-created-files.d.ts +48 -0
- package/dist/src/commands/patch/removal-created-files.js +83 -0
- package/dist/src/commands/patch/rename.js +15 -3
- package/dist/src/commands/patch/reserve.d.ts +33 -0
- package/dist/src/commands/patch/reserve.js +152 -0
- package/dist/src/commands/patch/retire.js +11 -6
- package/dist/src/commands/patch/split-plan.d.ts +10 -1
- package/dist/src/commands/patch/split-plan.js +16 -1
- package/dist/src/commands/patch/split.js +14 -5
- package/dist/src/commands/patch/stage.d.ts +34 -0
- package/dist/src/commands/patch/stage.js +153 -0
- package/dist/src/commands/patch/staged-dependency-remove.d.ts +31 -0
- package/dist/src/commands/patch/staged-dependency-remove.js +80 -0
- package/dist/src/commands/patch/staged-dependency.js +40 -98
- package/dist/src/commands/re-export-adjacent.d.ts +5 -0
- package/dist/src/commands/re-export-adjacent.js +4 -3
- package/dist/src/commands/re-export-bulk-scan.d.ts +2 -1
- package/dist/src/commands/re-export-bulk-scan.js +22 -7
- package/dist/src/commands/re-export-hunks.d.ts +35 -0
- package/dist/src/commands/re-export-hunks.js +220 -0
- package/dist/src/commands/re-export-options.js +29 -2
- package/dist/src/commands/re-export-purity-scope.d.ts +18 -0
- package/dist/src/commands/re-export-purity-scope.js +131 -0
- package/dist/src/commands/re-export-register.js +15 -1
- package/dist/src/commands/re-export-removed.d.ts +1 -1
- package/dist/src/commands/re-export-removed.js +17 -2
- package/dist/src/commands/re-export-scan.d.ts +2 -0
- package/dist/src/commands/re-export-scan.js +4 -1
- package/dist/src/commands/re-export-single.js +102 -42
- package/dist/src/commands/re-export-stale-registrations.d.ts +18 -0
- package/dist/src/commands/re-export-stale-registrations.js +62 -0
- package/dist/src/commands/re-export.js +35 -34
- package/dist/src/commands/status-output.js +5 -1
- package/dist/src/commands/test-build-furnace.d.ts +3 -2
- package/dist/src/commands/test-build-furnace.js +8 -2
- package/dist/src/commands/test-build-phase.d.ts +2 -0
- package/dist/src/commands/test-build-phase.js +34 -17
- package/dist/src/commands/test-checkjs.js +3 -2
- package/dist/src/commands/test-dispatch.d.ts +39 -0
- package/dist/src/commands/test-dispatch.js +220 -0
- package/dist/src/commands/test-furnace-reach.d.ts +37 -0
- package/dist/src/commands/test-furnace-reach.js +132 -0
- package/dist/src/commands/test-orchestrate.d.ts +14 -0
- package/dist/src/commands/test-orchestrate.js +25 -4
- package/dist/src/commands/test-perf-scope.d.ts +21 -0
- package/dist/src/commands/test-perf-scope.js +55 -0
- package/dist/src/commands/test-prelock.js +100 -4
- package/dist/src/commands/test-register.js +18 -3
- package/dist/src/commands/test-results.d.ts +62 -0
- package/dist/src/commands/test-results.js +62 -0
- package/dist/src/commands/test-run.d.ts +13 -55
- package/dist/src/commands/test-run.js +73 -101
- package/dist/src/commands/test-shards.d.ts +110 -0
- package/dist/src/commands/test-shards.js +255 -0
- package/dist/src/commands/test-stale-gate.d.ts +5 -1
- package/dist/src/commands/test-stale-gate.js +11 -2
- package/dist/src/commands/test-verdict.d.ts +2 -1
- package/dist/src/commands/test.d.ts +1 -1
- package/dist/src/commands/test.js +68 -75
- package/dist/src/commands/token-lint.js +48 -8
- package/dist/src/commands/verify.js +9 -2
- package/dist/src/core/build-baseline-types.d.ts +13 -0
- package/dist/src/core/build-baseline-validate.js +9 -0
- package/dist/src/core/build-baseline.js +7 -0
- package/dist/src/core/build-prepare.d.ts +6 -0
- package/dist/src/core/build-prepare.js +29 -3
- package/dist/src/core/config-paths.d.ts +1 -1
- package/dist/src/core/config-paths.js +2 -0
- package/dist/src/core/config-validate-check.js +83 -7
- package/dist/src/core/config-validate-test-toolchains.js +14 -0
- package/dist/src/core/config-validate-token-scales.d.ts +3 -0
- package/dist/src/core/config-validate-token-scales.js +47 -5
- package/dist/src/core/config-validate.js +6 -0
- package/dist/src/core/coverage-extend.js +2 -2
- package/dist/src/core/coverage-records.d.ts +11 -0
- package/dist/src/core/coverage-records.js +34 -0
- package/dist/src/core/engine-session-lock.d.ts +6 -0
- package/dist/src/core/engine-session-lock.js +10 -2
- package/dist/src/core/file-lock-shared.d.ts +57 -0
- package/dist/src/core/file-lock-shared.js +117 -0
- package/dist/src/core/file-lock.d.ts +9 -0
- package/dist/src/core/file-lock.js +58 -2
- package/dist/src/core/furnace-apply.js +10 -10
- package/dist/src/core/furnace-config-validate-exceptions.d.ts +11 -3
- package/dist/src/core/furnace-config-validate-exceptions.js +59 -8
- package/dist/src/core/furnace-config-validate.js +7 -1
- package/dist/src/core/furnace-registration-jar-inplace.d.ts +12 -0
- package/dist/src/core/furnace-registration-jar-inplace.js +80 -0
- package/dist/src/core/furnace-validate-accessibility.d.ts +5 -3
- package/dist/src/core/furnace-validate-accessibility.js +75 -30
- package/dist/src/core/furnace-validate-exceptions.d.ts +13 -4
- package/dist/src/core/furnace-validate-exceptions.js +59 -4
- package/dist/src/core/furnace-validate-icon-button.js +30 -1
- package/dist/src/core/history-log-file.js +8 -1
- package/dist/src/core/line-prefixer.d.ts +18 -0
- package/dist/src/core/line-prefixer.js +34 -0
- package/dist/src/core/mach.d.ts +7 -0
- package/dist/src/core/mach.js +24 -9
- package/dist/src/core/module-resolution-preflight.d.ts +19 -3
- package/dist/src/core/module-resolution-preflight.js +24 -6
- package/dist/src/core/negative-control-compiled.d.ts +36 -0
- package/dist/src/core/negative-control-compiled.js +87 -0
- package/dist/src/core/negative-control-diff.d.ts +14 -2
- package/dist/src/core/negative-control-diff.js +49 -6
- package/dist/src/core/negative-control.d.ts +12 -0
- package/dist/src/core/negative-control.js +48 -5
- package/dist/src/core/park-store.d.ts +63 -0
- package/dist/src/core/park-store.js +216 -0
- package/dist/src/core/patch-export-update.d.ts +4 -0
- package/dist/src/core/patch-export-update.js +12 -3
- package/dist/src/core/patch-export.d.ts +3 -2
- package/dist/src/core/patch-export.js +21 -14
- package/dist/src/core/patch-files.js +26 -8
- package/dist/src/core/patch-lint-checkjs-any-import.d.ts +6 -4
- package/dist/src/core/patch-lint-checkjs-any-import.js +9 -7
- package/dist/src/core/patch-lint-checkjs-diagnostics.d.ts +17 -0
- package/dist/src/core/patch-lint-checkjs-diagnostics.js +32 -0
- package/dist/src/core/patch-lint-checkjs.d.ts +10 -1
- package/dist/src/core/patch-lint-checkjs.js +13 -3
- package/dist/src/core/patch-lint-cross.d.ts +3 -1
- package/dist/src/core/patch-lint-cross.js +5 -0
- package/dist/src/core/patch-lint-css.js +14 -10
- package/dist/src/core/patch-lint-forward-registration-extended.d.ts +5 -0
- package/dist/src/core/patch-lint-forward-registration-extended.js +1 -1
- package/dist/src/core/patch-lint-ignore.d.ts +56 -12
- package/dist/src/core/patch-lint-ignore.js +173 -43
- package/dist/src/core/patch-lint-ownership.d.ts +10 -0
- package/dist/src/core/patch-lint-ownership.js +26 -0
- package/dist/src/core/patch-lint-size.js +9 -1
- package/dist/src/core/patch-lint-token-scale.d.ts +26 -8
- package/dist/src/core/patch-lint-token-scale.js +206 -29
- package/dist/src/core/patch-lint.js +2 -2
- package/dist/src/core/patch-manifest-io.js +8 -1
- package/dist/src/core/patch-manifest-key-order.d.ts +24 -0
- package/dist/src/core/patch-manifest-key-order.js +61 -0
- package/dist/src/core/patch-manifest-stage.d.ts +46 -0
- package/dist/src/core/patch-manifest-stage.js +96 -0
- package/dist/src/core/patch-manifest-validate.js +27 -1
- package/dist/src/core/patch-order-legal.d.ts +2 -1
- package/dist/src/core/patch-order-legal.js +7 -2
- package/dist/src/core/patch-policy.d.ts +6 -2
- package/dist/src/core/patch-policy.js +14 -7
- package/dist/src/core/patch-retired.d.ts +26 -4
- package/dist/src/core/patch-retired.js +40 -2
- package/dist/src/core/run-log.d.ts +6 -0
- package/dist/src/core/run-log.js +17 -1
- package/dist/src/core/test-harness-crash.d.ts +2 -1
- package/dist/src/core/test-harness-crash.js +5 -8
- package/dist/src/core/test-harness-signature.d.ts +16 -0
- package/dist/src/core/test-harness-signature.js +19 -1
- package/dist/src/core/test-raw-log.d.ts +66 -0
- package/dist/src/core/test-raw-log.js +122 -0
- package/dist/src/core/test-run-completeness.d.ts +47 -7
- package/dist/src/core/test-run-completeness.js +70 -23
- package/dist/src/core/test-stale-check.d.ts +10 -1
- package/dist/src/core/test-stale-check.js +15 -1
- package/dist/src/core/test-xpcshell-retry.d.ts +2 -0
- package/dist/src/core/test-xpcshell-retry.js +2 -1
- package/dist/src/core/token-lint.d.ts +5 -2
- package/dist/src/core/token-lint.js +8 -3
- package/dist/src/core/token-sibling-sheets.d.ts +46 -0
- package/dist/src/core/token-sibling-sheets.js +119 -0
- package/dist/src/core/tree-guard.js +2 -0
- package/dist/src/core/typecheck-shim.d.ts +6 -1
- package/dist/src/core/typecheck-shim.js +139 -2
- package/dist/src/core/typecheck.js +3 -1
- package/dist/src/index.d.ts +9 -3
- package/dist/src/index.js +4 -1
- package/dist/src/types/commands/index.d.ts +2 -2
- package/dist/src/types/commands/options.d.ts +68 -7
- package/dist/src/types/commands/patches.d.ts +43 -0
- package/dist/src/types/config.d.ts +74 -2
- package/dist/src/types/furnace.d.ts +29 -0
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/utils/options.d.ts +3 -2
- package/dist/src/utils/options.js +9 -4
- package/docs/configuration.md +110 -9
- package/docs/furnace.md +61 -1
- package/docs/lifecycle-invariants.md +13 -11
- package/docs/machine-output.md +68 -18
- package/docs/patch-workflow.md +174 -13
- package/docs/testing.md +89 -5
- package/package.json +3 -3
|
@@ -18,10 +18,14 @@
|
|
|
18
18
|
* `FAIL reason=test-failures`, and a short start count is stamped on the
|
|
19
19
|
* verdict line as `started=<n>/<m> first-unstarted=<path>`.
|
|
20
20
|
*
|
|
21
|
-
*
|
|
22
|
-
* requested file. The suite-specific xpcshell
|
|
23
|
-
* with a result-summary block alone and print
|
|
24
|
-
* run that never names its files cannot be
|
|
21
|
+
* From streamed or captured text, the start-count check only runs when at
|
|
22
|
+
* least one start marker names a requested file. The suite-specific xpcshell
|
|
23
|
+
* dispatch can prove execution with a result-summary block alone and print
|
|
24
|
+
* no `TEST_START` line, and a run that never names its files cannot be
|
|
25
|
+
* counted against them. The structured raw log names every test by its
|
|
26
|
+
* manifest id, so a raw log whose starts name none of the requested files
|
|
27
|
+
* ran something else: a `--jobs` instance that read another instance's test
|
|
28
|
+
* list once passed on that instance's file.
|
|
25
29
|
*/
|
|
26
30
|
import { SHUTDOWN_REENTRY_PATTERN, START_MARKER_PATTERN, TEST_FILE_BASENAME_PATTERN, } from './test-harness-crash.js';
|
|
27
31
|
/**
|
|
@@ -33,38 +37,70 @@ const SKIP_MARKER_PATTERN = /\bTEST[-_]SKIP(?:PED)?\b[:| ]*\s*(\S+)?/;
|
|
|
33
37
|
function basenameOf(path) {
|
|
34
38
|
return path.slice(path.lastIndexOf('/') + 1);
|
|
35
39
|
}
|
|
40
|
+
/** Collects the start and skip marker names in `output`, line by line. */
|
|
41
|
+
function scanStartMarkers(output) {
|
|
42
|
+
const markers = { started: [], skipped: [] };
|
|
43
|
+
for (const line of output.split(/\r?\n/))
|
|
44
|
+
recordMarkerLine(line, markers);
|
|
45
|
+
return markers;
|
|
46
|
+
}
|
|
47
|
+
function recordMarkerLine(line, markers) {
|
|
48
|
+
const start = START_MARKER_PATTERN.exec(line)?.[1];
|
|
49
|
+
if (start !== undefined) {
|
|
50
|
+
markers.started.push(start);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const skip = SKIP_MARKER_PATTERN.exec(line)?.[1];
|
|
54
|
+
if (skip !== undefined)
|
|
55
|
+
markers.skipped.push(skip);
|
|
56
|
+
}
|
|
57
|
+
/** Creates a {@link StartMarkerTracker}. */
|
|
58
|
+
export function createStartMarkerTracker() {
|
|
59
|
+
const collected = { started: [], skipped: [] };
|
|
60
|
+
const pending = { stdout: '', stderr: '' };
|
|
61
|
+
return {
|
|
62
|
+
onChunk(stream, chunk) {
|
|
63
|
+
const lines = `${pending[stream]}${chunk}`.split(/\r?\n/);
|
|
64
|
+
pending[stream] = lines.pop() ?? '';
|
|
65
|
+
for (const line of lines)
|
|
66
|
+
recordMarkerLine(line, collected);
|
|
67
|
+
},
|
|
68
|
+
markers() {
|
|
69
|
+
const tail = { started: [], skipped: [] };
|
|
70
|
+
recordMarkerLine(pending.stdout, tail);
|
|
71
|
+
recordMarkerLine(pending.stderr, tail);
|
|
72
|
+
return {
|
|
73
|
+
started: [...collected.started, ...tail.started],
|
|
74
|
+
skipped: [...collected.skipped, ...tail.skipped],
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
36
79
|
/**
|
|
37
80
|
* Counts the requested test files that produced a start or skip marker.
|
|
38
81
|
* Returns undefined when nothing can be counted: no test-file-shaped
|
|
39
82
|
* request, or no start line that names any requested file.
|
|
40
83
|
*
|
|
41
|
-
* @param
|
|
84
|
+
* @param evidence - Captured mach stdout and stderr, or the markers
|
|
85
|
+
* collected from the complete stream
|
|
42
86
|
* @param requestedPaths - Dispatched paths, in dispatch order
|
|
87
|
+
* @param authoritative - The markers come from the raw log, so a run whose
|
|
88
|
+
* starts name no requested file is counted (as none started) instead of
|
|
89
|
+
* being left uncounted
|
|
43
90
|
*/
|
|
44
|
-
export function countStartedFiles(
|
|
91
|
+
export function countStartedFiles(evidence, requestedPaths, authoritative = false) {
|
|
45
92
|
const requested = requestedPaths.filter((path) => TEST_FILE_BASENAME_PATTERN.test(basenameOf(path)));
|
|
46
93
|
if (requested.length === 0)
|
|
47
94
|
return undefined;
|
|
48
|
-
const started =
|
|
49
|
-
const skipped = [];
|
|
50
|
-
for (const line of output.split(/\r?\n/)) {
|
|
51
|
-
const start = START_MARKER_PATTERN.exec(line)?.[1];
|
|
52
|
-
if (start !== undefined) {
|
|
53
|
-
started.push(start);
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const skip = SKIP_MARKER_PATTERN.exec(line)?.[1];
|
|
57
|
-
if (skip !== undefined)
|
|
58
|
-
skipped.push(skip);
|
|
59
|
-
}
|
|
95
|
+
const { started, skipped } = typeof evidence === 'string' ? scanStartMarkers(evidence) : evidence;
|
|
60
96
|
const names = (path, list) => {
|
|
61
97
|
const base = basenameOf(path);
|
|
62
98
|
return list.some((name) => name.includes(base));
|
|
63
99
|
};
|
|
64
100
|
// Counting needs a dialect that names the requested files on its start
|
|
65
101
|
// lines. When no start line names any of them, the output cannot be
|
|
66
|
-
// counted against the request at all.
|
|
67
|
-
if (!requested.some((path) => names(path, started)))
|
|
102
|
+
// counted against the request at all, unless it is the raw log.
|
|
103
|
+
if (!authoritative && !requested.some((path) => names(path, started)))
|
|
68
104
|
return undefined;
|
|
69
105
|
const unstarted = requested.filter((path) => !names(path, started) && !names(path, skipped));
|
|
70
106
|
const firstUnstarted = unstarted[0];
|
|
@@ -82,15 +118,21 @@ export function countStartedFiles(output, requestedPaths) {
|
|
|
82
118
|
* @param verdict - The classifier's verdict
|
|
83
119
|
* @param output - Captured mach stdout and stderr
|
|
84
120
|
* @param requestedPaths - Dispatched paths, in dispatch order
|
|
121
|
+
* @param tracked - Start markers collected from the complete stream (or
|
|
122
|
+
* the structured raw log); without them the capped capture is scanned
|
|
85
123
|
*/
|
|
86
|
-
export function vetoIncompletePass(verdict, output, requestedPaths) {
|
|
124
|
+
export function vetoIncompletePass(verdict, output, requestedPaths, tracked) {
|
|
87
125
|
if (verdict.kind !== 'tests-ran-ok')
|
|
88
126
|
return verdict;
|
|
89
127
|
const shutdownLine = output
|
|
90
128
|
.split(/\r?\n/)
|
|
91
129
|
.find((line) => SHUTDOWN_REENTRY_PATTERN.test(line))
|
|
92
130
|
?.trim();
|
|
93
|
-
|
|
131
|
+
// Tracked markers win whenever they saw a start line at all. An empty
|
|
132
|
+
// tracker means nothing was streamed through it, and the capture is then
|
|
133
|
+
// the only evidence there is.
|
|
134
|
+
const useTracked = tracked !== undefined && tracked.markers.started.length > 0;
|
|
135
|
+
const counted = countStartedFiles(useTracked ? tracked.markers : output, requestedPaths, useTracked && tracked.source === 'raw');
|
|
94
136
|
const unexpected = verdict.unexpected ?? 0;
|
|
95
137
|
const truncated = counted?.firstUnstarted !== undefined;
|
|
96
138
|
if (unexpected === 0 && shutdownLine === undefined && !truncated)
|
|
@@ -98,7 +140,12 @@ export function vetoIncompletePass(verdict, output, requestedPaths) {
|
|
|
98
140
|
const evidence = {
|
|
99
141
|
started: counted?.started ?? 0,
|
|
100
142
|
requested: counted?.requested ?? 0,
|
|
101
|
-
...(counted?.firstUnstarted !== undefined
|
|
143
|
+
...(counted?.firstUnstarted !== undefined
|
|
144
|
+
? {
|
|
145
|
+
firstUnstarted: counted.firstUnstarted,
|
|
146
|
+
startedSource: useTracked ? tracked.source : 'capture',
|
|
147
|
+
}
|
|
148
|
+
: {}),
|
|
102
149
|
...(shutdownLine !== undefined ? { shutdownLine } : {}),
|
|
103
150
|
...(unexpected > 0 ? { unexpected } : {}),
|
|
104
151
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BuildBaseline, TestPackagingCoverage } from './build-baseline-types.js';
|
|
1
|
+
import type { BaselineRecorder, BuildBaseline, TestPackagingCoverage } from './build-baseline-types.js';
|
|
2
2
|
import { type StaleExemption } from './test-stale-exempt.js';
|
|
3
3
|
/** Result of the stale-build preflight probe. */
|
|
4
4
|
export interface StaleBuildResult {
|
|
@@ -97,6 +97,15 @@ export interface CoverageRefusalDetail {
|
|
|
97
97
|
changedInputs?: Readonly<Record<string, readonly string[]>>;
|
|
98
98
|
/** The record carries a full build's anchor forward for unchanged paths. */
|
|
99
99
|
carriesFullAnchor?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Who wrote the record and when, so a run whose coverage a peer's scoped
|
|
102
|
+
* build replaced can tell whose build that was.
|
|
103
|
+
*/
|
|
104
|
+
recordedBy?: string | undefined;
|
|
105
|
+
builtAt?: string | undefined;
|
|
106
|
+
recorder?: BaselineRecorder | undefined;
|
|
107
|
+
/** Whether the recorder's process is still running (it may still be using the packaging). */
|
|
108
|
+
recorderAlive?: boolean | undefined;
|
|
100
109
|
}
|
|
101
110
|
/**
|
|
102
111
|
* Formats the refusal shown when a non-`--build` run requests paths the
|
|
@@ -163,6 +163,20 @@ export async function findChangedTestManifestsForPaths(engineDir, baseline, unco
|
|
|
163
163
|
});
|
|
164
164
|
return hits.slice(0, STALE_PATHS_LIMIT);
|
|
165
165
|
}
|
|
166
|
+
/** The refusal's sentence naming who wrote the coverage record. */
|
|
167
|
+
function formatCoverageHolder(detail) {
|
|
168
|
+
if (detail.recorder === undefined && detail.recordedBy === undefined)
|
|
169
|
+
return '';
|
|
170
|
+
const what = detail.recordedBy !== undefined ? `"${detail.recordedBy}"` : 'a build';
|
|
171
|
+
const when = detail.builtAt !== undefined ? ` at ${detail.builtAt}` : '';
|
|
172
|
+
const recorder = detail.recorder;
|
|
173
|
+
const who = recorder === undefined
|
|
174
|
+
? ''
|
|
175
|
+
: ` (pid ${recorder.pid}${detail.recorderAlive === true ? ', still running' : ''}` +
|
|
176
|
+
(recorder.sessionId !== undefined ? `, session ${recorder.sessionId}` : '') +
|
|
177
|
+
`, invocation ${recorder.invocationId})`;
|
|
178
|
+
return ` The current record was written by ${what}${when}${who}.`;
|
|
179
|
+
}
|
|
166
180
|
/**
|
|
167
181
|
* Formats the refusal shown when a non-`--build` run requests paths the
|
|
168
182
|
* packaged runtime's scoped `test --build` coverage does not include. It is
|
|
@@ -210,7 +224,7 @@ export function formatTestCoverageRefusal(uncovered, coverage, changedManifests
|
|
|
210
224
|
return (`The packaged test runtime was produced by a scoped "fireforge test --build" covering only: ${scope}.\n` +
|
|
211
225
|
`The requested run needs ${cap(uncovered)}, which that packaging does not cover — support ` +
|
|
212
226
|
'fixtures for those manifests may be missing from obj-*/_tests/, and the run can hang ' +
|
|
213
|
-
`rather than fail.${affectedLine}${manifestLine} ${rebuildHint} ` +
|
|
227
|
+
`rather than fail.${formatCoverageHolder(detail)}${affectedLine}${manifestLine} ${rebuildHint} ` +
|
|
214
228
|
'(--allow-stale-build does not bypass this check — it accepts stale content, not missing coverage.)');
|
|
215
229
|
}
|
|
216
230
|
/**
|
|
@@ -22,6 +22,8 @@ export interface XpcshellRetryOptions {
|
|
|
22
22
|
kind?: MachTestSuiteKind | undefined;
|
|
23
23
|
/** Whether the run was started with full harness output. */
|
|
24
24
|
fullOutput?: boolean | undefined;
|
|
25
|
+
/** Per-chunk feed for the retried run's output (start-marker tracking). */
|
|
26
|
+
onOutputChunk?: ((stream: 'stdout' | 'stderr', chunk: string) => void) | undefined;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Removes a stale xpcshell install symlink and retries the focused mach test
|
|
@@ -9,7 +9,7 @@ import { tryRepairStaleXpcshellTestSymlink } from './test-stale-symlink.js';
|
|
|
9
9
|
* generic command.
|
|
10
10
|
*/
|
|
11
11
|
export async function retryAfterXpcshellSymlinkRepair(options) {
|
|
12
|
-
const { engineDir, objDir, result, classification, normalizedPaths, extraArgs, env, kind = 'test', fullOutput, } = options;
|
|
12
|
+
const { engineDir, objDir, result, classification, normalizedPaths, extraArgs, env, kind = 'test', fullOutput, onOutputChunk, } = options;
|
|
13
13
|
if (result.exitCode !== 0 &&
|
|
14
14
|
classification.xpcshell.length > 0 &&
|
|
15
15
|
classification.nonXpcshell.length === 0) {
|
|
@@ -23,6 +23,7 @@ export async function retryAfterXpcshellSymlinkRepair(options) {
|
|
|
23
23
|
args: extraArgs,
|
|
24
24
|
env,
|
|
25
25
|
fullOutput,
|
|
26
|
+
...(onOutputChunk === undefined ? {} : { teardown: { onOutputChunk } }),
|
|
26
27
|
});
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -7,9 +7,12 @@
|
|
|
7
7
|
* every other theme resolves it to nothing.
|
|
8
8
|
* - `token-undeclared`: a `var(--<prefix>…)` reference in the tokens CSS or
|
|
9
9
|
* in a CSS file the patch queue touches names a token no block of the
|
|
10
|
-
* tokens CSS declares. Same-file declarations,
|
|
10
|
+
* tokens CSS declares. Same-file declarations, declarations of a sheet
|
|
11
|
+
* that loads beside it (see `token-sibling-sheets.ts`), `furnace.json`
|
|
11
12
|
* `tokenAllowlist` and `runtimeVariables` are exempt, matching the
|
|
12
|
-
* `token-prefix-violation` rule's notion of a runtime channel.
|
|
13
|
+
* `token-prefix-violation` rule's notion of a runtime channel. A
|
|
14
|
+
* reference with a fallback (`var(--x, 0)`) is optional by construction
|
|
15
|
+
* (a host hook, a channel set from JS) and is not reported.
|
|
13
16
|
*
|
|
14
17
|
* Built on `token-category.ts`'s base-block and comment-mask primitives, so
|
|
15
18
|
* this report and `token add` agree on which block is the base.
|
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
* every other theme resolves it to nothing.
|
|
9
9
|
* - `token-undeclared`: a `var(--<prefix>…)` reference in the tokens CSS or
|
|
10
10
|
* in a CSS file the patch queue touches names a token no block of the
|
|
11
|
-
* tokens CSS declares. Same-file declarations,
|
|
11
|
+
* tokens CSS declares. Same-file declarations, declarations of a sheet
|
|
12
|
+
* that loads beside it (see `token-sibling-sheets.ts`), `furnace.json`
|
|
12
13
|
* `tokenAllowlist` and `runtimeVariables` are exempt, matching the
|
|
13
|
-
* `token-prefix-violation` rule's notion of a runtime channel.
|
|
14
|
+
* `token-prefix-violation` rule's notion of a runtime channel. A
|
|
15
|
+
* reference with a fallback (`var(--x, 0)`) is optional by construction
|
|
16
|
+
* (a host hook, a channel set from JS) and is not reported.
|
|
14
17
|
*
|
|
15
18
|
* Built on `token-category.ts`'s base-block and comment-mask primitives, so
|
|
16
19
|
* this report and `token add` agree on which block is the base.
|
|
@@ -104,8 +107,10 @@ export function lintUndeclaredTokenReferences(file, css, tokenPrefix, declared,
|
|
|
104
107
|
const findings = [];
|
|
105
108
|
const seen = new Set();
|
|
106
109
|
for (const [index, line] of maskCommentLines(lines).entries()) {
|
|
107
|
-
for (const match of line.matchAll(/var\(\s*(--[A-Za-z0-9_-]+)
|
|
110
|
+
for (const match of line.matchAll(/var\(\s*(--[A-Za-z0-9_-]+)\s*(,)?/g)) {
|
|
108
111
|
const name = match[1] ?? '';
|
|
112
|
+
if (match[2] !== undefined)
|
|
113
|
+
continue;
|
|
109
114
|
if (!name.startsWith(tokenPrefix) || declared.has(name) || local.has(name))
|
|
110
115
|
continue;
|
|
111
116
|
if (exempt.has(name) || seen.has(name))
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which stylesheets load together, so `token lint` can resolve a token one
|
|
3
|
+
* sheet references against the declarations of the sheets beside it.
|
|
4
|
+
*
|
|
5
|
+
* A widget sheet may read a token its host document's other sheet
|
|
6
|
+
* declares; judged alone it looks undeclared. Two sources say which sheets
|
|
7
|
+
* share a document:
|
|
8
|
+
*
|
|
9
|
+
* - links the queue's documents make: `<link rel="stylesheet">` (and
|
|
10
|
+
* `<html:link>`) and `<?xml-stylesheet?>` in markup and Lit templates,
|
|
11
|
+
* and CSS `@import`. A `chrome://` URL resolves through the jar.mn lines
|
|
12
|
+
* the queue adds; a relative URL resolves beside the document, and only
|
|
13
|
+
* to a sheet the queue touches.
|
|
14
|
+
* - `furnace.json#tokenSiblingSheets`: `{ "<glob>": ["<path or glob>"] }`,
|
|
15
|
+
* for pairings no link in the queue shows (an upstream host document).
|
|
16
|
+
*
|
|
17
|
+
* Sheets linked from one document are siblings of each other; an
|
|
18
|
+
* `@import` makes the importing and the imported sheet siblings.
|
|
19
|
+
*/
|
|
20
|
+
/** The stylesheet URLs one document or sheet loads, in order. */
|
|
21
|
+
export declare function collectStylesheetUrls(file: string, content: string): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Resolves a stylesheet URL to an engine-relative path, or undefined.
|
|
24
|
+
*
|
|
25
|
+
* @param url - The URL as written
|
|
26
|
+
* @param from - Engine-relative path of the document or sheet holding it
|
|
27
|
+
* @param jarTargets - jar target (`content/<pkg>/<path>`) → packaged source
|
|
28
|
+
* @param knownSheets - Sheets a relative URL may resolve to
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveStylesheetUrl(url: string, from: string, jarTargets: ReadonlyMap<string, string>, knownSheets: ReadonlySet<string>): string | undefined;
|
|
31
|
+
/** Inputs of {@link buildSiblingSheetMap}. */
|
|
32
|
+
export interface SiblingSheetInputs {
|
|
33
|
+
/** Documents and sheets to read links from: engine-relative path and content. */
|
|
34
|
+
documents: Iterable<readonly [string, string]>;
|
|
35
|
+
/** jar target → packaged source, from the queue's jar.mn lines. */
|
|
36
|
+
jarTargets: ReadonlyMap<string, string>;
|
|
37
|
+
/** The sheets `token lint` judges. */
|
|
38
|
+
sheets: readonly string[];
|
|
39
|
+
/** `furnace.json#tokenSiblingSheets`. */
|
|
40
|
+
explicit?: Readonly<Record<string, readonly string[]>> | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Maps each sheet to the other sheets that load beside it. A sheet with no
|
|
44
|
+
* siblings is absent.
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildSiblingSheetMap(inputs: SiblingSheetInputs): Map<string, Set<string>>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Which stylesheets load together, so `token lint` can resolve a token one
|
|
4
|
+
* sheet references against the declarations of the sheets beside it.
|
|
5
|
+
*
|
|
6
|
+
* A widget sheet may read a token its host document's other sheet
|
|
7
|
+
* declares; judged alone it looks undeclared. Two sources say which sheets
|
|
8
|
+
* share a document:
|
|
9
|
+
*
|
|
10
|
+
* - links the queue's documents make: `<link rel="stylesheet">` (and
|
|
11
|
+
* `<html:link>`) and `<?xml-stylesheet?>` in markup and Lit templates,
|
|
12
|
+
* and CSS `@import`. A `chrome://` URL resolves through the jar.mn lines
|
|
13
|
+
* the queue adds; a relative URL resolves beside the document, and only
|
|
14
|
+
* to a sheet the queue touches.
|
|
15
|
+
* - `furnace.json#tokenSiblingSheets`: `{ "<glob>": ["<path or glob>"] }`,
|
|
16
|
+
* for pairings no link in the queue shows (an upstream host document).
|
|
17
|
+
*
|
|
18
|
+
* Sheets linked from one document are siblings of each other; an
|
|
19
|
+
* `@import` makes the importing and the imported sheet siblings.
|
|
20
|
+
*/
|
|
21
|
+
import { dirname, posix } from 'node:path';
|
|
22
|
+
import { matchesAnyGlob } from '../utils/path-glob.js';
|
|
23
|
+
import { normalizePathSlashes } from '../utils/paths.js';
|
|
24
|
+
const LINK_TAG = /<(?:html:)?link\b[^>]*>/gi;
|
|
25
|
+
const STYLESHEET_PI = /<\?xml-stylesheet\b[^?]*?href\s*=\s*["']([^"']+)["']/gi;
|
|
26
|
+
const CSS_IMPORT = /@import\s+(?:url\(\s*)?["']([^"']+)["']/gi;
|
|
27
|
+
/** The stylesheet URLs one document or sheet loads, in order. */
|
|
28
|
+
export function collectStylesheetUrls(file, content) {
|
|
29
|
+
const urls = [];
|
|
30
|
+
if (file.endsWith('.css')) {
|
|
31
|
+
for (const match of content.matchAll(CSS_IMPORT))
|
|
32
|
+
urls.push(match[1] ?? '');
|
|
33
|
+
return urls.filter((url) => url !== '');
|
|
34
|
+
}
|
|
35
|
+
for (const match of content.matchAll(LINK_TAG)) {
|
|
36
|
+
const tag = match[0];
|
|
37
|
+
if (!/\brel\s*=\s*["']stylesheet["']/i.test(tag))
|
|
38
|
+
continue;
|
|
39
|
+
const href = /\bhref\s*=\s*["']([^"'$]+)["']/i.exec(tag)?.[1];
|
|
40
|
+
if (href !== undefined)
|
|
41
|
+
urls.push(href);
|
|
42
|
+
}
|
|
43
|
+
for (const match of content.matchAll(STYLESHEET_PI))
|
|
44
|
+
urls.push(match[1] ?? '');
|
|
45
|
+
return urls.filter((url) => url.endsWith('.css'));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolves a stylesheet URL to an engine-relative path, or undefined.
|
|
49
|
+
*
|
|
50
|
+
* @param url - The URL as written
|
|
51
|
+
* @param from - Engine-relative path of the document or sheet holding it
|
|
52
|
+
* @param jarTargets - jar target (`content/<pkg>/<path>`) → packaged source
|
|
53
|
+
* @param knownSheets - Sheets a relative URL may resolve to
|
|
54
|
+
*/
|
|
55
|
+
export function resolveStylesheetUrl(url, from, jarTargets, knownSheets) {
|
|
56
|
+
const chrome = /^chrome:\/\/([\w.-]+)\/(content|skin|locale)\/(.+)$/.exec(url);
|
|
57
|
+
if (chrome !== null) {
|
|
58
|
+
const [, pkg = '', kind = '', path = ''] = chrome;
|
|
59
|
+
const candidates = kind === 'skin'
|
|
60
|
+
? [`skin/classic/${pkg}/${path}`, `skin/${pkg}/${path}`]
|
|
61
|
+
: [`${kind}/${pkg}/${path}`];
|
|
62
|
+
for (const target of candidates) {
|
|
63
|
+
const source = jarTargets.get(target);
|
|
64
|
+
if (source !== undefined)
|
|
65
|
+
return source;
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
if (/^[a-z][\w+.-]*:/i.test(url))
|
|
70
|
+
return undefined;
|
|
71
|
+
const base = normalizePathSlashes(dirname(from));
|
|
72
|
+
const resolved = posix.normalize(posix.join(base === '.' ? '' : base, url));
|
|
73
|
+
return knownSheets.has(resolved) ? resolved : undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Maps each sheet to the other sheets that load beside it. A sheet with no
|
|
77
|
+
* siblings is absent.
|
|
78
|
+
*/
|
|
79
|
+
export function buildSiblingSheetMap(inputs) {
|
|
80
|
+
const known = new Set(inputs.sheets);
|
|
81
|
+
const siblings = new Map();
|
|
82
|
+
const link = (group) => {
|
|
83
|
+
for (const sheet of group) {
|
|
84
|
+
const set = siblings.get(sheet) ?? new Set();
|
|
85
|
+
for (const other of group)
|
|
86
|
+
if (other !== sheet)
|
|
87
|
+
set.add(other);
|
|
88
|
+
if (set.size > 0)
|
|
89
|
+
siblings.set(sheet, set);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
for (const [file, content] of inputs.documents) {
|
|
93
|
+
const linked = collectStylesheetUrls(file, content)
|
|
94
|
+
.map((url) => resolveStylesheetUrl(url, file, inputs.jarTargets, known))
|
|
95
|
+
.filter((sheet) => sheet !== undefined);
|
|
96
|
+
// An @import pairs the importing sheet with what it imports.
|
|
97
|
+
link(file.endsWith('.css') ? [file, ...linked] : linked);
|
|
98
|
+
}
|
|
99
|
+
for (const [pattern, partners] of Object.entries(inputs.explicit ?? {})) {
|
|
100
|
+
const owners = inputs.sheets.filter((sheet) => matchesAnyGlob(sheet, [pattern]));
|
|
101
|
+
for (const owner of owners) {
|
|
102
|
+
const set = siblings.get(owner) ?? new Set();
|
|
103
|
+
for (const partner of partners) {
|
|
104
|
+
if (/[*?]/.test(partner)) {
|
|
105
|
+
for (const sheet of inputs.sheets) {
|
|
106
|
+
if (sheet !== owner && matchesAnyGlob(sheet, [partner]))
|
|
107
|
+
set.add(sheet);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (partner !== owner) {
|
|
111
|
+
set.add(partner);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (set.size > 0)
|
|
115
|
+
siblings.set(owner, set);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return siblings;
|
|
119
|
+
}
|
|
@@ -36,6 +36,8 @@ export const TREE_COMMAND_VERDICTS = {
|
|
|
36
36
|
export: 'conditional',
|
|
37
37
|
'export-all': 'conditional',
|
|
38
38
|
're-export': 'conditional',
|
|
39
|
+
// Parks live in the primary tree's .fireforge/ and rewrite engine files.
|
|
40
|
+
park: 'refused',
|
|
39
41
|
patch: 'refused',
|
|
40
42
|
rebase: 'refused',
|
|
41
43
|
package: 'refused',
|
|
@@ -81,5 +81,10 @@ export interface ComposedShim {
|
|
|
81
81
|
* @param projectRoot - Absolute project root, used to resolve the relative
|
|
82
82
|
* shim path
|
|
83
83
|
* @param extraShimPath - Optional project-relative path to an extra `.d.ts`
|
|
84
|
+
* @param options - `litTypes` appends {@link LIT_TYPES_SHIM} after the
|
|
85
|
+
* built-in shim (before the extra shim, which can still merge into it),
|
|
86
|
+
* and {@link LOOSE_LIT_SHIM} otherwise
|
|
84
87
|
*/
|
|
85
|
-
export declare function composeShimSource(projectRoot: string, extraShimPath: string | undefined
|
|
88
|
+
export declare function composeShimSource(projectRoot: string, extraShimPath: string | undefined, options?: {
|
|
89
|
+
litTypes?: boolean | undefined;
|
|
90
|
+
}): Promise<ComposedShim>;
|
|
@@ -289,6 +289,140 @@ export const UNDEFINED_IDENTIFIER_CODES = new Set([
|
|
|
289
289
|
2304, // Cannot find name '{0}'.
|
|
290
290
|
2552, // Cannot find name '{0}'. Did you mean '{1}'?
|
|
291
291
|
]);
|
|
292
|
+
/**
|
|
293
|
+
* Typed Lit, opt-in through `typecheck.litTypes`. Declares the two chrome
|
|
294
|
+
* modules widgets import Lit from, so they no longer fall to the
|
|
295
|
+
* `chrome:*` wildcard as `any`: `LitElement` (with `ReactiveElement`'s
|
|
296
|
+
* lifecycle) and `MozLitElement` carry closed member lists, so a misspelt
|
|
297
|
+
* member of a widget host is TS2339, as `Cu` is in the built-in shim.
|
|
298
|
+
* Template helpers and directives stay loose. The global
|
|
299
|
+
* `MozLitElementWith<Extra>` types a widget's query getters and
|
|
300
|
+
* `static properties` members: the widget casts its `MozLitElement` import
|
|
301
|
+
* to it before extending ({@link LOOSE_LIT_SHIM} keeps it `any` without
|
|
302
|
+
* typed Lit). A project
|
|
303
|
+
* shim can merge members into `LitElementShimMembers`; a project whose
|
|
304
|
+
* jsconfig `paths`
|
|
305
|
+
* maps these URLs to the real sources gets those instead, since a resolved
|
|
306
|
+
* file wins over an ambient module.
|
|
307
|
+
*/
|
|
308
|
+
const LIT_TYPES_SHIM = `
|
|
309
|
+
// ── FireForge typed Lit (typecheck.litTypes) ──
|
|
310
|
+
interface LitPropertyDeclarationShim {
|
|
311
|
+
type?: unknown;
|
|
312
|
+
attribute?: boolean | string;
|
|
313
|
+
reflect?: boolean;
|
|
314
|
+
state?: boolean;
|
|
315
|
+
noAccessor?: boolean;
|
|
316
|
+
converter?: unknown;
|
|
317
|
+
hasChanged?(value: unknown, oldValue: unknown): boolean;
|
|
318
|
+
fluent?: boolean;
|
|
319
|
+
}
|
|
320
|
+
interface LitElementShimMembers {
|
|
321
|
+
readonly renderRoot: HTMLElement | DocumentFragment;
|
|
322
|
+
readonly isUpdatePending: boolean;
|
|
323
|
+
readonly hasUpdated: boolean;
|
|
324
|
+
readonly updateComplete: Promise<boolean>;
|
|
325
|
+
renderOptions: any;
|
|
326
|
+
requestUpdate(name?: PropertyKey, oldValue?: unknown, options?: LitPropertyDeclarationShim): void;
|
|
327
|
+
addController(controller: any): void;
|
|
328
|
+
removeController(controller: any): void;
|
|
329
|
+
connectedCallback(): void;
|
|
330
|
+
disconnectedCallback(): void;
|
|
331
|
+
attributeChangedCallback(name: string, oldValue: string | null, value: string | null): void;
|
|
332
|
+
createRenderRoot(): HTMLElement | DocumentFragment;
|
|
333
|
+
enableUpdating(requestedUpdate: boolean): void;
|
|
334
|
+
scheduleUpdate(): void | Promise<unknown>;
|
|
335
|
+
performUpdate(): void;
|
|
336
|
+
getUpdateComplete(): Promise<boolean>;
|
|
337
|
+
shouldUpdate(changedProperties: Map<PropertyKey, unknown>): boolean;
|
|
338
|
+
willUpdate(changedProperties: Map<PropertyKey, unknown>): void;
|
|
339
|
+
update(changedProperties: Map<PropertyKey, unknown>): void;
|
|
340
|
+
render(): unknown;
|
|
341
|
+
firstUpdated(changedProperties: Map<PropertyKey, unknown>): void;
|
|
342
|
+
updated(changedProperties: Map<PropertyKey, unknown>): void;
|
|
343
|
+
}
|
|
344
|
+
declare module 'chrome://global/content/vendor/lit.all.mjs' {
|
|
345
|
+
export class ReactiveElement extends HTMLElement {
|
|
346
|
+
static properties: Record<string, LitPropertyDeclarationShim>;
|
|
347
|
+
static styles: any;
|
|
348
|
+
static shadowRootOptions: ShadowRootInit;
|
|
349
|
+
static readonly observedAttributes: string[];
|
|
350
|
+
static createProperty(name: PropertyKey, options?: LitPropertyDeclarationShim): void;
|
|
351
|
+
static addInitializer(initializer: (element: ReactiveElement) => void): void;
|
|
352
|
+
}
|
|
353
|
+
export interface ReactiveElement extends LitElementShimMembers {}
|
|
354
|
+
export class LitElement extends ReactiveElement {}
|
|
355
|
+
export const html: (strings: TemplateStringsArray, ...values: unknown[]) => any;
|
|
356
|
+
export const svg: (strings: TemplateStringsArray, ...values: unknown[]) => any;
|
|
357
|
+
export const css: (strings: TemplateStringsArray, ...values: unknown[]) => any;
|
|
358
|
+
export const nothing: any;
|
|
359
|
+
export const noChange: any;
|
|
360
|
+
export const render: any;
|
|
361
|
+
export const unsafeCSS: any;
|
|
362
|
+
export const classMap: any;
|
|
363
|
+
export const styleMap: any;
|
|
364
|
+
export const ifDefined: any;
|
|
365
|
+
export const repeat: any;
|
|
366
|
+
export const when: any;
|
|
367
|
+
export const map: any;
|
|
368
|
+
export const live: any;
|
|
369
|
+
export const ref: any;
|
|
370
|
+
export const createRef: any;
|
|
371
|
+
export const until: any;
|
|
372
|
+
export const guard: any;
|
|
373
|
+
export const choose: any;
|
|
374
|
+
export const keyed: any;
|
|
375
|
+
export const cache: any;
|
|
376
|
+
export const join: any;
|
|
377
|
+
export const range: any;
|
|
378
|
+
export const unsafeHTML: any;
|
|
379
|
+
export const unsafeSVG: any;
|
|
380
|
+
export const literal: any;
|
|
381
|
+
export const unsafeStatic: any;
|
|
382
|
+
export const staticHtml: any;
|
|
383
|
+
export const staticSvg: any;
|
|
384
|
+
export const directive: any;
|
|
385
|
+
export const Directive: any;
|
|
386
|
+
export const AsyncDirective: any;
|
|
387
|
+
export const PartType: any;
|
|
388
|
+
export const defaultConverter: any;
|
|
389
|
+
export const notEqual: any;
|
|
390
|
+
export const adoptStyles: any;
|
|
391
|
+
export const supportsAdoptingStyleSheets: boolean;
|
|
392
|
+
export const CSSResult: any;
|
|
393
|
+
export const isServer: boolean;
|
|
394
|
+
}
|
|
395
|
+
declare module 'chrome://global/content/lit-utils.mjs' {
|
|
396
|
+
import { LitElement } from 'chrome://global/content/vendor/lit.all.mjs';
|
|
397
|
+
export class MozLitElement extends LitElement {
|
|
398
|
+
static queries: Record<string, string | Record<string, unknown>>;
|
|
399
|
+
static fragment: unknown;
|
|
400
|
+
dispatchOnUpdateComplete(event: Event): Promise<void>;
|
|
401
|
+
}
|
|
402
|
+
export const MozBaseInputElement: any;
|
|
403
|
+
export const MozBoolInputElement: any;
|
|
404
|
+
export const SelectControlBaseElement: any;
|
|
405
|
+
export const SelectControlItemMixin: any;
|
|
406
|
+
}
|
|
407
|
+
// MozLitElement with instance members Extra: what a widget casts its base
|
|
408
|
+
// to for the getters static queries installs (and properties it declares
|
|
409
|
+
// only in static properties). A class field would redefine a query getter
|
|
410
|
+
// and throw, and a constructor declaration reads it before renderRoot.
|
|
411
|
+
type MozLitElementWith<Extra> = Pick<
|
|
412
|
+
typeof import('chrome://global/content/lit-utils.mjs').MozLitElement,
|
|
413
|
+
keyof typeof import('chrome://global/content/lit-utils.mjs').MozLitElement
|
|
414
|
+
> &
|
|
415
|
+
(new () => import('chrome://global/content/lit-utils.mjs').MozLitElement & Extra);
|
|
416
|
+
`;
|
|
417
|
+
/**
|
|
418
|
+
* Without typed Lit, `MozLitElementWith<Extra>` is `any`, as the base it
|
|
419
|
+
* casts is: the same widget source checks under per-patch checkJs and a
|
|
420
|
+
* project typecheck that leaves `litTypes` off.
|
|
421
|
+
*/
|
|
422
|
+
const LOOSE_LIT_SHIM = `
|
|
423
|
+
// FireForge loose Lit (typecheck.litTypes off): see typecheck-shim.ts.
|
|
424
|
+
type MozLitElementWith<Extra> = any;
|
|
425
|
+
`;
|
|
292
426
|
/** Hint appended to reported undefined-identifier diagnostics. */
|
|
293
427
|
export const UNDEFINED_IDENTIFIER_HINT = '(undefined identifier — import or declare it, add the global to the extra shim, ' +
|
|
294
428
|
'or tune the "undefinedIdentifiers" setting)';
|
|
@@ -350,9 +484,12 @@ async function inlineTripleSlashReferences(source, baseDir, seen) {
|
|
|
350
484
|
* @param projectRoot - Absolute project root, used to resolve the relative
|
|
351
485
|
* shim path
|
|
352
486
|
* @param extraShimPath - Optional project-relative path to an extra `.d.ts`
|
|
487
|
+
* @param options - `litTypes` appends {@link LIT_TYPES_SHIM} after the
|
|
488
|
+
* built-in shim (before the extra shim, which can still merge into it),
|
|
489
|
+
* and {@link LOOSE_LIT_SHIM} otherwise
|
|
353
490
|
*/
|
|
354
|
-
export async function composeShimSource(projectRoot, extraShimPath) {
|
|
355
|
-
const base = FIREFOX_GLOBALS_SHIM
|
|
491
|
+
export async function composeShimSource(projectRoot, extraShimPath, options = {}) {
|
|
492
|
+
const base = `${FIREFOX_GLOBALS_SHIM}\n${options.litTypes === true ? LIT_TYPES_SHIM : LOOSE_LIT_SHIM}`;
|
|
356
493
|
if (!extraShimPath) {
|
|
357
494
|
return { source: base, extraShimAppended: false };
|
|
358
495
|
}
|
|
@@ -102,7 +102,9 @@ export async function runTypecheck(projectRoot, cfg, runOptions = {}) {
|
|
|
102
102
|
const cached = shimCache.get(key);
|
|
103
103
|
if (cached !== undefined)
|
|
104
104
|
return cached;
|
|
105
|
-
const composed = await composeShimSource(projectRoot, extraShim
|
|
105
|
+
const composed = await composeShimSource(projectRoot, extraShim, {
|
|
106
|
+
litTypes: cfg.litTypes,
|
|
107
|
+
});
|
|
106
108
|
if (composed.extraShimAppended) {
|
|
107
109
|
verbose(`typecheck: extra shim ${extraShim ?? ''} appended to Firefox globals shim`);
|
|
108
110
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -24,13 +24,19 @@ export { ensureFurnaceConfig, loadFurnaceConfig, loadFurnaceState, saveFurnaceSt
|
|
|
24
24
|
export { validateAllComponents, validateComponent } from './core/furnace-validate.js';
|
|
25
25
|
export type { PatchSizeThresholds, PatchSizeTierDecision } from './core/patch-lint.js';
|
|
26
26
|
export { countNonBinaryDiffLines, filesMeasuredByFileTooLarge, getPatchSizeThresholds, isTestFile, resolvePatchSizeTier, } from './core/patch-lint.js';
|
|
27
|
-
export type { CodeLineCount } from './core/patch-lint-code-lines.js';
|
|
28
|
-
export { countCodeLines } from './core/patch-lint-code-lines.js';
|
|
27
|
+
export type { CodeLineCount, CodeLineMask } from './core/patch-lint-code-lines.js';
|
|
28
|
+
export { codeLineMask, countCodeLines } from './core/patch-lint-code-lines.js';
|
|
29
29
|
export type { ResolvedFileSizeTier } from './core/patch-lint-file-size.js';
|
|
30
30
|
export { resolveFileSizeThresholds } from './core/patch-lint-file-size.js';
|
|
31
|
+
export type { PatchSizeMeasurement } from './core/patch-lint-size.js';
|
|
32
|
+
export { measurePatchSize } from './core/patch-lint-size.js';
|
|
31
33
|
export type { ResolvedPatchFilesTier } from './core/patch-lint-size-thresholds.js';
|
|
34
|
+
export { isPatchSizeRegistrationFile } from './core/patch-lint-size-thresholds.js';
|
|
35
|
+
export type { PatchPolicyIssue, PatchPolicyIssueCode } from './core/patch-policy.js';
|
|
36
|
+
export { evaluatePatchPolicyContentForQueue } from './core/patch-policy-content.js';
|
|
32
37
|
export type { AddTokenOptions, AddTokenResult, TokenMode } from './core/token-manager.js';
|
|
33
38
|
export { addToken, getTokensCssPath, validateTokenAdd } from './core/token-manager.js';
|
|
34
39
|
export { CancellationError, CommandError, FireForgeError, GeneralError, InvalidArgumentError, ResolutionError, } from './errors/base.js';
|
|
35
40
|
export { ExitCode } from './errors/codes.js';
|
|
36
|
-
export type {
|
|
41
|
+
export type { PatchesManifest, PatchMetadata } from './types/commands/index.js';
|
|
42
|
+
export type { ApplyResult, BuildConfig, ComponentType, CustomComponentConfig, DryRunAction, FireForgeConfig, FirefoxConfig, FirefoxProduct, FurnaceConfig, FurnaceState, OverrideComponentConfig, OverrideType, PatchLintFileSizeThresholds, PatchLintFileSizeTier, PatchLintPatchSizeMetric, ProjectLicense, StepError, ValidationIssue, WireConfig, } from './types/index.js';
|