extension 3.0.0-next.9 → 3.1.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -24
- package/dist/cli-lib/messages.d.ts +9 -0
- package/dist/cli.js +159 -208
- package/dist/utils/normalize-options.d.ts +2 -0
- package/dist/utils.d.ts +1 -1
- package/package.json +21 -19
- package/types/css-content.d.ts +8 -0
- package/types/css-modules.d.ts +8 -0
- package/types/extension-create-shim.d.ts +24 -0
- package/types/extension-develop-shim.d.ts +103 -0
- package/types/images.d.ts +8 -0
- package/types/index.d.ts +9 -2
- package/types/index.ts +8 -0
- package/types/js-frameworks.d.ts +8 -0
- package/types/polyfill.d.ts +8 -0
package/README.md
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
[npm-version-image]: https://img.shields.io/npm/v/extension.svg?color=0971fe
|
|
2
2
|
[npm-version-url]: https://www.npmjs.com/package/extension
|
|
3
|
-
[
|
|
3
|
+
[npm-downloads-image]: https://img.shields.io/npm/dm/extension.svg?color=0971fe
|
|
4
|
+
[npm-downloads-url]: https://www.npmjs.com/package/extension
|
|
5
|
+
[action-image]: https://github.com/extension-js/extension.js/actions/workflows/ci.yml/badge.svg?branch=main&color=0971fe
|
|
4
6
|
[action-url]: https://github.com/extension-js/extension.js/actions
|
|
5
|
-
[discord-image]: https://img.shields.io/discord/1253608412890271755?label=Discord&logo=discord&style=flat&color=
|
|
7
|
+
[discord-image]: https://img.shields.io/discord/1253608412890271755?label=Discord&logo=discord&style=flat&color=0971fe
|
|
6
8
|
[discord-url]: https://discord.gg/v9h2RgeTSN
|
|
7
|
-
[snyk-image]: https://snyk.io/test/github/extension-js/extension/badge.svg?color=
|
|
9
|
+
[snyk-image]: https://snyk.io/test/github/extension-js/extension/badge.svg?color=0971fe
|
|
8
10
|
[snyk-url]: https://snyk.io/test/github/extension-js/extension
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
[![Version][npm-version-image]][npm-version-url] [![Downloads][npm-downloads-image]][npm-downloads-url] [![CI][action-image]][action-url] [![Discord][discord-image]][discord-url]
|
|
13
|
+
|
|
14
|
+
# Extension.js
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
> The cross-browser extension framework
|
|
13
17
|
|
|
14
18
|
<img alt="Logo" align="right" src="https://avatars.githubusercontent.com/u/172809806" width="15.5%" />
|
|
15
19
|
|
|
16
|
-
- [Create
|
|
17
|
-
- [
|
|
18
|
-
- [Start
|
|
19
|
-
- [I have
|
|
20
|
+
- [Create a new extension](#create-a-new-extension) — How to create a new extension.
|
|
21
|
+
- [Watch demo](#watch-demo) — See how creating a new extension works.
|
|
22
|
+
- [Start from an example](https://github.com/extension-js/extension.js/tree/main/examples) — Start from a working baseline.
|
|
23
|
+
- [I have an extension](#i-have-an-extension) — Use only specific parts of Extension.js.
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
Create cross-browser extensions without manual build configuration.<br />Use Extension.js to develop, build, and preview across browsers with a unified workflow.
|
|
22
26
|
|
|
23
|
-
## Create
|
|
27
|
+
## Create a new extension
|
|
24
28
|
|
|
25
29
|
Use the `create` command to generate a new extension. Also works with pnpm, yarn, and bun.
|
|
26
30
|
|
|
@@ -30,11 +34,11 @@ cd my-extension
|
|
|
30
34
|
npm run dev
|
|
31
35
|
```
|
|
32
36
|
|
|
33
|
-
### Watch
|
|
37
|
+
### Watch demo
|
|
34
38
|
|
|
35
|
-
https://github.com/cezaraugusto/extension/assets/4672033/7263d368-99c4-434f-a60a-72c489672586
|
|
39
|
+
[Watch demo](https://github.com/cezaraugusto/extension/assets/4672033/7263d368-99c4-434f-a60a-72c489672586)
|
|
36
40
|
|
|
37
|
-
## Web
|
|
41
|
+
## Web standards and framework support
|
|
38
42
|
|
|
39
43
|
<!-- For a preview of extensions running these technologies, see the [templates](https://templates.extension.land) website. -->
|
|
40
44
|
|
|
@@ -46,15 +50,18 @@ https://github.com/cezaraugusto/extension/assets/4672033/7263d368-99c4-434f-a60a
|
|
|
46
50
|
|
|
47
51
|
</div>
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
<details>
|
|
54
|
+
<summary>Get started from a sample</summary>
|
|
55
|
+
|
|
56
|
+
## Get started
|
|
50
57
|
|
|
51
58
|
Start developing an extension using a sample from Chrome Extension Samples
|
|
52
59
|
|
|
53
60
|
See the example below where we request the sample [page-redder](https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/functional-samples/sample.page-redder) from [Google Chrome Extension Samples](https://github.com/GoogleChrome/chrome-extensions-samples).
|
|
54
61
|
|
|
55
|
-
### Watch
|
|
62
|
+
### Watch demo
|
|
56
63
|
|
|
57
|
-
https://github.com/cezaraugusto/extension/assets/4672033/ee221a94-6ec7-4e04-8553-8812288927f1
|
|
64
|
+
[Watch demo](https://github.com/cezaraugusto/extension/assets/4672033/ee221a94-6ec7-4e04-8553-8812288927f1)
|
|
58
65
|
|
|
59
66
|
### Try Yourself
|
|
60
67
|
|
|
@@ -64,13 +71,13 @@ npx extension@latest dev https://github.com/GoogleChrome/chrome-extensions-sampl
|
|
|
64
71
|
|
|
65
72
|
</details>
|
|
66
73
|
|
|
67
|
-
## I have
|
|
74
|
+
## I have an extension
|
|
68
75
|
|
|
69
76
|
If you have an existing extension which is using a package manager, you can install the Extension.js package and manually create the scripts used to run your extension.
|
|
70
77
|
|
|
71
|
-
### See
|
|
78
|
+
### See how it works
|
|
72
79
|
|
|
73
|
-
https://github.com/cezaraugusto/extension/assets/4672033/48694a23-b7f1-4098-9c5d-eff49983739c
|
|
80
|
+
[See how it works](https://github.com/cezaraugusto/extension/assets/4672033/48694a23-b7f1-4098-9c5d-eff49983739c)
|
|
74
81
|
|
|
75
82
|
**Step 1 - Install extension as a `devDependency`**
|
|
76
83
|
|
|
@@ -102,9 +109,9 @@ Done. You are all set!
|
|
|
102
109
|
|
|
103
110
|
## Using a specific browser for development
|
|
104
111
|
|
|
105
|
-
| <img src="https://
|
|
106
|
-
|
|
|
107
|
-
|
|
|
112
|
+
| <img src="https://media.extension.land/logos/browsers/chrome.svg" width="70"> | <img src="https://media.extension.land/logos/browsers/edge.svg" width="70"> | <img src="https://media.extension.land/logos/browsers/firefox.svg" width="70"> | <img src="https://media.extension.land/logos/browsers/safari.svg" width="70"> | <img src="https://media.extension.land/logos/browsers/chromium.svg" width="70"> | <img src="https://media.extension.land/logos/browsers/firefox.svg" width="70"> |
|
|
113
|
+
| :---------------------------------------------------------------------------: | :-------------------------------------------------------------------------: | :----------------------------------------------------------------------------: | :---------------------------------------------------------------------------: | :-----------------------------------------------------------------------------: | :----------------------------------------------------------------------------: |
|
|
114
|
+
| Chrome browser<br>✅ | Edge browser<br>✅ | Firefox browser<br>✅ | Safari browser<br>(soon) | Chromium-based<br>✅ | Gecko-based<br>✅ |
|
|
108
115
|
|
|
109
116
|
### Browser flags and custom binaries
|
|
110
117
|
|
|
@@ -133,7 +140,7 @@ npx extension@latest dev --gecko-binary "/Applications/Firefox.app/Contents/MacO
|
|
|
133
140
|
<div align="center">
|
|
134
141
|
<p>
|
|
135
142
|
<span style="font-size:21px; color:black;">Browser testing via</span><br>
|
|
136
|
-
<a href="https://www.lambdatest.com/?utm_source=extensionjs&utm_medium=sponsor" target="_blank">
|
|
143
|
+
<a href="https://www.lambdatest.com/?utm_source=extensionjs&utm_medium=sponsor" target="_blank" rel="noopener noreferrer">
|
|
137
144
|
<img src="https://www.lambdatest.com/blue-logo.png" width="250" height="45" alt="LambdaTest Logo" />
|
|
138
145
|
</a>
|
|
139
146
|
</p>
|
|
@@ -7,6 +7,15 @@ export declare const fmt: {
|
|
|
7
7
|
block(title: string, rows: Array<[string, string]>): string;
|
|
8
8
|
truncate(input: unknown, max?: number): string;
|
|
9
9
|
};
|
|
10
|
+
export declare const commandDescriptions: {
|
|
11
|
+
readonly create: "Creates a new extension from a template (React, TypeScript, Vue, Svelte, etc.)";
|
|
12
|
+
readonly dev: "Starts the development server with hot reloading";
|
|
13
|
+
readonly start: "Builds and starts the extension in production mode";
|
|
14
|
+
readonly preview: "Previews the extension in production mode without building";
|
|
15
|
+
readonly build: "Builds the extension for packaging/distribution";
|
|
16
|
+
readonly cleanup: "Cleans up orphaned instances and frees unused ports";
|
|
17
|
+
};
|
|
18
|
+
export declare function unhandledError(err: unknown): string;
|
|
10
19
|
export declare function updateFailed(err: any): string;
|
|
11
20
|
export declare function checkUpdates(packageJson: Record<string, any>, update: {
|
|
12
21
|
latest: string;
|
package/dist/cli.js
CHANGED
|
@@ -23,25 +23,63 @@ var __webpack_require__ = {};
|
|
|
23
23
|
})();
|
|
24
24
|
var __webpack_exports__ = {};
|
|
25
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.
|
|
26
|
+
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.1.0-next.10","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-create":"^3.1.0-next.10","extension-develop":"^3.1.0-next.10","commander":"^14.0.2","pintor":"0.3.0","semver":"^7.7.3","update-check":"^1.5.4"},"devDependencies":{"@rslib/core":"^0.19.2","@types/chrome":"^0.1.33","@types/node":"^25.0.9","@types/react":"^19.2.8","@types/react-dom":"^19.2.3","@types/webextension-polyfill":"0.12.4","@types/mock-fs":"^4.13.4","@types/semver":"^7.7.1","mock-fs":"^5.5.0","webextension-polyfill":"^0.12.0","tsconfig":"*","typescript":"5.9.3","vitest":"^4.0.17"}}');
|
|
27
27
|
const external_update_check_namespaceObject = require("update-check");
|
|
28
28
|
var external_update_check_default = /*#__PURE__*/ __webpack_require__.n(external_update_check_namespaceObject);
|
|
29
29
|
const external_pintor_namespaceObject = require("pintor");
|
|
30
30
|
var external_pintor_default = /*#__PURE__*/ __webpack_require__.n(external_pintor_namespaceObject);
|
|
31
31
|
function getLoggingPrefix(type) {
|
|
32
|
-
|
|
32
|
+
const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
|
|
33
|
+
if (isAuthor) {
|
|
34
|
+
const base = 'error' === type ? 'ERROR Author says' : '►►► Author says';
|
|
35
|
+
return external_pintor_default().brightMagenta(base);
|
|
36
|
+
}
|
|
33
37
|
if ('error' === type) return external_pintor_default().red('ERROR');
|
|
34
|
-
if ('warn' === type) return external_pintor_default().brightYellow(
|
|
35
|
-
if ('info' === type) return external_pintor_default().gray(
|
|
36
|
-
return external_pintor_default().green(
|
|
38
|
+
if ('warn' === type) return external_pintor_default().brightYellow('►►►');
|
|
39
|
+
if ('info' === type) return external_pintor_default().gray('►►►');
|
|
40
|
+
return external_pintor_default().green('►►►');
|
|
37
41
|
}
|
|
38
42
|
const code = (text)=>external_pintor_default().blue(text);
|
|
39
43
|
const arg = (text)=>external_pintor_default().gray(text);
|
|
44
|
+
const fmt = {
|
|
45
|
+
heading: (title)=>external_pintor_default().underline(external_pintor_default().blue(title)),
|
|
46
|
+
label: (k)=>external_pintor_default().gray(k.toUpperCase()),
|
|
47
|
+
val: (v)=>external_pintor_default().underline(v),
|
|
48
|
+
code: (v)=>external_pintor_default().blue(v),
|
|
49
|
+
bullet: (s)=>`- ${s}`,
|
|
50
|
+
block (title, rows) {
|
|
51
|
+
const head = fmt.heading(title);
|
|
52
|
+
const body = rows.map(([k, v])=>`${fmt.label(k)} ${v}`).join('\n');
|
|
53
|
+
return `${head}\n${body}`;
|
|
54
|
+
},
|
|
55
|
+
truncate (input, max = 800) {
|
|
56
|
+
const s = (()=>{
|
|
57
|
+
try {
|
|
58
|
+
return 'string' == typeof input ? input : JSON.stringify(input);
|
|
59
|
+
} catch {
|
|
60
|
+
return String(input);
|
|
61
|
+
}
|
|
62
|
+
})();
|
|
63
|
+
return s.length > max ? s.slice(0, max) + '…' : s;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const commandDescriptions = {
|
|
67
|
+
create: 'Creates a new extension from a template (React, TypeScript, Vue, Svelte, etc.)',
|
|
68
|
+
dev: 'Starts the development server with hot reloading',
|
|
69
|
+
start: 'Builds and starts the extension in production mode',
|
|
70
|
+
preview: 'Previews the extension in production mode without building',
|
|
71
|
+
build: 'Builds the extension for packaging/distribution',
|
|
72
|
+
cleanup: 'Cleans up orphaned instances and frees unused ports'
|
|
73
|
+
};
|
|
74
|
+
function unhandledError(err) {
|
|
75
|
+
const message = err instanceof Error ? err.stack || err.message : 'string' == typeof err ? err : fmt.truncate(err);
|
|
76
|
+
return `${getLoggingPrefix('error')} ${external_pintor_default().red(String(message || 'Unknown error'))}`;
|
|
77
|
+
}
|
|
40
78
|
function updateFailed(err) {
|
|
41
|
-
return `${getLoggingPrefix('error')} Failed to check for updates.\n${external_pintor_default().red(String(
|
|
79
|
+
return `${getLoggingPrefix('error')} Failed to check for updates.\n${external_pintor_default().red(String(err?.message || err))}`;
|
|
42
80
|
}
|
|
43
81
|
function checkUpdates(packageJson, update) {
|
|
44
|
-
return `${getLoggingPrefix('info')}
|
|
82
|
+
return `${getLoggingPrefix('info')} 🧩 ${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.`;
|
|
45
83
|
}
|
|
46
84
|
function programUserHelp() {
|
|
47
85
|
return `\n${getLoggingPrefix('info')} ${external_pintor_default().underline('Help center for the Extension.js program')}
|
|
@@ -56,22 +94,22 @@ Example
|
|
|
56
94
|
|
|
57
95
|
Available Commands
|
|
58
96
|
- ${code('extension create ' + arg('<project-name|project-path>'))}
|
|
59
|
-
|
|
97
|
+
${commandDescriptions.create}
|
|
60
98
|
|
|
61
99
|
- ${code('extension dev ' + arg('[project-path|remote-url]'))}
|
|
62
|
-
|
|
100
|
+
${commandDescriptions.dev}
|
|
63
101
|
|
|
64
102
|
- ${code('extension start ' + arg('[project-path|remote-url]'))}
|
|
65
|
-
|
|
103
|
+
${commandDescriptions.start}
|
|
66
104
|
|
|
67
105
|
- ${code('extension preview ' + arg('[project-path|remote-url]'))}
|
|
68
|
-
|
|
106
|
+
${commandDescriptions.preview}
|
|
69
107
|
|
|
70
108
|
- ${code('extension build ' + arg('[project-path|remote-url]'))}
|
|
71
|
-
|
|
109
|
+
${commandDescriptions.build}
|
|
72
110
|
|
|
73
111
|
- ${code('extension cleanup')}
|
|
74
|
-
|
|
112
|
+
${commandDescriptions.cleanup}
|
|
75
113
|
|
|
76
114
|
Common Options
|
|
77
115
|
- ${code('--browser')} ${arg('<chrome|edge|firefox|chromium|chromium-based|gecko-based|firefox-based>')} Target browser/engine (default: chrome)
|
|
@@ -144,7 +182,7 @@ Centralized Logger (for AI & CI)
|
|
|
144
182
|
- ${code('--no-log-color')} ${arg(' ')} Disable ANSI colors (pretty)
|
|
145
183
|
- ${code('--log-url')} ${arg('<substring|/regex/>')} Filter by URL
|
|
146
184
|
- ${code('--log-tab')} ${arg('<id>')} Filter by tabId
|
|
147
|
-
- Good CI pattern: ${code('
|
|
185
|
+
- Good CI pattern: ${code('EXTENSION_AUTHOR_MODE=development EXTENSION_AUTO_EXIT_MS=6000 extension dev ./ext --logs=info --log-format=json')}
|
|
148
186
|
|
|
149
187
|
Special Folders for Entrypoints
|
|
150
188
|
- Use special folders to handle entrypoints and assets not declared in manifest.json:
|
|
@@ -154,17 +192,17 @@ Special Folders for Entrypoints
|
|
|
154
192
|
|
|
155
193
|
Predictable Output Paths
|
|
156
194
|
- Core HTML destinations are standardized across browsers so you can reference them safely in code/tests:
|
|
157
|
-
- ${code('devtools_page')}
|
|
158
|
-
- ${code('sidebar_action.default_panel')} (MV2) and ${code('side_panel.default_path')} (MV3)
|
|
159
|
-
- ${code('options_ui.page')} and ${code('options_page')}
|
|
160
|
-
- ${code('background.page')}
|
|
161
|
-
- ${code('action.default_popup')}, ${code('browser_action.default_popup')}, ${code('page_action.default_popup')}
|
|
195
|
+
- ${code('devtools_page')} → ${code('devtools/index.html')}
|
|
196
|
+
- ${code('sidebar_action.default_panel')} (MV2) and ${code('side_panel.default_path')} (MV3) → ${code('sidebar/index.html')}
|
|
197
|
+
- ${code('options_ui.page')} and ${code('options_page')} → ${code('options/index.html')}
|
|
198
|
+
- ${code('background.page')} → ${code('background/index.html')}
|
|
199
|
+
- ${code('action.default_popup')}, ${code('browser_action.default_popup')}, ${code('page_action.default_popup')} → ${code('action/index.html')}
|
|
162
200
|
- Other predictable outputs:
|
|
163
|
-
- ${code('chrome_url_overrides.*')}
|
|
164
|
-
- ${code("content_scripts[n].js/css")}
|
|
165
|
-
- ${code('sandbox.pages[]')}
|
|
166
|
-
- ${code("user_scripts.api_script")}
|
|
167
|
-
- ${code('icons/*')}
|
|
201
|
+
- ${code('chrome_url_overrides.*')} → ${code('chrome_url_overrides/<key>.html')}
|
|
202
|
+
- ${code("content_scripts[n].js/css")} → ${code("content_scripts/content-<n>.{js,css}")}
|
|
203
|
+
- ${code('sandbox.pages[]')} → ${code('sandbox/page-<n>.html')}
|
|
204
|
+
- ${code("user_scripts.api_script")} → ${code("user_scripts/api_script.js")}
|
|
205
|
+
- ${code('icons/*')} → ${code('icons/')} (feature-specific icon folders preserved where applicable)
|
|
168
206
|
|
|
169
207
|
Public & Special Folders (Output Behavior)
|
|
170
208
|
- ${external_pintor_default().underline(code('public/'))} is the web root in output. Authors can use ${code('/foo')}, ${code('/public/foo')}, ${code('public/foo')}, or ${code('./public/foo')} and they all emit as ${code('dist/<browser>/foo')}.
|
|
@@ -237,7 +275,7 @@ Source Inspection & Real-Time Monitoring
|
|
|
237
275
|
- Example: ${code('extension dev --source=' + arg('https://example.com'))}
|
|
238
276
|
|
|
239
277
|
Non-Destructive Testing in CI
|
|
240
|
-
- Prefer ${code('
|
|
278
|
+
- Prefer ${code('EXTENSION_AUTHOR_MODE=development')} to copy local templates and avoid network.
|
|
241
279
|
- Reuse Playwright's Chromium via ${code('--chromium-binary')} path when available.
|
|
242
280
|
- Set ${code(arg('EXTENSION_AUTO_EXIT_MS'))} and ${code(arg('EXTENSION_FORCE_KILL_MS'))} for non-interactive dev sessions.
|
|
243
281
|
|
|
@@ -271,7 +309,7 @@ async function check_updates_checkUpdates(packageJson) {
|
|
|
271
309
|
try {
|
|
272
310
|
update = await external_update_check_default()(packageJson);
|
|
273
311
|
} catch (err) {
|
|
274
|
-
if ('
|
|
312
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.error(updateFailed(err));
|
|
275
313
|
}
|
|
276
314
|
if (update && isStableVersion(update.latest)) console.log(checkUpdates(packageJson, update));
|
|
277
315
|
}
|
|
@@ -412,29 +450,28 @@ class Telemetry {
|
|
|
412
450
|
this.track('cli_telemetry_consent', {
|
|
413
451
|
value: 'implicit_opt_in'
|
|
414
452
|
});
|
|
415
|
-
console.log('[extension] anonymous telemetry helps us improve. Pass --no-telemetry to opt out. Read more in TELEMETRY.md
|
|
453
|
+
console.log(`${external_pintor_default().gray('►►► system')} [extension] anonymous telemetry helps us improve. Pass --no-telemetry to opt out. Read more in TELEMETRY.md.`);
|
|
416
454
|
}
|
|
417
455
|
}
|
|
418
456
|
}
|
|
419
457
|
}
|
|
420
458
|
function summarizeManifest(manifest) {
|
|
421
|
-
|
|
422
|
-
const
|
|
423
|
-
const
|
|
424
|
-
const
|
|
425
|
-
const hostPermissions = Array.isArray(null == manifest ? void 0 : manifest.host_permissions) ? manifest.host_permissions : [];
|
|
459
|
+
const mv = manifest?.manifest_version === 2 ? 2 : 3;
|
|
460
|
+
const permissions = Array.isArray(manifest?.permissions) ? manifest.permissions : [];
|
|
461
|
+
const optionalPermissions = Array.isArray(manifest?.optional_permissions) ? manifest.optional_permissions : [];
|
|
462
|
+
const hostPermissions = Array.isArray(manifest?.host_permissions) ? manifest.host_permissions : [];
|
|
426
463
|
const usesAllUrls = [
|
|
427
464
|
...permissions,
|
|
428
465
|
...hostPermissions
|
|
429
466
|
].includes('<all_urls>');
|
|
430
467
|
const usesDeclarativeNetRequest = permissions.includes('declarativeNetRequest') || permissions.includes('declarativeNetRequestWithHostAccess');
|
|
431
|
-
const background =
|
|
468
|
+
const background = manifest?.background;
|
|
432
469
|
let backgroundType = 'none';
|
|
433
|
-
if (3 === mv &&
|
|
434
|
-
else if (2 === mv && (Array.isArray(
|
|
435
|
-
const contentScriptsCount = Array.isArray(
|
|
436
|
-
const hasDevtoolsPage = Boolean(
|
|
437
|
-
const hasActionPopup = Boolean(
|
|
470
|
+
if (3 === mv && background?.service_worker) backgroundType = 'service_worker';
|
|
471
|
+
else if (2 === mv && (Array.isArray(background?.scripts) && background.scripts.length > 0 || background?.page)) backgroundType = 'event_page';
|
|
472
|
+
const contentScriptsCount = Array.isArray(manifest?.content_scripts) ? manifest.content_scripts.length : 0;
|
|
473
|
+
const hasDevtoolsPage = Boolean(manifest?.devtools_page);
|
|
474
|
+
const hasActionPopup = Boolean(manifest?.action?.default_popup);
|
|
438
475
|
return {
|
|
439
476
|
mv,
|
|
440
477
|
permissions_count: permissions.length,
|
|
@@ -452,6 +489,28 @@ function isTelemetryDisabledFromArgs(argv) {
|
|
|
452
489
|
return argv.includes('--no-telemetry');
|
|
453
490
|
}
|
|
454
491
|
const telemetryDisabled = isTelemetryDisabledFromArgs(process.argv);
|
|
492
|
+
function findManifestJson(projectRoot) {
|
|
493
|
+
const stack = [
|
|
494
|
+
projectRoot
|
|
495
|
+
];
|
|
496
|
+
while(stack.length > 0){
|
|
497
|
+
const dir = stack.pop();
|
|
498
|
+
if (!dir) continue;
|
|
499
|
+
let entries;
|
|
500
|
+
try {
|
|
501
|
+
entries = external_fs_default().readdirSync(dir, {
|
|
502
|
+
withFileTypes: true
|
|
503
|
+
});
|
|
504
|
+
} catch {
|
|
505
|
+
continue;
|
|
506
|
+
}
|
|
507
|
+
for (const entry of entries){
|
|
508
|
+
if (entry.isFile() && 'manifest.json' === entry.name) return external_path_default().join(dir, entry.name);
|
|
509
|
+
if (entry.isDirectory() && !entry.name.startsWith('.') && 'node_modules' !== entry.name && 'dist' !== entry.name) stack.push(external_path_default().join(dir, entry.name));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
455
514
|
const telemetry_cli_telemetry = new Telemetry({
|
|
456
515
|
app: 'extension',
|
|
457
516
|
version: package_namespaceObject.version,
|
|
@@ -471,9 +530,8 @@ if (!telemetryDisabled) {
|
|
|
471
530
|
telemetry_cli_telemetry.track('cli_boot', {
|
|
472
531
|
command_guess: invoked
|
|
473
532
|
});
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
if (external_fs_default().existsSync(manifestPath)) {
|
|
533
|
+
const manifestPath = findManifestJson(process.cwd());
|
|
534
|
+
if (manifestPath) {
|
|
477
535
|
const raw = external_fs_default().readFileSync(manifestPath, 'utf8');
|
|
478
536
|
const json = JSON.parse(raw);
|
|
479
537
|
const summary = summarizeManifest(json);
|
|
@@ -490,19 +548,17 @@ if (!telemetryDisabled) {
|
|
|
490
548
|
process.on('uncaughtException', function(err) {
|
|
491
549
|
telemetry_cli_telemetry.track('cli_error', {
|
|
492
550
|
command_guess: invoked,
|
|
493
|
-
error_name: String(
|
|
551
|
+
error_name: String(err?.name || 'Error').slice(0, 64)
|
|
494
552
|
});
|
|
495
553
|
});
|
|
496
554
|
process.on('unhandledRejection', function(reason) {
|
|
497
555
|
telemetry_cli_telemetry.track('cli_error', {
|
|
498
556
|
command_guess: invoked,
|
|
499
|
-
error_name: String(
|
|
557
|
+
error_name: String(reason?.name || 'PromiseRejection').slice(0, 64)
|
|
500
558
|
});
|
|
501
559
|
});
|
|
502
560
|
}
|
|
503
|
-
|
|
504
|
-
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
505
|
-
const external_node_url_namespaceObject = require("node:url");
|
|
561
|
+
require("node:url");
|
|
506
562
|
function parseOptionalBoolean(value) {
|
|
507
563
|
if (void 0 === value) return true;
|
|
508
564
|
const normalized = String(value).trim().toLowerCase();
|
|
@@ -513,87 +569,6 @@ function parseOptionalBoolean(value) {
|
|
|
513
569
|
'off'
|
|
514
570
|
].includes(normalized);
|
|
515
571
|
}
|
|
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
|
|
531
|
-
});
|
|
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
|
-
}
|
|
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);
|
|
593
|
-
}
|
|
594
|
-
} catch {}
|
|
595
|
-
return await import((0, external_node_url_namespaceObject.pathToFileURL)(external_node_path_default().join(modulePath, 'dist', 'module.js')).href);
|
|
596
|
-
}
|
|
597
572
|
const vendors = (browser)=>{
|
|
598
573
|
const value = browser ?? 'chromium';
|
|
599
574
|
return 'all' === value ? [
|
|
@@ -618,7 +593,7 @@ function validateVendorsOrExit(vendorsList, onInvalid) {
|
|
|
618
593
|
}
|
|
619
594
|
}
|
|
620
595
|
function registerCreateCommand(program, telemetry) {
|
|
621
|
-
program.command('create').arguments('<project-name|project-path>').usage('create <project-name|project-path> [options]').description(
|
|
596
|
+
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 (enabled by default)', parseOptionalBoolean, true).action(async function(pathOrRemoteUrl, { template, install }) {
|
|
622
597
|
const startedAt = Date.now();
|
|
623
598
|
telemetry.track('cli_command_start', {
|
|
624
599
|
command: 'create',
|
|
@@ -626,11 +601,21 @@ function registerCreateCommand(program, telemetry) {
|
|
|
626
601
|
install: Boolean(install)
|
|
627
602
|
});
|
|
628
603
|
try {
|
|
629
|
-
await (
|
|
604
|
+
const { extensionCreate } = await import("extension-create");
|
|
605
|
+
const { ensureDependencies, preflightOptionalDependenciesForProject } = await import("extension-develop");
|
|
606
|
+
const projectPath = external_path_namespaceObject.isAbsolute(pathOrRemoteUrl) ? pathOrRemoteUrl : external_path_namespaceObject.join(process.cwd(), pathOrRemoteUrl);
|
|
607
|
+
await extensionCreate(pathOrRemoteUrl, {
|
|
630
608
|
template,
|
|
631
609
|
install,
|
|
632
610
|
cliVersion: package_namespaceObject.version
|
|
633
611
|
});
|
|
612
|
+
if (install) {
|
|
613
|
+
await ensureDependencies(projectPath, {
|
|
614
|
+
skipProjectInstall: true,
|
|
615
|
+
showRunAgainMessage: false
|
|
616
|
+
});
|
|
617
|
+
await preflightOptionalDependenciesForProject(projectPath, 'development');
|
|
618
|
+
}
|
|
634
619
|
telemetry.track('cli_command_finish', {
|
|
635
620
|
command: 'create',
|
|
636
621
|
duration_ms: Date.now() - startedAt,
|
|
@@ -648,9 +633,30 @@ function registerCreateCommand(program, telemetry) {
|
|
|
648
633
|
}
|
|
649
634
|
});
|
|
650
635
|
}
|
|
636
|
+
function normalizeSourceOption(source, startingUrl) {
|
|
637
|
+
if (!source) return;
|
|
638
|
+
const hasExplicitSourceString = 'string' == typeof source && 'true' !== String(source).trim().toLowerCase();
|
|
639
|
+
const hasStartingUrl = 'string' == typeof startingUrl && String(startingUrl).trim().length > 0;
|
|
640
|
+
if (!hasExplicitSourceString) return hasStartingUrl ? String(startingUrl) : 'https://example.com';
|
|
641
|
+
return String(source);
|
|
642
|
+
}
|
|
643
|
+
function parseLogContexts(raw) {
|
|
644
|
+
if (!raw || 0 === String(raw).trim().length) return;
|
|
645
|
+
if ('all' === String(raw).trim().toLowerCase()) return;
|
|
646
|
+
const allowed = [
|
|
647
|
+
'background',
|
|
648
|
+
'content',
|
|
649
|
+
'page',
|
|
650
|
+
'sidebar',
|
|
651
|
+
'popup',
|
|
652
|
+
'options',
|
|
653
|
+
'devtools'
|
|
654
|
+
];
|
|
655
|
+
const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
|
|
656
|
+
return values.length > 0 ? values : void 0;
|
|
657
|
+
}
|
|
651
658
|
function registerDevCommand(program, telemetry) {
|
|
652
|
-
program.command('dev').arguments('[project-path|remote-url]').usage('dev [project-path|remote-url] [options]').description(
|
|
653
|
-
var _devOptions_polyfill;
|
|
659
|
+
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 }) {
|
|
654
660
|
if (devOptions.author || devOptions['authorMode']) {
|
|
655
661
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
656
662
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
@@ -659,7 +665,7 @@ function registerDevCommand(program, telemetry) {
|
|
|
659
665
|
telemetry.track('cli_command_start', {
|
|
660
666
|
command: 'dev',
|
|
661
667
|
vendors: vendors(browser),
|
|
662
|
-
polyfill_used:
|
|
668
|
+
polyfill_used: devOptions.polyfill?.toString() !== 'false',
|
|
663
669
|
log_level: devOptions.logLevel || 'off',
|
|
664
670
|
log_format: devOptions.logFormat || 'pretty',
|
|
665
671
|
custom_binary_used: Boolean(devOptions.chromiumBinary || devOptions.geckoBinary)
|
|
@@ -668,22 +674,13 @@ function registerDevCommand(program, telemetry) {
|
|
|
668
674
|
validateVendorsOrExit(list, (invalid, supported)=>{
|
|
669
675
|
console.error(unsupportedBrowserFlag(invalid, supported));
|
|
670
676
|
});
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
if (!hasExplicitSourceString) devOptions.source = hasStartingUrl ? String(devOptions.startingUrl) : 'https://example.com';
|
|
677
|
+
const normalizedSource = normalizeSourceOption(devOptions.source, devOptions.startingUrl);
|
|
678
|
+
if (normalizedSource) {
|
|
679
|
+
devOptions.source = normalizedSource;
|
|
675
680
|
devOptions.watchSource = true;
|
|
676
681
|
}
|
|
677
|
-
const
|
|
678
|
-
const major = String(package_namespaceObject.version).split('.')[0] || '2';
|
|
679
|
-
let extensionDev;
|
|
680
|
-
try {
|
|
681
|
-
({ extensionDev } = await requireOrDlx('extension-develop', versionExact));
|
|
682
|
-
} catch {
|
|
683
|
-
({ extensionDev } = await requireOrDlx('extension-develop', major));
|
|
684
|
-
}
|
|
682
|
+
const { extensionDev } = await import("extension-develop");
|
|
685
683
|
for (const vendor of list){
|
|
686
|
-
var _devOptions_polyfill1;
|
|
687
684
|
const vendorStart = Date.now();
|
|
688
685
|
telemetry.track('cli_vendor_start', {
|
|
689
686
|
command: 'dev',
|
|
@@ -697,28 +694,13 @@ function registerDevCommand(program, telemetry) {
|
|
|
697
694
|
browser: vendor,
|
|
698
695
|
chromiumBinary: devOptions.chromiumBinary,
|
|
699
696
|
geckoBinary: devOptions.geckoBinary,
|
|
700
|
-
polyfill:
|
|
697
|
+
polyfill: devOptions.polyfill?.toString() !== 'false',
|
|
701
698
|
open: devOptions.open,
|
|
702
699
|
startingUrl: devOptions.startingUrl,
|
|
703
700
|
source: devOptions.source,
|
|
704
701
|
watchSource: devOptions.watchSource,
|
|
705
702
|
logLevel: logsOption || devOptions.logLevel || 'off',
|
|
706
|
-
logContexts: (
|
|
707
|
-
const raw = logContextOption || devOptions.logContexts;
|
|
708
|
-
if (!raw || 0 === String(raw).trim().length) return;
|
|
709
|
-
if ('all' === String(raw).trim().toLowerCase()) return;
|
|
710
|
-
const allowed = [
|
|
711
|
-
'background',
|
|
712
|
-
'content',
|
|
713
|
-
'page',
|
|
714
|
-
'sidebar',
|
|
715
|
-
'popup',
|
|
716
|
-
'options',
|
|
717
|
-
'devtools'
|
|
718
|
-
];
|
|
719
|
-
const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
|
|
720
|
-
return values.length ? values : void 0;
|
|
721
|
-
})(),
|
|
703
|
+
logContexts: parseLogContexts(logContextOption),
|
|
722
704
|
logFormat: devOptions.logFormat || 'pretty',
|
|
723
705
|
logTimestamps: false !== devOptions.logTimestamps,
|
|
724
706
|
logColor: false !== devOptions.logColor,
|
|
@@ -741,9 +723,8 @@ function registerDevCommand(program, telemetry) {
|
|
|
741
723
|
});
|
|
742
724
|
}
|
|
743
725
|
function registerStartCommand(program, telemetry) {
|
|
744
|
-
program.command('start').arguments('[project-path|remote-url]').usage('start [project-path|remote-url] [options]').description(
|
|
745
|
-
|
|
746
|
-
if (startOptions.author || startOptions['authorMode']) {
|
|
726
|
+
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 }) {
|
|
727
|
+
if (startOptions.author || startOptions.authorMode) {
|
|
747
728
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
748
729
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
749
730
|
}
|
|
@@ -751,14 +732,13 @@ function registerStartCommand(program, telemetry) {
|
|
|
751
732
|
telemetry.track('cli_command_start', {
|
|
752
733
|
command: 'start',
|
|
753
734
|
vendors: vendors(browser),
|
|
754
|
-
polyfill_used:
|
|
735
|
+
polyfill_used: startOptions.polyfill?.toString() !== 'false'
|
|
755
736
|
});
|
|
756
737
|
const list = vendors(browser);
|
|
757
738
|
validateVendorsOrExit(list, (invalid, supported)=>{
|
|
758
739
|
console.error(unsupportedBrowserFlag(invalid, supported));
|
|
759
740
|
});
|
|
760
|
-
const
|
|
761
|
-
const { extensionStart } = await requireOrDlx('extension-develop', major);
|
|
741
|
+
const { extensionStart } = await import("extension-develop");
|
|
762
742
|
for (const vendor of list){
|
|
763
743
|
const vendorStart = Date.now();
|
|
764
744
|
telemetry.track('cli_vendor_start', {
|
|
@@ -767,22 +747,7 @@ function registerStartCommand(program, telemetry) {
|
|
|
767
747
|
});
|
|
768
748
|
const logsOption = startOptions.logs;
|
|
769
749
|
const logContextOption = startOptions.logContext;
|
|
770
|
-
const logContexts = (
|
|
771
|
-
const raw = logContextOption || startOptions.logContexts;
|
|
772
|
-
if (!raw || 0 === String(raw).trim().length) return;
|
|
773
|
-
if ('all' === String(raw).trim().toLowerCase()) return;
|
|
774
|
-
const allowed = [
|
|
775
|
-
'background',
|
|
776
|
-
'content',
|
|
777
|
-
'page',
|
|
778
|
-
'sidebar',
|
|
779
|
-
'popup',
|
|
780
|
-
'options',
|
|
781
|
-
'devtools'
|
|
782
|
-
];
|
|
783
|
-
const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
|
|
784
|
-
return values.length ? values : void 0;
|
|
785
|
-
})();
|
|
750
|
+
const logContexts = parseLogContexts(logContextOption);
|
|
786
751
|
await extensionStart(pathOrRemoteUrl, {
|
|
787
752
|
mode: 'production',
|
|
788
753
|
profile: startOptions.profile,
|
|
@@ -816,7 +781,7 @@ function registerStartCommand(program, telemetry) {
|
|
|
816
781
|
});
|
|
817
782
|
}
|
|
818
783
|
function registerPreviewCommand(program, telemetry) {
|
|
819
|
-
program.command('preview').arguments('[project-name]').usage('preview [path-to-remote-extension] [options]').description(
|
|
784
|
+
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 }) {
|
|
820
785
|
if (previewOptions.author || previewOptions['authorMode']) {
|
|
821
786
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
822
787
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
@@ -834,8 +799,7 @@ function registerPreviewCommand(program, telemetry) {
|
|
|
834
799
|
const isRemote = 'string' == typeof pathOrRemoteUrl && /^https?:/i.test(pathOrRemoteUrl);
|
|
835
800
|
if (isRemote) process.env.EXTJS_LIGHT = '1';
|
|
836
801
|
}
|
|
837
|
-
const
|
|
838
|
-
const { extensionPreview } = await requireOrDlx('extension-develop', major);
|
|
802
|
+
const { extensionPreview } = await import("extension-develop");
|
|
839
803
|
for (const vendor of list){
|
|
840
804
|
const vendorStart = Date.now();
|
|
841
805
|
telemetry.track('cli_vendor_start', {
|
|
@@ -844,22 +808,7 @@ function registerPreviewCommand(program, telemetry) {
|
|
|
844
808
|
});
|
|
845
809
|
const logsOption = previewOptions.logs;
|
|
846
810
|
const logContextOption = previewOptions.logContext;
|
|
847
|
-
const logContexts = (
|
|
848
|
-
const raw = logContextOption || previewOptions.logContexts;
|
|
849
|
-
if (!raw || 0 === String(raw).trim().length) return;
|
|
850
|
-
if ('all' === String(raw).trim().toLowerCase()) return;
|
|
851
|
-
const allowed = [
|
|
852
|
-
'background',
|
|
853
|
-
'content',
|
|
854
|
-
'page',
|
|
855
|
-
'sidebar',
|
|
856
|
-
'popup',
|
|
857
|
-
'options',
|
|
858
|
-
'devtools'
|
|
859
|
-
];
|
|
860
|
-
const values = String(raw).split(',').map((s)=>s.trim()).filter((s)=>s.length > 0).filter((c)=>allowed.includes(c));
|
|
861
|
-
return values.length ? values : void 0;
|
|
862
|
-
})();
|
|
811
|
+
const logContexts = parseLogContexts(logContextOption);
|
|
863
812
|
await extensionPreview(pathOrRemoteUrl, {
|
|
864
813
|
mode: 'production',
|
|
865
814
|
profile: previewOptions.profile,
|
|
@@ -893,7 +842,7 @@ function registerPreviewCommand(program, telemetry) {
|
|
|
893
842
|
});
|
|
894
843
|
}
|
|
895
844
|
function registerBuildCommand(program, telemetry) {
|
|
896
|
-
program.command('build').arguments('[project-name]').usage('build [path-to-remote-extension] [options]').description(
|
|
845
|
+
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 }) {
|
|
897
846
|
if (buildOptions.author || buildOptions['authorMode']) {
|
|
898
847
|
process.env.EXTENSION_AUTHOR_MODE = 'true';
|
|
899
848
|
if (!process.env.EXTENSION_VERBOSE) process.env.EXTENSION_VERBOSE = '1';
|
|
@@ -910,8 +859,7 @@ function registerBuildCommand(program, telemetry) {
|
|
|
910
859
|
validateVendorsOrExit(list, (invalid, supported)=>{
|
|
911
860
|
console.error(unsupportedBrowserFlag(invalid, supported));
|
|
912
861
|
});
|
|
913
|
-
const
|
|
914
|
-
const { extensionBuild } = await requireOrDlx('extension-develop', major);
|
|
862
|
+
const { extensionBuild } = await import("extension-develop");
|
|
915
863
|
for (const vendor of list){
|
|
916
864
|
const vendorStart = Date.now();
|
|
917
865
|
telemetry.track('cli_vendor_start', {
|
|
@@ -959,8 +907,11 @@ if (process.argv.length <= 2) {
|
|
|
959
907
|
extensionJs.outputHelp();
|
|
960
908
|
process.exit(0);
|
|
961
909
|
}
|
|
962
|
-
extensionJs.
|
|
963
|
-
|
|
910
|
+
extensionJs.parseAsync().catch((err)=>{
|
|
911
|
+
console.error(unhandledError(err));
|
|
912
|
+
process.exit(1);
|
|
913
|
+
});
|
|
914
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
964
915
|
Object.defineProperty(exports, '__esModule', {
|
|
965
916
|
value: true
|
|
966
917
|
});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare function normalizeSourceOption(source: boolean | string | undefined, startingUrl?: string): string | undefined;
|
|
2
|
+
export declare function parseLogContexts(raw: string | undefined): Array<'background' | 'content' | 'page' | 'sidebar' | 'popup' | 'options' | 'devtools'> | undefined;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
export declare function resolveModuleEntry(modulePath: string, pkgJson: any): string | undefined;
|
|
1
2
|
export type Browser = 'chrome' | 'edge' | 'firefox' | 'chromium' | 'chromium-based' | 'gecko-based' | 'firefox-based';
|
|
2
3
|
export declare function parseOptionalBoolean(value?: string): boolean;
|
|
3
|
-
export declare function requireOrDlx(moduleName: string, versionHint?: string): Promise<any>;
|
|
4
4
|
export declare const vendors: (browser?: Browser | "all") => string[];
|
|
5
5
|
export declare function validateVendorsOrExit(vendorsList: string[], onInvalid: (invalid: string, supported: string[]) => void): void;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"license": "MIT",
|
|
3
3
|
"repository": {
|
|
4
4
|
"type": "git",
|
|
5
|
-
"url": "https://github.com/extension-js/extension.js",
|
|
5
|
+
"url": "git+https://github.com/extension-js/extension.js.git",
|
|
6
6
|
"directory": "programs/cli"
|
|
7
7
|
},
|
|
8
8
|
"engines": {
|
|
@@ -35,9 +35,12 @@
|
|
|
35
35
|
"extension": "./dist/cli.js"
|
|
36
36
|
},
|
|
37
37
|
"name": "extension",
|
|
38
|
-
"version": "3.
|
|
38
|
+
"version": "3.1.0-next.10",
|
|
39
39
|
"description": "Create cross-browser extensions with no build configuration.",
|
|
40
40
|
"homepage": "https://extension.js.org/",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/extension-js/extension.js/issues"
|
|
43
|
+
},
|
|
41
44
|
"author": {
|
|
42
45
|
"name": "Cezar Augusto",
|
|
43
46
|
"email": "boss@cezaraugusto.net",
|
|
@@ -45,12 +48,10 @@
|
|
|
45
48
|
},
|
|
46
49
|
"publishConfig": {
|
|
47
50
|
"access": "public",
|
|
48
|
-
"registry": "https://registry.npmjs.org"
|
|
49
|
-
"tag": "latest"
|
|
51
|
+
"registry": "https://registry.npmjs.org"
|
|
50
52
|
},
|
|
51
53
|
"scripts": {
|
|
52
|
-
"
|
|
53
|
-
"postinstall": "rslib build >/dev/null 2>&1 || true",
|
|
54
|
+
"prepublishOnly": "pnpm run compile",
|
|
54
55
|
"compile": "rslib build",
|
|
55
56
|
"watch": "rslib build --watch",
|
|
56
57
|
"test": "vitest run"
|
|
@@ -87,25 +88,26 @@
|
|
|
87
88
|
"cli"
|
|
88
89
|
],
|
|
89
90
|
"dependencies": {
|
|
90
|
-
"
|
|
91
|
-
"extension-
|
|
91
|
+
"extension-create": "^3.1.0-next.10",
|
|
92
|
+
"extension-develop": "^3.1.0-next.10",
|
|
93
|
+
"commander": "^14.0.2",
|
|
92
94
|
"pintor": "0.3.0",
|
|
93
|
-
"semver": "^7.
|
|
95
|
+
"semver": "^7.7.3",
|
|
94
96
|
"update-check": "^1.5.4"
|
|
95
97
|
},
|
|
96
98
|
"devDependencies": {
|
|
97
|
-
"@rslib/core": "^0.
|
|
98
|
-
"@types/chrome": "^0.
|
|
99
|
-
"@types/node": "^
|
|
100
|
-
"@types/react": "^19.
|
|
101
|
-
"@types/react-dom": "^19.
|
|
102
|
-
"@types/webextension-polyfill": "0.12.
|
|
99
|
+
"@rslib/core": "^0.19.2",
|
|
100
|
+
"@types/chrome": "^0.1.33",
|
|
101
|
+
"@types/node": "^25.0.9",
|
|
102
|
+
"@types/react": "^19.2.8",
|
|
103
|
+
"@types/react-dom": "^19.2.3",
|
|
104
|
+
"@types/webextension-polyfill": "0.12.4",
|
|
103
105
|
"@types/mock-fs": "^4.13.4",
|
|
104
|
-
"@types/semver": "^7.
|
|
105
|
-
"mock-fs": "^5.
|
|
106
|
+
"@types/semver": "^7.7.1",
|
|
107
|
+
"mock-fs": "^5.5.0",
|
|
106
108
|
"webextension-polyfill": "^0.12.0",
|
|
107
109
|
"tsconfig": "*",
|
|
108
|
-
"typescript": "5.
|
|
109
|
-
"vitest": "^
|
|
110
|
+
"typescript": "5.9.3",
|
|
111
|
+
"vitest": "^4.0.17"
|
|
110
112
|
}
|
|
111
113
|
}
|
package/types/css-content.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
1
9
|
type CSSContentData = Readonly<Record<string, string>>
|
|
2
10
|
|
|
3
11
|
declare module '*.css' {
|
package/types/css-modules.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
1
9
|
type CSSModuleData = Readonly<Record<string, string>>
|
|
2
10
|
|
|
3
11
|
declare module '*.module.css' {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
9
|
+
declare module 'extension-create' {
|
|
10
|
+
// These types mirror the public surface of programs/create/module.ts,
|
|
11
|
+
// but are intentionally loose on the CLI side. The real, precise types
|
|
12
|
+
// come from the installed `extension-create` package when consumers
|
|
13
|
+
// depend on it directly.
|
|
14
|
+
export interface CreateOptions {
|
|
15
|
+
template: string
|
|
16
|
+
install?: boolean
|
|
17
|
+
cliVersion?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function extensionCreate(
|
|
21
|
+
projectNameInput: string | undefined,
|
|
22
|
+
options: CreateOptions
|
|
23
|
+
): Promise<void>
|
|
24
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
9
|
+
declare module 'extension-develop' {
|
|
10
|
+
// These types mirror the public surface of programs/develop/module.ts,
|
|
11
|
+
// but are intentionally loose on the CLI side. The real, precise types
|
|
12
|
+
// come from the installed `extension-develop` package when consumers
|
|
13
|
+
// depend on it directly.
|
|
14
|
+
|
|
15
|
+
export type ExtensionBrowser =
|
|
16
|
+
| 'chrome'
|
|
17
|
+
| 'edge'
|
|
18
|
+
| 'firefox'
|
|
19
|
+
| 'chromium'
|
|
20
|
+
| 'chromium-based'
|
|
21
|
+
| 'gecko-based'
|
|
22
|
+
| 'firefox-based'
|
|
23
|
+
|
|
24
|
+
export type ExtensionMode = 'development' | 'production'
|
|
25
|
+
|
|
26
|
+
export interface BuildOptions {
|
|
27
|
+
browser?: ExtensionBrowser | 'all'
|
|
28
|
+
polyfill?: boolean
|
|
29
|
+
zip?: boolean
|
|
30
|
+
zipSource?: boolean
|
|
31
|
+
zipFilename?: string
|
|
32
|
+
silent?: boolean
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface DevOptions {
|
|
36
|
+
browser?: ExtensionBrowser | 'all'
|
|
37
|
+
profile?: string | boolean
|
|
38
|
+
persistProfile?: boolean
|
|
39
|
+
chromiumBinary?: string
|
|
40
|
+
geckoBinary?: string
|
|
41
|
+
polyfill?: boolean | string
|
|
42
|
+
open?: boolean
|
|
43
|
+
startingUrl?: string
|
|
44
|
+
source?: boolean | string
|
|
45
|
+
watchSource?: boolean
|
|
46
|
+
logLevel?: string
|
|
47
|
+
logFormat?: 'pretty' | 'json'
|
|
48
|
+
logTimestamps?: boolean
|
|
49
|
+
logColor?: boolean
|
|
50
|
+
logUrl?: string
|
|
51
|
+
logTab?: string | number
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface PreviewOptions extends DevOptions {}
|
|
55
|
+
|
|
56
|
+
export interface StartOptions extends DevOptions {}
|
|
57
|
+
|
|
58
|
+
export interface FileConfig {
|
|
59
|
+
[key: string]: unknown
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface Manifest {
|
|
63
|
+
[key: string]: unknown
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function extensionBuild(
|
|
67
|
+
pathOrRemoteUrl: string,
|
|
68
|
+
options: BuildOptions
|
|
69
|
+
): Promise<any>
|
|
70
|
+
|
|
71
|
+
export function extensionDev(
|
|
72
|
+
pathOrRemoteUrl: string,
|
|
73
|
+
options: DevOptions
|
|
74
|
+
): Promise<any>
|
|
75
|
+
|
|
76
|
+
export function extensionStart(
|
|
77
|
+
pathOrRemoteUrl: string,
|
|
78
|
+
options: StartOptions
|
|
79
|
+
): Promise<any>
|
|
80
|
+
|
|
81
|
+
export function extensionPreview(
|
|
82
|
+
pathOrRemoteUrl: string,
|
|
83
|
+
options: PreviewOptions
|
|
84
|
+
): Promise<any>
|
|
85
|
+
|
|
86
|
+
export function ensureDependencies(
|
|
87
|
+
projectPath?: string,
|
|
88
|
+
opts?: {
|
|
89
|
+
skipProjectInstall?: boolean
|
|
90
|
+
exitOnInstall?: boolean
|
|
91
|
+
showRunAgainMessage?: boolean
|
|
92
|
+
}
|
|
93
|
+
): Promise<{
|
|
94
|
+
installed: boolean
|
|
95
|
+
installedBuild: boolean
|
|
96
|
+
installedUser: boolean
|
|
97
|
+
}>
|
|
98
|
+
|
|
99
|
+
export function preflightOptionalDependenciesForProject(
|
|
100
|
+
pathOrRemoteUrl: string,
|
|
101
|
+
mode?: ExtensionMode
|
|
102
|
+
): Promise<void>
|
|
103
|
+
}
|
package/types/images.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
1
9
|
declare module '*.png' {
|
|
2
10
|
const content: string
|
|
3
11
|
|
package/types/index.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
1
9
|
/// <reference types="node" />
|
|
2
10
|
/// <reference types="chrome" />
|
|
3
11
|
/// <reference types="./js-frameworks.d.ts" />
|
|
@@ -20,8 +28,7 @@ interface ExtensionEnv {
|
|
|
20
28
|
EXTENSION_PUBLIC_BROWSER: ExtensionBrowser
|
|
21
29
|
EXTENSION_PUBLIC_MODE: ExtensionMode
|
|
22
30
|
EXTENSION_PUBLIC_DESCRIPTION_TEXT: string
|
|
23
|
-
|
|
24
|
-
EXTENSION_ENV: ExtensionMode
|
|
31
|
+
EXTENSION_PUBLIC_LLM_API_KEY: string
|
|
25
32
|
EXTENSION_AUTHOR_MODE: string
|
|
26
33
|
EXTENSION_PUBLIC_AUTHOR_MODE: string
|
|
27
34
|
}
|
package/types/index.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
1
9
|
/// <reference types="node" />
|
|
2
10
|
/// <reference types="react" />
|
|
3
11
|
/// <reference types="react-dom" />
|
package/types/js-frameworks.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
1
9
|
/// <reference types="react" />
|
|
2
10
|
/// <reference types="react-dom" />
|
|
3
11
|
/// <reference types="svelte" />
|
package/types/polyfill.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// ██████╗██╗ ██╗
|
|
2
|
+
// ██╔════╝██║ ██║
|
|
3
|
+
// ██║ ██║ ██║
|
|
4
|
+
// ██║ ██║ ██║
|
|
5
|
+
// ╚██████╗███████╗██║
|
|
6
|
+
// ╚═════╝╚══════╝╚═╝
|
|
7
|
+
// MIT License (c) 2020–present Cezar Augusto & the Extension.js authors — presence implies inheritance
|
|
8
|
+
|
|
1
9
|
/// <reference types="webextension-polyfill" />
|
|
2
10
|
|
|
3
11
|
declare global {
|