extension 4.1.19 → 4.1.20
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 +16 -15
- package/bin/extension.cjs +2 -0
- package/dist/browsers.cjs +66 -26
- package/dist/cli.cjs +194 -127
- package/dist/extension/browsers/browsers-lib/constants.d.ts +0 -2
- package/dist/extension/browsers/browsers-lib/messages.d.ts +1 -1
- package/dist/extension/browsers/browsers-lib/resolve-profile.d.ts +0 -35
- package/dist/extension/browsers/browsers-types.d.ts +0 -89
- package/dist/extension/browsers/index.d.ts +0 -28
- package/dist/extension/browsers/run-chromium/chromium-launch/extension-output-path.d.ts +0 -6
- package/dist/extension/browsers/run-chromium/chromium-launch/index.d.ts +0 -9
- package/dist/extension/browsers/run-chromium/chromium-types.d.ts +0 -11
- package/dist/extension/browsers/run-safari/safari-launch/index.d.ts +1 -6
- package/dist/extension/browsers/run-safari/safari-packager.d.ts +0 -15
- package/dist/extension/browsers/run-safari/safari-types.d.ts +0 -1
- package/dist/extension/commands/act.d.ts +0 -6
- package/dist/extension/commands/doctor.d.ts +0 -7
- package/dist/extension/commands/publish.d.ts +0 -6
- package/dist/extension/helpers/cli-explicit.d.ts +0 -15
- package/dist/extension/helpers/node-version-guard.d.ts +4 -1
- package/dist/extension/helpers/template-catalog.d.ts +1 -1
- package/dist/extension/helpers/template-corpus.generated.d.ts +1 -1
- package/dist/extension/helpers/vendors.d.ts +1 -0
- package/package.json +4 -4
package/dist/cli.cjs
CHANGED
|
@@ -741,16 +741,19 @@ var __webpack_modules__ = {
|
|
|
741
741
|
const tail = outputTail.trim().length ? `\n${pintor__rspack_import_8_default().gray('── last output ──')}\n${outputTail}` : `\n${pintor__rspack_import_8_default().gray('(no output captured)')}`;
|
|
742
742
|
return `${getLoggingPrefix('error')} Safari packaging tool ${pintor__rspack_import_8_default().underline(tool)} failed (${pintor__rspack_import_8_default().red(code)}).${tail}`;
|
|
743
743
|
}
|
|
744
|
+
const SAFARI_KEPT_ON_PURPOSE = {
|
|
745
|
+
world: 'Safari has honored the MAIN world since Safari 18, so the key stays'
|
|
746
|
+
};
|
|
744
747
|
function safariConverterWarnings(warnings) {
|
|
745
|
-
|
|
748
|
+
const kept = warnings.map((line)=>line.trim()).filter((line)=>line in SAFARI_KEPT_ON_PURPOSE);
|
|
749
|
+
const keptLines = kept.map((line)=>` ${pintor__rspack_import_8_default().yellow(line)} ${pintor__rspack_import_8_default().gray(SAFARI_KEPT_ON_PURPOSE[line])}`).join('\n');
|
|
750
|
+
return `${getLoggingPrefix('warn')} safari-web-extension-converter reported ${pintor__rspack_import_8_default().yellow(String(warnings.length))} ${1 === warnings.length ? 'warning' : 'warnings'}, some manifest keys/APIs may not be supported by Safari:\n` + warnings.map((line)=>` ${pintor__rspack_import_8_default().gray('•')} ${line}`).join('\n') + (kept.length ? `\nExtension.js kept ${1 === kept.length ? 'one of these keys' : 'some of these keys'} on purpose:\n${keptLines}` : '');
|
|
746
751
|
}
|
|
747
752
|
function safariDefaultBundleIdNote(bundleId) {
|
|
748
753
|
return `${getLoggingPrefix('warn')} The bundle id ${pintor__rspack_import_8_default().gray(bundleId)} is generated from the app name.\nEvery project built from the same source shares this id, and the first team to register it takes it.\nSet your own with ${pintor__rspack_import_8_default().blue('--bundle-id')} before your first submission.\nAfter a submission, a new id is a new extension with none of your users.`;
|
|
749
754
|
}
|
|
750
|
-
function safariOpenHint(appPath, appName
|
|
751
|
-
|
|
752
|
-
if (signed) return launch + `Then turn on ${pintor__rspack_import_8_default().yellow(appName)} in Safari ▸ Settings ▸ Extensions.`;
|
|
753
|
-
return launch + `Then enable ${pintor__rspack_import_8_default().yellow(appName)} via Safari ▸ Develop ▸ ` + `${pintor__rspack_import_8_default().yellow('Allow Unsigned Extensions')} and Safari ▸ Settings ▸ Extensions.`;
|
|
755
|
+
function safariOpenHint(appPath, appName) {
|
|
756
|
+
return `${getLoggingPrefix('info')} Launch it once to register with Safari: ${pintor__rspack_import_8_default().blue('open')} ${pintor__rspack_import_8_default().underline(`"${appPath}"`)}\nThen turn on ${pintor__rspack_import_8_default().yellow(appName)} in Safari ▸ Settings ▸ Extensions.`;
|
|
754
757
|
}
|
|
755
758
|
function safariDryRunNotBuilding() {
|
|
756
759
|
return `${getLoggingPrefix('info')} Dry run: skip the Safari app build.`;
|
|
@@ -762,8 +765,9 @@ var __webpack_modules__ = {
|
|
|
762
765
|
return `${getLoggingPrefix('info')} xcodebuild: ${pintor__rspack_import_8_default().gray(cmd)}.`;
|
|
763
766
|
}
|
|
764
767
|
function safariNextSteps(appName, signed) {
|
|
765
|
-
|
|
766
|
-
|
|
768
|
+
const steps = `${getLoggingPrefix('info')} One-time setup to load ${pintor__rspack_import_8_default().yellow(appName)} in Safari:\n ${pintor__rspack_import_8_default().gray('1.')} Safari ▸ Settings ▸ Extensions ▸ turn on ${pintor__rspack_import_8_default().yellow(appName)}\n`;
|
|
769
|
+
if (signed) return steps + ` ${pintor__rspack_import_8_default().gray('→')} Signed with your team id, so the identity is stable for distribution.`;
|
|
770
|
+
return steps + ` ${pintor__rspack_import_8_default().gray('→')} Ad-hoc signed, so it stays enabled across restarts.`;
|
|
767
771
|
}
|
|
768
772
|
function safariRegistered(appName) {
|
|
769
773
|
return `${getLoggingPrefix('success')} Safari recognizes ${pintor__rspack_import_8_default().yellow(appName)}, finish enabling it with the steps above.`;
|
|
@@ -772,7 +776,7 @@ var __webpack_modules__ = {
|
|
|
772
776
|
return `${getLoggingPrefix('info')} Safari hasn't picked up ${pintor__rspack_import_8_default().yellow(appName)} yet.\nOpen the app once, then check Safari ▸ Settings ▸ Extensions.`;
|
|
773
777
|
}
|
|
774
778
|
function safariRebuilt(appName) {
|
|
775
|
-
return `${getLoggingPrefix('success')} Rebuilt ${pintor__rspack_import_8_default().yellow(appName)}
|
|
779
|
+
return `${getLoggingPrefix('success')} Rebuilt ${pintor__rspack_import_8_default().yellow(appName)}.`;
|
|
776
780
|
}
|
|
777
781
|
function safariProjectStale() {
|
|
778
782
|
return `${getLoggingPrefix('info')} Regenerating the Xcode project, manifest.json or identity options changed since it was generated.`;
|
|
@@ -5927,7 +5931,24 @@ var __webpack_modules__ = {
|
|
|
5927
5931
|
});
|
|
5928
5932
|
}
|
|
5929
5933
|
function converterWarnings(output) {
|
|
5930
|
-
|
|
5934
|
+
const lines = output.split(/\r?\n/);
|
|
5935
|
+
const collected = [];
|
|
5936
|
+
let inWarning = false;
|
|
5937
|
+
for (const line of lines){
|
|
5938
|
+
const trimmed = line.trim();
|
|
5939
|
+
if (/warning/i.test(line)) {
|
|
5940
|
+
inWarning = true;
|
|
5941
|
+
if (trimmed.length > 0) collected.push(trimmed);
|
|
5942
|
+
continue;
|
|
5943
|
+
}
|
|
5944
|
+
const isContinuation = inWarning && /^\s/.test(line) && trimmed.length > 0;
|
|
5945
|
+
if (isContinuation) {
|
|
5946
|
+
collected.push(trimmed);
|
|
5947
|
+
continue;
|
|
5948
|
+
}
|
|
5949
|
+
inWarning = false;
|
|
5950
|
+
}
|
|
5951
|
+
return collected;
|
|
5931
5952
|
}
|
|
5932
5953
|
async function confirmRegisteredWithSafari(bundleIdentifier) {
|
|
5933
5954
|
const needle = `${bundleIdentifier}.Extension`;
|
|
@@ -6058,7 +6079,7 @@ var __webpack_modules__ = {
|
|
|
6058
6079
|
if (preservedKeys.length > 0) logger.info?.(messages.oB(preservedKeys));
|
|
6059
6080
|
(0, safari_config.x7)(config);
|
|
6060
6081
|
logger.info?.(messages.l_(config.projectLocation));
|
|
6061
|
-
} else logger.info?.(messages.oM());
|
|
6082
|
+
} else if ('full' === mode) logger.info?.(messages.oM());
|
|
6062
6083
|
if ('full' === mode) logger.info?.(messages.jR((0, safari_config.aD)(config)));
|
|
6063
6084
|
const built = await runTool('xcodebuild', xcodebuildArgs);
|
|
6064
6085
|
if (!built.ok) {
|
|
@@ -6073,7 +6094,7 @@ var __webpack_modules__ = {
|
|
|
6073
6094
|
}
|
|
6074
6095
|
logger.info?.(messages.Rl(appPath));
|
|
6075
6096
|
if (!config.open) {
|
|
6076
|
-
logger.info?.(messages.aO(appPath, config.appName
|
|
6097
|
+
logger.info?.(messages.aO(appPath, config.appName));
|
|
6077
6098
|
if (host.announceDevReady) await announceSafariDevSession(host, config, appPath);
|
|
6078
6099
|
return describePackage(config);
|
|
6079
6100
|
}
|
|
@@ -6218,36 +6239,55 @@ var __webpack_modules__ = {
|
|
|
6218
6239
|
function manifestFingerprintPath(config) {
|
|
6219
6240
|
return node_path__rspack_import_1.join(config.projectLocation, '.manifest-fingerprint');
|
|
6220
6241
|
}
|
|
6221
|
-
function
|
|
6222
|
-
if (null == obj) return JSON.stringify(obj);
|
|
6223
|
-
if ('object' != typeof obj) return JSON.stringify(obj);
|
|
6224
|
-
if (Array.isArray(obj)) return `[${obj.map(stableStringify).join(',')}]`;
|
|
6225
|
-
const keys = Object.keys(obj).sort();
|
|
6226
|
-
return `{${keys.map((k)=>`${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(',')}}`;
|
|
6227
|
-
}
|
|
6228
|
-
function readManifestRaw(extensionDir) {
|
|
6242
|
+
function topLevelEntries(extensionDir) {
|
|
6229
6243
|
try {
|
|
6230
|
-
return node_fs__rspack_import_0.
|
|
6244
|
+
return node_fs__rspack_import_0.readdirSync(extensionDir).sort();
|
|
6231
6245
|
} catch {
|
|
6232
|
-
return
|
|
6246
|
+
return [];
|
|
6233
6247
|
}
|
|
6234
6248
|
}
|
|
6235
|
-
function
|
|
6249
|
+
function iconsFingerprint(extensionDir) {
|
|
6236
6250
|
try {
|
|
6237
|
-
|
|
6251
|
+
const raw = node_fs__rspack_import_0.readFileSync(node_path__rspack_import_1.join(extensionDir, 'manifest.json'), 'utf8');
|
|
6252
|
+
const icons = JSON.parse(raw).icons;
|
|
6253
|
+
if (!icons || 'object' != typeof icons) return '';
|
|
6254
|
+
return Object.keys(icons).sort().map((size)=>`${size}:${String(icons[size])}`).join(',');
|
|
6238
6255
|
} catch {
|
|
6239
|
-
return
|
|
6256
|
+
return '';
|
|
6257
|
+
}
|
|
6258
|
+
}
|
|
6259
|
+
function asRecord(value) {
|
|
6260
|
+
return value && 'object' == typeof value && !Array.isArray(value) ? value : {};
|
|
6261
|
+
}
|
|
6262
|
+
function judgedManifestSurface(extensionDir) {
|
|
6263
|
+
const manifest = readManifest(extensionDir);
|
|
6264
|
+
const parts = [
|
|
6265
|
+
Object.keys(manifest).sort().join(',')
|
|
6266
|
+
];
|
|
6267
|
+
for (const listName of [
|
|
6268
|
+
'permissions',
|
|
6269
|
+
'optional_permissions'
|
|
6270
|
+
]){
|
|
6271
|
+
const list = manifest[listName];
|
|
6272
|
+
const names = Array.isArray(list) ? list.filter((entry)=>'string' == typeof entry).sort() : [];
|
|
6273
|
+
parts.push(`${listName}:${names.join(',')}`);
|
|
6240
6274
|
}
|
|
6275
|
+
const contentScripts = manifest.content_scripts;
|
|
6276
|
+
if (Array.isArray(contentScripts)) parts.push(contentScripts.map((entry)=>Object.keys(asRecord(entry)).sort().join('+')).join(';'));
|
|
6277
|
+
parts.push(Object.keys(asRecord(manifest.options_ui)).sort().join(','));
|
|
6278
|
+
return parts.join('|');
|
|
6241
6279
|
}
|
|
6242
6280
|
function composeProjectFingerprint(config) {
|
|
6243
6281
|
return JSON.stringify({
|
|
6244
|
-
v:
|
|
6282
|
+
v: 4,
|
|
6245
6283
|
identity: {
|
|
6246
6284
|
appName: config.appName,
|
|
6247
6285
|
bundleId: config.bundleIdentifier,
|
|
6248
6286
|
macOsOnly: config.macOsOnly
|
|
6249
6287
|
},
|
|
6250
|
-
|
|
6288
|
+
entries: topLevelEntries(config.extensionDir),
|
|
6289
|
+
icons: iconsFingerprint(config.extensionDir),
|
|
6290
|
+
judged: judgedManifestSurface(config.extensionDir)
|
|
6251
6291
|
});
|
|
6252
6292
|
}
|
|
6253
6293
|
function saveManifestFingerprint(config) {
|
|
@@ -6663,21 +6703,47 @@ var __webpack_modules__ = {
|
|
|
6663
6703
|
"./index.ts" (__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
|
|
6664
6704
|
const MIN_NODE_MAJOR = 22;
|
|
6665
6705
|
const MIN_NODE_MINOR = 12;
|
|
6706
|
+
const MIN_DENO_MAJOR = 2;
|
|
6707
|
+
const MIN_DENO_MINOR = 5;
|
|
6708
|
+
const BLOCKED_DENO_VERSIONS = [
|
|
6709
|
+
'2.8.0'
|
|
6710
|
+
];
|
|
6711
|
+
function meetsFloor(version, major, minor) {
|
|
6712
|
+
const [actualMajor, actualMinor] = version.split('.').map((part)=>parseInt(part, 10));
|
|
6713
|
+
if (!Number.isFinite(actualMajor)) return true;
|
|
6714
|
+
if (actualMajor !== major) return actualMajor > major;
|
|
6715
|
+
return (Number.isFinite(actualMinor) ? actualMinor : 0) >= minor;
|
|
6716
|
+
}
|
|
6666
6717
|
function isSupportedNodeVersion(version) {
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6718
|
+
return meetsFloor(version, MIN_NODE_MAJOR, MIN_NODE_MINOR);
|
|
6719
|
+
}
|
|
6720
|
+
function isSupportedDenoVersion(version) {
|
|
6721
|
+
if (BLOCKED_DENO_VERSIONS.includes(version)) return false;
|
|
6722
|
+
return meetsFloor(version, MIN_DENO_MAJOR, MIN_DENO_MINOR);
|
|
6671
6723
|
}
|
|
6672
6724
|
function detectBunVersion(versions = process.versions) {
|
|
6673
6725
|
const bunVersion = versions.bun;
|
|
6674
6726
|
return 'string' == typeof bunVersion && bunVersion.length > 0 ? bunVersion : void 0;
|
|
6675
6727
|
}
|
|
6728
|
+
function detectDenoVersion(versions = process.versions) {
|
|
6729
|
+
const denoVersion = versions.deno;
|
|
6730
|
+
return 'string' == typeof denoVersion && denoVersion.length > 0 ? denoVersion : void 0;
|
|
6731
|
+
}
|
|
6732
|
+
function unsupportedDenoVersionMessage(version) {
|
|
6733
|
+
if (BLOCKED_DENO_VERSIONS.includes(version)) return `[Extension.js] Deno ${version} cannot load node:querystring inside the bundler, so every build fails on it. Deno fixed that in 2.8.1. Run deno upgrade to build the extension on Deno.`;
|
|
6734
|
+
return `[Extension.js] Requires Deno >= ${MIN_DENO_MAJOR}.${MIN_DENO_MINOR} (you are on ${version}). Run deno upgrade, or run the extension CLI on Node.js >= ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR} instead.`;
|
|
6735
|
+
}
|
|
6676
6736
|
function unsupportedNodeVersionMessage(version, bunVersion) {
|
|
6677
6737
|
if (bunVersion) return `[Extension.js] The extension CLI runs on Node.js, not on the Bun runtime (Bun ${bunVersion}, reporting Node.js ${version}), so the Node.js you have installed is not the problem. Run it on Node.js instead: drop --bun from bunx or bun run, or unset run.bun in bunfig.toml, plain bunx runs the extension CLI on Node.js.`;
|
|
6678
6738
|
return `[Extension.js] Requires Node.js >= ${MIN_NODE_MAJOR}.${MIN_NODE_MINOR} (you are on ${version}). Upgrade Node.js to run the extension CLI.`;
|
|
6679
6739
|
}
|
|
6680
|
-
function enforceSupportedNodeVersion(version = process.versions.node, bunVersion = detectBunVersion()) {
|
|
6740
|
+
function enforceSupportedNodeVersion(version = process.versions.node, bunVersion = detectBunVersion(), denoVersion = detectDenoVersion()) {
|
|
6741
|
+
if (denoVersion) {
|
|
6742
|
+
if (isSupportedDenoVersion(denoVersion)) return;
|
|
6743
|
+
console.error(unsupportedDenoVersionMessage(denoVersion));
|
|
6744
|
+
process.exit(1);
|
|
6745
|
+
return;
|
|
6746
|
+
}
|
|
6681
6747
|
if (!bunVersion && isSupportedNodeVersion(version)) return;
|
|
6682
6748
|
console.error(unsupportedNodeVersionMessage(version, bunVersion));
|
|
6683
6749
|
process.exit(1);
|
|
@@ -7075,7 +7141,7 @@ var __webpack_modules__ = {
|
|
|
7075
7141
|
return Math.min(Math.max(n, min), max);
|
|
7076
7142
|
}
|
|
7077
7143
|
const TEMPLATE_CORPUS_REPO = 'extension-js/examples';
|
|
7078
|
-
const TEMPLATE_CORPUS_REF = '
|
|
7144
|
+
const TEMPLATE_CORPUS_REF = '39448a235ea1b02516e6d555bcae409db2258b7f';
|
|
7079
7145
|
const TEMPLATE_CORPUS_SLUGS = [
|
|
7080
7146
|
'action',
|
|
7081
7147
|
'action-locales',
|
|
@@ -8066,7 +8132,7 @@ AI assistants
|
|
|
8066
8132
|
return `${getLoggingPrefix('error')} Can't use ${messages_code(bundleId)} as a bundle identifier.\nUse reverse-DNS form: dot-separated segments of letters, digits and hyphens, each starting with a letter (e.g. ${messages_code('com.example.my-extension')}).`;
|
|
8067
8133
|
}
|
|
8068
8134
|
function safariCommandNotSupported(command) {
|
|
8069
|
-
return `${getLoggingPrefix('error')} ${messages_code(command)} can't load an extension into Safari
|
|
8135
|
+
return `${getLoggingPrefix('error')} ${messages_code(command)} can't load an extension into Safari.\nSafari loads an extension only from an app it has registered, and that app is enabled by hand once installed.\nIts automation route can load a folder but grants no website access, so content scripts never run.\nRun a live Safari session: ${messages_code('extension dev --browser safari')}\nOr package the app and open it: ${messages_code('extension build --browser safari --open')}\nBoth need macOS with Xcode, and Safari takes the enable gesture once in Safari ▸ Settings ▸ Extensions.`;
|
|
8070
8136
|
}
|
|
8071
8137
|
function programAIHelp() {
|
|
8072
8138
|
return `\n${getLoggingPrefix('info')} ${external_pintor_default().gray('Development tips for extension developers and AI assistants')}
|
|
@@ -8483,6 +8549,96 @@ Cross-browser compatibility
|
|
|
8483
8549
|
function sessionLogsPath(bridge, projectPath, browser) {
|
|
8484
8550
|
return sessionFilePath(bridge, 'logsPath', projectPath, browser, 'logs.ndjson');
|
|
8485
8551
|
}
|
|
8552
|
+
function isSafariVendor(value) {
|
|
8553
|
+
return 'safari' === value || 'webkit-based' === value;
|
|
8554
|
+
}
|
|
8555
|
+
const SUPPORTED_BROWSER_TARGETS = [
|
|
8556
|
+
'chrome',
|
|
8557
|
+
'chromium',
|
|
8558
|
+
'edge',
|
|
8559
|
+
'firefox',
|
|
8560
|
+
'brave',
|
|
8561
|
+
'opera',
|
|
8562
|
+
'vivaldi',
|
|
8563
|
+
'yandex',
|
|
8564
|
+
'waterfox',
|
|
8565
|
+
'librewolf',
|
|
8566
|
+
'chromium-based',
|
|
8567
|
+
'gecko-based',
|
|
8568
|
+
'firefox-based',
|
|
8569
|
+
'safari',
|
|
8570
|
+
'webkit-based'
|
|
8571
|
+
];
|
|
8572
|
+
const BROWSER_TARGETS_HELP = SUPPORTED_BROWSER_TARGETS.join(' | ');
|
|
8573
|
+
const SESSION_BROWSER_TARGETS_HELP = "chrome | chromium | edge | firefox | safari";
|
|
8574
|
+
const NO_SAFARI_BROWSER_TARGETS_HELP = SUPPORTED_BROWSER_TARGETS.filter((target)=>!isSafariVendor(target)).join(' | ');
|
|
8575
|
+
function parseOptionalBoolean(value) {
|
|
8576
|
+
if (void 0 === value) return true;
|
|
8577
|
+
const normalized = String(value).trim().toLowerCase();
|
|
8578
|
+
return ![
|
|
8579
|
+
'false',
|
|
8580
|
+
'0',
|
|
8581
|
+
'no',
|
|
8582
|
+
'off'
|
|
8583
|
+
].includes(normalized);
|
|
8584
|
+
}
|
|
8585
|
+
const vendors = (browser)=>{
|
|
8586
|
+
const value = browser ?? 'chromium';
|
|
8587
|
+
return 'all' === value ? [
|
|
8588
|
+
'chrome',
|
|
8589
|
+
'edge',
|
|
8590
|
+
'firefox'
|
|
8591
|
+
] : String(value).split(',').map((part)=>part.trim()).filter(Boolean);
|
|
8592
|
+
};
|
|
8593
|
+
const MANAGED_INSTALL_TARGETS = [
|
|
8594
|
+
'chrome',
|
|
8595
|
+
'chromium',
|
|
8596
|
+
'edge',
|
|
8597
|
+
'firefox',
|
|
8598
|
+
'chromium-based',
|
|
8599
|
+
'gecko-based',
|
|
8600
|
+
'firefox-based'
|
|
8601
|
+
];
|
|
8602
|
+
const MANAGED_INSTALL_TARGETS_HELP = [
|
|
8603
|
+
...MANAGED_INSTALL_TARGETS,
|
|
8604
|
+
'all'
|
|
8605
|
+
].join(' | ');
|
|
8606
|
+
const MANAGED_INSTALL_BINARIES = [
|
|
8607
|
+
'chrome',
|
|
8608
|
+
'chromium',
|
|
8609
|
+
'edge',
|
|
8610
|
+
'firefox'
|
|
8611
|
+
];
|
|
8612
|
+
const installTargets = (browser)=>'all' === browser ? [
|
|
8613
|
+
...MANAGED_INSTALL_BINARIES
|
|
8614
|
+
] : vendors(browser);
|
|
8615
|
+
function validateVendors(vendorsList, onInvalid) {
|
|
8616
|
+
const supported = SUPPORTED_BROWSER_TARGETS;
|
|
8617
|
+
for (const v of vendorsList)if (!supported.includes(v)) {
|
|
8618
|
+
onInvalid(v, supported);
|
|
8619
|
+
return false;
|
|
8620
|
+
}
|
|
8621
|
+
return true;
|
|
8622
|
+
}
|
|
8623
|
+
const MANAGED_INSTALL_TARGET_SET = new Set(MANAGED_INSTALL_TARGETS);
|
|
8624
|
+
const SUPPORTED_BROWSER_TARGET_SET = new Set(SUPPORTED_BROWSER_TARGETS);
|
|
8625
|
+
function classifyManagedInstallTarget(name) {
|
|
8626
|
+
const value = String(name || '').trim().toLowerCase();
|
|
8627
|
+
if (!value) return 'unknown';
|
|
8628
|
+
if (MANAGED_INSTALL_TARGET_SET.has(value)) return 'managed';
|
|
8629
|
+
if (SUPPORTED_BROWSER_TARGET_SET.has(value)) return 'not-installable';
|
|
8630
|
+
return 'unknown';
|
|
8631
|
+
}
|
|
8632
|
+
function firstNonManagedInstallTarget(targetsList) {
|
|
8633
|
+
for (const name of targetsList){
|
|
8634
|
+
const kind = classifyManagedInstallTarget(name);
|
|
8635
|
+
if ('managed' !== kind) return {
|
|
8636
|
+
name,
|
|
8637
|
+
kind
|
|
8638
|
+
};
|
|
8639
|
+
}
|
|
8640
|
+
return null;
|
|
8641
|
+
}
|
|
8486
8642
|
function parseLogSinceLocal(value) {
|
|
8487
8643
|
if (null == value || '' === value) return null;
|
|
8488
8644
|
if ('number' == typeof value) return Number.isFinite(value) ? {
|
|
@@ -8593,7 +8749,7 @@ Cross-browser compatibility
|
|
|
8593
8749
|
}
|
|
8594
8750
|
}
|
|
8595
8751
|
function registerLogsCommand(program) {
|
|
8596
|
-
program.command('logs').arguments('[project-path]').usage('[project-path] [options]').description(commandDescriptions.logs).option(
|
|
8752
|
+
program.command('logs').arguments('[project-path]').usage('[project-path] [options]').description(commandDescriptions.logs).option(`--browser <${SESSION_BROWSER_TARGETS_HELP}>`, 'which dist/extension-js/<browser> to read. Defaults to `chromium`').option('--follow', 'stream live via the control channel instead of printing and exiting').option('--context <list>', 'comma-separated contexts (background, content, popup, options, sidebar, devtools, page)').option('--level <off|error|warn|info|debug|trace|all>', 'minimum severity to show. Defaults to `all`').option('--signals-only', '[experimental] show only structured dx.signal diagnostics. No emitter ships yet, so this currently prints nothing').option('--since <seq|iso>', 'only show events after this sequence number or ISO timestamp').option('--url <glob|substring>', 'only events whose url/hostname matches (glob with * or plain substring)').option('--tab <id>', 'only events from this tab id').option('--output <pretty|json|ndjson>', 'output format. Defaults to pretty on a TTY, ndjson when piped').action(async (projectPathArg, options)=>{
|
|
8597
8753
|
const bridge = await loadExtensionDevelopBridgeModule();
|
|
8598
8754
|
const projectPath = resolveSessionProjectPath(bridge, projectPathArg);
|
|
8599
8755
|
const browser = options.browser || 'chromium';
|
|
@@ -8936,7 +9092,7 @@ Cross-browser compatibility
|
|
|
8936
9092
|
if (null != opts.tab && '' !== opts.tab) target.tabId = Number(opts.tab);
|
|
8937
9093
|
return target;
|
|
8938
9094
|
}
|
|
8939
|
-
const commonOptions = (cmd)=>cmd.option(
|
|
9095
|
+
const commonOptions = (cmd)=>cmd.option(`--browser <${SESSION_BROWSER_TARGETS_HELP}>`, 'which session to target (default chromium)').option('--timeout <ms>', 'command timeout in milliseconds (default 5000)').option('--output <pretty|json>', 'output format (default pretty)');
|
|
8940
9096
|
function registerActCommands(program) {
|
|
8941
9097
|
commonOptions(program.command('eval').arguments('<expression> [project-path]').description(commandDescriptions.eval).option('--context <background|popup|options|sidebar|devtools|newtab|history|bookmarks|content|page>', 'target context (default background). Extension pages (popup/options/sidebar/devtools/newtab/history/bookmarks) answer via their own in-page relay and must be open').option('--url <glob|substring>', 'for content/page: document to target (resolved to its tab)').option('--tab <id>', 'for content/page: a specific tab (default: the --url match, else the active tab)')).action(async (expression, projectPathArg, opts)=>{
|
|
8942
9098
|
await runCommand({
|
|
@@ -9107,97 +9263,8 @@ Cross-browser compatibility
|
|
|
9107
9263
|
const values = String(raw).split(',').map((value)=>value.trim()).filter((value)=>value.length > 0);
|
|
9108
9264
|
return values.length > 0 ? values : void 0;
|
|
9109
9265
|
}
|
|
9110
|
-
function isSafariVendor(value) {
|
|
9111
|
-
return 'safari' === value || 'webkit-based' === value;
|
|
9112
|
-
}
|
|
9113
|
-
const SUPPORTED_BROWSER_TARGETS = [
|
|
9114
|
-
'chrome',
|
|
9115
|
-
'chromium',
|
|
9116
|
-
'edge',
|
|
9117
|
-
'firefox',
|
|
9118
|
-
'brave',
|
|
9119
|
-
'opera',
|
|
9120
|
-
'vivaldi',
|
|
9121
|
-
'yandex',
|
|
9122
|
-
'waterfox',
|
|
9123
|
-
'librewolf',
|
|
9124
|
-
'chromium-based',
|
|
9125
|
-
'gecko-based',
|
|
9126
|
-
'firefox-based',
|
|
9127
|
-
'safari',
|
|
9128
|
-
'webkit-based'
|
|
9129
|
-
];
|
|
9130
|
-
const BROWSER_TARGETS_HELP = SUPPORTED_BROWSER_TARGETS.join(' | ');
|
|
9131
|
-
const NO_SAFARI_BROWSER_TARGETS_HELP = SUPPORTED_BROWSER_TARGETS.filter((target)=>!isSafariVendor(target)).join(' | ');
|
|
9132
|
-
function parseOptionalBoolean(value) {
|
|
9133
|
-
if (void 0 === value) return true;
|
|
9134
|
-
const normalized = String(value).trim().toLowerCase();
|
|
9135
|
-
return ![
|
|
9136
|
-
'false',
|
|
9137
|
-
'0',
|
|
9138
|
-
'no',
|
|
9139
|
-
'off'
|
|
9140
|
-
].includes(normalized);
|
|
9141
|
-
}
|
|
9142
|
-
const vendors = (browser)=>{
|
|
9143
|
-
const value = browser ?? 'chromium';
|
|
9144
|
-
return 'all' === value ? [
|
|
9145
|
-
'chrome',
|
|
9146
|
-
'edge',
|
|
9147
|
-
'firefox'
|
|
9148
|
-
] : String(value).split(',').map((part)=>part.trim()).filter(Boolean);
|
|
9149
|
-
};
|
|
9150
|
-
const MANAGED_INSTALL_TARGETS = [
|
|
9151
|
-
'chrome',
|
|
9152
|
-
'chromium',
|
|
9153
|
-
'edge',
|
|
9154
|
-
'firefox',
|
|
9155
|
-
'chromium-based',
|
|
9156
|
-
'gecko-based',
|
|
9157
|
-
'firefox-based'
|
|
9158
|
-
];
|
|
9159
|
-
const MANAGED_INSTALL_TARGETS_HELP = [
|
|
9160
|
-
...MANAGED_INSTALL_TARGETS,
|
|
9161
|
-
'all'
|
|
9162
|
-
].join(' | ');
|
|
9163
|
-
const MANAGED_INSTALL_BINARIES = [
|
|
9164
|
-
'chrome',
|
|
9165
|
-
'chromium',
|
|
9166
|
-
'edge',
|
|
9167
|
-
'firefox'
|
|
9168
|
-
];
|
|
9169
|
-
const installTargets = (browser)=>'all' === browser ? [
|
|
9170
|
-
...MANAGED_INSTALL_BINARIES
|
|
9171
|
-
] : vendors(browser);
|
|
9172
|
-
function validateVendors(vendorsList, onInvalid) {
|
|
9173
|
-
const supported = SUPPORTED_BROWSER_TARGETS;
|
|
9174
|
-
for (const v of vendorsList)if (!supported.includes(v)) {
|
|
9175
|
-
onInvalid(v, supported);
|
|
9176
|
-
return false;
|
|
9177
|
-
}
|
|
9178
|
-
return true;
|
|
9179
|
-
}
|
|
9180
|
-
const MANAGED_INSTALL_TARGET_SET = new Set(MANAGED_INSTALL_TARGETS);
|
|
9181
|
-
const SUPPORTED_BROWSER_TARGET_SET = new Set(SUPPORTED_BROWSER_TARGETS);
|
|
9182
|
-
function classifyManagedInstallTarget(name) {
|
|
9183
|
-
const value = String(name || '').trim().toLowerCase();
|
|
9184
|
-
if (!value) return 'unknown';
|
|
9185
|
-
if (MANAGED_INSTALL_TARGET_SET.has(value)) return 'managed';
|
|
9186
|
-
if (SUPPORTED_BROWSER_TARGET_SET.has(value)) return 'not-installable';
|
|
9187
|
-
return 'unknown';
|
|
9188
|
-
}
|
|
9189
|
-
function firstNonManagedInstallTarget(targetsList) {
|
|
9190
|
-
for (const name of targetsList){
|
|
9191
|
-
const kind = classifyManagedInstallTarget(name);
|
|
9192
|
-
if ('managed' !== kind) return {
|
|
9193
|
-
name,
|
|
9194
|
-
kind
|
|
9195
|
-
};
|
|
9196
|
-
}
|
|
9197
|
-
return null;
|
|
9198
|
-
}
|
|
9199
9266
|
function registerBuildCommand(program) {
|
|
9200
|
-
program.command('build').arguments('[project-name]').usage('[path-to-remote-extension] [options]').description(commandDescriptions.build).option(`--browser <${BROWSER_TARGETS_HELP}>`, 'specify a browser/engine to run. Defaults to `chromium`. `safari` builds a Safari app via Xcode (macOS only)').option('--polyfill [boolean]', 'whether or not to apply the cross-browser polyfill. Defaults to `false`', parseOptionalBoolean).option('--no-polyfill', 'disable the cross-browser polyfill').option('--zip [boolean]', 'whether or not to compress the extension into a ZIP file. Defaults to `false`', parseOptionalBoolean).option('--zip-source [boolean]', 'whether or not to include the source files in the ZIP file. Defaults to `false`', parseOptionalBoolean).option('--zip-filename <string>', 'specify the name of the ZIP file. Defaults to the extension name and version').option('--silent [boolean]', 'suppress the build summary output. Defaults to `false`', parseOptionalBoolean).option('--addon-lint [boolean]', 'check Firefox builds against addons.mozilla.org rules with addons-linter when it is installed. Findings print as warnings. Defaults to `true`', parseOptionalBoolean).option('--no-addon-lint', 'skip the addons.mozilla.org lint of Firefox builds').option('--install [boolean]', '[internal] install project dependencies when missing', parseOptionalBoolean).option('--extensions <list>', 'comma-separated list of companion extensions or store URLs to load').option('--mode <development|production|none>', 'bundler mode override (also sets NODE_ENV). Defaults to `production`').option('--open [boolean]', 'open the built Safari app after packaging (safari targets only). Defaults to `false`', parseOptionalBoolean).option('--app-name <name>', 'override the Safari app name (safari targets only). Defaults to the manifest `name`').option('--bundle-id <reverse.dns>', 'set a user-owned Safari bundle identifier (safari targets only). Defaults to a generated dev.extensionjs.* id').option('--development-team <id>', 'sign the Safari app with an Apple Developer team id (safari targets only). Without it the build is ad-hoc signed, which Safari
|
|
9267
|
+
program.command('build').arguments('[project-name]').usage('[path-to-remote-extension] [options]').description(commandDescriptions.build).option(`--browser <${BROWSER_TARGETS_HELP}>`, 'specify a browser/engine to run. Defaults to `chromium`. `safari` builds a Safari app via Xcode (macOS only)').option('--polyfill [boolean]', 'whether or not to apply the cross-browser polyfill. Defaults to `false`', parseOptionalBoolean).option('--no-polyfill', 'disable the cross-browser polyfill').option('--zip [boolean]', 'whether or not to compress the extension into a ZIP file. Defaults to `false`', parseOptionalBoolean).option('--zip-source [boolean]', 'whether or not to include the source files in the ZIP file. Defaults to `false`', parseOptionalBoolean).option('--zip-filename <string>', 'specify the name of the ZIP file. Defaults to the extension name and version').option('--silent [boolean]', 'suppress the build summary output. Defaults to `false`', parseOptionalBoolean).option('--addon-lint [boolean]', 'check Firefox builds against addons.mozilla.org rules with addons-linter when it is installed. Findings print as warnings. Defaults to `true`', parseOptionalBoolean).option('--no-addon-lint', 'skip the addons.mozilla.org lint of Firefox builds').option('--install [boolean]', '[internal] install project dependencies when missing', parseOptionalBoolean).option('--extensions <list>', 'comma-separated list of companion extensions or store URLs to load').option('--mode <development|production|none>', 'bundler mode override (also sets NODE_ENV). Defaults to `production`').option('--open [boolean]', 'open the built Safari app after packaging (safari targets only). Defaults to `false`', parseOptionalBoolean).option('--app-name <name>', 'override the Safari app name (safari targets only). Defaults to the manifest `name`').option('--bundle-id <reverse.dns>', 'set a user-owned Safari bundle identifier (safari targets only). Defaults to a generated dev.extensionjs.* id').option('--development-team <id>', 'sign the Safari app with an Apple Developer team id (safari targets only). Without it the build is ad-hoc signed, which Safari loads locally with no per-launch toggle. Use a team id for a stable identity you can distribute').option('--macos-only [boolean]', 'generate a macOS-only Safari Xcode project (safari targets only). Pass `false` for a universal macOS + iOS project. Defaults to `true`', parseOptionalBoolean).option('--force-regenerate', 'regenerate the Safari Xcode project even when up to date (safari targets only)').option('--output <pretty|json>', 'result format. Use json for a schema-1 envelope on stdout').addOption(new external_commander_namespaceObject.Option('--debug', 'print maintainer diagnostics alongside normal output')).addOption(new external_commander_namespaceObject.Option('--author, --author-mode', 'deprecated alias for --debug').hideHelp()).action(async (pathOrRemoteUrl, { browser: cliBrowser, ...buildOptions })=>{
|
|
9201
9268
|
const browser = cliBrowser ?? await resolveConfigBrowser(pathOrRemoteUrl || process.cwd(), 'build') ?? 'chromium';
|
|
9202
9269
|
if (buildOptions.debug || buildOptions.author || buildOptions.authorMode) {
|
|
9203
9270
|
process.env.EXTENSION_DEBUG = '1';
|
|
@@ -9833,7 +9900,7 @@ Cross-browser compatibility
|
|
|
9833
9900
|
return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : 8080;
|
|
9834
9901
|
}
|
|
9835
9902
|
function registerDevCommand(program) {
|
|
9836
|
-
program.command('dev').arguments('[project-path|remote-url]').usage('[project-path|remote-url] [options]').description(commandDescriptions.dev).addHelpText('after', "\nAdditional options:\n --no-browser stop the browser launch, the dev server still starts\n --no-reload emit a dev-mode dist without the content-script reload runtime, tabs need a manual reload to see changes\n --wait wait for ready contract and exit, pair with --output json for machine output\n" + BROWSER_LAUNCH_HELP_FOOTER).option('--profile <path-to-file | boolean>', 'what path to use for the browser profile. A boolean value of false sets the profile to the default user profile. Defaults to a fresh profile').option(`-b, --browser <${BROWSER_TARGETS_HELP}>`, 'specify a browser/engine to run. Defaults to `chromium`. `safari` builds and opens a Safari app via Xcode (macOS only
|
|
9903
|
+
program.command('dev').arguments('[project-path|remote-url]').usage('[project-path|remote-url] [options]').description(commandDescriptions.dev).addHelpText('after', "\nAdditional options:\n --no-browser stop the browser launch, the dev server still starts\n --no-reload emit a dev-mode dist without the content-script reload runtime, tabs need a manual reload to see changes\n --wait wait for ready contract and exit, pair with --output json for machine output\n" + BROWSER_LAUNCH_HELP_FOOTER).option('--profile <path-to-file | boolean>', 'what path to use for the browser profile. A boolean value of false sets the profile to the default user profile. Defaults to a fresh profile').option(`-b, --browser <${BROWSER_TARGETS_HELP}>`, 'specify a browser/engine to run. Defaults to `chromium`. `safari` builds and opens a Safari app via Xcode (macOS only)').option('--chromium-binary <path-to-binary>', 'specify a path to the Chromium binary. This option overrides the --browser setting. Defaults to the system default').addOption(geckoBinaryOption()).addOption(firefoxBinaryAliasOption()).option('--safari-binary <path-to-binary>', 'specify the Safari binary to open after packaging (safari targets only)').option('--app-name <name>', 'override the Safari app name (safari targets only). Defaults to the manifest `name`').option('--bundle-id <reverse.dns>', 'set a user-owned Safari bundle identifier (safari targets only). Defaults to a generated dev.extensionjs.* id').option('--development-team <id>', 'sign the Safari app with an Apple Developer team id (safari targets only). Without it the build is ad-hoc signed, which Safari loads locally with no per-launch toggle. Use a team id for a stable identity you can distribute').option('--macos-only [boolean]', 'generate a macOS-only Safari Xcode project (safari targets only). Pass `false` for a universal macOS + iOS project. Defaults to `true`', parseOptionalBoolean).option('--force-regenerate', 'regenerate the Safari Xcode project even when up to date (safari targets only)').option('--polyfill [boolean]', 'whether or not to apply the cross-browser polyfill. Defaults to `true`', parseOptionalBoolean).option('--no-polyfill', 'disable the cross-browser polyfill').option('--no-open', NO_OPEN_FLAG_DESCRIPTION).option('--starting-url <url>', 'specify the starting URL for the browser. Defaults to `undefined`').option('--port <port>', 'specify the port to use for the development server. Defaults to `8080`').option('--host <host>', 'specify the host to bind the dev server to. Use 0.0.0.0 for Docker/devcontainers. Defaults to `127.0.0.1`').option('--public-host <host>', 'connectable host the browser (HMR + reload bridge) dials when it differs from the bind host (e.g. a remote/devcontainer). Defaults to the bind host, or 127.0.0.1 when bound to 0.0.0.0').option('--log-context <list>', '[experimental] comma-separated contexts to include (background,content,page,sidebar,popup,options,devtools). Use `all` to include all contexts (default)').option('--logs <off|error|warn|info|debug|trace|all>', '[experimental] minimum centralized logger level to display in terminal (default: off)').option('--log-format <pretty|json|ndjson>', '[experimental] output format for logger events. Defaults to `pretty`').option('--no-log-timestamps', 'disable ISO timestamps in pretty output').option('--no-log-color', 'disable color in pretty output').option('--log-url <pattern>', '[experimental] only show logs where event.url matches this substring or regex (/re/i)').option('--log-tab <id>', 'only show logs for a specific tabId (number)').option('--extensions <list>', 'comma-separated list of companion extensions or store URLs to load').option('--install [boolean]', '[internal] install project dependencies when missing', parseOptionalBoolean).option('--wait [boolean]', 'wait for dist/extension-js/<browser>/ready.json and exit', parseOptionalBoolean).option('--wait-timeout <ms>', 'timeout in milliseconds when using --wait (default: 60000)').option('--output <pretty|json>', 'result format. Use json for a schema-1 envelope on stdout').addOption(new external_commander_namespaceObject.Option('--wait-format <pretty|json>').hideHelp()).addOption(new external_commander_namespaceObject.Option('--debug', 'print maintainer diagnostics alongside normal output')).addOption(new external_commander_namespaceObject.Option('--author, --author-mode', 'deprecated alias for --debug').hideHelp()).option('--allow-control', 'enable the agent-bridge control channel for bounded act (storage/reload/open): see `extension reload|storage|open`').option('--allow-eval', 'additionally enable `extension eval` (implies --allow-control, runs arbitrary code in a context, writes a 0600 session token)').option('--parent-pid <pid>', 'exit when the given process dies. For wrappers that spawn `extension dev`, so a leaked dev server can never outlive its owner').action(async (pathOrRemoteUrl, options, command)=>{
|
|
9837
9904
|
const { browser: cliBrowser, ...devOptions } = options;
|
|
9838
9905
|
const browser = cliBrowser ?? await resolveConfigBrowser(pathOrRemoteUrl || process.cwd(), 'dev') ?? 'chromium';
|
|
9839
9906
|
if (devOptions.debug || devOptions.author || devOptions.authorMode) {
|
|
@@ -10313,7 +10380,7 @@ Cross-browser compatibility
|
|
|
10313
10380
|
browser: messaging.Lp.E_BROWSER_LAUNCH
|
|
10314
10381
|
};
|
|
10315
10382
|
function registerDoctorCommand(program) {
|
|
10316
|
-
program.command('doctor').argument('[project-path]', 'path to the extension project root or the folder holding its manifest').option(
|
|
10383
|
+
program.command('doctor').argument('[project-path]', 'path to the extension project root or the folder holding its manifest').option(`--browser <${SESSION_BROWSER_TARGETS_HELP}>`, 'which session to diagnose (defaults to the single live session, else chromium)').option('--output <pretty|json>', 'result format. Use json for a schema-1 envelope on stdout').description(commandDescriptions.doctor).action(async (projectPathArg, opts)=>{
|
|
10317
10384
|
const asJson = isJsonOutput(opts);
|
|
10318
10385
|
let results;
|
|
10319
10386
|
try {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
export declare const DEFAULT_DEBUG_PORT = 9222;
|
|
2
2
|
export declare const PORT_OFFSET = 100;
|
|
3
3
|
export declare const CDP_COMMAND_TIMEOUT_MS: number;
|
|
4
|
-
/** CDP HTTP endpoint timeout for /json discovery (ms). Override: EXTENSION_CDP_HTTP_TIMEOUT_MS */
|
|
5
4
|
export declare const CDP_HTTP_TIMEOUT_MS: number;
|
|
6
5
|
export declare const RDP_EVAL_TIMEOUT_MS: number;
|
|
7
|
-
/** Firefox RDP connect retry count. Override: EXTENSION_RDP_MAX_RETRIES */
|
|
8
6
|
export declare const RDP_MAX_RETRIES: number;
|
|
9
7
|
export declare const RDP_RETRY_INTERVAL_MS: number;
|
|
10
8
|
export declare const CDP_HEARTBEAT_INTERVAL_MS: number;
|
|
@@ -72,7 +72,7 @@ export declare function safariOpening(target: string): string;
|
|
|
72
72
|
export declare function safariToolFailed(tool: string, exitCode: number | null, outputTail: string): string;
|
|
73
73
|
export declare function safariConverterWarnings(warnings: string[]): string;
|
|
74
74
|
export declare function safariDefaultBundleIdNote(bundleId: string): string;
|
|
75
|
-
export declare function safariOpenHint(appPath: string, appName: string
|
|
75
|
+
export declare function safariOpenHint(appPath: string, appName: string): string;
|
|
76
76
|
export declare function safariDryRunNotBuilding(): string;
|
|
77
77
|
export declare function safariDryRunConverter(cmd: string): string;
|
|
78
78
|
export declare function safariDryRunXcodebuild(cmd: string): string;
|
|
@@ -1,33 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The single decision about what profile a development run gets. Both the
|
|
3
|
-
* chromium and firefox launchers route through this so the profile contract
|
|
4
|
-
* (`false`, `copyFromProfile`, `keepProfileChanges`, the env switch, explicit
|
|
5
|
-
* paths and the plain ephemeral default) is interpreted in exactly one place.
|
|
6
|
-
*
|
|
7
|
-
* - `system`, the browser's own default profile. No managed directory is
|
|
8
|
-
* created, seeded or cleaned and no profile launch arg is
|
|
9
|
-
* emitted. Produced by `profile: false` and by the
|
|
10
|
-
* EXTENSION_USE_SYSTEM_PROFILE / EXTJS_USE_SYSTEM_PROFILE switch.
|
|
11
|
-
* - `explicit`, a user-provided profile path; launched against exactly that
|
|
12
|
-
* directory.
|
|
13
|
-
* - `managed`, a directory under `dist/extension-js/profiles/<browser>-profile`
|
|
14
|
-
* that extension.js owns. Ephemeral by default (marked so it is
|
|
15
|
-
* reclaimed on browser exit); persistent (`dev`) when
|
|
16
|
-
* `persistProfile` or `keepProfileChanges` is set, in which case
|
|
17
|
-
* the marker is withheld so the cleanup hook skips it.
|
|
18
|
-
*/
|
|
19
1
|
export type ProfileKind = 'system' | 'explicit' | 'managed';
|
|
20
2
|
export interface ResolveProfileInput {
|
|
21
3
|
rawProfile?: string | boolean;
|
|
22
|
-
/** Managed-profile base directory: `<distRoot>/extension-js/profiles/<browser>-profile`. */
|
|
23
4
|
managedBaseDir: string;
|
|
24
|
-
/** EXTENSION_USE_SYSTEM_PROFILE / EXTJS_USE_SYSTEM_PROFILE resolved to a boolean. */
|
|
25
5
|
useSystemProfile: boolean;
|
|
26
|
-
/** `persistProfile` option (stable `dev` directory, never auto-cleaned). */
|
|
27
6
|
persistProfile?: boolean;
|
|
28
|
-
/** `keepProfileChanges` option, keep the managed profile and its changes across runs. */
|
|
29
7
|
keepProfileChanges?: boolean;
|
|
30
|
-
/** `copyFromProfile` option, seed the managed profile as a copy of this path. */
|
|
31
8
|
copyFromProfile?: string;
|
|
32
9
|
resolveExplicit: (trimmedProfile: string) => string;
|
|
33
10
|
provision?: boolean;
|
|
@@ -35,21 +12,9 @@ export interface ResolveProfileInput {
|
|
|
35
12
|
export interface ResolvedProfile {
|
|
36
13
|
kind: ProfileKind;
|
|
37
14
|
profilePath: string;
|
|
38
|
-
/** True when the managed profile is persisted (no cleanup on exit). */
|
|
39
15
|
persisted: boolean;
|
|
40
|
-
/** Set when `copyFromProfile` seeded this run, for logging/visibility. */
|
|
41
16
|
seededFrom?: string;
|
|
42
17
|
}
|
|
43
|
-
/**
|
|
44
|
-
* The one interpretation of the `--profile` / `profile` option value.
|
|
45
|
-
* Commander delivers flag values as strings, so `--profile false` arrives as
|
|
46
|
-
* the string `'false'`. Without this normalization that string reads as an
|
|
47
|
-
* explicit path and a literal profile directory named `false` gets created.
|
|
48
|
-
*
|
|
49
|
-
* - `false` / `'false'`: the browser's own default profile (system).
|
|
50
|
-
* - `true` / `'true'`: the managed default (same as leaving the option unset).
|
|
51
|
-
* - any other string: an explicit profile path.
|
|
52
|
-
*/
|
|
53
18
|
export declare function normalizeProfileOption(value: string | boolean | undefined): string | false | undefined;
|
|
54
19
|
export declare function ensureProfileRootIgnoreFile(managedBaseDir: string): void;
|
|
55
20
|
export declare function seedProfileFrom(source: string, dest: string): void;
|