@hominis/fireforge 0.19.5 → 0.20.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 +30 -0
- package/README.md +21 -8
- package/dist/src/commands/config.js +1 -0
- package/dist/src/commands/download.js +188 -185
- package/dist/src/commands/export-flow.js +2 -13
- package/dist/src/commands/furnace/create-validation.d.ts +6 -0
- package/dist/src/commands/furnace/create-validation.js +59 -0
- package/dist/src/commands/furnace/create.d.ts +7 -7
- package/dist/src/commands/furnace/create.js +21 -96
- package/dist/src/commands/furnace/index.js +2 -2
- package/dist/src/commands/furnace/refresh.js +11 -2
- package/dist/src/commands/furnace/remove-state.d.ts +5 -0
- package/dist/src/commands/furnace/remove-state.js +14 -0
- package/dist/src/commands/furnace/remove.js +30 -45
- package/dist/src/commands/furnace/rename-helpers.d.ts +13 -0
- package/dist/src/commands/furnace/rename-helpers.js +42 -0
- package/dist/src/commands/furnace/rename.js +27 -47
- 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 +5 -0
- package/dist/src/core/config.js +11 -7
- package/dist/src/core/file-lock.js +2 -2
- package/dist/src/core/firefox-cache.d.ts +1 -1
- package/dist/src/core/firefox-cache.js +43 -17
- package/dist/src/core/firefox-download.js +12 -4
- package/dist/src/core/firefox.d.ts +1 -1
- package/dist/src/core/firefox.js +2 -2
- package/dist/src/core/furnace-refresh.js +16 -5
- package/dist/src/core/patch-lint-imports.d.ts +5 -0
- package/dist/src/core/patch-lint-imports.js +68 -0
- package/dist/src/core/patch-lint.js +2 -3
- package/dist/src/types/commands/options.d.ts +9 -9
- package/dist/src/types/config.d.ts +2 -0
- package/dist/src/utils/fs.d.ts +5 -0
- package/dist/src/utils/fs.js +54 -1
- package/dist/src/utils/process.js +4 -1
- package/package.json +1 -1
package/dist/src/utils/fs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: EUPL-1.2
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { access, copyFile as fsCopyFile, mkdir, open, readdir, readFile, rename, rm, statfs, } from 'node:fs/promises';
|
|
3
|
+
import { access, chmod, copyFile as fsCopyFile, mkdir, open, readdir, readFile, rename, rm, stat, statfs, } from 'node:fs/promises';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
const RETRIABLE_REMOVE_ERRORS = new Set(['ENOTEMPTY', 'EBUSY', 'EPERM']);
|
|
6
6
|
function sleep(ms) {
|
|
@@ -22,6 +22,25 @@ export async function pathExists(path) {
|
|
|
22
22
|
return false;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Checks if a path exists while surfacing permission errors.
|
|
27
|
+
* @param path - Path to check
|
|
28
|
+
*/
|
|
29
|
+
export async function pathExistsStrict(path) {
|
|
30
|
+
try {
|
|
31
|
+
await access(path);
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
const code = error instanceof Error && 'code' in error && typeof error.code === 'string'
|
|
36
|
+
? error.code
|
|
37
|
+
: undefined;
|
|
38
|
+
if (code === 'ENOENT') {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
25
44
|
/**
|
|
26
45
|
* Ensures a directory exists, creating it recursively if needed.
|
|
27
46
|
* @param path - Directory path to ensure
|
|
@@ -137,6 +156,18 @@ export async function writeTextIfChanged(path, content) {
|
|
|
137
156
|
*/
|
|
138
157
|
export async function writeFileAtomic(path, content) {
|
|
139
158
|
await ensureParentDir(path);
|
|
159
|
+
let existingMode;
|
|
160
|
+
try {
|
|
161
|
+
existingMode = (await stat(path)).mode;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
const code = error instanceof Error && 'code' in error && typeof error.code === 'string'
|
|
165
|
+
? error.code
|
|
166
|
+
: undefined;
|
|
167
|
+
if (code !== 'ENOENT') {
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
140
171
|
const tempPath = createAtomicTempPath(path);
|
|
141
172
|
const handle = await open(tempPath, 'w');
|
|
142
173
|
try {
|
|
@@ -150,13 +181,35 @@ export async function writeFileAtomic(path, content) {
|
|
|
150
181
|
}
|
|
151
182
|
await handle.close();
|
|
152
183
|
try {
|
|
184
|
+
if (existingMode !== undefined) {
|
|
185
|
+
await chmod(tempPath, existingMode);
|
|
186
|
+
}
|
|
153
187
|
await rename(tempPath, path);
|
|
188
|
+
await syncParentDir(path);
|
|
154
189
|
}
|
|
155
190
|
catch (error) {
|
|
156
191
|
await rm(tempPath, { force: true });
|
|
157
192
|
throw error;
|
|
158
193
|
}
|
|
159
194
|
}
|
|
195
|
+
async function syncParentDir(path) {
|
|
196
|
+
let directoryHandle;
|
|
197
|
+
try {
|
|
198
|
+
directoryHandle = await open(dirname(path), 'r');
|
|
199
|
+
await directoryHandle.sync();
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
void error;
|
|
203
|
+
}
|
|
204
|
+
finally {
|
|
205
|
+
try {
|
|
206
|
+
await directoryHandle?.close();
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
void error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
160
213
|
/**
|
|
161
214
|
* Copies a directory recursively.
|
|
162
215
|
* @param src - Source directory path
|
|
@@ -367,7 +367,10 @@ export async function findExecutable(name) {
|
|
|
367
367
|
const result = await exec(command, [name]);
|
|
368
368
|
if (result.exitCode === 0 && result.stdout.trim()) {
|
|
369
369
|
// Return the first line (first match)
|
|
370
|
-
return result.stdout
|
|
370
|
+
return result.stdout
|
|
371
|
+
.split(/\r?\n/)
|
|
372
|
+
.map((line) => line.trim())
|
|
373
|
+
.find((line) => line.length > 0);
|
|
371
374
|
}
|
|
372
375
|
return undefined;
|
|
373
376
|
}
|