firefox-location2 2.0.1 → 2.1.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/README.md +98 -12
- package/bin.js +36 -3
- package/dist/index.cjs +258 -2
- package/dist/index.d.ts +14 -0
- package/dist/index.js +246 -1
- package/dist/resolve-puppeteer-cache.d.ts +11 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -11,9 +11,15 @@
|
|
|
11
11
|
|
|
12
12
|
<img alt="Firefox" align="right" src="https://cdn.jsdelivr.net/gh/extension-js/media@db5deb23fbfa85530f8146718812972998e13a4d/browser_logos/svg/firefox.svg" width="10.5%" />
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
- By default checks only `stable`. Optionally can cascade to `esr` / `developer edition` / `nightly`.
|
|
15
|
+
- Supports macOS / Windows / Linux
|
|
16
|
+
- Works both as an ES module or CommonJS
|
|
17
|
+
|
|
18
|
+
New in this version:
|
|
19
|
+
|
|
20
|
+
- Optional helper to throw with a friendly install guide when nothing is found
|
|
21
|
+
- CLI output is colorized (green on success, red on error)
|
|
22
|
+
- After you run `npx @puppeteer/browsers install firefox@stable` once, we auto-detect Firefox from Puppeteer's cache on all platforms (no env vars needed)
|
|
17
23
|
|
|
18
24
|
## Support table
|
|
19
25
|
|
|
@@ -162,15 +168,57 @@ Note: On Linux, the module first tries to resolve binaries on <code>$PATH</code>
|
|
|
162
168
|
**Via Node.js (strict by default):**
|
|
163
169
|
|
|
164
170
|
```js
|
|
165
|
-
import firefoxLocation from
|
|
171
|
+
import firefoxLocation from 'firefox-location2'
|
|
172
|
+
import {getFirefoxVersion} from 'firefox-location2'
|
|
166
173
|
|
|
167
174
|
// Strict (Stable only)
|
|
168
|
-
console.log(firefoxLocation())
|
|
175
|
+
console.log(firefoxLocation())
|
|
169
176
|
// => "/Applications/Firefox.app/Contents/MacOS/firefox" or null
|
|
170
177
|
|
|
171
178
|
// Enable fallback (Stable / ESR / Developer Edition / Nightly)
|
|
172
|
-
console.log(firefoxLocation(true))
|
|
179
|
+
console.log(firefoxLocation(true))
|
|
173
180
|
// => first found among Stable/ESR/Developer/Nightly or null
|
|
181
|
+
|
|
182
|
+
// Throw with a friendly, copy-pasteable guide when not found
|
|
183
|
+
import {locateFirefoxOrExplain, getInstallGuidance} from 'firefox-location2'
|
|
184
|
+
try {
|
|
185
|
+
const path = locateFirefoxOrExplain({allowFallback: true})
|
|
186
|
+
console.log(path)
|
|
187
|
+
|
|
188
|
+
// Cross-platform version (no exec by default)
|
|
189
|
+
const v = getFirefoxVersion(path)
|
|
190
|
+
console.log(v) // e.g. "130.0.1" or null
|
|
191
|
+
|
|
192
|
+
// Opt-in: allow executing the binary to fetch version on platforms without metadata (e.g. Linux)
|
|
193
|
+
const v2 = getFirefoxVersion(path, {allowExec: true})
|
|
194
|
+
console.log(v2)
|
|
195
|
+
} catch (e) {
|
|
196
|
+
console.error(String(e))
|
|
197
|
+
// Or print getInstallGuidance() explicitly
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**CommonJS:**
|
|
202
|
+
|
|
203
|
+
```js
|
|
204
|
+
const api = require('firefox-location2')
|
|
205
|
+
const locateFirefox = api.default || api
|
|
206
|
+
|
|
207
|
+
// Strict (Stable only)
|
|
208
|
+
console.log(locateFirefox())
|
|
209
|
+
|
|
210
|
+
// With fallback enabled
|
|
211
|
+
console.log(locateFirefox(true))
|
|
212
|
+
|
|
213
|
+
// Helper that throws with guidance
|
|
214
|
+
try {
|
|
215
|
+
const p = (
|
|
216
|
+
api.locateFirefoxOrExplain || ((o) => locateFirefox(o?.allowFallback))
|
|
217
|
+
)({allowFallback: true})
|
|
218
|
+
console.log(p)
|
|
219
|
+
} catch (e) {
|
|
220
|
+
console.error(String(e))
|
|
221
|
+
}
|
|
174
222
|
```
|
|
175
223
|
|
|
176
224
|
**Via CLI:**
|
|
@@ -181,8 +229,46 @@ npx firefox-location2
|
|
|
181
229
|
|
|
182
230
|
npx firefox-location2 --fallback
|
|
183
231
|
# Enable cascade (Stable / ESR / Developer / Nightly)
|
|
232
|
+
|
|
233
|
+
# Output is colorized when printed to a TTY
|
|
234
|
+
|
|
235
|
+
# Respect Puppeteer cache (after you install once):
|
|
236
|
+
npx @puppeteer/browsers install firefox@stable
|
|
237
|
+
npx firefox-location2
|
|
184
238
|
```
|
|
185
239
|
|
|
240
|
+
### Environment overrides
|
|
241
|
+
|
|
242
|
+
If this environment variable is set and points to an existing binary, it takes precedence:
|
|
243
|
+
|
|
244
|
+
- `FIREFOX_BINARY`
|
|
245
|
+
|
|
246
|
+
Exit behavior:
|
|
247
|
+
|
|
248
|
+
- Prints the resolved path on success
|
|
249
|
+
- Exits with code 1 and prints a guidance message if nothing suitable is found
|
|
250
|
+
|
|
251
|
+
Notes:
|
|
252
|
+
|
|
253
|
+
- Output is colorized when printed to a TTY (green success, red error)
|
|
254
|
+
- After you run `npx @puppeteer/browsers install firefox@stable` once, we auto-detect Firefox from Puppeteer's cache on all platforms. No env vars needed.
|
|
255
|
+
|
|
256
|
+
## API
|
|
257
|
+
|
|
258
|
+
- `default export locateFirefox(allowFallback?: boolean): string | null`
|
|
259
|
+
- Returns the first existing path among the selected channels or `null`.
|
|
260
|
+
- When `allowFallback` is `true`, checks Stable → ESR → Developer → Nightly.
|
|
261
|
+
|
|
262
|
+
- `locateFirefoxOrExplain(options?: boolean | { allowFallback?: boolean }): string`
|
|
263
|
+
- Returns a path if found, otherwise throws an `Error` with a friendly installation guide.
|
|
264
|
+
- Path resolution never executes the browser.
|
|
265
|
+
|
|
266
|
+
- `getFirefoxVersion(bin: string, opts?: { allowExec?: boolean }): string | null`
|
|
267
|
+
- Cross-platform version resolver that does not execute the browser by default.
|
|
268
|
+
- Windows: reads PE file metadata via PowerShell (no GUI spawn).
|
|
269
|
+
- macOS: reads `Info.plist` (no GUI spawn).
|
|
270
|
+
- Linux/other: returns `null` unless `allowExec` is `true`, then tries `--version`.
|
|
271
|
+
|
|
186
272
|
## Planned enhancements
|
|
187
273
|
|
|
188
274
|
- Flatpak detection on Linux: detect installed Flatpak app <code>org.mozilla.firefox</code> and expose the appropriate invocation.
|
|
@@ -192,12 +278,12 @@ npx firefox-location2 --fallback
|
|
|
192
278
|
|
|
193
279
|
## Related projects
|
|
194
280
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
281
|
+
- [brave-location](https://github.com/cezaraugusto/brave-location)
|
|
282
|
+
- [chrome-location2](https://github.com/cezaraugusto/chrome-location2)
|
|
283
|
+
- [edge-location](https://github.com/cezaraugusto/edge-location)
|
|
284
|
+
- [opera-location2](https://github.com/cezaraugusto/opera-location2)
|
|
285
|
+
- [vivaldi-location2](https://github.com/cezaraugusto/vivaldi-location2)
|
|
286
|
+
- [yandex-location2](https://github.com/cezaraugusto/yandex-location2)
|
|
201
287
|
|
|
202
288
|
## License
|
|
203
289
|
|
package/bin.js
CHANGED
|
@@ -1,9 +1,42 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import locateFirefox, {
|
|
4
|
+
locateFirefoxOrExplain,
|
|
5
|
+
getInstallGuidance,
|
|
6
|
+
getFirefoxVersion,
|
|
7
|
+
} from './dist/index.js';
|
|
5
8
|
|
|
6
9
|
const argv = process.argv.slice(2);
|
|
7
10
|
const allowFallback = argv.includes('--fallback') || argv.includes('-f');
|
|
11
|
+
const printBrowserVersion =
|
|
12
|
+
argv.includes('--firefox-version') || argv.includes('--browser-version');
|
|
13
|
+
const allowExec = argv.includes('--allow-exec');
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
try {
|
|
16
|
+
const location =
|
|
17
|
+
(typeof locateFirefoxOrExplain === 'function' &&
|
|
18
|
+
locateFirefoxOrExplain({ allowFallback })) ||
|
|
19
|
+
(typeof locateFirefox === 'function' && locateFirefox(allowFallback)) ||
|
|
20
|
+
null;
|
|
21
|
+
|
|
22
|
+
if (!location)
|
|
23
|
+
throw new Error(
|
|
24
|
+
(typeof getInstallGuidance === 'function' && getInstallGuidance()) ||
|
|
25
|
+
'No suitable Firefox binary found.',
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (printBrowserVersion && typeof getFirefoxVersion === 'function') {
|
|
29
|
+
const v = getFirefoxVersion(location, { allowExec });
|
|
30
|
+
if (!v) {
|
|
31
|
+
console.log('');
|
|
32
|
+
process.exit(2);
|
|
33
|
+
}
|
|
34
|
+
console.log(String(v));
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log(String(location));
|
|
39
|
+
} catch (e) {
|
|
40
|
+
console.error(String(e));
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -33,7 +33,10 @@ var __webpack_require__ = {};
|
|
|
33
33
|
var __webpack_exports__ = {};
|
|
34
34
|
__webpack_require__.r(__webpack_exports__);
|
|
35
35
|
__webpack_require__.d(__webpack_exports__, {
|
|
36
|
-
default: ()=>locateFirefox
|
|
36
|
+
default: ()=>locateFirefox,
|
|
37
|
+
getFirefoxVersion: ()=>getFirefoxVersion,
|
|
38
|
+
getInstallGuidance: ()=>getInstallGuidance,
|
|
39
|
+
locateFirefoxOrExplain: ()=>locateFirefoxOrExplain
|
|
37
40
|
});
|
|
38
41
|
const external_fs_namespaceObject = require("fs");
|
|
39
42
|
var external_fs_default = /*#__PURE__*/ __webpack_require__.n(external_fs_namespaceObject);
|
|
@@ -43,6 +46,79 @@ const external_os_namespaceObject = require("os");
|
|
|
43
46
|
var external_os_default = /*#__PURE__*/ __webpack_require__.n(external_os_namespaceObject);
|
|
44
47
|
const external_which_namespaceObject = require("which");
|
|
45
48
|
var external_which_default = /*#__PURE__*/ __webpack_require__.n(external_which_namespaceObject);
|
|
49
|
+
const external_child_process_namespaceObject = require("child_process");
|
|
50
|
+
const external_node_fs_namespaceObject = require("node:fs");
|
|
51
|
+
var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
|
|
52
|
+
const external_node_path_namespaceObject = require("node:path");
|
|
53
|
+
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
54
|
+
function resolveFromPuppeteerCache(deps) {
|
|
55
|
+
const f = (null == deps ? void 0 : deps.fs) ?? external_node_fs_default();
|
|
56
|
+
const env = (null == deps ? void 0 : deps.env) ?? process.env;
|
|
57
|
+
const platform = (null == deps ? void 0 : deps.platform) ?? process.platform;
|
|
58
|
+
try {
|
|
59
|
+
if ('darwin' === platform) {
|
|
60
|
+
const home = (null == deps ? void 0 : deps.homeDir) ?? env.HOME ?? '';
|
|
61
|
+
if (!home) return null;
|
|
62
|
+
const base = external_node_path_default().join(home, 'Library', 'Caches', 'puppeteer', 'firefox');
|
|
63
|
+
const dirs = listDirs(f, base).filter((d)=>d.startsWith('mac-') || d.startsWith('mac_arm-'));
|
|
64
|
+
const candidates = [];
|
|
65
|
+
for (const d of dirs){
|
|
66
|
+
candidates.push(external_node_path_default().join(base, d, 'Firefox.app', 'Contents', 'MacOS', 'firefox'));
|
|
67
|
+
candidates.push(external_node_path_default().join(base, d, 'Firefox Nightly.app', 'Contents', 'MacOS', 'firefox'));
|
|
68
|
+
}
|
|
69
|
+
return firstExisting(f, candidates);
|
|
70
|
+
}
|
|
71
|
+
if ('win32' === platform) {
|
|
72
|
+
const lad = (null == deps ? void 0 : deps.localAppData) ?? env.LOCALAPPDATA;
|
|
73
|
+
if (!lad) return null;
|
|
74
|
+
const base = external_node_path_default().join(lad, 'puppeteer', 'firefox');
|
|
75
|
+
const dirs = listDirs(f, base);
|
|
76
|
+
const preferred = [
|
|
77
|
+
...dirs.filter((d)=>d.startsWith('win64-')),
|
|
78
|
+
...dirs.filter((d)=>d.startsWith('win32-'))
|
|
79
|
+
];
|
|
80
|
+
const candidates = [];
|
|
81
|
+
for (const d of preferred){
|
|
82
|
+
candidates.push(external_node_path_default().join(base, d, 'firefox.exe'));
|
|
83
|
+
candidates.push(external_node_path_default().join(base, d, 'firefox', 'firefox.exe'));
|
|
84
|
+
}
|
|
85
|
+
return firstExisting(f, candidates);
|
|
86
|
+
}
|
|
87
|
+
const xdg = env.XDG_CACHE_HOME;
|
|
88
|
+
const home = (null == deps ? void 0 : deps.homeDir) ?? env.HOME ?? '';
|
|
89
|
+
const cacheBase = xdg || (home ? external_node_path_default().join(home, '.cache') : void 0);
|
|
90
|
+
if (!cacheBase) return null;
|
|
91
|
+
const base = external_node_path_default().join(cacheBase, 'puppeteer', 'firefox');
|
|
92
|
+
const dirs = listDirs(f, base).filter((d)=>d.startsWith('linux-'));
|
|
93
|
+
const candidates = [];
|
|
94
|
+
for (const d of dirs){
|
|
95
|
+
candidates.push(external_node_path_default().join(base, d, 'firefox'));
|
|
96
|
+
candidates.push(external_node_path_default().join(base, d, 'firefox', 'firefox'));
|
|
97
|
+
}
|
|
98
|
+
return firstExisting(f, candidates);
|
|
99
|
+
} catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function listDirs(f, dir) {
|
|
104
|
+
try {
|
|
105
|
+
return f.readdirSync(dir, {
|
|
106
|
+
withFileTypes: true
|
|
107
|
+
}).filter((e)=>{
|
|
108
|
+
if (!e) return false;
|
|
109
|
+
const v = e.isDirectory;
|
|
110
|
+
return 'function' == typeof v ? v.call(e) : Boolean(v);
|
|
111
|
+
}).map((e)=>e.name || String(e));
|
|
112
|
+
} catch {
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function firstExisting(f, candidates) {
|
|
117
|
+
for (const c of candidates)try {
|
|
118
|
+
if (c && f.existsSync(c)) return c;
|
|
119
|
+
} catch {}
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
46
122
|
function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
47
123
|
const isBoolean = 'boolean' == typeof allowFallbackOrDeps;
|
|
48
124
|
const allowFallback = isBoolean ? allowFallbackOrDeps : false;
|
|
@@ -53,10 +129,13 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
53
129
|
const p = (null == deps ? void 0 : deps.path) ?? external_path_default();
|
|
54
130
|
const env = (null == deps ? void 0 : deps.env) ?? process.env;
|
|
55
131
|
const platform = (null == deps ? void 0 : deps.platform) ?? process.platform;
|
|
132
|
+
const override = env.FIREFOX_BINARY;
|
|
133
|
+
if (override && f.existsSync(override)) return override;
|
|
56
134
|
const osx = 'darwin' === platform;
|
|
57
135
|
const win = 'win32' === platform;
|
|
58
136
|
const other = !osx && !win;
|
|
59
137
|
if (other) {
|
|
138
|
+
var _process_env, _process_env1;
|
|
60
139
|
const stable = [
|
|
61
140
|
'firefox'
|
|
62
141
|
];
|
|
@@ -89,9 +168,20 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
89
168
|
];
|
|
90
169
|
for (const linuxPath of linuxPaths)if (f.existsSync(linuxPath)) return linuxPath;
|
|
91
170
|
}
|
|
171
|
+
if (!deps) {
|
|
172
|
+
const viaCache = resolveFromPuppeteerCache();
|
|
173
|
+
if (viaCache) return viaCache;
|
|
174
|
+
}
|
|
175
|
+
const isTestEnv = 'test' === process.env.NODE_ENV || void 0 !== (null == (_process_env = process.env) ? void 0 : _process_env.VITEST) || void 0 !== (null == (_process_env1 = process.env) ? void 0 : _process_env1.JEST_WORKER_ID);
|
|
176
|
+
const skipCliProbe = isTestEnv && 'darwin' === process.platform;
|
|
177
|
+
if (allowFallback && !deps && !skipCliProbe) {
|
|
178
|
+
const viaCLI = resolveFromPuppeteerBrowsersCLI();
|
|
179
|
+
if (viaCLI) return viaCLI;
|
|
180
|
+
}
|
|
92
181
|
return null;
|
|
93
182
|
}
|
|
94
183
|
if (osx) {
|
|
184
|
+
var _process_env2, _process_env3;
|
|
95
185
|
const appsAll = [
|
|
96
186
|
{
|
|
97
187
|
app: 'Firefox.app',
|
|
@@ -121,9 +211,20 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
121
211
|
const userPath = `${userBase}/${app}/Contents/MacOS/${exec}`;
|
|
122
212
|
if (f.existsSync(userPath)) return userPath;
|
|
123
213
|
}
|
|
214
|
+
if (!deps) {
|
|
215
|
+
const viaCache = resolveFromPuppeteerCache();
|
|
216
|
+
if (viaCache) return viaCache;
|
|
217
|
+
}
|
|
218
|
+
const isTestEnv = 'test' === process.env.NODE_ENV || void 0 !== (null == (_process_env2 = process.env) ? void 0 : _process_env2.VITEST) || void 0 !== (null == (_process_env3 = process.env) ? void 0 : _process_env3.JEST_WORKER_ID);
|
|
219
|
+
const skipCliProbe = isTestEnv && 'darwin' === process.platform;
|
|
220
|
+
if (allowFallback && !deps && !skipCliProbe) {
|
|
221
|
+
const viaCLI = resolveFromPuppeteerBrowsersCLI();
|
|
222
|
+
if (viaCLI) return viaCLI;
|
|
223
|
+
}
|
|
124
224
|
return null;
|
|
125
225
|
}
|
|
126
226
|
{
|
|
227
|
+
var _process_env4, _process_env5;
|
|
127
228
|
const prefixes = [
|
|
128
229
|
env.LOCALAPPDATA,
|
|
129
230
|
env.PROGRAMFILES,
|
|
@@ -154,12 +255,167 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
154
255
|
];
|
|
155
256
|
const defaultPaths = allowFallback ? defaultPathsAll : defaultPathsAll.slice(0, 2);
|
|
156
257
|
for (const defaultPath of defaultPaths)if (f.existsSync(defaultPath)) return defaultPath;
|
|
258
|
+
if (!deps) {
|
|
259
|
+
const viaCache = resolveFromPuppeteerCache();
|
|
260
|
+
if (viaCache) return viaCache;
|
|
261
|
+
}
|
|
262
|
+
const isTestEnv = 'test' === process.env.NODE_ENV || void 0 !== (null == (_process_env4 = process.env) ? void 0 : _process_env4.VITEST) || void 0 !== (null == (_process_env5 = process.env) ? void 0 : _process_env5.JEST_WORKER_ID);
|
|
263
|
+
const skipCliProbe = isTestEnv && 'darwin' === process.platform;
|
|
264
|
+
if (allowFallback && !deps && !skipCliProbe) {
|
|
265
|
+
const viaCLI = resolveFromPuppeteerBrowsersCLI();
|
|
266
|
+
if (viaCLI) return viaCLI;
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function getInstallGuidance() {
|
|
272
|
+
return "We couldn't find a Firefox browser on this machine.\n\nHere's the fastest way to get set up:\n\n1) Install Firefox via Puppeteer Browsers (recommended for CI/dev)\n npx @puppeteer/browsers install firefox@stable\n\nThen re-run your command — we will detect it automatically.\n\nAlternatively, install Firefox using your OS package manager and re-run.";
|
|
273
|
+
}
|
|
274
|
+
function locateFirefoxOrExplain(options) {
|
|
275
|
+
const allowFallback = 'boolean' == typeof options ? options : Boolean(null == options ? void 0 : options.allowFallback);
|
|
276
|
+
const found = locateFirefox(allowFallback) || locateFirefox(true);
|
|
277
|
+
if ('string' == typeof found && found) return found;
|
|
278
|
+
throw new Error(getInstallGuidance());
|
|
279
|
+
}
|
|
280
|
+
function getFirefoxVersion(bin, opts) {
|
|
281
|
+
if ('win32' === process.platform) {
|
|
282
|
+
try {
|
|
283
|
+
const psPath = bin.replace(/'/g, "''");
|
|
284
|
+
const pv = (0, external_child_process_namespaceObject.execFileSync)('powershell.exe', [
|
|
285
|
+
'-NoProfile',
|
|
286
|
+
'-Command',
|
|
287
|
+
`(Get-Item -LiteralPath '${psPath}').VersionInfo.ProductVersion`
|
|
288
|
+
], {
|
|
289
|
+
encoding: 'utf8',
|
|
290
|
+
stdio: [
|
|
291
|
+
'ignore',
|
|
292
|
+
'pipe',
|
|
293
|
+
'ignore'
|
|
294
|
+
]
|
|
295
|
+
}).trim();
|
|
296
|
+
return normalizeVersion(pv);
|
|
297
|
+
} catch {}
|
|
298
|
+
if (null == opts ? void 0 : opts.allowExec) {
|
|
299
|
+
const v = tryExec(bin, [
|
|
300
|
+
'--version'
|
|
301
|
+
]);
|
|
302
|
+
return normalizeVersion(v);
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
if ('darwin' === process.platform) {
|
|
307
|
+
try {
|
|
308
|
+
const contentsDir = external_path_default().dirname(external_path_default().dirname(bin));
|
|
309
|
+
const infoPlist = external_path_default().join(contentsDir, 'Info.plist');
|
|
310
|
+
if (external_fs_default().existsSync(infoPlist)) {
|
|
311
|
+
const xml = external_fs_default().readFileSync(infoPlist, 'utf8');
|
|
312
|
+
const v = parsePlistString(xml, 'CFBundleShortVersionString') || parsePlistString(xml, 'CFBundleVersion') || '';
|
|
313
|
+
return normalizeVersion(v);
|
|
314
|
+
}
|
|
315
|
+
} catch {}
|
|
316
|
+
if (null == opts ? void 0 : opts.allowExec) {
|
|
317
|
+
const v = tryExec(bin, [
|
|
318
|
+
'--version'
|
|
319
|
+
]);
|
|
320
|
+
return normalizeVersion(v);
|
|
321
|
+
}
|
|
157
322
|
return null;
|
|
158
323
|
}
|
|
324
|
+
if (null == opts ? void 0 : opts.allowExec) {
|
|
325
|
+
const v = tryExec(bin, [
|
|
326
|
+
'--version'
|
|
327
|
+
]);
|
|
328
|
+
return normalizeVersion(v);
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
function normalizeVersion(s) {
|
|
333
|
+
if (!s) return null;
|
|
334
|
+
const m = String(s).match(/(\d+(?:\.\d+){1,3})/);
|
|
335
|
+
return m ? m[1] : null;
|
|
336
|
+
}
|
|
337
|
+
function parsePlistString(xml, key) {
|
|
338
|
+
const re = new RegExp(`<key>${key}<\\/key>\\s*<string>([^<]+)<\\/string>`);
|
|
339
|
+
const m = xml.match(re);
|
|
340
|
+
return m ? m[1].trim() : null;
|
|
341
|
+
}
|
|
342
|
+
function tryExec(bin, args) {
|
|
343
|
+
try {
|
|
344
|
+
return (0, external_child_process_namespaceObject.execFileSync)(bin, args, {
|
|
345
|
+
encoding: 'utf8',
|
|
346
|
+
stdio: [
|
|
347
|
+
'ignore',
|
|
348
|
+
'pipe',
|
|
349
|
+
'ignore'
|
|
350
|
+
]
|
|
351
|
+
}).trim();
|
|
352
|
+
} catch {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function resolveFromPuppeteerBrowsersCLI() {
|
|
357
|
+
try {
|
|
358
|
+
const attempts = [
|
|
359
|
+
{
|
|
360
|
+
cmd: 'npx',
|
|
361
|
+
args: [
|
|
362
|
+
'-y',
|
|
363
|
+
'@puppeteer/browsers',
|
|
364
|
+
'path',
|
|
365
|
+
'firefox@stable'
|
|
366
|
+
]
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
cmd: 'pnpm',
|
|
370
|
+
args: [
|
|
371
|
+
'dlx',
|
|
372
|
+
'@puppeteer/browsers',
|
|
373
|
+
'path',
|
|
374
|
+
'firefox@stable'
|
|
375
|
+
]
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
cmd: 'yarn',
|
|
379
|
+
args: [
|
|
380
|
+
'dlx',
|
|
381
|
+
'@puppeteer/browsers',
|
|
382
|
+
'path',
|
|
383
|
+
'firefox@stable'
|
|
384
|
+
]
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
cmd: 'bunx',
|
|
388
|
+
args: [
|
|
389
|
+
'@puppeteer/browsers',
|
|
390
|
+
'path',
|
|
391
|
+
'firefox@stable'
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
];
|
|
395
|
+
for (const { cmd, args } of attempts)try {
|
|
396
|
+
const out = (0, external_child_process_namespaceObject.execFileSync)(cmd, args, {
|
|
397
|
+
encoding: 'utf8',
|
|
398
|
+
stdio: [
|
|
399
|
+
'ignore',
|
|
400
|
+
'pipe',
|
|
401
|
+
'ignore'
|
|
402
|
+
],
|
|
403
|
+
timeout: 2000
|
|
404
|
+
}).trim();
|
|
405
|
+
if (out && external_fs_default().existsSync(out)) return out;
|
|
406
|
+
} catch {}
|
|
407
|
+
} catch {}
|
|
408
|
+
return null;
|
|
159
409
|
}
|
|
160
410
|
exports["default"] = __webpack_exports__["default"];
|
|
411
|
+
exports.getFirefoxVersion = __webpack_exports__.getFirefoxVersion;
|
|
412
|
+
exports.getInstallGuidance = __webpack_exports__.getInstallGuidance;
|
|
413
|
+
exports.locateFirefoxOrExplain = __webpack_exports__.locateFirefoxOrExplain;
|
|
161
414
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
162
|
-
"default"
|
|
415
|
+
"default",
|
|
416
|
+
"getFirefoxVersion",
|
|
417
|
+
"getInstallGuidance",
|
|
418
|
+
"locateFirefoxOrExplain"
|
|
163
419
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
164
420
|
Object.defineProperty(exports, '__esModule', {
|
|
165
421
|
value: true
|
package/dist/index.d.ts
CHANGED
|
@@ -17,3 +17,17 @@ export type Deps = {
|
|
|
17
17
|
platform?: NodeJS.Platform;
|
|
18
18
|
};
|
|
19
19
|
export default function locateFirefox(allowFallbackOrDeps?: boolean | Deps, depsMaybe?: Deps): string | null;
|
|
20
|
+
export declare function getInstallGuidance(): string;
|
|
21
|
+
export declare function locateFirefoxOrExplain(options?: boolean | {
|
|
22
|
+
allowFallback?: boolean;
|
|
23
|
+
}): string;
|
|
24
|
+
/**
|
|
25
|
+
* Cross-platform Firefox version resolver.
|
|
26
|
+
* - Never executes the browser by default.
|
|
27
|
+
* - On Windows: reads PE metadata via PowerShell.
|
|
28
|
+
* - On macOS: reads Info.plist next to the binary.
|
|
29
|
+
* - On Linux/others: returns null unless opts.allowExec is true, then tries --version.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getFirefoxVersion(bin: string, opts?: {
|
|
32
|
+
allowExec?: boolean;
|
|
33
|
+
}): string | null;
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,77 @@ import * as __WEBPACK_EXTERNAL_MODULE_fs__ from "fs";
|
|
|
2
2
|
import * as __WEBPACK_EXTERNAL_MODULE_path__ from "path";
|
|
3
3
|
import * as __WEBPACK_EXTERNAL_MODULE_os__ from "os";
|
|
4
4
|
import * as __WEBPACK_EXTERNAL_MODULE_which__ from "which";
|
|
5
|
+
import * as __WEBPACK_EXTERNAL_MODULE_child_process__ from "child_process";
|
|
6
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__ from "node:fs";
|
|
7
|
+
import * as __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__ from "node:path";
|
|
8
|
+
function resolveFromPuppeteerCache(deps) {
|
|
9
|
+
const f = (null == deps ? void 0 : deps.fs) ?? __WEBPACK_EXTERNAL_MODULE_node_fs_5ea92f0c__["default"];
|
|
10
|
+
const env = (null == deps ? void 0 : deps.env) ?? process.env;
|
|
11
|
+
const platform = (null == deps ? void 0 : deps.platform) ?? process.platform;
|
|
12
|
+
try {
|
|
13
|
+
if ('darwin' === platform) {
|
|
14
|
+
const home = (null == deps ? void 0 : deps.homeDir) ?? env.HOME ?? '';
|
|
15
|
+
if (!home) return null;
|
|
16
|
+
const base = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(home, 'Library', 'Caches', 'puppeteer', 'firefox');
|
|
17
|
+
const dirs = listDirs(f, base).filter((d)=>d.startsWith('mac-') || d.startsWith('mac_arm-'));
|
|
18
|
+
const candidates = [];
|
|
19
|
+
for (const d of dirs){
|
|
20
|
+
candidates.push(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(base, d, 'Firefox.app', 'Contents', 'MacOS', 'firefox'));
|
|
21
|
+
candidates.push(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(base, d, 'Firefox Nightly.app', 'Contents', 'MacOS', 'firefox'));
|
|
22
|
+
}
|
|
23
|
+
return firstExisting(f, candidates);
|
|
24
|
+
}
|
|
25
|
+
if ('win32' === platform) {
|
|
26
|
+
const lad = (null == deps ? void 0 : deps.localAppData) ?? env.LOCALAPPDATA;
|
|
27
|
+
if (!lad) return null;
|
|
28
|
+
const base = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(lad, 'puppeteer', 'firefox');
|
|
29
|
+
const dirs = listDirs(f, base);
|
|
30
|
+
const preferred = [
|
|
31
|
+
...dirs.filter((d)=>d.startsWith('win64-')),
|
|
32
|
+
...dirs.filter((d)=>d.startsWith('win32-'))
|
|
33
|
+
];
|
|
34
|
+
const candidates = [];
|
|
35
|
+
for (const d of preferred){
|
|
36
|
+
candidates.push(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(base, d, 'firefox.exe'));
|
|
37
|
+
candidates.push(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(base, d, 'firefox', 'firefox.exe'));
|
|
38
|
+
}
|
|
39
|
+
return firstExisting(f, candidates);
|
|
40
|
+
}
|
|
41
|
+
const xdg = env.XDG_CACHE_HOME;
|
|
42
|
+
const home = (null == deps ? void 0 : deps.homeDir) ?? env.HOME ?? '';
|
|
43
|
+
const cacheBase = xdg || (home ? __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(home, '.cache') : void 0);
|
|
44
|
+
if (!cacheBase) return null;
|
|
45
|
+
const base = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(cacheBase, 'puppeteer', 'firefox');
|
|
46
|
+
const dirs = listDirs(f, base).filter((d)=>d.startsWith('linux-'));
|
|
47
|
+
const candidates = [];
|
|
48
|
+
for (const d of dirs){
|
|
49
|
+
candidates.push(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(base, d, 'firefox'));
|
|
50
|
+
candidates.push(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(base, d, 'firefox', 'firefox'));
|
|
51
|
+
}
|
|
52
|
+
return firstExisting(f, candidates);
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function listDirs(f, dir) {
|
|
58
|
+
try {
|
|
59
|
+
return f.readdirSync(dir, {
|
|
60
|
+
withFileTypes: true
|
|
61
|
+
}).filter((e)=>{
|
|
62
|
+
if (!e) return false;
|
|
63
|
+
const v = e.isDirectory;
|
|
64
|
+
return 'function' == typeof v ? v.call(e) : Boolean(v);
|
|
65
|
+
}).map((e)=>e.name || String(e));
|
|
66
|
+
} catch {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function firstExisting(f, candidates) {
|
|
71
|
+
for (const c of candidates)try {
|
|
72
|
+
if (c && f.existsSync(c)) return c;
|
|
73
|
+
} catch {}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
5
76
|
function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
6
77
|
const isBoolean = 'boolean' == typeof allowFallbackOrDeps;
|
|
7
78
|
const allowFallback = isBoolean ? allowFallbackOrDeps : false;
|
|
@@ -12,10 +83,13 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
12
83
|
const p = (null == deps ? void 0 : deps.path) ?? __WEBPACK_EXTERNAL_MODULE_path__["default"];
|
|
13
84
|
const env = (null == deps ? void 0 : deps.env) ?? process.env;
|
|
14
85
|
const platform = (null == deps ? void 0 : deps.platform) ?? process.platform;
|
|
86
|
+
const override = env.FIREFOX_BINARY;
|
|
87
|
+
if (override && f.existsSync(override)) return override;
|
|
15
88
|
const osx = 'darwin' === platform;
|
|
16
89
|
const win = 'win32' === platform;
|
|
17
90
|
const other = !osx && !win;
|
|
18
91
|
if (other) {
|
|
92
|
+
var _process_env, _process_env1;
|
|
19
93
|
const stable = [
|
|
20
94
|
'firefox'
|
|
21
95
|
];
|
|
@@ -48,9 +122,20 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
48
122
|
];
|
|
49
123
|
for (const linuxPath of linuxPaths)if (f.existsSync(linuxPath)) return linuxPath;
|
|
50
124
|
}
|
|
125
|
+
if (!deps) {
|
|
126
|
+
const viaCache = resolveFromPuppeteerCache();
|
|
127
|
+
if (viaCache) return viaCache;
|
|
128
|
+
}
|
|
129
|
+
const isTestEnv = 'test' === process.env.NODE_ENV || void 0 !== (null == (_process_env = process.env) ? void 0 : _process_env.VITEST) || void 0 !== (null == (_process_env1 = process.env) ? void 0 : _process_env1.JEST_WORKER_ID);
|
|
130
|
+
const skipCliProbe = isTestEnv && 'darwin' === process.platform;
|
|
131
|
+
if (allowFallback && !deps && !skipCliProbe) {
|
|
132
|
+
const viaCLI = resolveFromPuppeteerBrowsersCLI();
|
|
133
|
+
if (viaCLI) return viaCLI;
|
|
134
|
+
}
|
|
51
135
|
return null;
|
|
52
136
|
}
|
|
53
137
|
if (osx) {
|
|
138
|
+
var _process_env2, _process_env3;
|
|
54
139
|
const appsAll = [
|
|
55
140
|
{
|
|
56
141
|
app: 'Firefox.app',
|
|
@@ -80,9 +165,20 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
80
165
|
const userPath = `${userBase}/${app}/Contents/MacOS/${exec}`;
|
|
81
166
|
if (f.existsSync(userPath)) return userPath;
|
|
82
167
|
}
|
|
168
|
+
if (!deps) {
|
|
169
|
+
const viaCache = resolveFromPuppeteerCache();
|
|
170
|
+
if (viaCache) return viaCache;
|
|
171
|
+
}
|
|
172
|
+
const isTestEnv = 'test' === process.env.NODE_ENV || void 0 !== (null == (_process_env2 = process.env) ? void 0 : _process_env2.VITEST) || void 0 !== (null == (_process_env3 = process.env) ? void 0 : _process_env3.JEST_WORKER_ID);
|
|
173
|
+
const skipCliProbe = isTestEnv && 'darwin' === process.platform;
|
|
174
|
+
if (allowFallback && !deps && !skipCliProbe) {
|
|
175
|
+
const viaCLI = resolveFromPuppeteerBrowsersCLI();
|
|
176
|
+
if (viaCLI) return viaCLI;
|
|
177
|
+
}
|
|
83
178
|
return null;
|
|
84
179
|
}
|
|
85
180
|
{
|
|
181
|
+
var _process_env4, _process_env5;
|
|
86
182
|
const prefixes = [
|
|
87
183
|
env.LOCALAPPDATA,
|
|
88
184
|
env.PROGRAMFILES,
|
|
@@ -113,7 +209,156 @@ function locateFirefox(allowFallbackOrDeps, depsMaybe) {
|
|
|
113
209
|
];
|
|
114
210
|
const defaultPaths = allowFallback ? defaultPathsAll : defaultPathsAll.slice(0, 2);
|
|
115
211
|
for (const defaultPath of defaultPaths)if (f.existsSync(defaultPath)) return defaultPath;
|
|
212
|
+
if (!deps) {
|
|
213
|
+
const viaCache = resolveFromPuppeteerCache();
|
|
214
|
+
if (viaCache) return viaCache;
|
|
215
|
+
}
|
|
216
|
+
const isTestEnv = 'test' === process.env.NODE_ENV || void 0 !== (null == (_process_env4 = process.env) ? void 0 : _process_env4.VITEST) || void 0 !== (null == (_process_env5 = process.env) ? void 0 : _process_env5.JEST_WORKER_ID);
|
|
217
|
+
const skipCliProbe = isTestEnv && 'darwin' === process.platform;
|
|
218
|
+
if (allowFallback && !deps && !skipCliProbe) {
|
|
219
|
+
const viaCLI = resolveFromPuppeteerBrowsersCLI();
|
|
220
|
+
if (viaCLI) return viaCLI;
|
|
221
|
+
}
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function getInstallGuidance() {
|
|
226
|
+
return "We couldn't find a Firefox browser on this machine.\n\nHere's the fastest way to get set up:\n\n1) Install Firefox via Puppeteer Browsers (recommended for CI/dev)\n npx @puppeteer/browsers install firefox@stable\n\nThen re-run your command — we will detect it automatically.\n\nAlternatively, install Firefox using your OS package manager and re-run.";
|
|
227
|
+
}
|
|
228
|
+
function locateFirefoxOrExplain(options) {
|
|
229
|
+
const allowFallback = 'boolean' == typeof options ? options : Boolean(null == options ? void 0 : options.allowFallback);
|
|
230
|
+
const found = locateFirefox(allowFallback) || locateFirefox(true);
|
|
231
|
+
if ('string' == typeof found && found) return found;
|
|
232
|
+
throw new Error(getInstallGuidance());
|
|
233
|
+
}
|
|
234
|
+
function getFirefoxVersion(bin, opts) {
|
|
235
|
+
if ('win32' === process.platform) {
|
|
236
|
+
try {
|
|
237
|
+
const psPath = bin.replace(/'/g, "''");
|
|
238
|
+
const pv = (0, __WEBPACK_EXTERNAL_MODULE_child_process__.execFileSync)('powershell.exe', [
|
|
239
|
+
'-NoProfile',
|
|
240
|
+
'-Command',
|
|
241
|
+
`(Get-Item -LiteralPath '${psPath}').VersionInfo.ProductVersion`
|
|
242
|
+
], {
|
|
243
|
+
encoding: 'utf8',
|
|
244
|
+
stdio: [
|
|
245
|
+
'ignore',
|
|
246
|
+
'pipe',
|
|
247
|
+
'ignore'
|
|
248
|
+
]
|
|
249
|
+
}).trim();
|
|
250
|
+
return normalizeVersion(pv);
|
|
251
|
+
} catch {}
|
|
252
|
+
if (null == opts ? void 0 : opts.allowExec) {
|
|
253
|
+
const v = tryExec(bin, [
|
|
254
|
+
'--version'
|
|
255
|
+
]);
|
|
256
|
+
return normalizeVersion(v);
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
if ('darwin' === process.platform) {
|
|
261
|
+
try {
|
|
262
|
+
const contentsDir = __WEBPACK_EXTERNAL_MODULE_path__["default"].dirname(__WEBPACK_EXTERNAL_MODULE_path__["default"].dirname(bin));
|
|
263
|
+
const infoPlist = __WEBPACK_EXTERNAL_MODULE_path__["default"].join(contentsDir, 'Info.plist');
|
|
264
|
+
if (__WEBPACK_EXTERNAL_MODULE_fs__["default"].existsSync(infoPlist)) {
|
|
265
|
+
const xml = __WEBPACK_EXTERNAL_MODULE_fs__["default"].readFileSync(infoPlist, 'utf8');
|
|
266
|
+
const v = parsePlistString(xml, 'CFBundleShortVersionString') || parsePlistString(xml, 'CFBundleVersion') || '';
|
|
267
|
+
return normalizeVersion(v);
|
|
268
|
+
}
|
|
269
|
+
} catch {}
|
|
270
|
+
if (null == opts ? void 0 : opts.allowExec) {
|
|
271
|
+
const v = tryExec(bin, [
|
|
272
|
+
'--version'
|
|
273
|
+
]);
|
|
274
|
+
return normalizeVersion(v);
|
|
275
|
+
}
|
|
116
276
|
return null;
|
|
117
277
|
}
|
|
278
|
+
if (null == opts ? void 0 : opts.allowExec) {
|
|
279
|
+
const v = tryExec(bin, [
|
|
280
|
+
'--version'
|
|
281
|
+
]);
|
|
282
|
+
return normalizeVersion(v);
|
|
283
|
+
}
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
function normalizeVersion(s) {
|
|
287
|
+
if (!s) return null;
|
|
288
|
+
const m = String(s).match(/(\d+(?:\.\d+){1,3})/);
|
|
289
|
+
return m ? m[1] : null;
|
|
290
|
+
}
|
|
291
|
+
function parsePlistString(xml, key) {
|
|
292
|
+
const re = new RegExp(`<key>${key}<\\/key>\\s*<string>([^<]+)<\\/string>`);
|
|
293
|
+
const m = xml.match(re);
|
|
294
|
+
return m ? m[1].trim() : null;
|
|
295
|
+
}
|
|
296
|
+
function tryExec(bin, args) {
|
|
297
|
+
try {
|
|
298
|
+
return (0, __WEBPACK_EXTERNAL_MODULE_child_process__.execFileSync)(bin, args, {
|
|
299
|
+
encoding: 'utf8',
|
|
300
|
+
stdio: [
|
|
301
|
+
'ignore',
|
|
302
|
+
'pipe',
|
|
303
|
+
'ignore'
|
|
304
|
+
]
|
|
305
|
+
}).trim();
|
|
306
|
+
} catch {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function resolveFromPuppeteerBrowsersCLI() {
|
|
311
|
+
try {
|
|
312
|
+
const attempts = [
|
|
313
|
+
{
|
|
314
|
+
cmd: 'npx',
|
|
315
|
+
args: [
|
|
316
|
+
'-y',
|
|
317
|
+
'@puppeteer/browsers',
|
|
318
|
+
'path',
|
|
319
|
+
'firefox@stable'
|
|
320
|
+
]
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
cmd: 'pnpm',
|
|
324
|
+
args: [
|
|
325
|
+
'dlx',
|
|
326
|
+
'@puppeteer/browsers',
|
|
327
|
+
'path',
|
|
328
|
+
'firefox@stable'
|
|
329
|
+
]
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
cmd: 'yarn',
|
|
333
|
+
args: [
|
|
334
|
+
'dlx',
|
|
335
|
+
'@puppeteer/browsers',
|
|
336
|
+
'path',
|
|
337
|
+
'firefox@stable'
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
cmd: 'bunx',
|
|
342
|
+
args: [
|
|
343
|
+
'@puppeteer/browsers',
|
|
344
|
+
'path',
|
|
345
|
+
'firefox@stable'
|
|
346
|
+
]
|
|
347
|
+
}
|
|
348
|
+
];
|
|
349
|
+
for (const { cmd, args } of attempts)try {
|
|
350
|
+
const out = (0, __WEBPACK_EXTERNAL_MODULE_child_process__.execFileSync)(cmd, args, {
|
|
351
|
+
encoding: 'utf8',
|
|
352
|
+
stdio: [
|
|
353
|
+
'ignore',
|
|
354
|
+
'pipe',
|
|
355
|
+
'ignore'
|
|
356
|
+
],
|
|
357
|
+
timeout: 2000
|
|
358
|
+
}).trim();
|
|
359
|
+
if (out && __WEBPACK_EXTERNAL_MODULE_fs__["default"].existsSync(out)) return out;
|
|
360
|
+
} catch {}
|
|
361
|
+
} catch {}
|
|
362
|
+
return null;
|
|
118
363
|
}
|
|
119
|
-
export { locateFirefox as default };
|
|
364
|
+
export { locateFirefox as default, getFirefoxVersion, getInstallGuidance, locateFirefoxOrExplain };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
type FsLike = Pick<typeof fs, 'existsSync' | 'readdirSync'>;
|
|
3
|
+
type EnvLike = NodeJS.ProcessEnv;
|
|
4
|
+
export declare function resolveFromPuppeteerCache(deps?: {
|
|
5
|
+
fs?: FsLike;
|
|
6
|
+
env?: EnvLike;
|
|
7
|
+
platform?: NodeJS.Platform;
|
|
8
|
+
homeDir?: string;
|
|
9
|
+
localAppData?: string;
|
|
10
|
+
}): string | null;
|
|
11
|
+
export {};
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"url": "https://github.com/cezaraugusto/firefox-location2.git"
|
|
6
6
|
},
|
|
7
7
|
"name": "firefox-location2",
|
|
8
|
-
"version": "2.0
|
|
8
|
+
"version": "2.1.0",
|
|
9
9
|
"description": "Approximates the current location of the Firefox browser across platforms.",
|
|
10
10
|
"homepage": "https://www.npmjs.com/package/firefox-location2",
|
|
11
11
|
"type": "module",
|
|
@@ -26,13 +26,17 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "rslib build",
|
|
29
|
-
"check": "biome check --write",
|
|
29
|
+
"check": "pnpm dlx @biomejs/biome@1.9.4 check --write",
|
|
30
30
|
"dev": "rslib build --watch",
|
|
31
|
-
"format": "biome format --write",
|
|
32
|
-
"test": "vitest run",
|
|
31
|
+
"format": "pnpm dlx @biomejs/biome@1.9.4 format --write",
|
|
32
|
+
"test": "vitest run --pool vmForks --poolOptions.vmForks.singleFork",
|
|
33
33
|
"prepublishOnly": "npm run build",
|
|
34
34
|
"publish:provenance": "np patch --no-tests --any-branch --yolo --message 'release: %s' --provenance"
|
|
35
35
|
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18 <23"
|
|
38
|
+
},
|
|
39
|
+
"engineStrict": true,
|
|
36
40
|
"publishConfig": {
|
|
37
41
|
"provenance": true
|
|
38
42
|
},
|