extension 4.0.24 → 4.0.26
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.cjs
CHANGED
|
@@ -6216,6 +6216,153 @@ var __webpack_modules__ = {
|
|
|
6216
6216
|
var external_pintor_ = __webpack_require__("pintor");
|
|
6217
6217
|
var external_pintor_default = /*#__PURE__*/ __webpack_require__.n(external_pintor_);
|
|
6218
6218
|
var messaging = __webpack_require__("./helpers/messaging.ts");
|
|
6219
|
+
const DEFAULT_TEMPLATE = "javascript";
|
|
6220
|
+
const TEMPLATE_CATALOG_URL = 'https://github.com/extension-js/examples/tree/main/examples';
|
|
6221
|
+
const TEMPLATE_GROUPS = [
|
|
6222
|
+
{
|
|
6223
|
+
title: 'Starters',
|
|
6224
|
+
summary: 'a bare manifest, or one language or framework with sidebar UI',
|
|
6225
|
+
templates: [
|
|
6226
|
+
'init',
|
|
6227
|
+
"javascript",
|
|
6228
|
+
"typescript",
|
|
6229
|
+
'react',
|
|
6230
|
+
'preact',
|
|
6231
|
+
'vue',
|
|
6232
|
+
'svelte'
|
|
6233
|
+
]
|
|
6234
|
+
},
|
|
6235
|
+
{
|
|
6236
|
+
title: 'Sidebar',
|
|
6237
|
+
summary: 'side panel on Chromium, sidebar action on Firefox',
|
|
6238
|
+
templates: [
|
|
6239
|
+
'sidebar',
|
|
6240
|
+
'sidebar-antd',
|
|
6241
|
+
'sidebar-shadcn',
|
|
6242
|
+
'sidebar-monorepo-turbopack',
|
|
6243
|
+
'ai-chatgpt',
|
|
6244
|
+
'ai-claude',
|
|
6245
|
+
'ai-gemini',
|
|
6246
|
+
'ai-perplexity',
|
|
6247
|
+
'playwright',
|
|
6248
|
+
'transformers-js'
|
|
6249
|
+
]
|
|
6250
|
+
},
|
|
6251
|
+
{
|
|
6252
|
+
title: "Content scripts",
|
|
6253
|
+
summary: 'code injected into the pages you browse',
|
|
6254
|
+
templates: [
|
|
6255
|
+
'content',
|
|
6256
|
+
'content-css-modules',
|
|
6257
|
+
'content-custom-font',
|
|
6258
|
+
'content-env',
|
|
6259
|
+
'content-less',
|
|
6260
|
+
'content-less-modules',
|
|
6261
|
+
'content-main-world',
|
|
6262
|
+
'content-multi-one-entry',
|
|
6263
|
+
'content-multi-three-entries',
|
|
6264
|
+
'content-preact',
|
|
6265
|
+
'content-react',
|
|
6266
|
+
'content-sass',
|
|
6267
|
+
'content-sass-modules',
|
|
6268
|
+
'content-svelte',
|
|
6269
|
+
"content-typescript",
|
|
6270
|
+
'content-vue'
|
|
6271
|
+
]
|
|
6272
|
+
},
|
|
6273
|
+
{
|
|
6274
|
+
title: 'New tab',
|
|
6275
|
+
summary: 'replaces the browser new tab page',
|
|
6276
|
+
templates: [
|
|
6277
|
+
'new',
|
|
6278
|
+
'new-browser-flags',
|
|
6279
|
+
'new-config-eslint',
|
|
6280
|
+
'new-config-prettier',
|
|
6281
|
+
'new-config-stylelint',
|
|
6282
|
+
'new-crypto',
|
|
6283
|
+
'new-env',
|
|
6284
|
+
'new-less',
|
|
6285
|
+
'new-preact',
|
|
6286
|
+
'new-react',
|
|
6287
|
+
'new-react-router',
|
|
6288
|
+
'new-sass',
|
|
6289
|
+
'new-svelte',
|
|
6290
|
+
"new-typescript",
|
|
6291
|
+
'new-vue'
|
|
6292
|
+
]
|
|
6293
|
+
},
|
|
6294
|
+
{
|
|
6295
|
+
title: 'Toolbar action',
|
|
6296
|
+
summary: 'popup opened from the toolbar button',
|
|
6297
|
+
templates: [
|
|
6298
|
+
'action',
|
|
6299
|
+
'action-locales'
|
|
6300
|
+
]
|
|
6301
|
+
},
|
|
6302
|
+
{
|
|
6303
|
+
title: 'Special folders',
|
|
6304
|
+
summary: "pages/ and scripts/ entrypoints",
|
|
6305
|
+
templates: [
|
|
6306
|
+
'special-folders-pages',
|
|
6307
|
+
"special-folders-scripts"
|
|
6308
|
+
]
|
|
6309
|
+
}
|
|
6310
|
+
];
|
|
6311
|
+
const TEMPLATE_ALIASES = [];
|
|
6312
|
+
function listTemplates() {
|
|
6313
|
+
return TEMPLATE_GROUPS.flatMap((group)=>group.templates);
|
|
6314
|
+
}
|
|
6315
|
+
function wrapSlugs(slugs, indent, width) {
|
|
6316
|
+
const lines = [];
|
|
6317
|
+
let current = '';
|
|
6318
|
+
for (const slug of slugs){
|
|
6319
|
+
const candidate = current ? `${current}, ${slug}` : slug;
|
|
6320
|
+
if (current && indent.length + candidate.length + 1 > width) {
|
|
6321
|
+
lines.push(`${indent}${current},`);
|
|
6322
|
+
current = slug;
|
|
6323
|
+
continue;
|
|
6324
|
+
}
|
|
6325
|
+
current = candidate;
|
|
6326
|
+
}
|
|
6327
|
+
if (current) lines.push(indent + current);
|
|
6328
|
+
return lines;
|
|
6329
|
+
}
|
|
6330
|
+
function renderTemplateList({ color = true, width = 78 } = {}) {
|
|
6331
|
+
const title = (text)=>color ? external_pintor_default().green(text) : text;
|
|
6332
|
+
const dim = (text)=>color ? external_pintor_default().gray(text) : text;
|
|
6333
|
+
const slug = (text)=>color ? external_pintor_default().blue(text) : text;
|
|
6334
|
+
const lines = [];
|
|
6335
|
+
for (const group of TEMPLATE_GROUPS){
|
|
6336
|
+
lines.push(` ${title(group.title)} ${dim(`(${group.summary})`)}`);
|
|
6337
|
+
for (const line of wrapSlugs(group.templates, ' ', width))lines.push(slug(line));
|
|
6338
|
+
lines.push('');
|
|
6339
|
+
}
|
|
6340
|
+
lines.push(` ${title('Aliases')}`);
|
|
6341
|
+
for (const alias of TEMPLATE_ALIASES){
|
|
6342
|
+
lines.push(` ${slug(alias.name)} ${dim(alias.note)}`);
|
|
6343
|
+
lines.push(dim(' pass its URL to scaffold the catalog folder instead'));
|
|
6344
|
+
}
|
|
6345
|
+
return lines.join('\n');
|
|
6346
|
+
}
|
|
6347
|
+
function renderCreateTemplateHelp() {
|
|
6348
|
+
const total = listTemplates().length;
|
|
6349
|
+
const dim = (text)=>external_pintor_default().gray(text);
|
|
6350
|
+
return [
|
|
6351
|
+
'',
|
|
6352
|
+
external_pintor_default().underline(external_pintor_default().blue(`Templates (${total})`)),
|
|
6353
|
+
renderTemplateList(),
|
|
6354
|
+
'',
|
|
6355
|
+
` ${external_pintor_default().green('Default')}`,
|
|
6356
|
+
` ${external_pintor_default().blue(DEFAULT_TEMPLATE)} ${dim('is used when --template is omitted. It ships inside the CLI,')}`,
|
|
6357
|
+
dim(' so it scaffolds with no network call.'),
|
|
6358
|
+
'',
|
|
6359
|
+
` ${external_pintor_default().green('Everything else')}`,
|
|
6360
|
+
dim(' downloads the catalog archive at create time, so it needs the'),
|
|
6361
|
+
dim(' network and takes longer. A GitHub URL or a ZIP URL also works.'),
|
|
6362
|
+
` ${external_pintor_default().blue(TEMPLATE_CATALOG_URL)}`,
|
|
6363
|
+
''
|
|
6364
|
+
].join('\n');
|
|
6365
|
+
}
|
|
6219
6366
|
function getLoggingPrefix(type) {
|
|
6220
6367
|
return (0, messaging.Pl)(type);
|
|
6221
6368
|
}
|
|
@@ -6638,11 +6785,11 @@ Environment variables
|
|
|
6638
6785
|
- Example: ${messages_code(messages_arg('EXTENSION_PUBLIC_API_KEY=your_key'))}
|
|
6639
6786
|
|
|
6640
6787
|
Available templates
|
|
6641
|
-
|
|
6642
|
-
- ${external_pintor_default().green('
|
|
6643
|
-
- ${
|
|
6644
|
-
-
|
|
6645
|
-
-
|
|
6788
|
+
${TEMPLATE_GROUPS.map((group)=>`- ${external_pintor_default().green(group.title)} ${messages_arg(`(${group.summary})`)}: ${group.templates.map((template)=>messages_code(template)).join(', ')}`).join('\n')}
|
|
6789
|
+
- ${external_pintor_default().green('Alias')}: ${TEMPLATE_ALIASES.map((alias)=>`${messages_code(alias.name)} ${messages_arg(alias.note)}`).join(', ')}
|
|
6790
|
+
- ${messages_code(DEFAULT_TEMPLATE)} is the default when ${messages_code('--template')} is omitted. It ships inside the CLI and needs no network.
|
|
6791
|
+
- Every other name is downloaded from ${messages_code(TEMPLATE_CATALOG_URL)} at create time. A GitHub or ZIP URL works in place of a name.
|
|
6792
|
+
- A name that is not on this list fails with ${messages_code('TemplateNotFoundError')}. Run ${messages_code('extension create --help')} for the same list.
|
|
6646
6793
|
|
|
6647
6794
|
Webpack/Rspack configuration
|
|
6648
6795
|
- Create ${external_pintor_default().underline(messages_code(messages_arg('extension.config.js')))} for custom webpack configuration
|
|
@@ -6774,6 +6921,31 @@ Cross-browser compatibility
|
|
|
6774
6921
|
description: 'Connectable host the browser dials for HMR + the reload bridge when it differs from the bind host (remote/devcontainer)'
|
|
6775
6922
|
}
|
|
6776
6923
|
],
|
|
6924
|
+
templates: {
|
|
6925
|
+
default: DEFAULT_TEMPLATE,
|
|
6926
|
+
bundled: [
|
|
6927
|
+
DEFAULT_TEMPLATE
|
|
6928
|
+
],
|
|
6929
|
+
catalogUrl: TEMPLATE_CATALOG_URL,
|
|
6930
|
+
names: listTemplates(),
|
|
6931
|
+
groups: TEMPLATE_GROUPS.map((group)=>({
|
|
6932
|
+
title: group.title,
|
|
6933
|
+
summary: group.summary,
|
|
6934
|
+
templates: [
|
|
6935
|
+
...group.templates
|
|
6936
|
+
]
|
|
6937
|
+
})),
|
|
6938
|
+
aliases: TEMPLATE_ALIASES.map((alias)=>({
|
|
6939
|
+
...alias
|
|
6940
|
+
})),
|
|
6941
|
+
notes: [
|
|
6942
|
+
`extension create <name> with no --template scaffolds ${DEFAULT_TEMPLATE}`,
|
|
6943
|
+
`${DEFAULT_TEMPLATE} is bundled with the CLI and scaffolds offline. Every other name downloads the examples archive at create time`,
|
|
6944
|
+
'a GitHub URL or a ZIP URL is accepted in place of a catalog name',
|
|
6945
|
+
'a name outside names[] fails with TemplateNotFoundError and creates nothing',
|
|
6946
|
+
'this list ships with the CLI, so it is the list this CLI version can scaffold, not necessarily the current contents of the catalog repository'
|
|
6947
|
+
]
|
|
6948
|
+
},
|
|
6777
6949
|
capabilities: {
|
|
6778
6950
|
logger: {
|
|
6779
6951
|
levels: [
|
|
@@ -7444,7 +7616,7 @@ Cross-browser compatibility
|
|
|
7444
7616
|
return messaging.Lp.E_INTERNAL;
|
|
7445
7617
|
}
|
|
7446
7618
|
function registerCreateCommand(program) {
|
|
7447
|
-
program.command('create').arguments('<project-name|project-path>').usage('<project-name|project-path> [options]').description(commandDescriptions.create).option('-t, --template <template-name>',
|
|
7619
|
+
program.command('create').arguments('<project-name|project-path>').usage('<project-name|project-path> [options]').description(commandDescriptions.create).option('-t, --template <template-name>', `catalog name, GitHub URL, or ZIP URL to scaffold from; every catalog name is listed below (default: ${DEFAULT_TEMPLATE})`).option('--install [boolean]', 'whether or not to install the dependencies after creating the project (disabled by default, pass --install to opt in)', parseOptionalBoolean, false).option('--source <source>', 'attribution tag for where this create was initiated (e.g. cli, templates); recorded in anonymous telemetry only').option('--output <pretty|json>', 'result format. Use json for a schema-1 envelope on stdout').addHelpText('after', renderCreateTemplateHelp()).action(async (pathOrRemoteUrl, { template, install, output })=>{
|
|
7448
7620
|
const asJson = 'json' === output;
|
|
7449
7621
|
if (!process.env.EXTENSION_CREATE_DEVELOP_ROOT) try {
|
|
7450
7622
|
process.env.EXTENSION_CREATE_DEVELOP_ROOT = resolveExtensionDevelopRoot();
|
|
@@ -8633,9 +8805,10 @@ Cross-browser compatibility
|
|
|
8633
8805
|
});
|
|
8634
8806
|
}
|
|
8635
8807
|
const DEFAULT_API = 'https://www.extension.dev';
|
|
8808
|
+
const PUBLISH_DOCS_URL = 'https://docs.extension.dev/tools/publish';
|
|
8636
8809
|
function buildPublishRequest(opts) {
|
|
8637
8810
|
const token = String(opts.token || process.env.EXTENSION_DEV_TOKEN || '').trim();
|
|
8638
|
-
if (!token) throw new Error(
|
|
8811
|
+
if (!token) throw new Error(`No token. Publishing needs an extension.dev access token.\nGet one: ${PUBLISH_DOCS_URL}\nThen set EXTENSION_DEV_TOKEN, or pass --token.`);
|
|
8639
8812
|
const base = String(opts.api || process.env.EXTENSION_DEV_API_URL || DEFAULT_API).replace(/\/+$/, '');
|
|
8640
8813
|
const body = {};
|
|
8641
8814
|
if (null != opts.ttl && '' !== opts.ttl) body.ttlHours = Number(opts.ttl);
|
|
@@ -8667,7 +8840,7 @@ Cross-browser compatibility
|
|
|
8667
8840
|
await failWith('denied', {
|
|
8668
8841
|
code: messaging.Lp.E_AUTH_REQUIRED,
|
|
8669
8842
|
message
|
|
8670
|
-
}, message,
|
|
8843
|
+
}, message, `Get a token at ${PUBLISH_DOCS_URL}, then set EXTENSION_DEV_TOKEN or pass --token.`);
|
|
8671
8844
|
return;
|
|
8672
8845
|
}
|
|
8673
8846
|
let res;
|
|
@@ -8852,6 +9025,7 @@ Cross-browser compatibility
|
|
|
8852
9025
|
else obj[key] = value;
|
|
8853
9026
|
return obj;
|
|
8854
9027
|
}
|
|
9028
|
+
const VERSION_MAX_LENGTH = 64;
|
|
8855
9029
|
function sanitizeTag(value) {
|
|
8856
9030
|
return String(value).trim().replace(/[^a-zA-Z0-9._-]/g, '').slice(0, 64);
|
|
8857
9031
|
}
|
|
@@ -8870,6 +9044,17 @@ Cross-browser compatibility
|
|
|
8870
9044
|
const v = process.env;
|
|
8871
9045
|
return Boolean(v.CI || v.GITHUB_ACTIONS || v.GITLAB_CI || v.BUILDKITE || v.CIRCLECI || v.TRAVIS);
|
|
8872
9046
|
}
|
|
9047
|
+
const INSTALL_DIRECTORY_MARKERS = [
|
|
9048
|
+
'node_modules',
|
|
9049
|
+
'.pnpm',
|
|
9050
|
+
'.yarn',
|
|
9051
|
+
'.npm',
|
|
9052
|
+
'.bun'
|
|
9053
|
+
];
|
|
9054
|
+
function isSourceCheckout(startDir = __dirname) {
|
|
9055
|
+
const segments = String(startDir ?? '').split(/[\\/]+/);
|
|
9056
|
+
return !segments.some((segment)=>INSTALL_DIRECTORY_MARKERS.includes(segment));
|
|
9057
|
+
}
|
|
8873
9058
|
function configDir() {
|
|
8874
9059
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
8875
9060
|
if (xdg) return external_node_path_default().join(xdg, 'extensionjs');
|
|
@@ -8973,21 +9158,19 @@ Cross-browser compatibility
|
|
|
8973
9158
|
source: 'env'
|
|
8974
9159
|
};
|
|
8975
9160
|
const storage = resolveTelemetryStorage();
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
};
|
|
8982
|
-
if ('disabled' === stored) return {
|
|
8983
|
-
enabled: false,
|
|
8984
|
-
source: 'config'
|
|
8985
|
-
};
|
|
8986
|
-
}
|
|
9161
|
+
const stored = storage ? readConsentFile(storage.consentFile) : null;
|
|
9162
|
+
if ('disabled' === stored) return {
|
|
9163
|
+
enabled: false,
|
|
9164
|
+
source: 'config'
|
|
9165
|
+
};
|
|
8987
9166
|
if (isCI() && !process.stdout.isTTY) return {
|
|
8988
9167
|
enabled: false,
|
|
8989
9168
|
source: 'ci'
|
|
8990
9169
|
};
|
|
9170
|
+
if ('enabled' === stored) return {
|
|
9171
|
+
enabled: true,
|
|
9172
|
+
source: 'config'
|
|
9173
|
+
};
|
|
8991
9174
|
return {
|
|
8992
9175
|
enabled: true,
|
|
8993
9176
|
source: 'default'
|
|
@@ -9019,7 +9202,7 @@ Cross-browser compatibility
|
|
|
9019
9202
|
const enforcedProps = {
|
|
9020
9203
|
command: String(props.command ?? 'unknown').slice(0, 32),
|
|
9021
9204
|
success: Boolean(props.success),
|
|
9022
|
-
version: String(props.version ?? this.version).slice(0,
|
|
9205
|
+
version: String(props.version ?? this.version).slice(0, VERSION_MAX_LENGTH)
|
|
9023
9206
|
};
|
|
9024
9207
|
if (props.template) enforcedProps.template = sanitizeTag(props.template);
|
|
9025
9208
|
if (props.source) enforcedProps.source = sanitizeTag(props.source);
|
|
@@ -9122,7 +9305,8 @@ Cross-browser compatibility
|
|
|
9122
9305
|
os: process.platform,
|
|
9123
9306
|
arch: process.arch,
|
|
9124
9307
|
node_major: Number(String(process.versions.node).split('.')[0]) || 0,
|
|
9125
|
-
is_ci: isCI()
|
|
9308
|
+
is_ci: isCI(),
|
|
9309
|
+
is_source_build: isSourceCheckout()
|
|
9126
9310
|
};
|
|
9127
9311
|
if (!this.disabled) {
|
|
9128
9312
|
this.storage = resolveTelemetryStorage();
|
|
@@ -221,6 +221,23 @@ export type ProgramAIHelpJSON = {
|
|
|
221
221
|
default?: string;
|
|
222
222
|
description: string;
|
|
223
223
|
}>;
|
|
224
|
+
templates: {
|
|
225
|
+
default: string;
|
|
226
|
+
bundled: string[];
|
|
227
|
+
catalogUrl: string;
|
|
228
|
+
names: string[];
|
|
229
|
+
groups: Array<{
|
|
230
|
+
title: string;
|
|
231
|
+
summary: string;
|
|
232
|
+
templates: string[];
|
|
233
|
+
}>;
|
|
234
|
+
aliases: Array<{
|
|
235
|
+
name: string;
|
|
236
|
+
resolvesTo: string;
|
|
237
|
+
note: string;
|
|
238
|
+
}>;
|
|
239
|
+
notes: string[];
|
|
240
|
+
};
|
|
224
241
|
capabilities: {
|
|
225
242
|
logger: {
|
|
226
243
|
levels: string[];
|
|
@@ -24,6 +24,7 @@ type TelemetryStorage = {
|
|
|
24
24
|
consentFile: string;
|
|
25
25
|
};
|
|
26
26
|
export declare const DEFAULT_POSTHOG_KEY: string;
|
|
27
|
+
export declare function isSourceCheckout(startDir?: string): boolean;
|
|
27
28
|
export declare function resolveTelemetryStorage(): TelemetryStorage | null;
|
|
28
29
|
export declare function resolveTelemetryConsent(argv?: string[]): {
|
|
29
30
|
enabled: boolean;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const DEFAULT_TEMPLATE = "javascript";
|
|
2
|
+
export declare const TEMPLATE_CATALOG_URL = "https://github.com/extension-js/examples/tree/main/examples";
|
|
3
|
+
export interface TemplateGroup {
|
|
4
|
+
title: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
templates: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface TemplateAlias {
|
|
9
|
+
name: string;
|
|
10
|
+
resolvesTo: string;
|
|
11
|
+
note: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const TEMPLATE_GROUPS: readonly TemplateGroup[];
|
|
14
|
+
export declare const TEMPLATE_ALIASES: readonly TemplateAlias[];
|
|
15
|
+
export declare function listTemplates(): string[];
|
|
16
|
+
export declare function templateAliasFor(name: string): TemplateAlias | undefined;
|
|
17
|
+
export interface RenderTemplateListOptions {
|
|
18
|
+
color?: boolean;
|
|
19
|
+
width?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function renderTemplateList({ color, width }?: RenderTemplateListOptions): string;
|
|
22
|
+
export declare function renderCreateTemplateHelp(): string;
|
package/package.json
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"extension": "./bin/extension.cjs"
|
|
39
39
|
},
|
|
40
40
|
"name": "extension",
|
|
41
|
-
"version": "4.0.
|
|
41
|
+
"version": "4.0.26",
|
|
42
42
|
"description": "The cross-browser extension framework. Build Chrome, Edge, Firefox, and Safari extensions with no build configuration.",
|
|
43
43
|
"homepage": "https://extension.js.org/",
|
|
44
44
|
"bugs": {
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
"vivaldi-location2": "2.1.0",
|
|
107
107
|
"waterfox-location": "2.1.0",
|
|
108
108
|
"yandex-location": "2.1.0",
|
|
109
|
-
"extension-create": "4.0.
|
|
110
|
-
"extension-develop": "4.0.
|
|
111
|
-
"extension-install": "4.0.
|
|
109
|
+
"extension-create": "4.0.26",
|
|
110
|
+
"extension-develop": "4.0.26",
|
|
111
|
+
"extension-install": "4.0.26",
|
|
112
112
|
"commander": "^15.0.0",
|
|
113
113
|
"pintor": "0.3.0",
|
|
114
114
|
"semver": "^7.7.3",
|