extension 2.0.0-rc.9 → 2.0.1

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 CHANGED
@@ -1,134 +1,83 @@
1
- [action-image]: https://github.com/extension-js/extension.js/actions/workflows/ci.yml/badge.svg?branch=main
2
- [action-url]: https://github.com/extension-js/extension.js/actions
3
- [npm-image]: https://img.shields.io/npm/v/extension.svg
4
- [npm-url]: https://npmjs.org/package/extension
5
- [downloads-image]: https://img.shields.io/npm/dm/extension.svg
1
+ [npm-version-image]: https://img.shields.io/npm/v/extension.svg?color=0971fe
2
+ [npm-version-url]: https://www.npmjs.com/package/extension
3
+ [downloads-image]: https://img.shields.io/npm/dm/extension.svg?color=2ecc40
6
4
  [downloads-url]: https://npmjs.org/package/extension
7
- [node]: https://img.shields.io/node/v/extension.svg
8
- [node-url]: https://nodejs.org
9
- [prs]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg
10
- [prs-url]: https://github.com/extension-js/extension/blob/main/CONTRIBUTING.md
11
- [snyk-image]: https://snyk.io/test/github/extension-js/extension/badge.svg
12
- [snyk-url]: https://snyk.io/test/github/extension-js/extension
13
- [fossa-image]: https://app.fossa.com/api/projects/git%2Bgithub.com%2Fcezaraugusto%2Fextension.svg?type=shield&issueType=license
14
- [fossa-url]: https://app.fossa.com/projects/git%2Bgithub.com%2Fcezaraugusto%2Fextension?ref=badge_shield&issueType=license
15
- [discord-image]: https://img.shields.io/discord/1253608412890271755?label=Discord&logo=discord&style=flat
5
+ [action-image]: https://github.com/extension-js/extension.js/actions/workflows/ci.yml/badge.svg?branch=main&color=2ecc40
6
+ [action-url]: https://github.com/extension-js/extension.js/actions
7
+ [coverage-image]: https://img.shields.io/codecov/c/github/extension-js/extension.js?color=2ecc40
8
+ [coverage-url]: https://codecov.io/github/extension-js/extension.js
9
+ [discord-image]: https://img.shields.io/discord/1253608412890271755?label=Discord&logo=discord&style=flat&color=2ecc40
16
10
  [discord-url]: https://discord.gg/v9h2RgeTSN
11
+ [snyk-image]: https://snyk.io/test/github/extension-js/extension/badge.svg?color=2ecc40
12
+ [snyk-url]: https://snyk.io/test/github/extension-js/extension
17
13
 
18
- # Extension.js [![fossa][fossa-image]][fossa-url] [![Known Vulnerabilities][snyk-image]][snyk-url] [![workflow][action-image]][action-url] [![discord][discord-image]][discord-url]
19
-
20
- <!-- > Plug-and-play, zero-config, cross-browser extension development tool. -->
21
-
22
- <!-- > Make it very easy to develop cross-browser extensions. -->
23
-
24
- <!-- <img alt="Extension.js with all the browser runners open" src="https://github.com/cezaraugusto/extension.js/assets/4672033/f0f5bbfc-e873-4856-9fdd-db2b42d9ab96">
25
- <hr> -->
26
-
27
- <img alt="Logo" align="right" src="https://user-images.githubusercontent.com/4672033/102850460-4d22aa80-43f8-11eb-82db-9efce586f73e.png" width="25%" />
14
+ > The cross-browser extension framework
28
15
 
29
- <!-- **Create cross-browser extensions with no build configuration.** -->
16
+ # Extension.js [![Version][npm-version-image]][npm-version-url] [![Downloads][downloads-image]][downloads-url] [![workflow][action-image]][action-url] [![coverage][coverage-image]][coverage-url] [![discord][discord-image]][discord-url]
30
17
 
31
- > Plug-and-play, zero-config, cross-browser extension development tool.
18
+ <img alt="Logo" align="right" src="https://avatars.githubusercontent.com/u/172809806" width="20%" />
32
19
 
33
20
  - [Create A New Extension](#create-a-new-extension) — How to create a new extension.
34
21
  - [Get Started Immediately](#get-started-immediately) — Get work done in no time.
35
- - [I have An Extension](#i-have-an-extension) - Use only specific parts of Extension.js.
22
+ - [Start From An Example](https://github.com/extension-js/extension.js/tree/main/examples) Start with your favorite tool.
23
+ - [I have An Extension](#i-have-an-extension) — Use only specific parts of Extension.js.
36
24
 
37
- Extension.js is a plug-and-play, zero-config, cross-browser extension development tool with built-in support for TypeScript, WebAssembly, and modern JavaScript.
25
+ Extension.js makes it very easy to develop cross-browser extensions.<br />Developers prefer it for its fast builds, unified interface, and zero configuration setup.
38
26
 
39
27
  ## Create A New Extension
40
28
 
29
+ Use the `create` command to generate a new extension. Also works with pnpm, yarn, and bun.
30
+
41
31
  ```bash
42
- npx extension create my-extension
32
+ npx extension@latest create my-extension
43
33
  cd my-extension
44
34
  npm run dev
45
35
  ```
46
36
 
47
- A new browser instance will open up with your extension ready for development.
48
-
49
- You are done. Time to hack on your extension!
37
+ ### Watch Demo
50
38
 
51
39
  https://github.com/cezaraugusto/extension/assets/4672033/7263d368-99c4-434f-a60a-72c489672586
52
40
 
53
- ## Web Standards and Modern JavaScript Support
41
+ ## Web Standards and Framework Support
54
42
 
55
- For a preview of extensions running these technologies, see documentation about [Templates](https://extension.js.org/docs/getting-started/templates).
43
+ <!-- For a preview of extensions running these technologies, see the [templates](https://templates.extension.land) website. -->
56
44
 
57
- | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/a9e2541a-96f0-4caa-9fc9-5fc5c3e901c8" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/b42c5330-9e2a-4045-99c3-1f7d264dfaf4" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/f19edff3-9005-4f50-b05c-fba615896a7f" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/ff64721d-d145-4213-930d-e70193f8d57e" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/15f1314a-aa65-4ce2-a3f3-cf53c4f730cf" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/c5f8a127-3c2a-4ceb-bb46-948cf2c8bd89" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/de1082fd-7cf6-4202-8c12-a5c3cd3e5b42" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/78e5fe3d-dc79-4aa2-954e-1a5973d1d9db" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/8807efd9-93e5-4db5-a1d2-9ac524f7ecc2" width="70"> |
45
+ | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/a9e2541a-96f0-4caa-9fc9-5fc5c3e901c8" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/b42c5330-9e2a-4045-99c3-1f7d264dfaf4" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/f19edff3-9005-4f50-b05c-fba615896a7f" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/ff64721d-d145-4213-930d-e70193f8d57e" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/15f1314a-aa65-4ce2-a3f3-cf53c4f730cf" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/de1082fd-7cf6-4202-8c12-a5c3cd3e5b42" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/8807efd9-93e5-4db5-a1d2-9ac524f7ecc2" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/c5f8a127-3c2a-4ceb-bb46-948cf2c8bd89" width="70"> | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/78e5fe3d-dc79-4aa2-954e-1a5973d1d9db" width="70"> |
58
46
  | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------: |
59
- | ESNext<br>✅ | TypeScript<br>✅ | WASM<br>✅ | React<br>✅ | Vue<br>✅ | Angular<br>👋 | Svelte<br>✅ | Solid<br>👋 | Preact<br>✅ |
47
+ | ESNext<br>latest | TypeScript<br>latest | WASM<br>latest | React<br>18+ | Vue<br>3+ | Svelte<br>5+ | Preact<br>10+ | Angular<br>👋 | Solid<br>👋 |
60
48
 
61
49
  👋 = PR Welcome!
62
50
 
63
51
  ## Get Started Immediately
64
52
 
65
- ### Use Chrome to start developing an extension from Chrome Extension Samples
53
+ Start developing an extension using a sample from Chrome Extension Samples
66
54
 
67
- > 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).
55
+ 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).
68
56
 
69
- ```bash
70
- npx extension dev https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/functional-samples/sample.page-redder --browser=edge
71
- ```
57
+ ### Watch Demo
72
58
 
73
59
  https://github.com/cezaraugusto/extension/assets/4672033/ee221a94-6ec7-4e04-8553-8812288927f1
74
60
 
75
- </details>
76
-
77
- <details>
78
- <summary>
79
- 🔥 Use Edge to start developing an extension from Chrome Extension Samples
80
- </summary>
81
-
82
- > See the example below where we request the sample [magic8ball](https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/api-samples/topSites/magic8ball) from from [Google Chrome Extension Samples](https://github.com/GoogleChrome/chrome-extensions-samples) with Edge as the runtime browser.
83
-
84
- ```bash
85
- npx extension dev https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/api-samples/topSites/magic8ball --browser=edge
86
- ```
87
-
88
- https://github.com/cezaraugusto/extension/assets/4672033/2db2a1f6-3110-4380-9a49-dc9d034146aa
89
-
90
- </details>
91
-
92
- <details>
93
- <summary>
94
- 🔥🔥 Use Edge to start developing a Mozilla Add-On from MDN WebExtensions Examples
95
- </summary>
96
-
97
- > See the example below where we request the sample [Apply CSS](https://github.com/mdn/webextensions-examples/tree/main/apply-css) from [MDN WebExtensions Examples](https://github.com/mdn/webextensions-examples) using Edge as the runtime browser.
61
+ ### Try Yourself
98
62
 
99
63
  ```bash
100
- npx extension dev https://github.com/mdn/webextensions-examples/tree/main/apply-css --browser=edge --polyfill=true
64
+ npx extension@latest dev https://github.com/GoogleChrome/chrome-extensions-samples/tree/main/functional-samples/sample.page-redder --browser=edge
101
65
  ```
102
66
 
103
- https://github.com/cezaraugusto/extension/assets/4672033/130cb430-1567-419c-8c90-23fddcf20f00
104
-
105
67
  </details>
106
68
 
107
- <details>
108
- <summary>
109
- 🔥🔥🔥 Use Chrome and Firefox to start developing a Mozilla Add-On from MDN WebExtensions Examples
110
- </summary>
111
-
112
- > See the example below where we request the sample [firefox-code-search](https://github.com/mdn/webextensions-examples/tree/main/firefox-code-search) from [MDN WebExtensions Examples](https://github.com/mdn/webextensions-examples) using Chrome and Firefox as the runtime browsers.
113
-
114
- ```bash
115
- npx extension dev https://github.com/mdn/webextensions-examples/tree/main/firefox-code-search --browser=chrome,firefox --polyfill=true
116
- ```
117
-
118
- https://github.com/cezaraugusto/extension.js/assets/4672033/ac94b608-c936-40df-bce7-63ffd7fe31c5
69
+ ## I have An Extension
119
70
 
120
- </details>
71
+ 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.
121
72
 
122
- ## I have An Extension
73
+ ### See How It Works
123
74
 
124
75
  https://github.com/cezaraugusto/extension/assets/4672033/48694a23-b7f1-4098-9c5d-eff49983739c
125
76
 
126
- 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. See the demo above or follow these instructions to get it done:
127
-
128
77
  **Step 1 - Install extension as a `devDependency`**
129
78
 
130
79
  ```bash
131
- npm install extension --save-dev
80
+ npm install extension@latest --save-dev
132
81
  ```
133
82
 
134
83
  **Step 2 - Link your npm scripts with the executable Extension.js commands**
@@ -138,7 +87,7 @@ npm install extension --save-dev
138
87
  "scripts": {
139
88
  "build": "extension build",
140
89
  "dev": "extension dev",
141
- "start": "extension start"
90
+ "preview": "extension preview"
142
91
  },
143
92
  "devDependencies": {
144
93
  // ...other dependencies
@@ -150,36 +99,39 @@ npm install extension --save-dev
150
99
  Done. You are all set!
151
100
 
152
101
  - To develop the extension, run `npm run dev`.
153
- - To visualize the extension in production mode, run `npm run start`.
154
102
  - To build the extension in production mode, run `npm run build`.
103
+ - To visualize the extension in production mode, run `npm run build` and `npm run preview`.
155
104
 
156
105
  ## Using a specific browser for development
157
106
 
158
- ### Desktop Browsers
107
+ | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/chromium/chromium.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari-ios/safari-ios.svg" width="70"> |
108
+ | :-----------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: |
109
+ | Chrome browser<br>✅ | Edge browser<br>✅ | Firefox browser<br>✅ | Opera browser<br>☑️ | Safari browser<br>❌ | Chromium-based<br>☑️ | Gecko-based<br>☑️ | Firefox (Android)<br>❌ | Safari (iOS)<br>❌ |
110
+
111
+ ### Browser flags and custom binaries
159
112
 
160
- | <img src="https://github.com/cezaraugusto/extension.js/assets/4672033/6ce53a31-c6f6-4a1c-b927-e9ec7fd2df78" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/brave/brave.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/chromium/chromium.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera.svg" width="70"> | <img width="70" src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari.svg"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/vivaldi/vivaldi.svg" width="70"> |
161
- | :---------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------: |
162
- | Arc<br>☑️ | Brave<br>☑️ | Chrome<br>✅ | Chromium<br>☑️ | Edge<br>✅ | Firefox<br>✅ | Opera<br>☑️ | Safari<br>⛔️ | Vivaldi<br>☑️ |
113
+ Use these flags with `extension dev`, `extension start`, or `extension preview`:
163
114
 
164
- ☑️ = It is theoretically possible to load all Chromium forks given the current support for Chrome. There is a request ticket for [supporting all Chromium-based browsers](https://github.com/cezaraugusto/extension.js/issues/59). Most requested features are added first, so thumbs up it to speed-up the development process.
115
+ - Select a browser: `--browser <chrome | edge | firefox>`
116
+ - Custom Chromium binary: `--chromium-binary <path-to-binary>`
117
+ - Custom Gecko (Firefox) binary: `--gecko-binary <path-to-binary>`
165
118
 
166
- ### Mobile Browsers
119
+ Examples:
167
120
 
168
- | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox.svg" width="70"> | <img src="https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari-ios/safari-ios.svg" width="70"> |
169
- | :-------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------: |
170
- | Firefox (Android)<br>⛔️ | Safari (iOS)<br>⛔️ |
121
+ ```bash
122
+ # Chrome (system default)
123
+ npx extension@latest dev --browser=chrome
171
124
 
172
- If you want to target a specific browser, just pass the `--browser` flag to the `dev`/`start` command (based on the list available above), like `npx extension dev path/to/extension --browser=edge`.
125
+ # Edge
126
+ npx extension@latest dev --browser=edge
173
127
 
174
- > Hint
175
- > Pass --browser="all" to load all available browsers at once.
128
+ # Custom Chrome/Chromium path
129
+ npx extension@latest dev --chromium-binary "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
176
130
 
177
- ```sh
178
- extension dev --browser=all
131
+ # Custom Firefox path
132
+ npx extension@latest dev --gecko-binary "/Applications/Firefox.app/Contents/MacOS/firefox"
179
133
  ```
180
134
 
181
- <img alt="Extension.js with all the browser runners open" src="https://github.com/cezaraugusto/extension.js/assets/4672033/f0f5bbfc-e873-4856-9fdd-db2b42d9ab96">
182
-
183
135
  ## License
184
136
 
185
- MIT (c) Cezar Augusto.
137
+ MIT (c) Cezar Augusto and the Extension.js Authors.
@@ -0,0 +1 @@
1
+ export default function checkUpdates(packageJson: Record<string, any>): Promise<void>;
@@ -0,0 +1,10 @@
1
+ export declare function updateFailed(err: any): string;
2
+ export declare function checkUpdates(packageJson: Record<string, any>, update: {
3
+ latest: string;
4
+ }): string;
5
+ export declare function unsupportedNodeVersion(): string;
6
+ export declare function noURLWithoutStart(argument: string): string;
7
+ export declare function notImplemented(argument: string): string;
8
+ export declare function programUserHelp(): string;
9
+ export declare function unsupportedBrowserFlag(value: string, supported: string[]): string;
10
+ export declare function programAIHelp(): string;
package/dist/cli.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export { FileConfig, Manifest } from 'extension-develop';
2
+ export type { FileConfig, Manifest } from 'extension-develop';
package/dist/cli.js CHANGED
@@ -1,329 +1,345 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
3
+ var __webpack_modules__ = {
4
+ "extension-develop": function(module) {
5
+ module.exports = import("extension-develop").then(function(module) {
6
+ return module;
7
+ });
8
+ }
16
9
  };
17
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
- // If the importer is in node compatibility mode or this is not an ESM
19
- // file that has been converted to a CommonJS file using a Babel-
20
- // compatible transform (i.e. "__esModule" has not been set), then set
21
- // "default" to the CommonJS "module.exports" for node compatibility.
22
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
- mod
24
- ));
25
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
10
+ var __webpack_module_cache__ = {};
11
+ function __webpack_require__(moduleId) {
12
+ var cachedModule = __webpack_module_cache__[moduleId];
13
+ if (void 0 !== cachedModule) return cachedModule.exports;
14
+ var module = __webpack_module_cache__[moduleId] = {
15
+ exports: {}
16
+ };
17
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
18
+ return module.exports;
19
+ }
20
+ (()=>{
21
+ __webpack_require__.n = (module)=>{
22
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
23
+ __webpack_require__.d(getter, {
24
+ a: getter
25
+ });
26
+ return getter;
27
+ };
28
+ })();
29
+ (()=>{
30
+ __webpack_require__.d = (exports1, definition)=>{
31
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
32
+ enumerable: true,
33
+ get: definition[key]
34
+ });
35
+ };
36
+ })();
37
+ (()=>{
38
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
39
+ })();
40
+ var __webpack_exports__ = {};
41
+ (()=>{
42
+ const external_commander_namespaceObject = require("commander");
43
+ const external_extension_create_namespaceObject = require("extension-create");
44
+ const external_pintor_namespaceObject = require("pintor");
45
+ var external_pintor_default = /*#__PURE__*/ __webpack_require__.n(external_pintor_namespaceObject);
46
+ function getLoggingPrefix(type) {
47
+ if ('error' === type) return external_pintor_default().red('ERROR');
48
+ if ('warn' === type) return external_pintor_default().brightYellow("\u25BA\u25BA\u25BA");
49
+ if ('info' === type) return external_pintor_default().blue("\u25BA\u25BA\u25BA");
50
+ return external_pintor_default().green("\u25BA\u25BA\u25BA");
51
+ }
52
+ const code = (text)=>external_pintor_default().blue(text);
53
+ const arg = (text)=>external_pintor_default().gray(text);
54
+ function updateFailed(err) {
55
+ return `${getLoggingPrefix('error')} Failed to check for updates.\n${external_pintor_default().red(String((null == err ? void 0 : err.message) || err))}`;
56
+ }
57
+ function checkUpdates(packageJson, update) {
58
+ return `${external_pintor_default().blue('Extension.js')} update available.\nYou are currently using version ${external_pintor_default().gray(String(packageJson.version))}. Latest stable is ${external_pintor_default().gray(String(update.latest))}. Please update to enjoy new features and improvements.`;
59
+ }
60
+ function programUserHelp() {
61
+ return `\n${getLoggingPrefix('info')} ${external_pintor_default().underline('Help center for the Extension.js program')}
26
62
 
27
- // cli.ts
28
- var cli_exports = {};
29
- module.exports = __toCommonJS(cli_exports);
30
- var import_commander = require("commander");
31
- var import_extension_create = require("extension-create");
32
- var import_extension_develop = require("extension-develop");
63
+ Usage: extension [command] [options]
33
64
 
34
- // cli-lib/messages.ts
35
- var import_safe = require("@colors/colors/safe");
36
- function updateFailed(err) {
37
- return "\u{1F9E9}\n" + (0, import_safe.red)(`Failed to check for updates: ${err.message}`);
38
- }
39
- function checkUpdates(packageJson, update) {
40
- return `\u{1F9E9}
41
- ${(0, import_safe.brightYellow)("Notice:")} A new version of ${(0, import_safe.brightGreen)(
42
- "Extension.js"
43
- )} is available!
44
- You are currently using version ${(0, import_safe.brightYellow)(packageJson.version)}.
45
- The latest stable version is ${(0, import_safe.brightYellow)(update.latest)}.
46
- Please update to the latest version to enjoy new features and improvements.
47
- `;
48
- }
49
- function programHelp() {
50
- return `\u{1F9E9}
51
- ${(0, import_safe.underline)("Help center for the Extension.js program")}
65
+ Notes
66
+ - All high-level commands offer their own \`--help\` with usage and flag lists.
52
67
 
53
- ${(0, import_safe.brightYellow)("Usage:")} extension [command] [options]
68
+ Example
69
+ - ${code('extension create --help')} outputs information about the "create" command.
54
70
 
55
- ${(0, import_safe.brightYellow)("Note:")} If you are looking for a specific list of options,
56
- all high-level commands offer their own \`--help\` file with
57
- information about usage and a list of command flags available.
71
+ Available Commands
72
+ - ${code('extension create ' + arg('<project-name|project-path>'))}
73
+ Creates a new extension from a template (React, TypeScript, Vue, Svelte, etc.)
58
74
 
59
- For example:
75
+ - ${code('extension dev ' + arg('[project-path|remote-url]'))}
76
+ Starts a development server with hot reloading
60
77
 
61
- ${(0, import_safe.brightGreen)("extension create --help")}
62
- outputs information about the "create" command.
78
+ - ${code('extension start ' + arg('[project-path|remote-url]'))}
79
+ Builds and starts the extension in production mode
63
80
 
64
- Options available:
81
+ - ${code('extension preview ' + arg('[project-path|remote-url]'))}
82
+ Previews the extension in production mode without building
65
83
 
66
- ${(0, import_safe.brightGreen)("extension create <extension-name>")}
67
- Creates a new extension from a template. The "create" command
68
- is optional and can be omitted.
84
+ - ${code('extension build ' + arg('[project-path|remote-url]'))}
85
+ Builds the extension for packaging/distribution
69
86
 
70
- ${(0, import_safe.brightGreen)("extension dev <extension-path>")}
71
- Starts a new browser instance in development mode, with the target
72
- extension loaded and auto-reloaded based on file changes.
87
+ - ${code('extension cleanup')}
88
+ Cleans up orphaned instances and frees unused ports
73
89
 
74
- ${(0, import_safe.brightGreen)("extension start <extension-path>")}
75
- Starts a new browser instance in production mode, with the target
76
- extension compiled based on the browser choice.
90
+ Common Options
91
+ - ${code('--browser')} ${arg('<chrome|edge|firefox>')} Target browser (default: chrome)
92
+ - ${code('--profile')} ${arg('<path|boolean>')} Browser profile configuration
93
+ - ${code('--polyfill')} ${arg('[boolean]')} Enable/disable cross-browser polyfill
94
+ - ${code('--port')} ${arg('<number>')} Development server port (default: 8080)
95
+ - ${code('--starting-url')} ${arg('<url>')} Initial URL to load in browser
96
+ - ${code('--silent')} ${arg('[boolean]')} Suppress console output during build
77
97
 
78
- ${(0, import_safe.brightGreen)("extension build <extension-path>")}
79
- Builds the target extension with browser defaults, ready for packaging.
98
+ Source Inspection
99
+ - ${code('--source')} ${arg('<url>')} Open URL and print HTML after content scripts inject
100
+ - ${code('--watch-source')} Monitor rebuild events and print HTML on reloads
80
101
 
81
- ${(0, import_safe.brightGreen)("extension --help")}
82
- This command ;) Outputs a help file with key command options.
102
+ Browser-Specific Options
103
+ - ${code('--chromium-binary')} ${arg('<path>')} Custom Chromium binary path
104
+ - ${code('--gecko-binary')} ${arg('<path>')} Custom Firefox/Gecko binary path
83
105
 
84
- ${(0, import_safe.brightYellow)("Feels something is wrong? Help by reporting a bug:")}
85
- ${(0, import_safe.underline)("https://github.com/cezaraugusto/extension/issues/new")}
86
- `;
87
- }
106
+ Build Options
107
+ - ${code('--zip')} ${arg('[boolean]')} Create ZIP archive of built extension
108
+ - ${code('--zip-source')} ${arg('[boolean]')} Include source files in ZIP
109
+ - ${code('--zip-filename')} ${arg('<name>')} Custom ZIP filename
88
110
 
89
- // check-updates.ts
90
- var import_update_check = __toESM(require("update-check"));
91
- function isStableVersion(version) {
92
- return !/[a-zA-Z]/.test(version);
93
- }
94
- async function checkUpdates2(packageJson) {
95
- let update = null;
96
- try {
97
- update = await (0, import_update_check.default)(packageJson);
98
- } catch (err) {
99
- if (process.env.EXTENSION_ENV === "development") {
100
- console.error(updateFailed(err));
111
+ ${code('extension --help')}
112
+ This command outputs a help file with key command options.
113
+
114
+ AI Assistants
115
+ - For AI-oriented guidance and deep-dive tips, run ${code('extension --ai-help')}
116
+
117
+ Report issues
118
+ - ${external_pintor_default().underline('https://github.com/cezaraugusto/extension/issues/new')}`;
101
119
  }
102
- }
103
- if (update && isStableVersion(update.latest)) {
104
- console.log(checkUpdates(packageJson, update));
105
- }
106
- }
120
+ function unsupportedBrowserFlag(value, supported) {
121
+ return `${getLoggingPrefix('error')} Unsupported --browser value: ${value}. Supported: ${supported.join(', ')}.`;
122
+ }
123
+ function programAIHelp() {
124
+ return `\n${getLoggingPrefix('info')} ${external_pintor_default().gray('Development tips for extension developers and AI assistants')}
107
125
 
108
- // package.json
109
- var package_default = {
110
- license: "MIT",
111
- repository: {
112
- type: "git",
113
- url: "https://github.com/cezaraugusto/extension.git",
114
- directory: "programs/cli"
115
- },
116
- engines: {
117
- node: ">=18"
118
- },
119
- name: "extension",
120
- version: "2.0.0-rc.9",
121
- description: "Create cross-browser extensions with no build configuration.",
122
- main: "./dist/cli.js",
123
- types: "./dist/cli.d.ts",
124
- files: [
125
- "dist",
126
- "README.md"
127
- ],
128
- bin: {
129
- extension: "./dist/cli.js"
130
- },
131
- author: {
132
- name: "Cezar Augusto",
133
- email: "boss@cezaraugusto.net",
134
- url: "https://cezaraugusto.com"
135
- },
136
- scripts: {
137
- watch: "pnpm compile --watch",
138
- "compile:types": "bash install_scripts.sh",
139
- "compile:readme-files": "node ./scripts/copyMarkdownFilesToCli.js",
140
- "compile:tailwind-config": "node ./scripts/copyTailwindConfig.js",
141
- "compile:stylelint-config": "node ./scripts/copyStylelintConfig.js",
142
- "compile:cli": "tsup-node ./cli.ts --format cjs --dts --target=node18",
143
- compile: "pnpm compile:readme-files && pnpm compile:tailwind-config && pnpm compile:stylelint-config && pnpm compile:cli && pnpm compile:types",
144
- clean: "rm -rf dist",
145
- test: 'echo "Note: no test specified" && exit 0',
146
- "test:cli": "jest __spec__/cli.spec.ts"
147
- },
148
- keywords: [
149
- "zero-config",
150
- "build",
151
- "develop",
152
- "browser",
153
- "extension",
154
- "chrome extension",
155
- "edge extension",
156
- "firefox extension",
157
- "safari extension",
158
- "web",
159
- "react",
160
- "typescript"
161
- ],
162
- dependencies: {
163
- "@colors/colors": "^1.6.0",
164
- "@types/chrome": "^0.0.287",
165
- "@types/firefox-webext-browser": "^120.0.4",
166
- "@types/node": "^22.10.1",
167
- "@types/react": "^19.0.1",
168
- "@types/react-dom": "^19.0.1",
169
- commander: "^12.1.0",
170
- "extension-create": "workspace:*",
171
- "extension-develop": "workspace:*",
172
- semver: "^7.6.3",
173
- "update-check": "^1.5.4",
174
- "webextension-polyfill": "^0.12.0"
175
- },
176
- devDependencies: {
177
- "@types/jest": "^29.5.14",
178
- "@types/mock-fs": "^4.13.4",
179
- "@types/semver": "^7.5.8",
180
- jest: "^29.7.0",
181
- "mock-fs": "^5.4.1",
182
- "ts-jest": "^29.2.5",
183
- tsconfig: "*",
184
- tsup: "^8.3.5",
185
- typescript: "5.7.2"
186
- }
187
- };
126
+ Browser-Specific Configuration
127
+ - Use browser prefixes in manifest.json for browser-specific fields:
128
+ ${code('{"firefox:manifest": 2, "chrome:manifest": 3}')}
129
+ This applies manifest v2 to Firefox only, v3 to Chrome/Edge.
188
130
 
189
- // cli.ts
190
- checkUpdates2(package_default);
191
- var extensionJs = import_commander.program;
192
- var vendors = (browser) => browser === "all" ? "chrome,edge,firefox".split(",") : browser.split(",");
193
- extensionJs.name(package_default.name).description(package_default.description).version(package_default.version).addHelpText("after", programHelp());
194
- extensionJs.command("create").arguments("<project-name|project-path>").usage("create <project-name|project-path> [options]").description("Creates a new extension.").option(
195
- "-t, --template <template-name>",
196
- "specify a template for the created project"
197
- ).option(
198
- "--install",
199
- "whether or not to install the dependencies after creating the project"
200
- ).action(async function(pathOrRemoteUrl, { template, install }) {
201
- await (0, import_extension_create.extensionCreate)(pathOrRemoteUrl, {
202
- template,
203
- install
204
- });
205
- });
206
- extensionJs.command("dev").arguments("[project-path|remote-url]").usage("dev [project-path|remote-url] [options]").description("Starts the development server (development mode)").option(
207
- "--profile <path-to-file | boolean>",
208
- "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"
209
- ).option(
210
- "--browser <chrome | edge | firefox>",
211
- "specify a browser to preview your extension in production mode. Defaults to `chrome`"
212
- ).option(
213
- "--chromium-binary <path-to-binary>",
214
- "specify a path to the Chromium binary. This option overrides the --browser setting. Defaults to the system default"
215
- ).option(
216
- "--gecko-binary <path-to-binary>",
217
- "specify a path to the Gecko binary. This option overrides the --browser setting. Defaults to the system default"
218
- ).option(
219
- "--polyfill [boolean]",
220
- "whether or not to apply the cross-browser polyfill. Defaults to `false`"
221
- ).option(
222
- "--open [boolean]",
223
- "whether or not to open the browser automatically. Defaults to `true`"
224
- ).option(
225
- "--starting-url <url>",
226
- "specify the starting URL for the browser. Defaults to `undefined`"
227
- ).action(async function(pathOrRemoteUrl, { browser = "chrome", ...devOptions }) {
228
- for (const vendor of vendors(browser)) {
229
- await (0, import_extension_develop.extensionDev)(pathOrRemoteUrl, {
230
- ...devOptions,
231
- profile: devOptions.profile,
232
- browser: vendor,
233
- chromiumBinary: devOptions.chromiumBinary,
234
- geckoBinary: devOptions.geckoBinary,
235
- // @ts-expect-error open is a boolean
236
- polyfill: devOptions.polyfill === "false" ? false : true,
237
- open: devOptions.open,
238
- startingUrl: devOptions.startingUrl
131
+ Special Folders for Entrypoints
132
+ - Use special folders to handle entrypoints and assets not declared in manifest.json:
133
+ - ${external_pintor_default().underline(code('public/'))} - Static assets automatically copied to build (resolves to output root)
134
+ - ${external_pintor_default().underline(code('pages/'))} - HTML files not declared in manifest (e.g., welcome pages)
135
+ - ${external_pintor_default().underline(code("scripts/"))} - JavaScript files not declared in manifest (e.g., executable scripts)
136
+
137
+ Shadow DOM for Content Scripts
138
+ - Add ${code('use shadow-dom')} directive to content scripts for style isolation
139
+ - Automatically creates ${code('#extension-root')} element with shadow DOM
140
+ - All CSS imports are automatically injected into shadow DOM
141
+ - Prevents style conflicts with host page
142
+
143
+ Environment Variables
144
+ - Use ${code(arg('EXTENSION_PUBLIC_*'))} prefix for variables accessible in extension code
145
+ - Supported in both ${code('process.env')} and ${code('import.meta.env')}
146
+ - Environment file priority: ${external_pintor_default().underline(code(arg('.env.{browser}.{mode}')))} > ${external_pintor_default().underline(code(arg('.env.{browser}')))} > ${external_pintor_default().underline(code(arg('.env.{mode}')))} > ${external_pintor_default().underline(code(arg('.env')))}
147
+ - Example: ${code(arg('EXTENSION_PUBLIC_API_KEY=your_key'))}
148
+
149
+ Available Templates
150
+ - ${external_pintor_default().green('Frameworks')}: ${code(arg('react'))}, ${code(arg('preact'))}, ${code(arg('vue'))}, ${code(arg('svelte'))}
151
+ - ${external_pintor_default().green('Languages')}: ${code(arg("javascript"))}, ${code(arg("typescript"))}
152
+ - ${external_pintor_default().green('Contexts')}: ${code(arg('content'))} (content scripts), ${code(arg('new'))} (new tab), ${code(arg('action'))} (popup)
153
+ - ${external_pintor_default().green('Styling')}: ${code(arg('tailwind'))}, ${code(arg('sass'))}, ${code(arg('less'))}
154
+ - ${external_pintor_default().green('Configs')}: ${code(arg('eslint'))}, ${code(arg('prettier'))}, ${code(arg('stylelint'))}
155
+
156
+ Webpack/Rspack Configuration
157
+ - Create ${external_pintor_default().underline(code(arg('extension.config.js')))} for custom webpack configuration
158
+ - Function receives base config, return modified config
159
+ - Supports all webpack/rspack loaders and plugins
160
+ - Example:
161
+ ${code('export default {')}
162
+ ${code(' config: (config) => {')}
163
+ ${code(" config.module.rules.push({ test: /\\.svg$/, use: ['@svgr/webpack'] })")}
164
+ ${code(' return config')}
165
+ ${code(' }')}
166
+ ${code('}')}
167
+
168
+ Managed Dependencies (Important)
169
+ - ${external_pintor_default().green('Do not add')} packages that ${external_pintor_default().blue('Extension.js')} already ships in its own toolchain.
170
+ - The guard only triggers when a managed package is declared in your ${code('package.json')} ${external_pintor_default().gray('and')} is referenced in your ${external_pintor_default().underline(code('extension.config.js'))}.
171
+ - In that case, the program will ${external_pintor_default().red('print an error and abort')} to avoid version conflicts.
172
+ - Remove the duplicate from your project ${code('package.json')} or avoid referencing it in ${external_pintor_default().underline(code('extension.config.js'))} and rely on the built-in version instead.
173
+ - If you truly need a different version, open an issue so we can evaluate a safe upgrade.
174
+
175
+ Framework-Specific Configuration
176
+ - Create ${external_pintor_default().underline(code(arg('vue.loader.js')))} for Vue-specific loader configuration
177
+ - Create ${external_pintor_default().underline(code(arg('svelte.loader.js')))} for Svelte-specific loader configuration
178
+ - Automatically detected and used by Extension.js
179
+ - Example svelte.loader.js:
180
+ ${code('module.exports = {')}
181
+ ${code(' preprocess: require("svelte-preprocess")({')}
182
+ ${code(" typescript: true")}
183
+ ${code(' })')}
184
+ ${code('}')}
185
+
186
+ Hot Module Replacement (HMR)
187
+ - Automatically enabled in development mode
188
+ - CSS changes trigger automatic style updates
189
+ - React/Preact/Vue/Svelte components hot reload
190
+ - Content scripts automatically re-inject on changes
191
+ - Service workers, _locales and manifest changes reload the extension
192
+
193
+ Source Inspection & Real-Time Monitoring
194
+ - Use ${code('--source')} ${arg('<url>')} to inspect page HTML after content script injection
195
+ - Use ${code('--watch-source')} to monitor real-time changes in stdout
196
+ - Automatically enables Chrome remote debugging (port 9222) when source inspection is active
197
+ - Extracts Shadow DOM content from ${code('#extension-root')} elements
198
+ - Perfect for debugging content script behavior and style injection
199
+ - Example: ${code('extension dev --source=' + arg('https://example.com') + ' --watch-source')}
200
+
201
+ Non-Destructive Testing in CI
202
+ - Prefer ${code('EXTENSION_ENV=development')} to copy local templates and avoid network.
203
+ - Reuse Playwright's Chromium via ${code('--chromium-binary')} path when available.
204
+ - Set ${code(arg('EXTENSION_AUTO_EXIT_MS'))} and ${code(arg('EXTENSION_FORCE_KILL_MS'))} for non-interactive dev sessions.
205
+
206
+ File Watching & HMR Examples
207
+ - Content script JS/TS changes trigger reinjection; CSS changes update styles live.
208
+ - For watch-source HTML prints, update a visible string in ${code("content/scripts.*")} and assert it appears in stdout.
209
+
210
+ Troubleshooting
211
+ - If HTML is not printed, ensure ${code('--source')} is provided and browser launched with debugging port.
212
+ - Use ${code('--silent true')} during builds to reduce noise; logs still surface errors.
213
+ - When ports conflict, pass ${code('--port 0')} to auto-select an available port.
214
+
215
+ Non-Interactive / Auto Mode (CI)
216
+ - Set ${code(arg('EXTENSION_AUTO_EXIT_MS'))} to enable self-termination after N milliseconds.
217
+ Useful when ${code('pnpm extension dev')} would otherwise hang under Rspack watch.
218
+ Example: ${code(arg('EXTENSION_AUTO_EXIT_MS=6000'))} pnpm extension dev ./templates/react --browser chrome --source ${arg('https://example.com')}
219
+ - Optional: ${code(arg('EXTENSION_FORCE_KILL_MS'))} to hard-exit after N ms as a fallback (defaults to auto-exit + 4000).
220
+
221
+ Cross-Browser Compatibility
222
+ - Use ${code('--polyfill')} flag to enable webextension-polyfill
223
+ - Automatically handles browser API differences
224
+ - Supports Chrome, Edge, Firefox with single codebase`;
225
+ }
226
+ const external_update_check_namespaceObject = require("update-check");
227
+ var external_update_check_default = /*#__PURE__*/ __webpack_require__.n(external_update_check_namespaceObject);
228
+ function isStableVersion(version) {
229
+ return !/[a-zA-Z]/.test(version);
230
+ }
231
+ async function check_updates_checkUpdates(packageJson) {
232
+ let update = null;
233
+ try {
234
+ update = await external_update_check_default()(packageJson);
235
+ } catch (err) {
236
+ if ('development' === process.env.EXTENSION_ENV) console.error(updateFailed(err));
237
+ }
238
+ if (update && isStableVersion(update.latest)) console.log(checkUpdates(packageJson, update));
239
+ }
240
+ var package_namespaceObject = JSON.parse('{"license":"MIT","repository":{"type":"git","url":"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","files":["dist","types"],"bin":{"extension":"./dist/cli.js"},"name":"extension","version":"2.0.1","description":"Create cross-browser extensions with no build configuration.","author":{"name":"Cezar Augusto","email":"boss@cezaraugusto.net","url":"https://cezaraugusto.com"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"scripts":{"watch":"rslib build --watch","compile":"rslib build","clean":"rm -rf dist","test":"echo \\"Note: no test specified\\" && exit 0","test:cli":"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":{"@types/chrome":"^0.0.287","@types/node":"^22.10.1","@types/react":"^19.0.1","@types/react-dom":"^19.0.1","@types/webextension-polyfill":"0.12.3","commander":"^12.1.0","extension-create":"workspace:*","extension-develop":"workspace:*","pintor":"0.3.0","semver":"^7.6.3","update-check":"^1.5.4","webextension-polyfill":"^0.12.0"},"devDependencies":{"@rslib/core":"^0.6.9","@types/mock-fs":"^4.13.4","@types/semver":"^7.5.8","mock-fs":"^5.4.1","tsconfig":"*","typescript":"5.7.2","vitest":"3.2.2"}}');
241
+ function parseOptionalBoolean(value) {
242
+ if (void 0 === value) return true;
243
+ const normalized = String(value).trim().toLowerCase();
244
+ return ![
245
+ 'false',
246
+ '0',
247
+ 'no',
248
+ 'off'
249
+ ].includes(normalized);
250
+ }
251
+ check_updates_checkUpdates(package_namespaceObject);
252
+ const extensionJs = external_commander_namespaceObject.program;
253
+ const vendors = (browser)=>'all' === browser ? 'chrome,edge,firefox'.split(',') : browser.split(',');
254
+ function validateVendorsOrExit(vendorsList) {
255
+ const supported = [
256
+ 'chrome',
257
+ 'edge',
258
+ 'firefox'
259
+ ];
260
+ for (const v of vendorsList)if (!supported.includes(v)) {
261
+ console.error(unsupportedBrowserFlag(v, supported));
262
+ process.exit(1);
263
+ }
264
+ }
265
+ extensionJs.name(package_namespaceObject.name).description(package_namespaceObject.description).version(package_namespaceObject.version).option('--ai-help', 'show AI-assistant oriented help and tips').addHelpText('after', programUserHelp());
266
+ extensionJs.command('create').arguments('<project-name|project-path>').usage('create <project-name|project-path> [options]').description('Creates a new extension.').option('-t, --template <template-name>', 'specify a template for the created project').option('--install [boolean]', 'whether or not to install the dependencies after creating the project (disabled by default)', parseOptionalBoolean, false).action(async function(pathOrRemoteUrl, { template, install }) {
267
+ await (0, external_extension_create_namespaceObject.extensionCreate)(pathOrRemoteUrl, {
268
+ template,
269
+ install,
270
+ cliVersion: package_namespaceObject.version
271
+ });
239
272
  });
240
- }
241
- });
242
- extensionJs.command("start").arguments("[project-path|remote-url]").usage("start [project-path|remote-url] [options]").description("Starts the development server (production mode)").option(
243
- "--profile <path-to-file | boolean>",
244
- "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"
245
- ).option(
246
- "--browser <chrome | edge | firefox>",
247
- "specify a browser to preview your extension in production mode. Defaults to `chrome`"
248
- ).option(
249
- "--polyfill [boolean]",
250
- "whether or not to apply the cross-browser polyfill. Defaults to `true`"
251
- ).option(
252
- "--chromium-binary <path-to-binary>",
253
- "specify a path to the Chromium binary. This option overrides the --browser setting. Defaults to the system default"
254
- ).option(
255
- "--gecko-binary <path-to-binary>",
256
- "specify a path to the Gecko binary. This option overrides the --browser setting. Defaults to the system default"
257
- ).option(
258
- "--starting-url <url>",
259
- "specify the starting URL for the browser. Defaults to `undefined`"
260
- ).action(async function(pathOrRemoteUrl, { browser = "chrome", ...startOptions }) {
261
- for (const vendor of vendors(browser)) {
262
- await (0, import_extension_develop.extensionStart)(pathOrRemoteUrl, {
263
- mode: "production",
264
- profile: startOptions.profile,
265
- browser: vendor,
266
- chromiumBinary: startOptions.chromiumBinary,
267
- geckoBinary: startOptions.geckoBinary,
268
- startingUrl: startOptions.startingUrl
273
+ extensionJs.command('dev').arguments('[project-path|remote-url]').usage('dev [project-path|remote-url] [options]').description('Starts the development server (development mode)').option('--profile <path-to-file | boolean>', 'what path to use for the browser profile. A boolean value of false sets the profile to the default user profile. Defaults to a fresh profile').option('--browser <chrome | edge | firefox>', 'specify a browser to preview your extension in production mode. Defaults to `chrome`').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 <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('--open [boolean]', 'whether or not to open the browser automatically. Defaults to `true`').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('--source [url]', "opens the provided URL in Chrome and prints the full, live HTML of the page after content scripts are injected").option('--watch-source', 'continuously monitors rebuild events and prints updated HTML whenever the extension reloads and reinjects into the page').action(async function(pathOrRemoteUrl, { browser = 'chrome', ...devOptions }) {
274
+ const list = vendors(browser);
275
+ validateVendorsOrExit(list);
276
+ const { extensionDev } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
277
+ for (const vendor of list){
278
+ var _devOptions_polyfill;
279
+ await extensionDev(pathOrRemoteUrl, {
280
+ ...devOptions,
281
+ profile: devOptions.profile,
282
+ browser: vendor,
283
+ chromiumBinary: devOptions.chromiumBinary,
284
+ geckoBinary: devOptions.geckoBinary,
285
+ polyfill: (null == (_devOptions_polyfill = devOptions.polyfill) ? void 0 : _devOptions_polyfill.toString()) !== 'false',
286
+ open: devOptions.open,
287
+ startingUrl: devOptions.startingUrl,
288
+ source: devOptions.source,
289
+ watchSource: devOptions.watchSource
290
+ });
291
+ }
269
292
  });
270
- }
271
- });
272
- extensionJs.command("preview").arguments("[project-name]").usage("preview [path-to-remote-extension] [options]").description("Preview the extension in production mode").option(
273
- "--profile <path-to-file | boolean>",
274
- "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"
275
- ).option(
276
- "--browser <chrome | edge | firefox>",
277
- "specify a browser to preview your extension in production mode. Defaults to `chrome`"
278
- ).option(
279
- "--chromium-binary <path-to-binary>",
280
- "specify a path to the Chromium binary. This option overrides the --browser setting. Defaults to the system default"
281
- ).option(
282
- "--gecko-binary <path-to-binary>",
283
- "specify a path to the Gecko binary. This option overrides the --browser setting. Defaults to the system default"
284
- ).option(
285
- "--starting-url <url>",
286
- "specify the starting URL for the browser. Defaults to `undefined`"
287
- ).action(async function(pathOrRemoteUrl, { browser = "chrome", ...previewOptions }) {
288
- for (const vendor of vendors(browser)) {
289
- await (0, import_extension_develop.extensionPreview)(pathOrRemoteUrl, {
290
- mode: "production",
291
- profile: previewOptions.profile,
292
- browser: vendor,
293
- chromiumBinary: previewOptions.chromiumBinary,
294
- geckoBinary: previewOptions.geckoBinary,
295
- startingUrl: previewOptions.startingUrl
293
+ extensionJs.command('start').arguments('[project-path|remote-url]').usage('start [project-path|remote-url] [options]').description('Starts the development server (production mode)').option('--profile <path-to-file | boolean>', 'what path to use for the browser profile. A boolean value of false sets the profile to the default user profile. Defaults to a fresh profile').option('--browser <chrome | edge | firefox>', 'specify a browser to preview your extension in production mode. Defaults to `chrome`').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 <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`').action(async function(pathOrRemoteUrl, { browser = 'chrome', ...startOptions }) {
294
+ const list = vendors(browser);
295
+ validateVendorsOrExit(list);
296
+ const { extensionStart } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
297
+ for (const vendor of list)await extensionStart(pathOrRemoteUrl, {
298
+ mode: 'production',
299
+ profile: startOptions.profile,
300
+ browser: vendor,
301
+ chromiumBinary: startOptions.chromiumBinary,
302
+ geckoBinary: startOptions.geckoBinary,
303
+ startingUrl: startOptions.startingUrl
304
+ });
296
305
  });
297
- }
298
- });
299
- extensionJs.command("build").arguments("[project-name]").usage("build [path-to-remote-extension] [options]").description("Builds the extension for production").option(
300
- "--browser <chrome | edge | firefox>",
301
- "specify a browser to preview your extension in production mode. Defaults to `chrome`"
302
- ).option(
303
- "--polyfill [boolean]",
304
- "whether or not to apply the cross-browser polyfill. Defaults to `false`"
305
- ).option(
306
- "--zip [boolean]",
307
- "whether or not to compress the extension into a ZIP file. Defaults to `false`"
308
- ).option(
309
- "--zip-source [boolean]",
310
- "whether or not to include the source files in the ZIP file. Defaults to `false`"
311
- ).option(
312
- "--zip-filename <string>",
313
- "specify the name of the ZIP file. Defaults to the extension name and version"
314
- ).option(
315
- "--silent [boolean]",
316
- "whether or not to open the browser automatically. Defaults to `false`"
317
- ).action(async function(pathOrRemoteUrl, { browser = "chrome", ...buildOptions }) {
318
- for (const vendor of vendors(browser)) {
319
- await (0, import_extension_develop.extensionBuild)(pathOrRemoteUrl, {
320
- browser: vendor,
321
- polyfill: buildOptions.polyfill,
322
- zip: buildOptions.zip,
323
- zipSource: buildOptions.zipSource,
324
- zipFilename: buildOptions.zipFilename,
325
- silent: buildOptions.silent
306
+ extensionJs.command('preview').arguments('[project-name]').usage('preview [path-to-remote-extension] [options]').description('Preview the extension in production mode').option('--profile <path-to-file | boolean>', 'what path to use for the browser profile. A boolean value of false sets the profile to the default user profile. Defaults to a fresh profile').option('--browser <chrome | edge | firefox>', 'specify a browser to preview your extension in production mode. Defaults to `chrome`').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 <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`').action(async function(pathOrRemoteUrl, { browser = 'chrome', ...previewOptions }) {
307
+ const list = vendors(browser);
308
+ validateVendorsOrExit(list);
309
+ const { extensionPreview } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
310
+ for (const vendor of list)await extensionPreview(pathOrRemoteUrl, {
311
+ mode: 'production',
312
+ profile: previewOptions.profile,
313
+ browser: vendor,
314
+ chromiumBinary: previewOptions.chromiumBinary,
315
+ geckoBinary: previewOptions.geckoBinary,
316
+ startingUrl: previewOptions.startingUrl
317
+ });
318
+ });
319
+ extensionJs.command('build').arguments('[project-name]').usage('build [path-to-remote-extension] [options]').description('Builds the extension for production').option('--browser <chrome | edge | firefox>', 'specify a browser to preview your extension in production mode. Defaults to `chrome`').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`').action(async function(pathOrRemoteUrl, { browser = 'chrome', ...buildOptions }) {
320
+ const list = vendors(browser);
321
+ validateVendorsOrExit(list);
322
+ const { extensionBuild } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
323
+ for (const vendor of list)await extensionBuild(pathOrRemoteUrl, {
324
+ browser: vendor,
325
+ polyfill: buildOptions.polyfill,
326
+ zip: buildOptions.zip,
327
+ zipSource: buildOptions.zipSource,
328
+ zipFilename: buildOptions.zipFilename,
329
+ silent: buildOptions.silent
330
+ });
331
+ });
332
+ extensionJs.command('cleanup').description('Clean up orphaned instances and free unused ports').action(async function() {
333
+ const { cleanupCommand } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "extension-develop"));
334
+ await cleanupCommand();
335
+ });
336
+ extensionJs.on('option:ai-help', function() {
337
+ console.log(programAIHelp());
338
+ process.exit(0);
326
339
  });
327
- }
340
+ extensionJs.parse();
341
+ })();
342
+ for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
343
+ Object.defineProperty(exports, '__esModule', {
344
+ value: true
328
345
  });
329
- extensionJs.parse();
@@ -0,0 +1,3 @@
1
+ import type { RslibConfig } from '@rslib/core';
2
+ declare const _default: RslibConfig;
3
+ export default _default;
@@ -1,31 +0,0 @@
1
- /// <reference types="node" />
2
- /// <reference types="chrome" />
3
- /// <reference types="./js-frameworks.d.ts" />
4
- /// <reference path="./css-content.d.ts" />
5
- /// <reference path="./css-modules.d.ts" />
6
- /// <reference path="./images.d.ts" />
7
-
8
- declare namespace NodeJS {
9
- interface ProcessEnv {
10
- readonly EXTENSION_BROWSER:
11
- | 'chrome'
12
- | 'edge'
13
- | 'firefox'
14
- | 'chromium-based'
15
- | 'gecko-based'
16
- readonly EXTENSION_MODE: 'development' | 'production'
17
- }
18
- }
19
-
20
- interface ImportMetaEnv {
21
- readonly EXTENSION_BROWSER: NodeJS.ProcessEnv['EXTENSION_BROWSER']
22
- readonly EXTENSION_MODE: NodeJS.ProcessEnv['EXTENSION_MODE']
23
- }
24
-
25
- interface ImportMeta {
26
- readonly env: ImportMetaEnv
27
- }
28
-
29
- interface Window {
30
- __EXTENSION_SHADOW_ROOT__: ShadowRoot
31
- }
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
package/package.json CHANGED
@@ -2,29 +2,40 @@
2
2
  "license": "MIT",
3
3
  "repository": {
4
4
  "type": "git",
5
- "url": "https://github.com/cezaraugusto/extension.git",
5
+ "url": "https://github.com/extension-js/extension.js.git",
6
6
  "directory": "programs/cli"
7
7
  },
8
8
  "engines": {
9
9
  "node": ">=18"
10
10
  },
11
- "name": "extension",
12
- "version": "2.0.0-rc.9",
13
- "description": "Create cross-browser extensions with no build configuration.",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/cli.d.ts",
14
+ "import": "./dist/cli.js",
15
+ "require": "./dist/cli.js"
16
+ }
17
+ },
14
18
  "main": "./dist/cli.js",
15
19
  "types": "./dist/cli.d.ts",
16
20
  "files": [
17
21
  "dist",
18
- "README.md"
22
+ "types"
19
23
  ],
20
24
  "bin": {
21
25
  "extension": "./dist/cli.js"
22
26
  },
27
+ "name": "extension",
28
+ "version": "2.0.1",
29
+ "description": "Create cross-browser extensions with no build configuration.",
23
30
  "author": {
24
31
  "name": "Cezar Augusto",
25
32
  "email": "boss@cezaraugusto.net",
26
33
  "url": "https://cezaraugusto.com"
27
34
  },
35
+ "publishConfig": {
36
+ "access": "public",
37
+ "registry": "https://registry.npmjs.org"
38
+ },
28
39
  "keywords": [
29
40
  "zero-config",
30
41
  "build",
@@ -37,43 +48,53 @@
37
48
  "safari extension",
38
49
  "web",
39
50
  "react",
40
- "typescript"
51
+ "typescript",
52
+ "webextension",
53
+ "browser-extension",
54
+ "chrome-extension",
55
+ "firefox-addon",
56
+ "edge-extension",
57
+ "safari-web-extension",
58
+ "manifest-v3",
59
+ "mv3",
60
+ "cross-browser",
61
+ "content-script",
62
+ "background-script",
63
+ "devtools",
64
+ "create-extension",
65
+ "scaffold",
66
+ "starter-template",
67
+ "boilerplate",
68
+ "cli"
41
69
  ],
42
70
  "dependencies": {
43
- "@colors/colors": "^1.6.0",
44
71
  "@types/chrome": "^0.0.287",
45
- "@types/firefox-webext-browser": "^120.0.4",
46
72
  "@types/node": "^22.10.1",
47
73
  "@types/react": "^19.0.1",
48
74
  "@types/react-dom": "^19.0.1",
75
+ "@types/webextension-polyfill": "0.12.3",
49
76
  "commander": "^12.1.0",
77
+ "pintor": "0.3.0",
50
78
  "semver": "^7.6.3",
51
79
  "update-check": "^1.5.4",
52
80
  "webextension-polyfill": "^0.12.0",
53
- "extension-develop": "2.0.0-rc.9",
54
- "extension-create": "2.0.0"
81
+ "extension-develop": "2.0.1",
82
+ "extension-create": "2.0.1"
55
83
  },
56
84
  "devDependencies": {
57
- "@types/jest": "^29.5.14",
85
+ "@rslib/core": "^0.6.9",
58
86
  "@types/mock-fs": "^4.13.4",
59
87
  "@types/semver": "^7.5.8",
60
- "jest": "^29.7.0",
61
88
  "mock-fs": "^5.4.1",
62
- "ts-jest": "^29.2.5",
63
89
  "tsconfig": "*",
64
- "tsup": "^8.3.5",
65
- "typescript": "5.7.2"
90
+ "typescript": "5.7.2",
91
+ "vitest": "3.2.2"
66
92
  },
67
93
  "scripts": {
68
- "watch": "pnpm compile --watch",
69
- "compile:types": "bash install_scripts.sh",
70
- "compile:readme-files": "node ./scripts/copyMarkdownFilesToCli.js",
71
- "compile:tailwind-config": "node ./scripts/copyTailwindConfig.js",
72
- "compile:stylelint-config": "node ./scripts/copyStylelintConfig.js",
73
- "compile:cli": "tsup-node ./cli.ts --format cjs --dts --target=node18",
74
- "compile": "pnpm compile:readme-files && pnpm compile:tailwind-config && pnpm compile:stylelint-config && pnpm compile:cli && pnpm compile:types",
94
+ "watch": "rslib build --watch",
95
+ "compile": "rslib build",
75
96
  "clean": "rm -rf dist",
76
97
  "test": "echo \"Note: no test specified\" && exit 0",
77
- "test:cli": "jest __spec__/cli.spec.ts"
98
+ "test:cli": "vitest run"
78
99
  }
79
100
  }
@@ -0,0 +1 @@
1
+ declare const x: number
@@ -1,7 +0,0 @@
1
- /** @type {import('stylelint').Config} */
2
- const stylelintRootConfig = {
3
- extends: [],
4
- rules: {}
5
- }
6
-
7
- module.exports = stylelintRootConfig
@@ -1,25 +0,0 @@
1
- const path = require('path')
2
- const fs = require('fs')
3
-
4
- const [, pathOrRemoteUrl] = process.argv.slice(2)
5
- const projectDir = pathOrRemoteUrl.startsWith('http')
6
- ? process.cwd() + path.basename(pathOrRemoteUrl)
7
- : path.resolve(__dirname, pathOrRemoteUrl)
8
-
9
- const tailwindConfig = path.join(projectDir, 'tailwind.config.js')
10
-
11
- /** @type {import('tailwindcss').Config} */
12
- const tailwindConfigData = fs.existsSync(tailwindConfig)
13
- ? require(tailwindConfig)
14
- : {content: []}
15
-
16
- /** @type {import('tailwindcss').Config} */
17
- const tailwindRootConfig = {
18
- ...tailwindConfigData,
19
- content: [
20
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
21
- ...tailwindConfigData.content.map((file) => path.join(projectDir, file))
22
- ]
23
- }
24
-
25
- module.exports = tailwindRootConfig
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes