extension 3.8.11 → 3.8.13
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 +0 -39
- package/dist/cli.cjs +151 -2
- package/dist/commands/dev-wait.d.ts +37 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -137,45 +137,6 @@ npx extension@latest dev --chromium-binary "/Applications/Google Chrome.app/Cont
|
|
|
137
137
|
npx extension@latest dev --gecko-binary "/Applications/Firefox.app/Contents/MacOS/firefox"
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
### Managed browser binaries
|
|
141
|
-
|
|
142
|
-
Use Extension.js commands to install/remove managed browser binaries:
|
|
143
|
-
|
|
144
|
-
```bash
|
|
145
|
-
# Install into Extension.js managed cache
|
|
146
|
-
npx extension@latest install --browser=chromium
|
|
147
|
-
npx extension@latest install --browser=firefox
|
|
148
|
-
|
|
149
|
-
# Show managed cache root
|
|
150
|
-
npx extension@latest install --where
|
|
151
|
-
|
|
152
|
-
# Show managed path for a specific browser
|
|
153
|
-
npx extension@latest install --where --browser=firefox
|
|
154
|
-
|
|
155
|
-
# Remove one browser binary
|
|
156
|
-
npx extension@latest uninstall chromium
|
|
157
|
-
|
|
158
|
-
# Remove all managed browser binaries
|
|
159
|
-
npx extension@latest uninstall --all
|
|
160
|
-
|
|
161
|
-
# Show managed cache root
|
|
162
|
-
npx extension@latest uninstall --where
|
|
163
|
-
|
|
164
|
-
# Show managed path(s) for target browser(s)
|
|
165
|
-
npx extension@latest uninstall --where --browser=chromium
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
`uninstall` only removes binaries from the Extension.js managed cache root (or `EXT_BROWSERS_CACHE_DIR` when set). It does not remove browser installations that were installed elsewhere (for example, system browsers or custom paths outside the managed cache).
|
|
169
|
-
|
|
170
|
-
`edge` note for Linux: Playwright channel installs may require a privileged interactive session (`sudo` prompt). If channel install cannot proceed but a system Edge binary is already present, Extension.js will use that existing binary. Otherwise, install Edge system-wide first and then run Extension.js with `--browser=edge` (or use `chromium`).
|
|
171
|
-
|
|
172
|
-
Default managed cache locations are stable and human-readable:
|
|
173
|
-
- macOS: `~/Library/Caches/extension.js/browsers`
|
|
174
|
-
- Linux: `~/.cache/extension.js/browsers` (or `$XDG_CACHE_HOME/extension.js/browsers`)
|
|
175
|
-
- Windows: `%LOCALAPPDATA%\\extension.js\\browsers`
|
|
176
|
-
|
|
177
|
-
If you want a custom path, set `EXT_BROWSERS_CACHE_DIR` to a clean location (for example, `EXT_BROWSERS_CACHE_DIR=/tmp/extension.js/browsers-dev`).
|
|
178
|
-
|
|
179
140
|
## Sponsors
|
|
180
141
|
|
|
181
142
|
<div align="center">
|
package/dist/cli.cjs
CHANGED
|
@@ -160,6 +160,7 @@ Source Inspection (dev command)
|
|
|
160
160
|
- When provided without a URL, falls back to ${messages_arg('--starting-url')} or ${messages_arg('https://example.com')}
|
|
161
161
|
- For ${code('extension dev')}, watch mode is enabled by default when ${code('--source')} is present
|
|
162
162
|
- ${messages_arg('Note:')} ${code('extension preview')} and ${code('extension start')} do not run source inspection in run-only preview mode.
|
|
163
|
+
- ${messages_arg('Automation sync:')} when using ${code('extension dev --no-browser')} or ${code('extension start --no-browser')}, run ${code('extension <dev|start> --wait --browser=<browser>')} in a second process to gate on ${code('ready.json')} (add ${code('--wait-format=json')} for machine-readable output).
|
|
163
164
|
- ${code('--watch-source')} ${messages_arg('[boolean]')} Re-print HTML on rebuilds or file changes
|
|
164
165
|
- ${code('--source-format')} ${messages_arg('<pretty|json|ndjson>')} Output format for page HTML (defaults to ${code('--log-format')} when present)
|
|
165
166
|
- ${code('--source-summary')} ${messages_arg('[boolean]')} Output a compact summary instead of full HTML
|
|
@@ -336,6 +337,7 @@ Source Inspection & Real-Time Monitoring
|
|
|
336
337
|
- Useful for debugging content script behavior and style injection
|
|
337
338
|
- Example: ${code('extension dev --source=' + messages_arg('https://example.com'))}
|
|
338
339
|
- ${messages_arg('Note:')} ${code('preview/start')} run in run-only mode and do not perform source inspection.
|
|
340
|
+
- For machine synchronization with ${code('--no-browser')}, use ${code('extension dev --wait --browser=<browser>')} or ${code('extension start --wait --browser=<browser>')} in a second process (use ${code('--wait-format=json')} when a parser consumes stdout).
|
|
339
341
|
|
|
340
342
|
Non-Destructive Testing in CI
|
|
341
343
|
- Prefer ${code('EXTENSION_AUTHOR_MODE=development')} to copy local templates and avoid network.
|
|
@@ -470,6 +472,8 @@ Cross-Browser Compatibility
|
|
|
470
472
|
'extension --ai-help --format json',
|
|
471
473
|
'extension dev ./my-ext --source https://example.com --source-format json',
|
|
472
474
|
'extension dev ./my-ext --logs=info --log-format=json',
|
|
475
|
+
'extension dev ./my-ext --wait --browser=chromium --wait-format=json',
|
|
476
|
+
'extension start ./my-ext --wait --browser=chromium --wait-format=json',
|
|
473
477
|
'extension install chromium',
|
|
474
478
|
'extension install --where',
|
|
475
479
|
'extension uninstall --where',
|
|
@@ -905,6 +909,105 @@ Cross-Browser Compatibility
|
|
|
905
909
|
}
|
|
906
910
|
});
|
|
907
911
|
}
|
|
912
|
+
function isHttpUrl(value) {
|
|
913
|
+
if (!value) return false;
|
|
914
|
+
return /^https?:\/\//i.test(value);
|
|
915
|
+
}
|
|
916
|
+
function resolveProjectPath(pathOrRemoteUrl) {
|
|
917
|
+
if (!pathOrRemoteUrl) return process.cwd();
|
|
918
|
+
return external_node_path_namespaceObject.isAbsolute(pathOrRemoteUrl) ? pathOrRemoteUrl : external_node_path_namespaceObject.join(process.cwd(), pathOrRemoteUrl);
|
|
919
|
+
}
|
|
920
|
+
function parseWaitTimeoutMs(value) {
|
|
921
|
+
const fallback = 60000;
|
|
922
|
+
if ('number' == typeof value && Number.isFinite(value) && value > 0) return Math.floor(value);
|
|
923
|
+
if ('string' == typeof value && value.trim()) {
|
|
924
|
+
const parsed = parseInt(value, 10);
|
|
925
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
926
|
+
}
|
|
927
|
+
return fallback;
|
|
928
|
+
}
|
|
929
|
+
function parseWaitFormat(value) {
|
|
930
|
+
return 'json' === value ? 'json' : 'pretty';
|
|
931
|
+
}
|
|
932
|
+
function isProcessLikelyAlive(pid) {
|
|
933
|
+
if ('number' != typeof pid || !Number.isInteger(pid) || pid <= 0) return true;
|
|
934
|
+
try {
|
|
935
|
+
process.kill(pid, 0);
|
|
936
|
+
return true;
|
|
937
|
+
} catch {
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
function isFreshContractPayload(payload, maxAgeMs) {
|
|
942
|
+
const candidates = [
|
|
943
|
+
payload.ts,
|
|
944
|
+
payload.compiledAt,
|
|
945
|
+
payload.startedAt
|
|
946
|
+
];
|
|
947
|
+
for (const candidate of candidates){
|
|
948
|
+
if (!candidate) continue;
|
|
949
|
+
const stamp = Date.parse(candidate);
|
|
950
|
+
if (Number.isFinite(stamp)) return Date.now() - stamp <= maxAgeMs;
|
|
951
|
+
}
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
async function waitForReadyContract(options) {
|
|
955
|
+
const readyPath = external_node_path_namespaceObject.join(options.projectPath, 'dist', 'extension-js', options.browser, 'ready.json');
|
|
956
|
+
const start = Date.now();
|
|
957
|
+
while(Date.now() - start < options.timeoutMs){
|
|
958
|
+
if (external_node_fs_namespaceObject.existsSync(readyPath)) try {
|
|
959
|
+
const payload = JSON.parse(external_node_fs_namespaceObject.readFileSync(readyPath, 'utf8'));
|
|
960
|
+
const isLive = isProcessLikelyAlive(payload.pid);
|
|
961
|
+
if (payload.command !== options.command) {
|
|
962
|
+
await new Promise((resolve)=>setTimeout(resolve, 250));
|
|
963
|
+
continue;
|
|
964
|
+
}
|
|
965
|
+
if (!isLive) {
|
|
966
|
+
if ('start' !== options.command || !isFreshContractPayload(payload, options.timeoutMs)) {
|
|
967
|
+
await new Promise((resolve)=>setTimeout(resolve, 250));
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
if ('ready' === payload.status) return payload;
|
|
972
|
+
if ('error' === payload.status) {
|
|
973
|
+
const detail = payload.message || payload.errors?.[0] || 'unknown error';
|
|
974
|
+
throw new Error(String(detail));
|
|
975
|
+
}
|
|
976
|
+
} catch (error) {
|
|
977
|
+
if (error instanceof Error) throw error;
|
|
978
|
+
throw new Error(String(error));
|
|
979
|
+
}
|
|
980
|
+
await new Promise((resolve)=>setTimeout(resolve, 250));
|
|
981
|
+
}
|
|
982
|
+
throw new Error(`Timed out waiting for ready contract at ${readyPath} (${options.timeoutMs} ms)`);
|
|
983
|
+
}
|
|
984
|
+
async function runWaitMode(options) {
|
|
985
|
+
if (isHttpUrl(options.pathOrRemoteUrl)) throw new Error('--wait requires a local project path (remote URLs are not supported)');
|
|
986
|
+
const projectPath = resolveProjectPath(options.pathOrRemoteUrl);
|
|
987
|
+
const timeoutMs = parseWaitTimeoutMs(options.waitTimeout);
|
|
988
|
+
const format = parseWaitFormat(options.waitFormat);
|
|
989
|
+
const results = [];
|
|
990
|
+
for (const browser of options.browsers){
|
|
991
|
+
const payload = await waitForReadyContract({
|
|
992
|
+
command: options.command,
|
|
993
|
+
projectPath,
|
|
994
|
+
browser,
|
|
995
|
+
timeoutMs
|
|
996
|
+
});
|
|
997
|
+
results.push({
|
|
998
|
+
...payload,
|
|
999
|
+
browser
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
return {
|
|
1003
|
+
projectPath,
|
|
1004
|
+
command: options.command,
|
|
1005
|
+
timeoutMs,
|
|
1006
|
+
format,
|
|
1007
|
+
browsers: options.browsers,
|
|
1008
|
+
results
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
908
1011
|
function normalizeSourceOption(source, startingUrl) {
|
|
909
1012
|
if (!source) return;
|
|
910
1013
|
const hasExplicitSourceString = 'string' == typeof source && 'true' !== String(source).trim().toLowerCase();
|
|
@@ -1012,7 +1115,7 @@ Cross-Browser Compatibility
|
|
|
1012
1115
|
}
|
|
1013
1116
|
const dev_require = (0, external_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
|
|
1014
1117
|
function registerDevCommand(program, telemetry) {
|
|
1015
|
-
program.command('dev').arguments('[project-path|remote-url]').usage('dev [project-path|remote-url] [options]').description(commandDescriptions.dev).addHelpText('after', '\nAdditional
|
|
1118
|
+
program.command('dev').arguments('[project-path|remote-url]').usage('dev [project-path|remote-url] [options]').description(commandDescriptions.dev).addHelpText('after', '\nAdditional options:\n --no-browser do not launch the browser (dev server still starts)\n --wait wait for ready contract and exit\n --wait-format pretty|json output for wait mode\n').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('--browser <chrome | chromium | edge | firefox | chromium-based | gecko-based | firefox-based>', 'specify a browser/engine to run. Defaults to `chromium`').option('--chromium-binary <path-to-binary>', 'specify a path to the Chromium binary. This option overrides the --browser setting. Defaults to the system default').option('--gecko-binary, --firefox-binary <path-to-binary>', 'specify a path to the Gecko binary. This option overrides the --browser setting. Defaults to the system default').option('--polyfill [boolean]', 'whether or not to apply the cross-browser polyfill. Defaults to `false`').option('--no-open', 'do not open the browser automatically (default: open)').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('--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('--source [url]', "[experimental] opens the provided URL in Chrome and prints the full, live HTML of the page after content scripts are injected").option('--watch-source [boolean]', '[experimental] re-print HTML on rebuilds or file changes (defaults to true when --source is present)', parseOptionalBoolean).option('--source-format <pretty|json|ndjson>', '[experimental] output format for source HTML (defaults to --log-format when present, otherwise JSON when --source is used)').option('--source-summary [boolean]', '[experimental] output a compact summary instead of full HTML', parseOptionalBoolean).option('--source-meta [boolean]', '[experimental] output page metadata (readyState, viewport, frames)', parseOptionalBoolean).option('--source-probe <selectors>', '[experimental] comma-separated CSS selectors to probe').option('--source-tree <off|root-only>', '[experimental] output a compact extension root tree').option('--source-console [boolean]', '[experimental] output console summary (best-effort)', parseOptionalBoolean).option('--source-dom [boolean]', '[experimental] output DOM snapshots and diffs (default: true when watch is enabled)', parseOptionalBoolean).option('--source-max-bytes <bytes>', '[experimental] limit HTML output size in bytes (0 disables truncation)').option('--source-redact <off|safe|strict>', '[experimental] redact sensitive content in HTML output (default: safe for JSON/NDJSON)').option('--source-include-shadow <off|open-only|all>', '[experimental] control Shadow DOM inclusion in HTML output (default: open-only)').option('--source-diff [boolean]', '[experimental] include diff metadata on watch updates (default: true when watch is enabled)', parseOptionalBoolean).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('--wait-format <pretty|json>', 'output format for --wait results (default: pretty)').option('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...devOptions }) {
|
|
1016
1119
|
if (devOptions.author || devOptions['authorMode']) {
|
|
1017
1120
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
1018
1121
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
@@ -1030,6 +1133,29 @@ Cross-Browser Compatibility
|
|
|
1030
1133
|
validateVendorsOrExit(list, (invalid, supported)=>{
|
|
1031
1134
|
console.error(unsupportedBrowserFlag(invalid, supported));
|
|
1032
1135
|
});
|
|
1136
|
+
if (devOptions.wait) {
|
|
1137
|
+
const waitResult = await runWaitMode({
|
|
1138
|
+
command: 'dev',
|
|
1139
|
+
pathOrRemoteUrl,
|
|
1140
|
+
browsers: list,
|
|
1141
|
+
waitTimeout: devOptions.waitTimeout,
|
|
1142
|
+
waitFormat: devOptions.waitFormat
|
|
1143
|
+
});
|
|
1144
|
+
if ('json' === waitResult.format) console.log(JSON.stringify({
|
|
1145
|
+
ok: true,
|
|
1146
|
+
mode: 'wait',
|
|
1147
|
+
command: 'dev',
|
|
1148
|
+
browsers: waitResult.browsers,
|
|
1149
|
+
results: waitResult.results
|
|
1150
|
+
}));
|
|
1151
|
+
telemetry.track('cli_command_finish', {
|
|
1152
|
+
command: 'dev',
|
|
1153
|
+
duration_ms: Date.now() - cmdStart,
|
|
1154
|
+
success: true,
|
|
1155
|
+
exit_code: 0
|
|
1156
|
+
});
|
|
1157
|
+
return;
|
|
1158
|
+
}
|
|
1033
1159
|
const normalizedSource = normalizeSourceOption(devOptions.source, devOptions.startingUrl);
|
|
1034
1160
|
if (normalizedSource) {
|
|
1035
1161
|
devOptions.source = normalizedSource;
|
|
@@ -1111,7 +1237,7 @@ Cross-Browser Compatibility
|
|
|
1111
1237
|
}
|
|
1112
1238
|
const start_require = (0, external_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
|
|
1113
1239
|
function registerStartCommand(program, telemetry) {
|
|
1114
|
-
program.command('start').arguments('[project-path|remote-url]').usage('start [project-path|remote-url] [options]').description(commandDescriptions.start).addHelpText('after', '\nAdditional
|
|
1240
|
+
program.command('start').arguments('[project-path|remote-url]').usage('start [project-path|remote-url] [options]').description(commandDescriptions.start).addHelpText('after', '\nAdditional options:\n --no-browser do not launch the browser (build still runs)\n --wait wait for ready contract and exit\n --wait-format pretty|json output for wait mode\n').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('--browser <chrome | chromium | edge | firefox | chromium-based | gecko-based | firefox-based>', 'specify a browser/engine to run. Defaults to `chromium`').option('--polyfill [boolean]', 'whether or not to apply the cross-browser polyfill. Defaults to `true`').option('--chromium-binary <path-to-binary>', 'specify a path to the Chromium binary. This option overrides the --browser setting. Defaults to the system default').option('--gecko-binary, --firefox-binary <path-to-binary>', 'specify a path to the Gecko binary. This option overrides the --browser setting. Defaults to the system default').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('--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('--source [url]', "[experimental] opens the provided URL in Chrome and prints the full, live HTML of the page after content scripts are injected").option('--watch-source [boolean]', '[experimental] re-print HTML on rebuilds or file changes', parseOptionalBoolean).option('--source-format <pretty|json|ndjson>', '[experimental] output format for source HTML (defaults to --log-format when present, otherwise JSON when --source is used)').option('--source-summary [boolean]', '[experimental] output a compact summary instead of full HTML', parseOptionalBoolean).option('--source-meta [boolean]', '[experimental] output page metadata (readyState, viewport, frames)', parseOptionalBoolean).option('--source-probe <selectors>', '[experimental] comma-separated CSS selectors to probe').option('--source-tree <off|root-only>', '[experimental] output a compact extension root tree').option('--source-console [boolean]', '[experimental] output console summary (best-effort)', parseOptionalBoolean).option('--source-dom [boolean]', '[experimental] output DOM snapshots and diffs (default: true when watch is enabled)', parseOptionalBoolean).option('--source-max-bytes <bytes>', '[experimental] limit HTML output size in bytes (0 disables truncation)').option('--source-redact <off|safe|strict>', '[experimental] redact sensitive content in HTML output (default: safe for JSON/NDJSON)').option('--source-include-shadow <off|open-only|all>', '[experimental] control Shadow DOM inclusion in HTML output (default: open-only)').option('--source-diff [boolean]', '[experimental] include diff metadata on watch updates (default: true when watch is enabled)', parseOptionalBoolean).option('--extensions <list>', 'comma-separated list of companion extensions or store URLs to load').option('--install [boolean]', '[experimental] 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('--wait-format <pretty|json>', 'output format for --wait results (default: pretty)').option('--author, --author-mode', '[experimental] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...startOptions }) {
|
|
1115
1241
|
const hasSourceInspectionFlags = void 0 !== startOptions.source || void 0 !== startOptions.watchSource || void 0 !== startOptions.sourceFormat || void 0 !== startOptions.sourceSummary || void 0 !== startOptions.sourceMeta || void 0 !== startOptions.sourceProbe || void 0 !== startOptions.sourceTree || void 0 !== startOptions.sourceConsole || void 0 !== startOptions.sourceDom || void 0 !== startOptions.sourceMaxBytes || void 0 !== startOptions.sourceRedact || void 0 !== startOptions.sourceIncludeShadow || void 0 !== startOptions.sourceDiff;
|
|
1116
1242
|
if (hasSourceInspectionFlags) {
|
|
1117
1243
|
console.error(sourceInspectionNotSupported('start'));
|
|
@@ -1131,6 +1257,29 @@ Cross-Browser Compatibility
|
|
|
1131
1257
|
validateVendorsOrExit(list, (invalid, supported)=>{
|
|
1132
1258
|
console.error(unsupportedBrowserFlag(invalid, supported));
|
|
1133
1259
|
});
|
|
1260
|
+
if (startOptions.wait) {
|
|
1261
|
+
const waitResult = await runWaitMode({
|
|
1262
|
+
command: 'start',
|
|
1263
|
+
pathOrRemoteUrl,
|
|
1264
|
+
browsers: list,
|
|
1265
|
+
waitTimeout: startOptions.waitTimeout,
|
|
1266
|
+
waitFormat: startOptions.waitFormat
|
|
1267
|
+
});
|
|
1268
|
+
if ('json' === waitResult.format) console.log(JSON.stringify({
|
|
1269
|
+
ok: true,
|
|
1270
|
+
mode: 'wait',
|
|
1271
|
+
command: 'start',
|
|
1272
|
+
browsers: waitResult.browsers,
|
|
1273
|
+
results: waitResult.results
|
|
1274
|
+
}));
|
|
1275
|
+
telemetry.track('cli_command_finish', {
|
|
1276
|
+
command: 'start',
|
|
1277
|
+
duration_ms: Date.now() - cmdStart,
|
|
1278
|
+
success: true,
|
|
1279
|
+
exit_code: 0
|
|
1280
|
+
});
|
|
1281
|
+
return;
|
|
1282
|
+
}
|
|
1134
1283
|
const normalizedSource = normalizeSourceOption(startOptions.source, startOptions.startingUrl);
|
|
1135
1284
|
if (normalizedSource) startOptions.source = normalizedSource;
|
|
1136
1285
|
const sourceEnabled = Boolean(startOptions.source || startOptions.watchSource);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type WaitFormat = 'pretty' | 'json';
|
|
2
|
+
export type WaitCommand = 'dev' | 'start';
|
|
3
|
+
export type ReadyContractPayload = {
|
|
4
|
+
status?: string;
|
|
5
|
+
message?: string;
|
|
6
|
+
errors?: string[];
|
|
7
|
+
code?: string;
|
|
8
|
+
command?: string;
|
|
9
|
+
browser?: string;
|
|
10
|
+
runId?: string;
|
|
11
|
+
startedAt?: string;
|
|
12
|
+
distPath?: string;
|
|
13
|
+
manifestPath?: string;
|
|
14
|
+
port?: number | null;
|
|
15
|
+
pid?: number;
|
|
16
|
+
ts?: string;
|
|
17
|
+
compiledAt?: string | null;
|
|
18
|
+
};
|
|
19
|
+
export type RunWaitModeOptions = {
|
|
20
|
+
command: WaitCommand;
|
|
21
|
+
pathOrRemoteUrl?: string;
|
|
22
|
+
browsers: string[];
|
|
23
|
+
waitTimeout?: string | number;
|
|
24
|
+
waitFormat?: string;
|
|
25
|
+
};
|
|
26
|
+
export type RunWaitModeResult = {
|
|
27
|
+
projectPath: string;
|
|
28
|
+
command: WaitCommand;
|
|
29
|
+
timeoutMs: number;
|
|
30
|
+
format: WaitFormat;
|
|
31
|
+
browsers: string[];
|
|
32
|
+
results: Array<ReadyContractPayload & {
|
|
33
|
+
browser: string;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
export declare function runWaitMode(options: RunWaitModeOptions): Promise<RunWaitModeResult>;
|
|
37
|
+
export declare function runDevWaitMode(options: Omit<RunWaitModeOptions, 'command'>): Promise<RunWaitModeResult>;
|
package/package.json
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"extension": "./bin/extension.cjs"
|
|
34
34
|
},
|
|
35
35
|
"name": "extension",
|
|
36
|
-
"version": "3.8.
|
|
36
|
+
"version": "3.8.13",
|
|
37
37
|
"description": "Create cross-browser extensions with no build configuration.",
|
|
38
38
|
"homepage": "https://extension.js.org/",
|
|
39
39
|
"bugs": {
|
|
@@ -90,9 +90,9 @@
|
|
|
90
90
|
"@types/chrome": "^0.1.33",
|
|
91
91
|
"@types/node": "^25.2.0",
|
|
92
92
|
"@types/webextension-polyfill": "0.12.4",
|
|
93
|
-
"extension-create": "3.8.
|
|
94
|
-
"extension-develop": "3.8.
|
|
95
|
-
"extension-install": "3.8.
|
|
93
|
+
"extension-create": "3.8.13",
|
|
94
|
+
"extension-develop": "3.8.13",
|
|
95
|
+
"extension-install": "3.8.13",
|
|
96
96
|
"commander": "^14.0.3",
|
|
97
97
|
"pintor": "0.3.0",
|
|
98
98
|
"semver": "^7.7.3",
|