@hominis/fireforge 0.49.0 → 0.49.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/dist/build-info.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.49.
|
|
4
|
-
"commit": "
|
|
5
|
-
"shortCommit": "
|
|
3
|
+
"version": "0.49.1",
|
|
4
|
+
"commit": "6348d3cae2e93096039d40ce0b52bfce0a0b9308",
|
|
5
|
+
"shortCommit": "6348d3cae2e9",
|
|
6
6
|
"dirty": false,
|
|
7
7
|
"dirtyHash": null,
|
|
8
|
-
"buildTime": "2026-10-
|
|
8
|
+
"buildTime": "2026-10-04T15:20:41.231Z"
|
|
9
9
|
}
|
|
@@ -30,6 +30,15 @@ function replacePrefix(value, oldRoot, newRoot) {
|
|
|
30
30
|
? newRoot + value.slice(oldRoot.length)
|
|
31
31
|
: value;
|
|
32
32
|
}
|
|
33
|
+
/** Rewrites references under oldRoot, including the forward-slash spelling mozbuild writes on Windows. */
|
|
34
|
+
function rewriteRootReferences(content, oldRoot, newRoot) {
|
|
35
|
+
const rewritten = content.replaceAll(oldRoot + sep, newRoot + sep);
|
|
36
|
+
if (sep !== '\\')
|
|
37
|
+
return rewritten;
|
|
38
|
+
return rewritten
|
|
39
|
+
.replaceAll(oldRoot + '/', newRoot + '/')
|
|
40
|
+
.replaceAll(oldRoot.replaceAll('\\', '/') + '/', newRoot.replaceAll('\\', '/') + '/');
|
|
41
|
+
}
|
|
33
42
|
function isDependencyMetadata(path) {
|
|
34
43
|
return (/\.(?:pp|d)$/.test(path) ||
|
|
35
44
|
/[/\\]faster[/\\]/.test(path) ||
|
|
@@ -72,6 +81,13 @@ export async function relocateObjdirProducts(engineDir, objDir, oldRoot) {
|
|
|
72
81
|
try {
|
|
73
82
|
await rename(temp, path);
|
|
74
83
|
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// Windows refuses to rename over a directory link; replace it in two steps.
|
|
86
|
+
if (process.platform !== 'win32' || getNodeErrorCode(error) !== 'EPERM')
|
|
87
|
+
throw error;
|
|
88
|
+
await rm(path);
|
|
89
|
+
await rename(temp, path);
|
|
90
|
+
}
|
|
75
91
|
finally {
|
|
76
92
|
await rm(temp, { force: true });
|
|
77
93
|
}
|
|
@@ -79,7 +95,7 @@ export async function relocateObjdirProducts(engineDir, objDir, oldRoot) {
|
|
|
79
95
|
}
|
|
80
96
|
else if (isDependencyMetadata(path)) {
|
|
81
97
|
const content = await readFile(path, 'utf8');
|
|
82
|
-
const rewritten = content
|
|
98
|
+
const rewritten = rewriteRootReferences(content, oldRoot, newRoot);
|
|
83
99
|
if (content !== rewritten)
|
|
84
100
|
await writeText(path, rewritten);
|
|
85
101
|
}
|
|
@@ -142,12 +142,14 @@ export function parseDiffGitHeader(line) {
|
|
|
142
142
|
return { sourcePath: candidate, targetPath: candidate };
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
// Rename/copy (differing paths):
|
|
146
|
-
|
|
147
|
-
if (
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
|
|
145
|
+
// Rename/copy (differing paths): split at the first ` b/` with a path on
|
|
146
|
+
// each side. indexOf keeps this linear where a lazy regex backtracks.
|
|
147
|
+
if (/[\n\r\u2028\u2029]/.test(rest))
|
|
148
|
+
return null;
|
|
149
|
+
const split = rest.indexOf(' b/', 1);
|
|
150
|
+
if (split === -1 || split + 3 >= rest.length)
|
|
151
|
+
return null;
|
|
152
|
+
return { sourcePath: rest.slice(0, split), targetPath: rest.slice(split + 3) };
|
|
151
153
|
}
|
|
152
154
|
/**
|
|
153
155
|
* Splits raw diff content into lines, tolerating CRLF-saved patch files.
|
|
@@ -209,6 +209,33 @@ export function findCategorySection(lines, category, tokensCssPath) {
|
|
|
209
209
|
}
|
|
210
210
|
return { categoryLine: section.categoryLine, sectionEnd: section.sectionEnd };
|
|
211
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Drops complete quoted strings from one CSS line in linear time. An
|
|
214
|
+
* unterminated quote is kept, and once one fails to close every later quote
|
|
215
|
+
* of that kind fails too, so no start position is ever rescanned.
|
|
216
|
+
*/
|
|
217
|
+
function stripCssStrings(line) {
|
|
218
|
+
let out = '';
|
|
219
|
+
const unterminated = new Set();
|
|
220
|
+
for (let i = 0; i < line.length; i++) {
|
|
221
|
+
const quote = line.charAt(i);
|
|
222
|
+
if ((quote !== '"' && quote !== "'") || unterminated.has(quote)) {
|
|
223
|
+
out += quote;
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
let end = i + 1;
|
|
227
|
+
while (end < line.length && line.charAt(end) !== quote)
|
|
228
|
+
end += line.charAt(end) === '\\' ? 2 : 1;
|
|
229
|
+
if (end >= line.length) {
|
|
230
|
+
unterminated.add(quote);
|
|
231
|
+
out += quote;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
i = end;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return out;
|
|
238
|
+
}
|
|
212
239
|
/** 0-based open/close line indices of the base `:root {` block. */
|
|
213
240
|
export function findBaseRootBounds(lines) {
|
|
214
241
|
const open = lines.findIndex((line) => /:root\s*\{/.test(line));
|
|
@@ -218,7 +245,7 @@ export function findBaseRootBounds(lines) {
|
|
|
218
245
|
let depth = 0;
|
|
219
246
|
for (let i = open; i < lines.length; i++) {
|
|
220
247
|
// Ignore braces in CSS strings (including data URLs).
|
|
221
|
-
const code = (masked[i] ?? '')
|
|
248
|
+
const code = stripCssStrings(masked[i] ?? '');
|
|
222
249
|
for (const char of code) {
|
|
223
250
|
if (char === '{')
|
|
224
251
|
depth++;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hominis/fireforge",
|
|
3
|
-
"version": "0.49.
|
|
3
|
+
"version": "0.49.1",
|
|
4
4
|
"description": "FireForge — a build tool for customizing Firefox",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"eslint-plugin-simple-import-sort": "^14.0.0",
|
|
77
77
|
"fast-check": "^4.6.0",
|
|
78
78
|
"husky": "^9.1.7",
|
|
79
|
-
"knip": "6.
|
|
79
|
+
"knip": "6.39.0",
|
|
80
80
|
"lint-staged": "^17.0.4",
|
|
81
|
-
"prettier": "3.9.
|
|
81
|
+
"prettier": "3.9.9",
|
|
82
82
|
"tsx": "^4.7.0",
|
|
83
83
|
"typescript": "~6.0.0",
|
|
84
84
|
"typescript-eslint": "^8.0.0",
|