extension 3.2.0-next.2 → 3.2.0-next.5
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-lib/telemetry.d.ts +1 -0
- package/dist/cli.js +86 -28
- package/package.json +4 -3
- package/types/extension-develop-shim.d.ts +2 -0
package/dist/cli.js
CHANGED
|
@@ -361,30 +361,76 @@ function configDir() {
|
|
|
361
361
|
if ('win32' === process.platform && process.env.APPDATA) return external_node_path_default().join(process.env.APPDATA, 'extensionjs');
|
|
362
362
|
return external_node_path_default().join(external_node_os_default().homedir(), '.config', 'extensionjs');
|
|
363
363
|
}
|
|
364
|
+
function telemetry_cacheDir() {
|
|
365
|
+
const xdg = process.env.XDG_CACHE_HOME;
|
|
366
|
+
if (xdg) return external_node_path_default().join(xdg, 'extensionjs');
|
|
367
|
+
if ('win32' === process.platform) {
|
|
368
|
+
const base = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
369
|
+
if (base) return external_node_path_default().join(base, 'extensionjs', 'Cache');
|
|
370
|
+
}
|
|
371
|
+
if ('darwin' === process.platform) return external_node_path_default().join(external_node_os_default().homedir(), 'Library', 'Caches', 'extensionjs');
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
364
374
|
function ensureDir(p) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
375
|
+
try {
|
|
376
|
+
if (external_node_fs_default().existsSync(p)) return true;
|
|
377
|
+
external_node_fs_default().mkdirSync(p, {
|
|
378
|
+
recursive: true
|
|
379
|
+
});
|
|
380
|
+
return true;
|
|
381
|
+
} catch {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
function ensureWritableDir(p) {
|
|
386
|
+
if (!ensureDir(p)) return false;
|
|
387
|
+
try {
|
|
388
|
+
external_node_fs_default().accessSync(p, external_node_fs_default().constants.W_OK);
|
|
389
|
+
const probe = external_node_path_default().join(p, `.write-test-${process.pid}-${Date.now()}`);
|
|
390
|
+
external_node_fs_default().writeFileSync(probe, 'ok', 'utf8');
|
|
391
|
+
external_node_fs_default().unlinkSync(probe);
|
|
392
|
+
return true;
|
|
393
|
+
} catch {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
369
396
|
}
|
|
370
397
|
function loadOrCreateId(file) {
|
|
371
|
-
|
|
398
|
+
try {
|
|
399
|
+
if (external_node_fs_default().existsSync(file)) return external_node_fs_default().readFileSync(file, 'utf8').trim();
|
|
400
|
+
} catch {}
|
|
372
401
|
const id = external_node_crypto_default().randomUUID();
|
|
373
|
-
ensureDir(external_node_path_default().dirname(file))
|
|
374
|
-
|
|
402
|
+
if (ensureDir(external_node_path_default().dirname(file))) try {
|
|
403
|
+
external_node_fs_default().writeFileSync(file, id, 'utf8');
|
|
404
|
+
} catch {}
|
|
375
405
|
return id;
|
|
376
406
|
}
|
|
377
|
-
function
|
|
378
|
-
const
|
|
379
|
-
|
|
380
|
-
|
|
407
|
+
function telemetryCandidates() {
|
|
408
|
+
const candidates = [
|
|
409
|
+
configDir(),
|
|
410
|
+
telemetry_cacheDir(),
|
|
411
|
+
external_node_path_default().join(external_node_os_default().tmpdir(), 'extensionjs'),
|
|
412
|
+
external_node_path_default().join(process.cwd(), '.cache', 'extensionjs')
|
|
413
|
+
].filter(Boolean);
|
|
414
|
+
return Array.from(new Set(candidates));
|
|
415
|
+
}
|
|
416
|
+
function resolveTelemetryStorage() {
|
|
417
|
+
for (const base of telemetryCandidates()){
|
|
418
|
+
const telemetryDir = external_node_path_default().join(base, 'telemetry');
|
|
419
|
+
if (ensureWritableDir(telemetryDir)) return {
|
|
420
|
+
telemetryDir,
|
|
421
|
+
auditFile: external_node_path_default().join(telemetryDir, 'events.jsonl'),
|
|
422
|
+
idFile: external_node_path_default().join(telemetryDir, 'anonymous-id'),
|
|
423
|
+
consentFile: external_node_path_default().join(telemetryDir, 'consent')
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
return null;
|
|
381
427
|
}
|
|
382
428
|
const DEFAULT_FLUSH_AT = Number(process.env.EXTENSION_TELEMETRY_FLUSH_AT || 10);
|
|
383
429
|
const DEFAULT_FLUSH_INTERVAL = Number(process.env.EXTENSION_TELEMETRY_FLUSH_INTERVAL || 2000);
|
|
384
430
|
const DEFAULT_TIMEOUT_MS = Number(process.env.EXTENSION_TELEMETRY_TIMEOUT_MS || 200);
|
|
385
431
|
class Telemetry {
|
|
386
432
|
track(event, props = {}) {
|
|
387
|
-
if (this.disabled) return;
|
|
433
|
+
if (this.disabled || !this.storage) return;
|
|
388
434
|
const payload = {
|
|
389
435
|
event,
|
|
390
436
|
properties: {
|
|
@@ -394,7 +440,12 @@ class Telemetry {
|
|
|
394
440
|
},
|
|
395
441
|
distinct_id: this.anonId
|
|
396
442
|
};
|
|
397
|
-
|
|
443
|
+
try {
|
|
444
|
+
external_node_fs_default().appendFileSync(this.storage.auditFile, JSON.stringify(payload) + '\n');
|
|
445
|
+
} catch {
|
|
446
|
+
this.disabled = true;
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
398
449
|
if (this.debug) console.error('[telemetry]', JSON.stringify(payload));
|
|
399
450
|
if (!this.apiKey || !this.host) return;
|
|
400
451
|
this.buffer.push(payload);
|
|
@@ -439,14 +490,16 @@ class Telemetry {
|
|
|
439
490
|
_define_property(this, "disabled", void 0);
|
|
440
491
|
_define_property(this, "apiKey", void 0);
|
|
441
492
|
_define_property(this, "host", void 0);
|
|
493
|
+
_define_property(this, "storage", null);
|
|
442
494
|
_define_property(this, "buffer", []);
|
|
443
495
|
_define_property(this, "timer", null);
|
|
444
496
|
this.debug = '1' === process.env.EXTENSION_TELEMETRY_DEBUG;
|
|
445
497
|
this.disabled = Boolean(init.disabled);
|
|
446
498
|
this.anonId = 'disabled';
|
|
447
499
|
if (!this.disabled) {
|
|
448
|
-
|
|
449
|
-
this.anonId = loadOrCreateId(idFile);
|
|
500
|
+
this.storage = resolveTelemetryStorage();
|
|
501
|
+
if (this.storage) this.anonId = loadOrCreateId(this.storage.idFile);
|
|
502
|
+
else this.disabled = true;
|
|
450
503
|
}
|
|
451
504
|
this.common = {
|
|
452
505
|
app: init.app,
|
|
@@ -459,15 +512,17 @@ class Telemetry {
|
|
|
459
512
|
};
|
|
460
513
|
this.apiKey = init.apiKey || process.env.EXTENSION_PUBLIC_POSTHOG_KEY;
|
|
461
514
|
this.host = init.host || process.env.EXTENSION_PUBLIC_POSTHOG_HOST;
|
|
462
|
-
if (!this.disabled) {
|
|
463
|
-
const consentPath =
|
|
464
|
-
|
|
465
|
-
external_node_fs_default().
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
515
|
+
if (!this.disabled && this.storage) {
|
|
516
|
+
const consentPath = this.storage.consentFile;
|
|
517
|
+
try {
|
|
518
|
+
if (!external_node_fs_default().existsSync(consentPath)) {
|
|
519
|
+
external_node_fs_default().writeFileSync(consentPath, 'ok', 'utf8');
|
|
520
|
+
this.track('cli_telemetry_consent', {
|
|
521
|
+
value: 'implicit_opt_in'
|
|
522
|
+
});
|
|
523
|
+
console.log(`${external_pintor_default().gray('►►►')} Telemetry is enabled for Extension.js. To opt out, run with --no-telemetry. Learn more in TELEMETRY.md.`);
|
|
524
|
+
}
|
|
525
|
+
} catch {}
|
|
471
526
|
}
|
|
472
527
|
}
|
|
473
528
|
}
|
|
@@ -669,7 +724,7 @@ function parseLogContexts(raw) {
|
|
|
669
724
|
return values.length > 0 ? values : void 0;
|
|
670
725
|
}
|
|
671
726
|
function registerDevCommand(program, telemetry) {
|
|
672
|
-
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 }) {
|
|
727
|
+
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('--install [boolean]', '[internal] install project dependencies when missing', parseOptionalBoolean).option('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...devOptions }) {
|
|
673
728
|
if (devOptions.author || devOptions['authorMode']) {
|
|
674
729
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
675
730
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
@@ -712,6 +767,7 @@ function registerDevCommand(program, telemetry) {
|
|
|
712
767
|
startingUrl: devOptions.startingUrl,
|
|
713
768
|
source: devOptions.source,
|
|
714
769
|
watchSource: devOptions.watchSource,
|
|
770
|
+
install: devOptions.install,
|
|
715
771
|
logLevel: logsOption || devOptions.logLevel || 'off',
|
|
716
772
|
logContexts: parseLogContexts(logContextOption),
|
|
717
773
|
logFormat: devOptions.logFormat || 'pretty',
|
|
@@ -736,7 +792,7 @@ function registerDevCommand(program, telemetry) {
|
|
|
736
792
|
});
|
|
737
793
|
}
|
|
738
794
|
function registerStartCommand(program, telemetry) {
|
|
739
|
-
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', '[
|
|
795
|
+
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('--install [boolean]', '[experimental] install project dependencies when missing', parseOptionalBoolean).option('--author, --author-mode', '[experimental] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...startOptions }) {
|
|
740
796
|
if (startOptions.author || startOptions.authorMode) {
|
|
741
797
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
742
798
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
@@ -769,6 +825,7 @@ function registerStartCommand(program, telemetry) {
|
|
|
769
825
|
geckoBinary: startOptions.geckoBinary,
|
|
770
826
|
startingUrl: startOptions.startingUrl,
|
|
771
827
|
port: startOptions.port,
|
|
828
|
+
install: startOptions.install,
|
|
772
829
|
source: 'string' == typeof startOptions.source ? startOptions.source : startOptions.source,
|
|
773
830
|
watchSource: startOptions.watchSource,
|
|
774
831
|
logLevel: logsOption || startOptions.logLevel || 'off',
|
|
@@ -855,7 +912,7 @@ function registerPreviewCommand(program, telemetry) {
|
|
|
855
912
|
});
|
|
856
913
|
}
|
|
857
914
|
function registerBuildCommand(program, telemetry) {
|
|
858
|
-
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 }) {
|
|
915
|
+
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('--install [boolean]', '[internal] install project dependencies when missing', parseOptionalBoolean).option('--author, --author-mode', '[internal] enable maintainer diagnostics (does not affect user runtime logs)').action(async function(pathOrRemoteUrl, { browser = 'chromium', ...buildOptions }) {
|
|
859
916
|
if (buildOptions.author || buildOptions['authorMode']) {
|
|
860
917
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
861
918
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
@@ -885,7 +942,8 @@ function registerBuildCommand(program, telemetry) {
|
|
|
885
942
|
zip: buildOptions.zip,
|
|
886
943
|
zipSource: buildOptions.zipSource,
|
|
887
944
|
zipFilename: buildOptions.zipFilename,
|
|
888
|
-
silent: buildOptions.silent
|
|
945
|
+
silent: buildOptions.silent,
|
|
946
|
+
install: buildOptions.install
|
|
889
947
|
});
|
|
890
948
|
telemetry.track('cli_build_summary', {
|
|
891
949
|
...buildSummary
|
package/package.json
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"extension": "./dist/cli.js"
|
|
36
36
|
},
|
|
37
37
|
"name": "extension",
|
|
38
|
-
"version": "3.2.0-next.
|
|
38
|
+
"version": "3.2.0-next.5",
|
|
39
39
|
"description": "Create cross-browser extensions with no build configuration.",
|
|
40
40
|
"homepage": "https://extension.js.org/",
|
|
41
41
|
"bugs": {
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"registry": "https://registry.npmjs.org"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
|
+
"pretest": "pnpm run compile",
|
|
54
55
|
"prepublishOnly": "pnpm run compile",
|
|
55
56
|
"compile": "rslib build",
|
|
56
57
|
"watch": "rslib build --watch",
|
|
@@ -88,8 +89,8 @@
|
|
|
88
89
|
"cli"
|
|
89
90
|
],
|
|
90
91
|
"dependencies": {
|
|
91
|
-
"extension-create": "^3.2.0-next.
|
|
92
|
-
"extension-develop": "^3.2.0-next.
|
|
92
|
+
"extension-create": "^3.2.0-next.5",
|
|
93
|
+
"extension-develop": "^3.2.0-next.5",
|
|
93
94
|
"commander": "^14.0.2",
|
|
94
95
|
"pintor": "0.3.0",
|
|
95
96
|
"semver": "^7.7.3",
|
|
@@ -30,6 +30,7 @@ declare module 'extension-develop' {
|
|
|
30
30
|
zipSource?: boolean
|
|
31
31
|
zipFilename?: string
|
|
32
32
|
silent?: boolean
|
|
33
|
+
install?: boolean
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export interface DevOptions {
|
|
@@ -49,6 +50,7 @@ declare module 'extension-develop' {
|
|
|
49
50
|
logColor?: boolean
|
|
50
51
|
logUrl?: string
|
|
51
52
|
logTab?: string | number
|
|
53
|
+
install?: boolean
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
export interface PreviewOptions extends DevOptions {}
|