extension 3.0.0-next.8 → 3.0.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/dist/cli.js CHANGED
@@ -1,6 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __webpack_require__ = {};
3
+ var __webpack_modules__ = {
4
+ "extension-develop": function(module) {
5
+ module.exports = import("extension-develop").then(function(module) {
6
+ return module;
7
+ });
8
+ }
9
+ };
10
+ var __webpack_module_cache__ = {};
11
+ function __webpack_require__(moduleId) {
12
+ var cachedModule = __webpack_module_cache__[moduleId];
13
+ if (void 0 !== cachedModule) return cachedModule.exports;
14
+ var module = __webpack_module_cache__[moduleId] = {
15
+ exports: {}
16
+ };
17
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
18
+ return module.exports;
19
+ }
4
20
  (()=>{
5
21
  __webpack_require__.n = (module)=>{
6
22
  var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
@@ -22,29 +38,68 @@ var __webpack_require__ = {};
22
38
  __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
23
39
  })();
24
40
  var __webpack_exports__ = {};
25
- const external_commander_namespaceObject = require("commander");
26
- var package_namespaceObject = JSON.parse('{"license":"MIT","repository":{"type":"git","url":"https://github.com/extension-js/extension.js","directory":"programs/cli"},"engines":{"node":">=18"},"exports":{".":{"types":"./dist/cli.d.ts","import":"./dist/cli.js","require":"./dist/cli.js"}},"main":"./dist/cli.js","types":"./dist/cli.d.ts","typesVersions":{"*":{"types":["./types/index.d.ts"],"types/*":["./types/*"]}},"files":["dist","types"],"bin":{"extension":"./dist/cli.js"},"name":"extension","version":"3.0.0-next.8","description":"Create cross-browser extensions with no build configuration.","homepage":"https://extension.js.org/","author":{"name":"Cezar Augusto","email":"boss@cezaraugusto.net","url":"https://cezaraugusto.com"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org","tag":"latest"},"scripts":{"prepare":"rslib build >/dev/null 2>&1 || true","postinstall":"rslib build >/dev/null 2>&1 || true","compile":"rslib build","watch":"rslib build --watch","test":"vitest run"},"keywords":["zero-config","build","develop","browser","extension","chrome extension","edge extension","firefox extension","safari extension","web","react","typescript","webextension","browser-extension","chrome-extension","firefox-addon","edge-extension","safari-web-extension","manifest-v3","mv3","cross-browser","content-script","background-script","devtools","create-extension","scaffold","starter-template","boilerplate","cli"],"dependencies":{"commander":"^12.1.0","extension-create":"^2.2.0","pintor":"0.3.0","semver":"^7.6.3","update-check":"^1.5.4"},"devDependencies":{"@rslib/core":"^0.6.9","@types/chrome":"^0.0.287","@types/node":"^22.10.1","@types/react":"^19.0.1","@types/react-dom":"^19.0.1","@types/webextension-polyfill":"0.12.3","@types/mock-fs":"^4.13.4","@types/semver":"^7.5.8","mock-fs":"^5.4.1","webextension-polyfill":"^0.12.0","tsconfig":"*","typescript":"5.7.2","vitest":"^3.2.4"}}');
27
- const external_update_check_namespaceObject = require("update-check");
28
- var external_update_check_default = /*#__PURE__*/ __webpack_require__.n(external_update_check_namespaceObject);
29
- const external_pintor_namespaceObject = require("pintor");
30
- var external_pintor_default = /*#__PURE__*/ __webpack_require__.n(external_pintor_namespaceObject);
31
- function getLoggingPrefix(type) {
32
- if ('true' === process.env.EXTENSION_AUTHOR_MODE) return external_pintor_default().brightMagenta('error' === type ? 'ERROR' : "\u25BA\u25BA\u25BA");
33
- if ('error' === type) return external_pintor_default().red('ERROR');
34
- if ('warn' === type) return external_pintor_default().brightYellow("\u25BA\u25BA\u25BA");
35
- if ('info' === type) return external_pintor_default().gray("\u25BA\u25BA\u25BA");
36
- return external_pintor_default().green("\u25BA\u25BA\u25BA");
37
- }
38
- const code = (text)=>external_pintor_default().blue(text);
39
- const arg = (text)=>external_pintor_default().gray(text);
40
- function updateFailed(err) {
41
- return `${getLoggingPrefix('error')} Failed to check for updates.\n${external_pintor_default().red(String((null == err ? void 0 : err.message) || err))}`;
42
- }
43
- function checkUpdates(packageJson, update) {
44
- return `${getLoggingPrefix('info')} \u{1F9E9} ${external_pintor_default().blue('Extension.js')} update available.\n\nYou are currently using version ${external_pintor_default().red(String(packageJson.version))}. Latest stable is ${external_pintor_default().green(String(update.latest))}.\nPlease update to enjoy new features and improvements.`;
45
- }
46
- function programUserHelp() {
47
- return `\n${getLoggingPrefix('info')} ${external_pintor_default().underline('Help center for the Extension.js program')}
41
+ (()=>{
42
+ const external_commander_namespaceObject = require("commander");
43
+ var package_namespaceObject = JSON.parse('{"license":"MIT","repository":{"type":"git","url":"git+https://github.com/extension-js/extension.js.git","directory":"programs/cli"},"engines":{"node":">=18"},"exports":{".":{"types":"./dist/cli.d.ts","import":"./dist/cli.js","require":"./dist/cli.js"}},"main":"./dist/cli.js","types":"./dist/cli.d.ts","typesVersions":{"*":{"types":["./types/index.d.ts"],"types/*":["./types/*"]}},"files":["dist","types"],"bin":{"extension":"./dist/cli.js"},"name":"extension","version":"3.0.0","description":"Create cross-browser extensions with no build configuration.","homepage":"https://extension.js.org/","bugs":{"url":"https://github.com/extension-js/extension.js/issues"},"author":{"name":"Cezar Augusto","email":"boss@cezaraugusto.net","url":"https://cezaraugusto.com"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"scripts":{"prepublishOnly":"pnpm run compile","compile":"rslib build","watch":"rslib build --watch","test":"vitest run"},"keywords":["zero-config","build","develop","browser","extension","chrome extension","edge extension","firefox extension","safari extension","web","react","typescript","webextension","browser-extension","chrome-extension","firefox-addon","edge-extension","safari-web-extension","manifest-v3","mv3","cross-browser","content-script","background-script","devtools","create-extension","scaffold","starter-template","boilerplate","cli"],"dependencies":{"extension-develop":"^3.0.0","commander":"^12.1.0","extension-create":"^2.2.0","pintor":"0.3.0","semver":"^7.6.3","update-check":"^1.5.4"},"devDependencies":{"@rslib/core":"^0.6.9","@types/chrome":"^0.0.287","@types/node":"^22.10.1","@types/react":"^19.0.1","@types/react-dom":"^19.0.1","@types/webextension-polyfill":"0.12.3","@types/mock-fs":"^4.13.4","@types/semver":"^7.5.8","mock-fs":"^5.4.1","webextension-polyfill":"^0.12.0","tsconfig":"*","typescript":"5.7.2","vitest":"^3.2.4"}}');
44
+ const external_update_check_namespaceObject = require("update-check");
45
+ var external_update_check_default = /*#__PURE__*/ __webpack_require__.n(external_update_check_namespaceObject);
46
+ const external_pintor_namespaceObject = require("pintor");
47
+ var external_pintor_default = /*#__PURE__*/ __webpack_require__.n(external_pintor_namespaceObject);
48
+ function getLoggingPrefix(type) {
49
+ const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
50
+ if (isAuthor) {
51
+ const base = 'error' === type ? 'ERROR Author says' : "\u25BA\u25BA\u25BA Author says";
52
+ return external_pintor_default().brightMagenta(base);
53
+ }
54
+ if ('error' === type) return external_pintor_default().red('ERROR');
55
+ if ('warn' === type) return external_pintor_default().brightYellow("\u25BA\u25BA\u25BA");
56
+ if ('info' === type) return external_pintor_default().gray("\u25BA\u25BA\u25BA");
57
+ return external_pintor_default().green("\u25BA\u25BA\u25BA");
58
+ }
59
+ const code = (text)=>external_pintor_default().blue(text);
60
+ const arg = (text)=>external_pintor_default().gray(text);
61
+ const fmt = {
62
+ heading: (title)=>external_pintor_default().underline(external_pintor_default().blue(title)),
63
+ label: (k)=>external_pintor_default().gray(k.toUpperCase()),
64
+ val: (v)=>external_pintor_default().underline(v),
65
+ code: (v)=>external_pintor_default().blue(v),
66
+ bullet: (s)=>`- ${s}`,
67
+ block (title, rows) {
68
+ const head = fmt.heading(title);
69
+ const body = rows.map(([k, v])=>`${fmt.label(k)} ${v}`).join('\n');
70
+ return `${head}\n${body}`;
71
+ },
72
+ truncate (input, max = 800) {
73
+ const s = (()=>{
74
+ try {
75
+ return 'string' == typeof input ? input : JSON.stringify(input);
76
+ } catch {
77
+ return String(input);
78
+ }
79
+ })();
80
+ return s.length > max ? s.slice(0, max) + "\u2026" : s;
81
+ }
82
+ };
83
+ const commandDescriptions = {
84
+ create: 'Creates a new extension from a template (React, TypeScript, Vue, Svelte, etc.)',
85
+ dev: 'Starts the development server with hot reloading',
86
+ start: 'Builds and starts the extension in production mode',
87
+ preview: 'Previews the extension in production mode without building',
88
+ build: 'Builds the extension for packaging/distribution',
89
+ cleanup: 'Cleans up orphaned instances and frees unused ports'
90
+ };
91
+ function unhandledError(err) {
92
+ const message = err instanceof Error ? err.stack || err.message : 'string' == typeof err ? err : fmt.truncate(err);
93
+ return `${getLoggingPrefix('error')} ${external_pintor_default().red(String(message || 'Unknown error'))}`;
94
+ }
95
+ function updateFailed(err) {
96
+ return `${getLoggingPrefix('error')} Failed to check for updates.\n${external_pintor_default().red(String((null == err ? void 0 : err.message) || err))}`;
97
+ }
98
+ function checkUpdates(packageJson, update) {
99
+ return `${getLoggingPrefix('info')} \u{1F9E9} ${external_pintor_default().blue('Extension.js')} update available.\n\nYou are currently using version ${external_pintor_default().red(String(packageJson.version))}. Latest stable is ${external_pintor_default().green(String(update.latest))}.\nUpdate to the latest stable to get fixes and new features.`;
100
+ }
101
+ function programUserHelp() {
102
+ return `\n${getLoggingPrefix('info')} ${external_pintor_default().underline('Help center for the Extension.js program')}
48
103
 
49
104
  Usage: extension [command] [options]
50
105
 
@@ -56,22 +111,22 @@ Example
56
111
 
57
112
  Available Commands
58
113
  - ${code('extension create ' + arg('<project-name|project-path>'))}
59
- Creates a new extension from a template (React, TypeScript, Vue, Svelte, etc.)
114
+ ${commandDescriptions.create}
60
115
 
61
116
  - ${code('extension dev ' + arg('[project-path|remote-url]'))}
62
- Starts a development server with hot reloading
117
+ ${commandDescriptions.dev}
63
118
 
64
119
  - ${code('extension start ' + arg('[project-path|remote-url]'))}
65
- Builds and starts the extension in production mode
120
+ ${commandDescriptions.start}
66
121
 
67
122
  - ${code('extension preview ' + arg('[project-path|remote-url]'))}
68
- Previews the extension in production mode without building
123
+ ${commandDescriptions.preview}
69
124
 
70
125
  - ${code('extension build ' + arg('[project-path|remote-url]'))}
71
- Builds the extension for packaging/distribution
126
+ ${commandDescriptions.build}
72
127
 
73
128
  - ${code('extension cleanup')}
74
- Cleans up orphaned instances and frees unused ports
129
+ ${commandDescriptions.cleanup}
75
130
 
76
131
  Common Options
77
132
  - ${code('--browser')} ${arg('<chrome|edge|firefox|chromium|chromium-based|gecko-based|firefox-based>')} Target browser/engine (default: chrome)
@@ -122,12 +177,12 @@ AI Assistants
122
177
 
123
178
  Report issues
124
179
  - ${external_pintor_default().underline('https://github.com/cezaraugusto/extension/issues/new')}`;
125
- }
126
- function unsupportedBrowserFlag(value, supported) {
127
- return `${getLoggingPrefix('error')} Unsupported --browser value: ${value}. Supported: ${supported.join(', ')}.`;
128
- }
129
- function programAIHelp() {
130
- return `\n${getLoggingPrefix('info')} ${external_pintor_default().gray('Development tips for extension developers and AI assistants')}
180
+ }
181
+ function unsupportedBrowserFlag(value, supported) {
182
+ return `${getLoggingPrefix('error')} Unsupported --browser value: ${value}. Supported: ${supported.join(', ')}.`;
183
+ }
184
+ function programAIHelp() {
185
+ return `\n${getLoggingPrefix('info')} ${external_pintor_default().gray('Development tips for extension developers and AI assistants')}
131
186
 
132
187
  Browser-Specific Configuration
133
188
  - Use browser prefixes in manifest.json for browser-specific fields:
@@ -144,7 +199,7 @@ Centralized Logger (for AI & CI)
144
199
  - ${code('--no-log-color')} ${arg(' ')} Disable ANSI colors (pretty)
145
200
  - ${code('--log-url')} ${arg('<substring|/regex/>')} Filter by URL
146
201
  - ${code('--log-tab')} ${arg('<id>')} Filter by tabId
147
- - Good CI pattern: ${code('EXTENSION_ENV=development EXTENSION_AUTO_EXIT_MS=6000 extension dev ./ext --logs=info --log-format=json')}
202
+ - Good CI pattern: ${code('EXTENSION_AUTHOR_MODE=development EXTENSION_AUTO_EXIT_MS=6000 extension dev ./ext --logs=info --log-format=json')}
148
203
 
149
204
  Special Folders for Entrypoints
150
205
  - Use special folders to handle entrypoints and assets not declared in manifest.json:
@@ -237,7 +292,7 @@ Source Inspection & Real-Time Monitoring
237
292
  - Example: ${code('extension dev --source=' + arg('https://example.com'))}
238
293
 
239
294
  Non-Destructive Testing in CI
240
- - Prefer ${code('EXTENSION_ENV=development')} to copy local templates and avoid network.
295
+ - Prefer ${code('EXTENSION_AUTHOR_MODE=development')} to copy local templates and avoid network.
241
296
  - Reuse Playwright's Chromium via ${code('--chromium-binary')} path when available.
242
297
  - Set ${code(arg('EXTENSION_AUTO_EXIT_MS'))} and ${code(arg('EXTENSION_FORCE_KILL_MS'))} for non-interactive dev sessions.
243
298
 
@@ -260,696 +315,615 @@ Cross-Browser Compatibility
260
315
  - Use ${code('--polyfill')} flag to enable webextension-polyfill
261
316
  - Automatically handles browser API differences
262
317
  - Supports Chrome, Edge, Firefox with single codebase`;
263
- }
264
- const external_semver_namespaceObject = require("semver");
265
- function isStableVersion(version) {
266
- const v = external_semver_namespaceObject.parse(version);
267
- return Boolean(v && 0 === v.prerelease.length);
268
- }
269
- async function check_updates_checkUpdates(packageJson) {
270
- let update = null;
271
- try {
272
- update = await external_update_check_default()(packageJson);
273
- } catch (err) {
274
- if ('development' === process.env.EXTENSION_ENV) console.error(updateFailed(err));
275
318
  }
276
- if (update && isStableVersion(update.latest)) console.log(checkUpdates(packageJson, update));
277
- }
278
- const external_fs_namespaceObject = require("fs");
279
- var external_fs_default = /*#__PURE__*/ __webpack_require__.n(external_fs_namespaceObject);
280
- const external_path_namespaceObject = require("path");
281
- var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
282
- const external_node_os_namespaceObject = require("node:os");
283
- var external_node_os_default = /*#__PURE__*/ __webpack_require__.n(external_node_os_namespaceObject);
284
- const external_node_fs_namespaceObject = require("node:fs");
285
- var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
286
- const external_node_path_namespaceObject = require("node:path");
287
- var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
288
- const external_node_crypto_namespaceObject = require("node:crypto");
289
- var external_node_crypto_default = /*#__PURE__*/ __webpack_require__.n(external_node_crypto_namespaceObject);
290
- function _define_property(obj, key, value) {
291
- if (key in obj) Object.defineProperty(obj, key, {
292
- value: value,
293
- enumerable: true,
294
- configurable: true,
295
- writable: true
296
- });
297
- else obj[key] = value;
298
- return obj;
299
- }
300
- function isCI() {
301
- const v = process.env;
302
- return Boolean(v.CI || v.GITHUB_ACTIONS || v.GITLAB_CI || v.BUILDKITE || v.CIRCLECI || v.TRAVIS);
303
- }
304
- function configDir() {
305
- const xdg = process.env.XDG_CONFIG_HOME;
306
- if (xdg) return external_node_path_default().join(xdg, 'extensionjs');
307
- if ('win32' === process.platform && process.env.APPDATA) return external_node_path_default().join(process.env.APPDATA, 'extensionjs');
308
- return external_node_path_default().join(external_node_os_default().homedir(), '.config', 'extensionjs');
309
- }
310
- function ensureDir(p) {
311
- if (external_node_fs_default().existsSync(p)) return;
312
- external_node_fs_default().mkdirSync(p, {
313
- recursive: true
314
- });
315
- }
316
- function loadOrCreateId(file) {
317
- if (external_node_fs_default().existsSync(file)) return external_node_fs_default().readFileSync(file, 'utf8').trim();
318
- const id = external_node_crypto_default().randomUUID();
319
- ensureDir(external_node_path_default().dirname(file));
320
- external_node_fs_default().writeFileSync(file, id, 'utf8');
321
- return id;
322
- }
323
- function auditFilePath() {
324
- const dir = external_node_path_default().join(configDir(), 'telemetry');
325
- ensureDir(dir);
326
- return external_node_path_default().join(dir, 'events.jsonl');
327
- }
328
- const DEFAULT_FLUSH_AT = Number(process.env.EXTENSION_TELEMETRY_FLUSH_AT || 10);
329
- const DEFAULT_FLUSH_INTERVAL = Number(process.env.EXTENSION_TELEMETRY_FLUSH_INTERVAL || 2000);
330
- const DEFAULT_TIMEOUT_MS = Number(process.env.EXTENSION_TELEMETRY_TIMEOUT_MS || 200);
331
- class Telemetry {
332
- track(event, props = {}) {
333
- if (this.disabled) return;
334
- const payload = {
335
- event,
336
- properties: {
337
- ...this.common,
338
- ...props,
339
- $ip: null
340
- },
341
- distinct_id: this.anonId
342
- };
343
- external_node_fs_default().appendFileSync(auditFilePath(), JSON.stringify(payload) + '\n');
344
- if (this.debug) console.error('[telemetry]', JSON.stringify(payload));
345
- if (!this.apiKey || !this.host) return;
346
- this.buffer.push(payload);
347
- if (this.buffer.length >= DEFAULT_FLUSH_AT) return void this.flush();
348
- if (!this.timer) this.timer = setTimeout(()=>{
349
- this.timer = null;
350
- this.flush();
351
- }, DEFAULT_FLUSH_INTERVAL);
319
+ const external_semver_namespaceObject = require("semver");
320
+ function isStableVersion(version) {
321
+ const v = external_semver_namespaceObject.parse(version);
322
+ return Boolean(v && 0 === v.prerelease.length);
352
323
  }
353
- async flush() {
354
- if (this.disabled || !this.apiKey || !this.host) return;
355
- if (0 === this.buffer.length) return;
356
- const batch = this.buffer.splice(0, this.buffer.length);
324
+ async function check_updates_checkUpdates(packageJson) {
325
+ let update = null;
357
326
  try {
358
- const ac = new AbortController();
359
- const t = setTimeout(()=>ac.abort(), DEFAULT_TIMEOUT_MS);
360
- const url = new URL('/capture/', this.host);
361
- await fetch(url.toString(), {
362
- method: 'POST',
363
- headers: {
364
- 'content-type': 'application/json'
365
- },
366
- body: JSON.stringify({
367
- api_key: this.apiKey,
368
- batch: batch.map((e)=>({
369
- event: e.event,
370
- properties: e.properties,
371
- distinct_id: e.distinct_id
372
- }))
373
- }),
374
- signal: ac.signal,
375
- keepalive: true
376
- }).catch(()=>{});
377
- clearTimeout(t);
378
- } catch {}
327
+ update = await external_update_check_default()(packageJson);
328
+ } catch (err) {
329
+ if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.error(updateFailed(err));
330
+ }
331
+ if (update && isStableVersion(update.latest)) console.log(checkUpdates(packageJson, update));
379
332
  }
380
- shutdown() {}
381
- constructor(init){
382
- _define_property(this, "anonId", void 0);
383
- _define_property(this, "common", void 0);
384
- _define_property(this, "debug", void 0);
385
- _define_property(this, "disabled", void 0);
386
- _define_property(this, "apiKey", void 0);
387
- _define_property(this, "host", void 0);
388
- _define_property(this, "buffer", []);
389
- _define_property(this, "timer", null);
390
- this.debug = '1' === process.env.EXTENSION_TELEMETRY_DEBUG;
391
- this.disabled = Boolean(init.disabled);
392
- this.anonId = 'disabled';
393
- if (!this.disabled) {
394
- const idFile = external_node_path_default().join(configDir(), 'telemetry', 'anonymous-id');
395
- this.anonId = loadOrCreateId(idFile);
333
+ const external_fs_namespaceObject = require("fs");
334
+ var external_fs_default = /*#__PURE__*/ __webpack_require__.n(external_fs_namespaceObject);
335
+ const external_path_namespaceObject = require("path");
336
+ var external_path_default = /*#__PURE__*/ __webpack_require__.n(external_path_namespaceObject);
337
+ const external_node_os_namespaceObject = require("node:os");
338
+ var external_node_os_default = /*#__PURE__*/ __webpack_require__.n(external_node_os_namespaceObject);
339
+ const external_node_fs_namespaceObject = require("node:fs");
340
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
341
+ const external_node_path_namespaceObject = require("node:path");
342
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
343
+ const external_node_crypto_namespaceObject = require("node:crypto");
344
+ var external_node_crypto_default = /*#__PURE__*/ __webpack_require__.n(external_node_crypto_namespaceObject);
345
+ function _define_property(obj, key, value) {
346
+ if (key in obj) Object.defineProperty(obj, key, {
347
+ value: value,
348
+ enumerable: true,
349
+ configurable: true,
350
+ writable: true
351
+ });
352
+ else obj[key] = value;
353
+ return obj;
354
+ }
355
+ function isCI() {
356
+ const v = process.env;
357
+ return Boolean(v.CI || v.GITHUB_ACTIONS || v.GITLAB_CI || v.BUILDKITE || v.CIRCLECI || v.TRAVIS);
358
+ }
359
+ function configDir() {
360
+ const xdg = process.env.XDG_CONFIG_HOME;
361
+ if (xdg) return external_node_path_default().join(xdg, 'extensionjs');
362
+ if ('win32' === process.platform && process.env.APPDATA) return external_node_path_default().join(process.env.APPDATA, 'extensionjs');
363
+ return external_node_path_default().join(external_node_os_default().homedir(), '.config', 'extensionjs');
364
+ }
365
+ function ensureDir(p) {
366
+ if (external_node_fs_default().existsSync(p)) return;
367
+ external_node_fs_default().mkdirSync(p, {
368
+ recursive: true
369
+ });
370
+ }
371
+ function loadOrCreateId(file) {
372
+ if (external_node_fs_default().existsSync(file)) return external_node_fs_default().readFileSync(file, 'utf8').trim();
373
+ const id = external_node_crypto_default().randomUUID();
374
+ ensureDir(external_node_path_default().dirname(file));
375
+ external_node_fs_default().writeFileSync(file, id, 'utf8');
376
+ return id;
377
+ }
378
+ function auditFilePath() {
379
+ const dir = external_node_path_default().join(configDir(), 'telemetry');
380
+ ensureDir(dir);
381
+ return external_node_path_default().join(dir, 'events.jsonl');
382
+ }
383
+ const DEFAULT_FLUSH_AT = Number(process.env.EXTENSION_TELEMETRY_FLUSH_AT || 10);
384
+ const DEFAULT_FLUSH_INTERVAL = Number(process.env.EXTENSION_TELEMETRY_FLUSH_INTERVAL || 2000);
385
+ const DEFAULT_TIMEOUT_MS = Number(process.env.EXTENSION_TELEMETRY_TIMEOUT_MS || 200);
386
+ class Telemetry {
387
+ track(event, props = {}) {
388
+ if (this.disabled) return;
389
+ const payload = {
390
+ event,
391
+ properties: {
392
+ ...this.common,
393
+ ...props,
394
+ $ip: null
395
+ },
396
+ distinct_id: this.anonId
397
+ };
398
+ external_node_fs_default().appendFileSync(auditFilePath(), JSON.stringify(payload) + '\n');
399
+ if (this.debug) console.error('[telemetry]', JSON.stringify(payload));
400
+ if (!this.apiKey || !this.host) return;
401
+ this.buffer.push(payload);
402
+ if (this.buffer.length >= DEFAULT_FLUSH_AT) return void this.flush();
403
+ if (!this.timer) this.timer = setTimeout(()=>{
404
+ this.timer = null;
405
+ this.flush();
406
+ }, DEFAULT_FLUSH_INTERVAL);
407
+ }
408
+ async flush() {
409
+ if (this.disabled || !this.apiKey || !this.host) return;
410
+ if (0 === this.buffer.length) return;
411
+ const batch = this.buffer.splice(0, this.buffer.length);
412
+ try {
413
+ const ac = new AbortController();
414
+ const t = setTimeout(()=>ac.abort(), DEFAULT_TIMEOUT_MS);
415
+ const url = new URL('/capture/', this.host);
416
+ await fetch(url.toString(), {
417
+ method: 'POST',
418
+ headers: {
419
+ 'content-type': 'application/json'
420
+ },
421
+ body: JSON.stringify({
422
+ api_key: this.apiKey,
423
+ batch: batch.map((e)=>({
424
+ event: e.event,
425
+ properties: e.properties,
426
+ distinct_id: e.distinct_id
427
+ }))
428
+ }),
429
+ signal: ac.signal,
430
+ keepalive: true
431
+ }).catch(()=>{});
432
+ clearTimeout(t);
433
+ } catch {}
396
434
  }
397
- this.common = {
398
- app: init.app,
399
- version: init.version,
400
- os: process.platform,
401
- arch: process.arch,
402
- node: process.versions.node,
403
- is_ci: isCI(),
404
- schema_version: 1
435
+ shutdown() {}
436
+ constructor(init){
437
+ _define_property(this, "anonId", void 0);
438
+ _define_property(this, "common", void 0);
439
+ _define_property(this, "debug", void 0);
440
+ _define_property(this, "disabled", void 0);
441
+ _define_property(this, "apiKey", void 0);
442
+ _define_property(this, "host", void 0);
443
+ _define_property(this, "buffer", []);
444
+ _define_property(this, "timer", null);
445
+ this.debug = '1' === process.env.EXTENSION_TELEMETRY_DEBUG;
446
+ this.disabled = Boolean(init.disabled);
447
+ this.anonId = 'disabled';
448
+ if (!this.disabled) {
449
+ const idFile = external_node_path_default().join(configDir(), 'telemetry', 'anonymous-id');
450
+ this.anonId = loadOrCreateId(idFile);
451
+ }
452
+ this.common = {
453
+ app: init.app,
454
+ version: init.version,
455
+ os: process.platform,
456
+ arch: process.arch,
457
+ node: process.versions.node,
458
+ is_ci: isCI(),
459
+ schema_version: 1
460
+ };
461
+ this.apiKey = init.apiKey || process.env.EXTENSION_PUBLIC_POSTHOG_KEY;
462
+ this.host = init.host || process.env.EXTENSION_PUBLIC_POSTHOG_HOST;
463
+ if (!this.disabled) {
464
+ const consentPath = external_node_path_default().join(configDir(), 'telemetry', 'consent');
465
+ if (!external_node_fs_default().existsSync(consentPath)) {
466
+ external_node_fs_default().writeFileSync(consentPath, 'ok', 'utf8');
467
+ this.track('cli_telemetry_consent', {
468
+ value: 'implicit_opt_in'
469
+ });
470
+ console.log(`${external_pintor_default().gray("\u25BA\u25BA\u25BA system")} [extension] anonymous telemetry helps us improve. Pass --no-telemetry to opt out. Read more in TELEMETRY.md.`);
471
+ }
472
+ }
473
+ }
474
+ }
475
+ function summarizeManifest(manifest) {
476
+ var _manifest_action;
477
+ const mv = (null == manifest ? void 0 : manifest.manifest_version) === 2 ? 2 : 3;
478
+ const permissions = Array.isArray(null == manifest ? void 0 : manifest.permissions) ? manifest.permissions : [];
479
+ const optionalPermissions = Array.isArray(null == manifest ? void 0 : manifest.optional_permissions) ? manifest.optional_permissions : [];
480
+ const hostPermissions = Array.isArray(null == manifest ? void 0 : manifest.host_permissions) ? manifest.host_permissions : [];
481
+ const usesAllUrls = [
482
+ ...permissions,
483
+ ...hostPermissions
484
+ ].includes('<all_urls>');
485
+ const usesDeclarativeNetRequest = permissions.includes('declarativeNetRequest') || permissions.includes('declarativeNetRequestWithHostAccess');
486
+ const background = null == manifest ? void 0 : manifest.background;
487
+ let backgroundType = 'none';
488
+ if (3 === mv && (null == background ? void 0 : background.service_worker)) backgroundType = 'service_worker';
489
+ else if (2 === mv && (Array.isArray(null == background ? void 0 : background.scripts) && background.scripts.length > 0 || (null == background ? void 0 : background.page))) backgroundType = 'event_page';
490
+ const contentScriptsCount = Array.isArray(null == manifest ? void 0 : manifest.content_scripts) ? manifest.content_scripts.length : 0;
491
+ const hasDevtoolsPage = Boolean(null == manifest ? void 0 : manifest.devtools_page);
492
+ const hasActionPopup = Boolean(null == manifest ? void 0 : null == (_manifest_action = manifest.action) ? void 0 : _manifest_action.default_popup);
493
+ return {
494
+ mv,
495
+ permissions_count: permissions.length,
496
+ optional_permissions_count: optionalPermissions.length,
497
+ host_permissions_count: hostPermissions.length,
498
+ uses_all_urls: usesAllUrls,
499
+ uses_declarative_net_request: usesDeclarativeNetRequest,
500
+ background_type: backgroundType,
501
+ content_scripts_count: contentScriptsCount,
502
+ has_devtools_page: hasDevtoolsPage,
503
+ has_action_popup: hasActionPopup
405
504
  };
406
- this.apiKey = init.apiKey || process.env.EXTENSION_PUBLIC_POSTHOG_KEY;
407
- this.host = init.host || process.env.EXTENSION_PUBLIC_POSTHOG_HOST;
408
- if (!this.disabled) {
409
- const consentPath = external_node_path_default().join(configDir(), 'telemetry', 'consent');
410
- if (!external_node_fs_default().existsSync(consentPath)) {
411
- external_node_fs_default().writeFileSync(consentPath, 'ok', 'utf8');
412
- this.track('cli_telemetry_consent', {
413
- value: 'implicit_opt_in'
505
+ }
506
+ function isTelemetryDisabledFromArgs(argv) {
507
+ return argv.includes('--no-telemetry');
508
+ }
509
+ const telemetryDisabled = isTelemetryDisabledFromArgs(process.argv);
510
+ function findManifestJson(projectRoot) {
511
+ const stack = [
512
+ projectRoot
513
+ ];
514
+ while(stack.length > 0){
515
+ const dir = stack.pop();
516
+ if (!dir) continue;
517
+ let entries;
518
+ try {
519
+ entries = external_fs_default().readdirSync(dir, {
520
+ withFileTypes: true
414
521
  });
415
- console.log('[extension] anonymous telemetry helps us improve. Pass --no-telemetry to opt out. Read more in TELEMETRY.md.');
522
+ } catch {
523
+ continue;
524
+ }
525
+ for (const entry of entries){
526
+ if (entry.isFile() && 'manifest.json' === entry.name) return external_path_default().join(dir, entry.name);
527
+ if (entry.isDirectory() && !entry.name.startsWith('.') && 'node_modules' !== entry.name && 'dist' !== entry.name) stack.push(external_path_default().join(dir, entry.name));
416
528
  }
417
529
  }
530
+ return null;
418
531
  }
419
- }
420
- function summarizeManifest(manifest) {
421
- var _manifest_action;
422
- const mv = (null == manifest ? void 0 : manifest.manifest_version) === 2 ? 2 : 3;
423
- const permissions = Array.isArray(null == manifest ? void 0 : manifest.permissions) ? manifest.permissions : [];
424
- const optionalPermissions = Array.isArray(null == manifest ? void 0 : manifest.optional_permissions) ? manifest.optional_permissions : [];
425
- const hostPermissions = Array.isArray(null == manifest ? void 0 : manifest.host_permissions) ? manifest.host_permissions : [];
426
- const usesAllUrls = [
427
- ...permissions,
428
- ...hostPermissions
429
- ].includes('<all_urls>');
430
- const usesDeclarativeNetRequest = permissions.includes('declarativeNetRequest') || permissions.includes('declarativeNetRequestWithHostAccess');
431
- const background = null == manifest ? void 0 : manifest.background;
432
- let backgroundType = 'none';
433
- if (3 === mv && (null == background ? void 0 : background.service_worker)) backgroundType = 'service_worker';
434
- else if (2 === mv && (Array.isArray(null == background ? void 0 : background.scripts) && background.scripts.length > 0 || (null == background ? void 0 : background.page))) backgroundType = 'event_page';
435
- const contentScriptsCount = Array.isArray(null == manifest ? void 0 : manifest.content_scripts) ? manifest.content_scripts.length : 0;
436
- const hasDevtoolsPage = Boolean(null == manifest ? void 0 : manifest.devtools_page);
437
- const hasActionPopup = Boolean(null == manifest ? void 0 : null == (_manifest_action = manifest.action) ? void 0 : _manifest_action.default_popup);
438
- return {
439
- mv,
440
- permissions_count: permissions.length,
441
- optional_permissions_count: optionalPermissions.length,
442
- host_permissions_count: hostPermissions.length,
443
- uses_all_urls: usesAllUrls,
444
- uses_declarative_net_request: usesDeclarativeNetRequest,
445
- background_type: backgroundType,
446
- content_scripts_count: contentScriptsCount,
447
- has_devtools_page: hasDevtoolsPage,
448
- has_action_popup: hasActionPopup
449
- };
450
- }
451
- function isTelemetryDisabledFromArgs(argv) {
452
- return argv.includes('--no-telemetry');
453
- }
454
- const telemetryDisabled = isTelemetryDisabledFromArgs(process.argv);
455
- const telemetry_cli_telemetry = new Telemetry({
456
- app: 'extension',
457
- version: package_namespaceObject.version,
458
- disabled: telemetryDisabled
459
- });
460
- if (!telemetryDisabled) {
461
- const startedAt = Date.now();
462
- const known = new Set([
463
- 'create',
464
- 'dev',
465
- 'start',
466
- 'preview',
467
- 'build',
468
- 'cleanup'
469
- ]);
470
- const invoked = process.argv.slice(2).find((a)=>known.has(a)) || 'unknown';
471
- telemetry_cli_telemetry.track('cli_boot', {
472
- command_guess: invoked
532
+ const telemetry_cli_telemetry = new Telemetry({
533
+ app: 'extension',
534
+ version: package_namespaceObject.version,
535
+ disabled: telemetryDisabled
473
536
  });
474
- const cwd = process.cwd();
475
- const manifestPath = external_path_default().join(cwd, 'manifest.json');
476
- if (external_fs_default().existsSync(manifestPath)) {
477
- const raw = external_fs_default().readFileSync(manifestPath, 'utf8');
478
- const json = JSON.parse(raw);
479
- const summary = summarizeManifest(json);
480
- telemetry_cli_telemetry.track('manifest_summary', summary);
481
- }
482
- process.on('beforeExit', async function() {
483
- telemetry_cli_telemetry.track('cli_shutdown', {
484
- command_guess: invoked,
485
- duration_ms: Date.now() - startedAt,
486
- exit_code: process.exitCode ?? 0
537
+ if (!telemetryDisabled) {
538
+ const startedAt = Date.now();
539
+ const known = new Set([
540
+ 'create',
541
+ 'dev',
542
+ 'start',
543
+ 'preview',
544
+ 'build',
545
+ 'cleanup'
546
+ ]);
547
+ const invoked = process.argv.slice(2).find((a)=>known.has(a)) || 'unknown';
548
+ telemetry_cli_telemetry.track('cli_boot', {
549
+ command_guess: invoked
487
550
  });
488
- await telemetry_cli_telemetry.flush();
489
- });
490
- process.on('uncaughtException', function(err) {
491
- telemetry_cli_telemetry.track('cli_error', {
492
- command_guess: invoked,
493
- error_name: String((null == err ? void 0 : err.name) || 'Error').slice(0, 64)
551
+ const manifestPath = findManifestJson(process.cwd());
552
+ if (manifestPath) {
553
+ const raw = external_fs_default().readFileSync(manifestPath, 'utf8');
554
+ const json = JSON.parse(raw);
555
+ const summary = summarizeManifest(json);
556
+ telemetry_cli_telemetry.track('manifest_summary', summary);
557
+ }
558
+ process.on('beforeExit', async function() {
559
+ telemetry_cli_telemetry.track('cli_shutdown', {
560
+ command_guess: invoked,
561
+ duration_ms: Date.now() - startedAt,
562
+ exit_code: process.exitCode ?? 0
563
+ });
564
+ await telemetry_cli_telemetry.flush();
494
565
  });
495
- });
496
- process.on('unhandledRejection', function(reason) {
497
- telemetry_cli_telemetry.track('cli_error', {
498
- command_guess: invoked,
499
- error_name: String((null == reason ? void 0 : reason.name) || 'PromiseRejection').slice(0, 64)
566
+ process.on('uncaughtException', function(err) {
567
+ telemetry_cli_telemetry.track('cli_error', {
568
+ command_guess: invoked,
569
+ error_name: String((null == err ? void 0 : err.name) || 'Error').slice(0, 64)
570
+ });
500
571
  });
501
- });
502
- }
503
- const external_extension_create_namespaceObject = require("extension-create");
504
- const external_node_child_process_namespaceObject = require("node:child_process");
505
- const external_node_url_namespaceObject = require("node:url");
506
- function parseOptionalBoolean(value) {
507
- if (void 0 === value) return true;
508
- const normalized = String(value).trim().toLowerCase();
509
- return ![
510
- 'false',
511
- '0',
512
- 'no',
513
- 'off'
514
- ].includes(normalized);
515
- }
516
- async function requireOrDlx(moduleName, versionHint) {
517
- try {
518
- return await import(moduleName);
519
- } catch {}
520
- const spec = versionHint ? `${moduleName}@${versionHint}` : moduleName;
521
- const cacheDir = external_node_path_default().join(external_node_os_default().tmpdir(), 'extensionjs-cache', spec);
522
- const modulePath = external_node_path_default().join(cacheDir, 'node_modules', moduleName);
523
- const prefer = String(process.env.EXTJS_DLX || '').trim().toLowerCase();
524
- const isWin = 'win32' === process.platform;
525
- const npmCmd = isWin ? 'npm.cmd' : 'npm';
526
- const pnpmCmd = isWin ? 'pnpm.cmd' : 'pnpm';
527
- const bunCmd = isWin ? 'bun.exe' : 'bun';
528
- try {
529
- external_node_fs_default().mkdirSync(cacheDir, {
530
- recursive: true
572
+ process.on('unhandledRejection', function(reason) {
573
+ telemetry_cli_telemetry.track('cli_error', {
574
+ command_guess: invoked,
575
+ error_name: String((null == reason ? void 0 : reason.name) || 'PromiseRejection').slice(0, 64)
576
+ });
531
577
  });
532
- } catch {}
533
- try {
534
- var _pkgJson_exports_, _pkgJson_exports, _pkgJson_exports_1, _pkgJson_exports1;
535
- const pkgJson = JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(modulePath, 'package.json'), 'utf8'));
536
- const main = pkgJson.main || (null == (_pkgJson_exports = pkgJson.exports) ? void 0 : null == (_pkgJson_exports_ = _pkgJson_exports['.']) ? void 0 : _pkgJson_exports_.import) || (null == (_pkgJson_exports1 = pkgJson.exports) ? void 0 : null == (_pkgJson_exports_1 = _pkgJson_exports1['.']) ? void 0 : _pkgJson_exports_1.require);
537
- if (main) {
538
- const resolved = (0, external_node_url_namespaceObject.pathToFileURL)(external_node_path_default().join(modulePath, main)).href;
539
- return await import(resolved);
540
- }
541
- } catch {}
542
- if ('pnpm' === prefer) try {
543
- external_node_fs_default().writeFileSync(external_node_path_default().join(cacheDir, 'package.json'), JSON.stringify({
544
- name: 'extensionjs-cache',
545
- private: true
546
- }, null, 2));
547
- } catch {}
548
- let status = 0;
549
- if ('pnpm' === prefer) {
550
- const args = [
551
- 'add',
552
- spec,
553
- '--reporter',
554
- 'silent',
555
- '--no-frozen-lockfile'
556
- ];
557
- status = (0, external_node_child_process_namespaceObject.spawnSync)(pnpmCmd, args, {
558
- cwd: cacheDir,
559
- stdio: 'ignore'
560
- }).status || 0;
561
- } else if ('bun' === prefer) {
562
- const args = [
563
- 'add',
564
- spec
565
- ];
566
- status = (0, external_node_child_process_namespaceObject.spawnSync)(bunCmd, args, {
567
- cwd: cacheDir,
568
- stdio: 'ignore'
569
- }).status || 0;
570
- } else {
571
- const args = [
572
- 'i',
573
- spec,
574
- '--no-fund',
575
- '--no-audit',
576
- '--prefer-online',
577
- '--omit=dev',
578
- '--no-package-lock'
579
- ];
580
- status = (0, external_node_child_process_namespaceObject.spawnSync)(npmCmd, args, {
581
- cwd: cacheDir,
582
- stdio: 'ignore'
583
- }).status || 0;
584
578
  }
585
- if (0 !== status) throw new Error(`Failed to install ${spec}`);
586
- try {
587
- var _pkgJson_exports_2, _pkgJson_exports2, _pkgJson_exports_3, _pkgJson_exports3;
588
- const pkgJson = JSON.parse(external_node_fs_default().readFileSync(external_node_path_default().join(modulePath, 'package.json'), 'utf8'));
589
- const main = pkgJson.main || (null == (_pkgJson_exports2 = pkgJson.exports) ? void 0 : null == (_pkgJson_exports_2 = _pkgJson_exports2['.']) ? void 0 : _pkgJson_exports_2.import) || (null == (_pkgJson_exports3 = pkgJson.exports) ? void 0 : null == (_pkgJson_exports_3 = _pkgJson_exports3['.']) ? void 0 : _pkgJson_exports_3.require);
590
- if (main) {
591
- const resolved = (0, external_node_url_namespaceObject.pathToFileURL)(external_node_path_default().join(modulePath, main)).href;
592
- return await import(resolved);
579
+ const external_extension_create_namespaceObject = require("extension-create");
580
+ require("node:url");
581
+ function parseOptionalBoolean(value) {
582
+ if (void 0 === value) return true;
583
+ const normalized = String(value).trim().toLowerCase();
584
+ return ![
585
+ 'false',
586
+ '0',
587
+ 'no',
588
+ 'off'
589
+ ].includes(normalized);
590
+ }
591
+ const vendors = (browser)=>{
592
+ const value = browser ?? 'chromium';
593
+ return 'all' === value ? [
594
+ 'chrome',
595
+ 'edge',
596
+ 'firefox'
597
+ ] : String(value).split(',');
598
+ };
599
+ function validateVendorsOrExit(vendorsList, onInvalid) {
600
+ const supported = [
601
+ 'chrome',
602
+ 'edge',
603
+ 'firefox',
604
+ 'chromium',
605
+ 'chromium-based',
606
+ 'gecko-based',
607
+ 'firefox-based'
608
+ ];
609
+ for (const v of vendorsList)if (!supported.includes(v)) {
610
+ onInvalid(v, supported);
611
+ process.exit(1);
593
612
  }
594
- } catch {}
595
- return await import((0, external_node_url_namespaceObject.pathToFileURL)(external_node_path_default().join(modulePath, 'dist', 'module.js')).href);
596
- }
597
- const vendors = (browser)=>{
598
- const value = browser ?? 'chromium';
599
- return 'all' === value ? [
600
- 'chrome',
601
- 'edge',
602
- 'firefox'
603
- ] : String(value).split(',');
604
- };
605
- function validateVendorsOrExit(vendorsList, onInvalid) {
606
- const supported = [
607
- 'chrome',
608
- 'edge',
609
- 'firefox',
610
- 'chromium',
611
- 'chromium-based',
612
- 'gecko-based',
613
- 'firefox-based'
614
- ];
615
- for (const v of vendorsList)if (!supported.includes(v)) {
616
- onInvalid(v, supported);
617
- process.exit(1);
618
613
  }
619
- }
620
- function registerCreateCommand(program, telemetry) {
621
- program.command('create').arguments('<project-name|project-path>').usage('create <project-name|project-path> [options]').description('Creates a new extension.').option('-t, --template <template-name>', 'specify a template for the created project').option('--install [boolean]', 'whether or not to install the dependencies after creating the project (disabled by default)', parseOptionalBoolean, false).action(async function(pathOrRemoteUrl, { template, install }) {
622
- const startedAt = Date.now();
623
- telemetry.track('cli_command_start', {
624
- command: 'create',
625
- template: template || 'default',
626
- install: Boolean(install)
627
- });
628
- try {
629
- await (0, external_extension_create_namespaceObject.extensionCreate)(pathOrRemoteUrl, {
630
- template,
631
- install,
632
- cliVersion: package_namespaceObject.version
633
- });
634
- telemetry.track('cli_command_finish', {
635
- command: 'create',
636
- duration_ms: Date.now() - startedAt,
637
- success: true,
638
- exit_code: 0
639
- });
640
- } catch (err) {
641
- telemetry.track('cli_command_finish', {
614
+ function registerCreateCommand(program, telemetry) {
615
+ program.command('create').arguments('<project-name|project-path>').usage('create <project-name|project-path> [options]').description(commandDescriptions.create).option('-t, --template <template-name>', 'specify a template for the created project').option('--install [boolean]', 'whether or not to install the dependencies after creating the project (disabled by default)', parseOptionalBoolean, false).action(async function(pathOrRemoteUrl, { template, install }) {
616
+ const startedAt = Date.now();
617
+ telemetry.track('cli_command_start', {
642
618
  command: 'create',
643
- duration_ms: Date.now() - startedAt,
644
- success: false,
645
- exit_code: 1
619
+ template: template || 'default',
620
+ install: Boolean(install)
646
621
  });
647
- throw err;
648
- }
649
- });
650
- }
651
- function registerDevCommand(program, telemetry) {
652
- program.command('dev').arguments('[project-path|remote-url]').usage('dev [project-path|remote-url] [options]').description('Starts the development server (development mode)').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>', '[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('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...devOptions }) {
653
- var _devOptions_polyfill;
654
- if (devOptions.author || devOptions['authorMode']) {
655
- process.env.EXTENSION_AUTHOR_MODE = 'true';
656
- if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
657
- }
658
- const cmdStart = Date.now();
659
- telemetry.track('cli_command_start', {
660
- command: 'dev',
661
- vendors: vendors(browser),
662
- polyfill_used: (null == (_devOptions_polyfill = devOptions.polyfill) ? void 0 : _devOptions_polyfill.toString()) !== 'false',
663
- log_level: devOptions.logLevel || 'off',
664
- log_format: devOptions.logFormat || 'pretty',
665
- custom_binary_used: Boolean(devOptions.chromiumBinary || devOptions.geckoBinary)
666
- });
667
- const list = vendors(browser);
668
- validateVendorsOrExit(list, (invalid, supported)=>{
669
- console.error(unsupportedBrowserFlag(invalid, supported));
622
+ try {
623
+ await (0, external_extension_create_namespaceObject.extensionCreate)(pathOrRemoteUrl, {
624
+ template,
625
+ install,
626
+ cliVersion: package_namespaceObject.version
627
+ });
628
+ telemetry.track('cli_command_finish', {
629
+ command: 'create',
630
+ duration_ms: Date.now() - startedAt,
631
+ success: true,
632
+ exit_code: 0
633
+ });
634
+ } catch (err) {
635
+ telemetry.track('cli_command_finish', {
636
+ command: 'create',
637
+ duration_ms: Date.now() - startedAt,
638
+ success: false,
639
+ exit_code: 1
640
+ });
641
+ throw err;
642
+ }
670
643
  });
671
- if (devOptions.source) {
672
- const hasExplicitSourceString = 'string' == typeof devOptions.source && 'true' !== String(devOptions.source).trim().toLowerCase();
673
- const hasStartingUrl = 'string' == typeof devOptions.startingUrl && String(devOptions.startingUrl).trim().length > 0;
674
- if (!hasExplicitSourceString) devOptions.source = hasStartingUrl ? String(devOptions.startingUrl) : 'https://example.com';
675
- devOptions.watchSource = true;
676
- }
677
- const versionSpec = String(package_namespaceObject.version);
678
- const { extensionDev } = await requireOrDlx('extension-develop', versionSpec);
679
- for (const vendor of list){
680
- var _devOptions_polyfill1;
681
- const vendorStart = Date.now();
682
- telemetry.track('cli_vendor_start', {
644
+ }
645
+ function normalizeSourceOption(source, startingUrl) {
646
+ if (!source) return;
647
+ const hasExplicitSourceString = 'string' == typeof source && 'true' !== String(source).trim().toLowerCase();
648
+ const hasStartingUrl = 'string' == typeof startingUrl && String(startingUrl).trim().length > 0;
649
+ if (!hasExplicitSourceString) return hasStartingUrl ? String(startingUrl) : 'https://example.com';
650
+ return String(source);
651
+ }
652
+ function parseLogContexts(raw) {
653
+ if (!raw || 0 === String(raw).trim().length) return;
654
+ if ('all' === String(raw).trim().toLowerCase()) return;
655
+ const allowed = [
656
+ 'background',
657
+ 'content',
658
+ 'page',
659
+ 'sidebar',
660
+ 'popup',
661
+ 'options',
662
+ 'devtools'
663
+ ];
664
+ const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
665
+ return values.length > 0 ? values : void 0;
666
+ }
667
+ function registerDevCommand(program, telemetry) {
668
+ program.command('dev').arguments('[project-path|remote-url]').usage('dev [project-path|remote-url] [options]').description(commandDescriptions.dev).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>', '[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('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...devOptions }) {
669
+ var _devOptions_polyfill;
670
+ if (devOptions.author || devOptions['authorMode']) {
671
+ process.env.EXTENSION_AUTHOR_MODE = 'true';
672
+ if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
673
+ }
674
+ const cmdStart = Date.now();
675
+ telemetry.track('cli_command_start', {
683
676
  command: 'dev',
684
- vendor
677
+ vendors: vendors(browser),
678
+ polyfill_used: (null == (_devOptions_polyfill = devOptions.polyfill) ? void 0 : _devOptions_polyfill.toString()) !== 'false',
679
+ log_level: devOptions.logLevel || 'off',
680
+ log_format: devOptions.logFormat || 'pretty',
681
+ custom_binary_used: Boolean(devOptions.chromiumBinary || devOptions.geckoBinary)
685
682
  });
686
- const logsOption = devOptions.logs;
687
- const logContextOption = devOptions.logContext;
688
- const devArgs = {
689
- ...devOptions,
690
- profile: devOptions.profile,
691
- browser: vendor,
692
- chromiumBinary: devOptions.chromiumBinary,
693
- geckoBinary: devOptions.geckoBinary,
694
- polyfill: (null == (_devOptions_polyfill1 = devOptions.polyfill) ? void 0 : _devOptions_polyfill1.toString()) !== 'false',
695
- open: devOptions.open,
696
- startingUrl: devOptions.startingUrl,
697
- source: devOptions.source,
698
- watchSource: devOptions.watchSource,
699
- logLevel: logsOption || devOptions.logLevel || 'off',
700
- logContexts: (()=>{
701
- const raw = logContextOption || devOptions.logContexts;
702
- if (!raw || 0 === String(raw).trim().length) return;
703
- if ('all' === String(raw).trim().toLowerCase()) return;
704
- const allowed = [
705
- 'background',
706
- 'content',
707
- 'page',
708
- 'sidebar',
709
- 'popup',
710
- 'options',
711
- 'devtools'
712
- ];
713
- const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
714
- return values.length ? values : void 0;
715
- })(),
716
- logFormat: devOptions.logFormat || 'pretty',
717
- logTimestamps: false !== devOptions.logTimestamps,
718
- logColor: false !== devOptions.logColor,
719
- logUrl: devOptions.logUrl,
720
- logTab: devOptions.logTab
721
- };
722
- await extensionDev(pathOrRemoteUrl, devArgs);
723
- telemetry.track('cli_vendor_finish', {
683
+ const list = vendors(browser);
684
+ validateVendorsOrExit(list, (invalid, supported)=>{
685
+ console.error(unsupportedBrowserFlag(invalid, supported));
686
+ });
687
+ const normalizedSource = normalizeSourceOption(devOptions.source, devOptions.startingUrl);
688
+ if (normalizedSource) {
689
+ devOptions.source = normalizedSource;
690
+ devOptions.watchSource = true;
691
+ }
692
+ const { extensionDev } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
693
+ for (const vendor of list){
694
+ var _devOptions_polyfill1;
695
+ const vendorStart = Date.now();
696
+ telemetry.track('cli_vendor_start', {
697
+ command: 'dev',
698
+ vendor
699
+ });
700
+ const logsOption = devOptions.logs;
701
+ const logContextOption = devOptions.logContext;
702
+ const devArgs = {
703
+ ...devOptions,
704
+ profile: devOptions.profile,
705
+ browser: vendor,
706
+ chromiumBinary: devOptions.chromiumBinary,
707
+ geckoBinary: devOptions.geckoBinary,
708
+ polyfill: (null == (_devOptions_polyfill1 = devOptions.polyfill) ? void 0 : _devOptions_polyfill1.toString()) !== 'false',
709
+ open: devOptions.open,
710
+ startingUrl: devOptions.startingUrl,
711
+ source: devOptions.source,
712
+ watchSource: devOptions.watchSource,
713
+ logLevel: logsOption || devOptions.logLevel || 'off',
714
+ logContexts: parseLogContexts(logContextOption),
715
+ logFormat: devOptions.logFormat || 'pretty',
716
+ logTimestamps: false !== devOptions.logTimestamps,
717
+ logColor: false !== devOptions.logColor,
718
+ logUrl: devOptions.logUrl,
719
+ logTab: devOptions.logTab
720
+ };
721
+ await extensionDev(pathOrRemoteUrl, devArgs);
722
+ telemetry.track('cli_vendor_finish', {
723
+ command: 'dev',
724
+ vendor,
725
+ duration_ms: Date.now() - vendorStart
726
+ });
727
+ }
728
+ telemetry.track('cli_command_finish', {
724
729
  command: 'dev',
725
- vendor,
726
- duration_ms: Date.now() - vendorStart
730
+ duration_ms: Date.now() - cmdStart,
731
+ success: 0 === process.exitCode || null == process.exitCode,
732
+ exit_code: process.exitCode ?? 0
727
733
  });
728
- }
729
- telemetry.track('cli_command_finish', {
730
- command: 'dev',
731
- duration_ms: Date.now() - cmdStart,
732
- success: 0 === process.exitCode || null == process.exitCode,
733
- exit_code: process.exitCode ?? 0
734
- });
735
- });
736
- }
737
- function registerStartCommand(program, telemetry) {
738
- program.command('start').arguments('[project-path|remote-url]').usage('start [project-path|remote-url] [options]').description('Starts the development server (production mode)').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>', '[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('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...startOptions }) {
739
- var _startOptions_polyfill;
740
- if (startOptions.author || startOptions['authorMode']) {
741
- process.env.EXTENSION_AUTHOR_MODE = 'true';
742
- if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
743
- }
744
- const cmdStart = Date.now();
745
- telemetry.track('cli_command_start', {
746
- command: 'start',
747
- vendors: vendors(browser),
748
- polyfill_used: (null == (_startOptions_polyfill = startOptions.polyfill) ? void 0 : _startOptions_polyfill.toString()) !== 'false'
749
734
  });
750
- const list = vendors(browser);
751
- validateVendorsOrExit(list, (invalid, supported)=>{
752
- console.error(unsupportedBrowserFlag(invalid, supported));
753
- });
754
- const major = String(package_namespaceObject.version).split('.')[0] || '2';
755
- const { extensionStart } = await requireOrDlx('extension-develop', major);
756
- for (const vendor of list){
757
- const vendorStart = Date.now();
758
- telemetry.track('cli_vendor_start', {
735
+ }
736
+ function registerStartCommand(program, telemetry) {
737
+ program.command('start').arguments('[project-path|remote-url]').usage('start [project-path|remote-url] [options]').description(commandDescriptions.start).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>', '[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('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...startOptions }) {
738
+ var _startOptions_polyfill;
739
+ if (startOptions.author || startOptions.authorMode) {
740
+ process.env.EXTENSION_AUTHOR_MODE = 'true';
741
+ if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
742
+ }
743
+ const cmdStart = Date.now();
744
+ telemetry.track('cli_command_start', {
759
745
  command: 'start',
760
- vendor
746
+ vendors: vendors(browser),
747
+ polyfill_used: (null == (_startOptions_polyfill = startOptions.polyfill) ? void 0 : _startOptions_polyfill.toString()) !== 'false'
761
748
  });
762
- const logsOption = startOptions.logs;
763
- const logContextOption = startOptions.logContext;
764
- const logContexts = (()=>{
765
- const raw = logContextOption || startOptions.logContexts;
766
- if (!raw || 0 === String(raw).trim().length) return;
767
- if ('all' === String(raw).trim().toLowerCase()) return;
768
- const allowed = [
769
- 'background',
770
- 'content',
771
- 'page',
772
- 'sidebar',
773
- 'popup',
774
- 'options',
775
- 'devtools'
776
- ];
777
- const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
778
- return values.length ? values : void 0;
779
- })();
780
- await extensionStart(pathOrRemoteUrl, {
781
- mode: 'production',
782
- profile: startOptions.profile,
783
- browser: vendor,
784
- chromiumBinary: startOptions.chromiumBinary,
785
- geckoBinary: startOptions.geckoBinary,
786
- startingUrl: startOptions.startingUrl,
787
- port: startOptions.port,
788
- source: 'string' == typeof startOptions.source ? startOptions.source : startOptions.source,
789
- watchSource: startOptions.watchSource,
790
- logLevel: logsOption || startOptions.logLevel || 'off',
791
- logContexts,
792
- logFormat: startOptions.logFormat || 'pretty',
793
- logTimestamps: false !== startOptions.logTimestamps,
794
- logColor: false !== startOptions.logColor,
795
- logUrl: startOptions.logUrl,
796
- logTab: startOptions.logTab
749
+ const list = vendors(browser);
750
+ validateVendorsOrExit(list, (invalid, supported)=>{
751
+ console.error(unsupportedBrowserFlag(invalid, supported));
797
752
  });
798
- telemetry.track('cli_vendor_finish', {
753
+ const { extensionStart } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
754
+ for (const vendor of list){
755
+ const vendorStart = Date.now();
756
+ telemetry.track('cli_vendor_start', {
757
+ command: 'start',
758
+ vendor
759
+ });
760
+ const logsOption = startOptions.logs;
761
+ const logContextOption = startOptions.logContext;
762
+ const logContexts = parseLogContexts(logContextOption);
763
+ await extensionStart(pathOrRemoteUrl, {
764
+ mode: 'production',
765
+ profile: startOptions.profile,
766
+ browser: vendor,
767
+ chromiumBinary: startOptions.chromiumBinary,
768
+ geckoBinary: startOptions.geckoBinary,
769
+ startingUrl: startOptions.startingUrl,
770
+ port: startOptions.port,
771
+ source: 'string' == typeof startOptions.source ? startOptions.source : startOptions.source,
772
+ watchSource: startOptions.watchSource,
773
+ logLevel: logsOption || startOptions.logLevel || 'off',
774
+ logContexts,
775
+ logFormat: startOptions.logFormat || 'pretty',
776
+ logTimestamps: false !== startOptions.logTimestamps,
777
+ logColor: false !== startOptions.logColor,
778
+ logUrl: startOptions.logUrl,
779
+ logTab: startOptions.logTab
780
+ });
781
+ telemetry.track('cli_vendor_finish', {
782
+ command: 'start',
783
+ vendor,
784
+ duration_ms: Date.now() - vendorStart
785
+ });
786
+ }
787
+ telemetry.track('cli_command_finish', {
799
788
  command: 'start',
800
- vendor,
801
- duration_ms: Date.now() - vendorStart
789
+ duration_ms: Date.now() - cmdStart,
790
+ success: 0 === process.exitCode || null == process.exitCode,
791
+ exit_code: process.exitCode ?? 0
802
792
  });
803
- }
804
- telemetry.track('cli_command_finish', {
805
- command: 'start',
806
- duration_ms: Date.now() - cmdStart,
807
- success: 0 === process.exitCode || null == process.exitCode,
808
- exit_code: process.exitCode ?? 0
809
793
  });
810
- });
811
- }
812
- function registerPreviewCommand(program, telemetry) {
813
- program.command('preview').arguments('[project-name]').usage('preview [path-to-remote-extension] [options]').description('Preview the extension in production mode').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('--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>', '[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('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...previewOptions }) {
814
- if (previewOptions.author || previewOptions['authorMode']) {
815
- process.env.EXTENSION_AUTHOR_MODE = 'true';
816
- if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
817
- }
818
- const cmdStart = Date.now();
819
- telemetry.track('cli_command_start', {
820
- command: 'preview',
821
- vendors: vendors(browser)
822
- });
823
- const list = vendors(browser);
824
- validateVendorsOrExit(list, (invalid, supported)=>{
825
- console.error(unsupportedBrowserFlag(invalid, supported));
826
- });
827
- if (!process.env.EXTJS_LIGHT) {
828
- const isRemote = 'string' == typeof pathOrRemoteUrl && /^https?:/i.test(pathOrRemoteUrl);
829
- if (isRemote) process.env.EXTJS_LIGHT = '1';
830
- }
831
- const major = String(package_namespaceObject.version).split('.')[0] || '2';
832
- const { extensionPreview } = await requireOrDlx('extension-develop', major);
833
- for (const vendor of list){
834
- const vendorStart = Date.now();
835
- telemetry.track('cli_vendor_start', {
794
+ }
795
+ function registerPreviewCommand(program, telemetry) {
796
+ program.command('preview').arguments('[project-name]').usage('preview [path-to-remote-extension] [options]').description(commandDescriptions.preview).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('--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>', '[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('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...previewOptions }) {
797
+ if (previewOptions.author || previewOptions['authorMode']) {
798
+ process.env.EXTENSION_AUTHOR_MODE = 'true';
799
+ if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
800
+ }
801
+ const cmdStart = Date.now();
802
+ telemetry.track('cli_command_start', {
836
803
  command: 'preview',
837
- vendor
804
+ vendors: vendors(browser)
838
805
  });
839
- const logsOption = previewOptions.logs;
840
- const logContextOption = previewOptions.logContext;
841
- const logContexts = (()=>{
842
- const raw = logContextOption || previewOptions.logContexts;
843
- if (!raw || 0 === String(raw).trim().length) return;
844
- if ('all' === String(raw).trim().toLowerCase()) return;
845
- const allowed = [
846
- 'background',
847
- 'content',
848
- 'page',
849
- 'sidebar',
850
- 'popup',
851
- 'options',
852
- 'devtools'
853
- ];
854
- const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
855
- return values.length ? values : void 0;
856
- })();
857
- await extensionPreview(pathOrRemoteUrl, {
858
- mode: 'production',
859
- profile: previewOptions.profile,
860
- browser: vendor,
861
- chromiumBinary: previewOptions.chromiumBinary,
862
- geckoBinary: previewOptions.geckoBinary,
863
- startingUrl: previewOptions.startingUrl,
864
- port: previewOptions.port,
865
- source: 'string' == typeof previewOptions.source ? previewOptions.source : previewOptions.source,
866
- watchSource: previewOptions.watchSource,
867
- logLevel: logsOption || previewOptions.logLevel || 'off',
868
- logContexts,
869
- logFormat: previewOptions.logFormat || 'pretty',
870
- logTimestamps: false !== previewOptions.logTimestamps,
871
- logColor: false !== previewOptions.logColor,
872
- logUrl: previewOptions.logUrl,
873
- logTab: previewOptions.logTab
806
+ const list = vendors(browser);
807
+ validateVendorsOrExit(list, (invalid, supported)=>{
808
+ console.error(unsupportedBrowserFlag(invalid, supported));
874
809
  });
875
- telemetry.track('cli_vendor_finish', {
810
+ if (!process.env.EXTJS_LIGHT) {
811
+ const isRemote = 'string' == typeof pathOrRemoteUrl && /^https?:/i.test(pathOrRemoteUrl);
812
+ if (isRemote) process.env.EXTJS_LIGHT = '1';
813
+ }
814
+ const { extensionPreview } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
815
+ for (const vendor of list){
816
+ const vendorStart = Date.now();
817
+ telemetry.track('cli_vendor_start', {
818
+ command: 'preview',
819
+ vendor
820
+ });
821
+ const logsOption = previewOptions.logs;
822
+ const logContextOption = previewOptions.logContext;
823
+ const logContexts = parseLogContexts(logContextOption);
824
+ await extensionPreview(pathOrRemoteUrl, {
825
+ mode: 'production',
826
+ profile: previewOptions.profile,
827
+ browser: vendor,
828
+ chromiumBinary: previewOptions.chromiumBinary,
829
+ geckoBinary: previewOptions.geckoBinary,
830
+ startingUrl: previewOptions.startingUrl,
831
+ port: previewOptions.port,
832
+ source: 'string' == typeof previewOptions.source ? previewOptions.source : previewOptions.source,
833
+ watchSource: previewOptions.watchSource,
834
+ logLevel: logsOption || previewOptions.logLevel || 'off',
835
+ logContexts,
836
+ logFormat: previewOptions.logFormat || 'pretty',
837
+ logTimestamps: false !== previewOptions.logTimestamps,
838
+ logColor: false !== previewOptions.logColor,
839
+ logUrl: previewOptions.logUrl,
840
+ logTab: previewOptions.logTab
841
+ });
842
+ telemetry.track('cli_vendor_finish', {
843
+ command: 'preview',
844
+ vendor,
845
+ duration_ms: Date.now() - vendorStart
846
+ });
847
+ }
848
+ telemetry.track('cli_command_finish', {
876
849
  command: 'preview',
877
- vendor,
878
- duration_ms: Date.now() - vendorStart
850
+ duration_ms: Date.now() - cmdStart,
851
+ success: 0 === process.exitCode || null == process.exitCode,
852
+ exit_code: process.exitCode ?? 0
879
853
  });
880
- }
881
- telemetry.track('cli_command_finish', {
882
- command: 'preview',
883
- duration_ms: Date.now() - cmdStart,
884
- success: 0 === process.exitCode || null == process.exitCode,
885
- exit_code: process.exitCode ?? 0
886
854
  });
887
- });
888
- }
889
- function registerBuildCommand(program, telemetry) {
890
- program.command('build').arguments('[project-name]').usage('build [path-to-remote-extension] [options]').description('Builds the extension for production').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 `false`').option('--zip [boolean]', 'whether or not to compress the extension into a ZIP file. Defaults to `false`').option('--zip-source [boolean]', 'whether or not to include the source files in the ZIP file. Defaults to `false`').option('--zip-filename <string>', 'specify the name of the ZIP file. Defaults to the extension name and version').option('--silent [boolean]', 'whether or not to open the browser automatically. Defaults to `false`').option('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...buildOptions }) {
891
- if (buildOptions.author || buildOptions['authorMode']) {
892
- process.env.EXTENSION_AUTHOR_MODE = 'true';
893
- if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
894
- }
895
- const cmdStart = Date.now();
896
- telemetry.track('cli_command_start', {
897
- command: 'build',
898
- vendors: vendors(browser),
899
- polyfill_used: buildOptions.polyfill || false,
900
- zip: buildOptions.zip || false,
901
- zip_source: buildOptions.zipSource || false
902
- });
903
- const list = vendors(browser);
904
- validateVendorsOrExit(list, (invalid, supported)=>{
905
- console.error(unsupportedBrowserFlag(invalid, supported));
906
- });
907
- const major = String(package_namespaceObject.version).split('.')[0] || '2';
908
- const { extensionBuild } = await requireOrDlx('extension-develop', major);
909
- for (const vendor of list){
910
- const vendorStart = Date.now();
911
- telemetry.track('cli_vendor_start', {
855
+ }
856
+ function registerBuildCommand(program, telemetry) {
857
+ program.command('build').arguments('[project-name]').usage('build [path-to-remote-extension] [options]').description(commandDescriptions.build).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 `false`').option('--zip [boolean]', 'whether or not to compress the extension into a ZIP file. Defaults to `false`').option('--zip-source [boolean]', 'whether or not to include the source files in the ZIP file. Defaults to `false`').option('--zip-filename <string>', 'specify the name of the ZIP file. Defaults to the extension name and version').option('--silent [boolean]', 'whether or not to open the browser automatically. Defaults to `false`').option('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...buildOptions }) {
858
+ if (buildOptions.author || buildOptions['authorMode']) {
859
+ process.env.EXTENSION_AUTHOR_MODE = 'true';
860
+ if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
861
+ }
862
+ const cmdStart = Date.now();
863
+ telemetry.track('cli_command_start', {
912
864
  command: 'build',
913
- vendor
865
+ vendors: vendors(browser),
866
+ polyfill_used: buildOptions.polyfill || false,
867
+ zip: buildOptions.zip || false,
868
+ zip_source: buildOptions.zipSource || false
914
869
  });
915
- const buildSummary = await extensionBuild(pathOrRemoteUrl, {
916
- browser: vendor,
917
- polyfill: buildOptions.polyfill,
918
- zip: buildOptions.zip,
919
- zipSource: buildOptions.zipSource,
920
- zipFilename: buildOptions.zipFilename,
921
- silent: buildOptions.silent
870
+ const list = vendors(browser);
871
+ validateVendorsOrExit(list, (invalid, supported)=>{
872
+ console.error(unsupportedBrowserFlag(invalid, supported));
922
873
  });
923
- telemetry.track('cli_build_summary', {
924
- ...buildSummary
925
- });
926
- telemetry.track('cli_vendor_finish', {
874
+ const { extensionBuild } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
875
+ for (const vendor of list){
876
+ const vendorStart = Date.now();
877
+ telemetry.track('cli_vendor_start', {
878
+ command: 'build',
879
+ vendor
880
+ });
881
+ const buildSummary = await extensionBuild(pathOrRemoteUrl, {
882
+ browser: vendor,
883
+ polyfill: buildOptions.polyfill,
884
+ zip: buildOptions.zip,
885
+ zipSource: buildOptions.zipSource,
886
+ zipFilename: buildOptions.zipFilename,
887
+ silent: buildOptions.silent
888
+ });
889
+ telemetry.track('cli_build_summary', {
890
+ ...buildSummary
891
+ });
892
+ telemetry.track('cli_vendor_finish', {
893
+ command: 'build',
894
+ vendor,
895
+ duration_ms: Date.now() - vendorStart
896
+ });
897
+ }
898
+ telemetry.track('cli_command_finish', {
927
899
  command: 'build',
928
- vendor,
929
- duration_ms: Date.now() - vendorStart
900
+ duration_ms: Date.now() - cmdStart,
901
+ success: 0 === process.exitCode || null == process.exitCode,
902
+ exit_code: process.exitCode ?? 0
930
903
  });
931
- }
932
- telemetry.track('cli_command_finish', {
933
- command: 'build',
934
- duration_ms: Date.now() - cmdStart,
935
- success: 0 === process.exitCode || null == process.exitCode,
936
- exit_code: process.exitCode ?? 0
937
904
  });
905
+ }
906
+ check_updates_checkUpdates(package_namespaceObject);
907
+ const extensionJs = external_commander_namespaceObject.program;
908
+ extensionJs.name(package_namespaceObject.name).description(package_namespaceObject.description).version(package_namespaceObject.version).option('--no-telemetry', 'disable anonymous telemetry for this run').option('--ai-help', 'show AI-assistant oriented help and tips').addHelpText('after', programUserHelp()).showHelpAfterError(true).showSuggestionAfterError(true);
909
+ registerCreateCommand(extensionJs, telemetry_cli_telemetry);
910
+ registerDevCommand(extensionJs, telemetry_cli_telemetry);
911
+ registerStartCommand(extensionJs, telemetry_cli_telemetry);
912
+ registerPreviewCommand(extensionJs, telemetry_cli_telemetry);
913
+ registerBuildCommand(extensionJs, telemetry_cli_telemetry);
914
+ extensionJs.on('option:ai-help', function() {
915
+ console.log(programAIHelp());
916
+ process.exit(0);
938
917
  });
939
- }
940
- check_updates_checkUpdates(package_namespaceObject);
941
- const extensionJs = external_commander_namespaceObject.program;
942
- extensionJs.name(package_namespaceObject.name).description(package_namespaceObject.description).version(package_namespaceObject.version).option('--no-telemetry', 'disable anonymous telemetry for this run').option('--ai-help', 'show AI-assistant oriented help and tips').addHelpText('after', programUserHelp());
943
- registerCreateCommand(extensionJs, telemetry_cli_telemetry);
944
- registerDevCommand(extensionJs, telemetry_cli_telemetry);
945
- registerStartCommand(extensionJs, telemetry_cli_telemetry);
946
- registerPreviewCommand(extensionJs, telemetry_cli_telemetry);
947
- registerBuildCommand(extensionJs, telemetry_cli_telemetry);
948
- extensionJs.on('option:ai-help', function() {
949
- console.log(programAIHelp());
950
- process.exit(0);
951
- });
952
- extensionJs.parse();
918
+ if (process.argv.length <= 2) {
919
+ extensionJs.outputHelp();
920
+ process.exit(0);
921
+ }
922
+ extensionJs.parseAsync().catch((err)=>{
923
+ console.error(unhandledError(err));
924
+ process.exit(1);
925
+ });
926
+ })();
953
927
  for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
954
928
  Object.defineProperty(exports, '__esModule', {
955
929
  value: true