Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 44e4bc5295 | |||
| f464d7d33f | |||
| d0672739f0 | |||
| 44464f914f | |||
| 8940c41bdb | |||
| 446f265b6c | |||
| 7a465684c0 | |||
| 0369316463 | |||
| 8b74291d18 | |||
| 739b738100 | |||
| 95442dd39b |
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
|
||||
@@ -20,3 +20,4 @@ templates/*/package-lock.json
|
||||
docs/api/config.md
|
||||
docs/api/cli.md
|
||||
stats.html
|
||||
.tool-versions
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
# Changelog
|
||||
|
||||
## v0.8.0
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.7.5...v0.8.0)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- ⚠️ Use `defineUnlistedScript` to define unlisted scripts ([#167](https://github.com/wxt-dev/wxt/pull/167))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Fix wrong links ([#166](https://github.com/wxt-dev/wxt/pull/166))
|
||||
|
||||
### 🌊 Types
|
||||
|
||||
- ⚠️ Rename `BackgroundScriptDefintition` to `BackgroundDefinition` ([446f265](https://github.com/wxt-dev/wxt/commit/446f265))
|
||||
|
||||
#### ⚠️ Breaking Changes
|
||||
|
||||
- ⚠️ Use `defineUnlistedScript` to define unlisted scripts ([#167](https://github.com/wxt-dev/wxt/pull/167))
|
||||
- ⚠️ Rename `BackgroundScriptDefintition` to `BackgroundDefinition` ([446f265](https://github.com/wxt-dev/wxt/commit/446f265))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- 渣渣120 <WOSHIZHAZHA120@qq.com>
|
||||
|
||||
## v0.7.5
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.7.4...v0.7.5)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- More consistent `version_name` generation between browsers ([#163](https://github.com/wxt-dev/wxt/pull/163))
|
||||
- Ignore non-manifest fields when merging content script entries ([#164](https://github.com/wxt-dev/wxt/pull/164))
|
||||
- Add `browser_style` to popup options ([#165](https://github.com/wxt-dev/wxt/pull/165))
|
||||
|
||||
## v0.7.4
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.7.3...v0.7.4)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export default defineUnlistedScript(() => {
|
||||
console.log('injected');
|
||||
});
|
||||
@@ -124,6 +124,7 @@ export default defineConfig({
|
||||
{ text: 'wxt', link: '/api/wxt.md' },
|
||||
{ text: 'wxt/browser', link: '/api/wxt-browser.md' },
|
||||
{ text: 'wxt/client', link: '/api/wxt-client.md' },
|
||||
{ text: 'wxt/sandbox', link: '/api/wxt-sandbox.md' },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# `wxt/sandbox` Reference
|
||||
|
||||
The `wxt/sandbox` module contains exports that do not use the `browser` global (ie: a "sandboxed" environment).
|
||||
|
||||
:::warning 🚧 Under construction
|
||||
This documentation does not exist yet. All APIs are documented with JSDoc, so for now, you can view the documentation in your editor.
|
||||
|
||||
```ts
|
||||
import { defineUnlistedScript } from 'wxt/sandbox';
|
||||
```
|
||||
|
||||
:::
|
||||
@@ -29,6 +29,7 @@
|
||||
}"
|
||||
/>
|
||||
<meta name="manifest.type" content="page_action|browser_action" />
|
||||
<meta name="manifest.browser_style" content="true|false" />
|
||||
<!-- Set include/exclude if the page should be removed from some builds -->
|
||||
<meta name="manifest.include" content="['chrome', ...]" />
|
||||
<meta name="manifest.exclude" content="['chrome', ...]" />
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
TypeScript files that are built, but are not included in the manifest.
|
||||
|
||||
You are responsible for loading/running these scripts where needed.
|
||||
|
||||
## Filenames
|
||||
|
||||
<EntrypointPatterns
|
||||
@@ -13,8 +15,23 @@ TypeScript files that are built, but are not included in the manifest.
|
||||
|
||||
## Definition
|
||||
|
||||
Unlike the background or content scripts, you can define this script's logic in the top level scope.
|
||||
```ts
|
||||
export default defineUnlistedScript(() => {
|
||||
// Executed when script is loaded
|
||||
});
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```ts
|
||||
// Code goes here
|
||||
export default defineUnlistedScript({
|
||||
// Set include/exclude if the script should be removed from some builds
|
||||
include: undefined | string[],
|
||||
exclude: undefined | string[],
|
||||
|
||||
// Executed when script is loaded
|
||||
main() {
|
||||
// ...
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -12,8 +12,9 @@ Some WXT APIs can be used without importing them:
|
||||
|
||||
- [`browser`](/api/wxt-browser#browser) from `wxt/browser`, a small wrapper around `webextension-polyfill`
|
||||
- [`defineContentScript`](/api/wxt-client#defiencontentscript) from `wxt/client`
|
||||
- [`defineBackground`](/api/wxt-client#definebackgroundscript) from `wxt/client`
|
||||
- [`defineBackground`](/api/wxt-client#definebackground) from `wxt/client`
|
||||
- [`createContentScriptUi`](/api/wxt-client#createcontentscriptui) from `wxt/client`
|
||||
- [`defineUnlistedScript`](/api/wxt-sandbox#defineunlistedscript) from `wxt/sandbox`
|
||||
|
||||
And more. All [`wxt/client`](/api/wxt-client) APIs can be used without imports.
|
||||
|
||||
|
||||
@@ -79,8 +79,8 @@ There are a number of message passing libraries you can use to improve the messa
|
||||
|
||||
Here are some that are compatible with WXT (because they are based off `webextension-polyfill` as well):
|
||||
|
||||
- [`@webext-core/messaging`](https://webext-core.aklinker1.io/guide/proxy-service/) - "A light-weight, type-safe wrapper around the `browser.runtime` messaging APIs"
|
||||
- [`@webext-core/proxy-service`](https://webext-core.aklinker1.io/guide/messaging/) - "Create TRPC-like services that can be called from anywhere but run in the background"
|
||||
- [`@webext-core/messaging`](https://webext-core.aklinker1.io/guide/messaging/) - "A light-weight, type-safe wrapper around the `browser.runtime` messaging APIs"
|
||||
- [`@webext-core/proxy-service`](https://webext-core.aklinker1.io/guide/proxy-service/) - "Create TRPC-like services that can be called from anywhere but run in the background"
|
||||
- [`webext-bridge`](https://github.com/zikaari/webext-bridge) - "Messaging in Web Extensions made super easy. Out of the box."
|
||||
|
||||
## Browser Differences
|
||||
|
||||
@@ -22,6 +22,7 @@ describe('Auto Imports', () => {
|
||||
const defineBackground: typeof import('wxt/client')['defineBackground']
|
||||
const defineConfig: typeof import('wxt')['defineConfig']
|
||||
const defineContentScript: typeof import('wxt/client')['defineContentScript']
|
||||
const defineUnlistedScript: typeof import('wxt/sandbox')['defineUnlistedScript']
|
||||
}
|
||||
"
|
||||
`);
|
||||
|
||||
@@ -194,15 +194,15 @@ describe('Manifest Content', () => {
|
||||
});
|
||||
|
||||
describe('content_scripts', () => {
|
||||
it('should group content scripts and styles together based on their matches and run_at', async () => {
|
||||
it('should group content scripts and styles together based on their manifest properties', async () => {
|
||||
const project = new TestProject();
|
||||
project.addFile(
|
||||
'entrypoints/one.content/index.ts',
|
||||
`import "./style.css";
|
||||
export default defineContentScript({
|
||||
matches: ["*://google.com/*"],
|
||||
main: () => {},
|
||||
})`,
|
||||
export default defineContentScript({
|
||||
matches: ["*://google.com/*"],
|
||||
main: () => {},
|
||||
})`,
|
||||
);
|
||||
project.addFile(
|
||||
'entrypoints/one.content/style.css',
|
||||
@@ -211,11 +211,11 @@ describe('Manifest Content', () => {
|
||||
project.addFile(
|
||||
'entrypoints/two.content/index.ts',
|
||||
`import "./style.css";
|
||||
export default defineContentScript({
|
||||
matches: ["*://google.com/*"],
|
||||
runAt: "document_end",
|
||||
main: () => {},
|
||||
})`,
|
||||
export default defineContentScript({
|
||||
matches: ["*://google.com/*"],
|
||||
runAt: "document_end",
|
||||
main: () => {},
|
||||
})`,
|
||||
);
|
||||
project.addFile(
|
||||
'entrypoints/two.content/style.css',
|
||||
@@ -224,11 +224,11 @@ describe('Manifest Content', () => {
|
||||
project.addFile(
|
||||
'entrypoints/three.content/index.ts',
|
||||
`import "./style.css";
|
||||
export default defineContentScript({
|
||||
matches: ["*://google.com/*"],
|
||||
runAt: "document_end",
|
||||
main: () => {},
|
||||
})`,
|
||||
export default defineContentScript({
|
||||
matches: ["*://google.com/*"],
|
||||
runAt: "document_end",
|
||||
main: () => {},
|
||||
})`,
|
||||
);
|
||||
project.addFile(
|
||||
'entrypoints/three.content/style.css',
|
||||
@@ -237,11 +237,11 @@ describe('Manifest Content', () => {
|
||||
project.addFile(
|
||||
'entrypoints/four.content/index.ts',
|
||||
`import "./style.css";
|
||||
export default defineContentScript({
|
||||
matches: ["*://duckduckgo.com/*"],
|
||||
runAt: "document_end",
|
||||
main: () => {},
|
||||
})`,
|
||||
export default defineContentScript({
|
||||
matches: ["*://duckduckgo.com/*"],
|
||||
runAt: "document_end",
|
||||
main: () => {},
|
||||
})`,
|
||||
);
|
||||
project.addFile(
|
||||
'entrypoints/four.content/style.css',
|
||||
@@ -276,15 +276,15 @@ describe('Manifest Content', () => {
|
||||
project.addFile(
|
||||
'entrypoints/one.content/index.ts',
|
||||
`export default defineContentScript({
|
||||
matches: ["*://google.com/*"],
|
||||
main: () => {},
|
||||
})`,
|
||||
matches: ["*://google.com/*"],
|
||||
main: () => {},
|
||||
})`,
|
||||
);
|
||||
project.addFile(
|
||||
'entrypoints/two.content/style.css',
|
||||
`body {
|
||||
background-color: red;
|
||||
}`,
|
||||
background-color: red;
|
||||
}`,
|
||||
);
|
||||
project.setConfigFileConfig({
|
||||
manifest: {
|
||||
@@ -333,7 +333,7 @@ describe('Manifest Content', () => {
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"css\\":[\\"content-scripts/content.css\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"css\\":[\\"content-scripts/content.css\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -360,7 +360,7 @@ describe('Manifest Content', () => {
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"css\\":[\\"content-scripts/content.css\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"css\\":[\\"content-scripts/content.css\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -385,10 +385,10 @@ describe('Manifest Content', () => {
|
||||
|
||||
expect(await project.serializeFile('.output/chrome-mv3/manifest.json'))
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
`);
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
`);
|
||||
});
|
||||
|
||||
it('should not add a content script entry for CSS when cssInjectionMode is "ui", but add a web_accessible_resources entry for MV2', async () => {
|
||||
@@ -416,7 +416,7 @@ describe('Manifest Content', () => {
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv2/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":2,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}],\\"web_accessible_resources\\":[\\"content-scripts/content.css\\"]}"
|
||||
{\\"manifest_version\\":2,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}],\\"web_accessible_resources\\":[\\"content-scripts/content.css\\"]}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -445,7 +445,7 @@ describe('Manifest Content', () => {
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}],\\"web_accessible_resources\\":[{\\"resources\\":[\\"content-scripts/content.css\\"],\\"matches\\":[\\"https://*.google.com/*\\"]}]}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}],\\"web_accessible_resources\\":[{\\"resources\\":[\\"content-scripts/content.css\\"],\\"matches\\":[\\"https://*.google.com/*\\"]}]}"
|
||||
`);
|
||||
});
|
||||
});
|
||||
@@ -480,7 +480,7 @@ describe('Manifest Content', () => {
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"web_accessible_resources\\":[{\\"resources\\":[\\"one.png\\"],\\"matches\\":[\\"https://one.com/*\\"]},{\\"resources\\":[\\"content-scripts/content.css\\"],\\"matches\\":[\\"https://*.google.com/*\\"]}],\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"web_accessible_resources\\":[{\\"resources\\":[\\"one.png\\"],\\"matches\\":[\\"https://one.com/*\\"]},{\\"resources\\":[\\"content-scripts/content.css\\"],\\"matches\\":[\\"https://*.google.com/*\\"]}],\\"content_scripts\\":[{\\"matches\\":[\\"https://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]}]}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -505,7 +505,7 @@ describe('Manifest Content', () => {
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"author\\":\\"Custom Author\\"}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"author\\":\\"Custom Author\\"}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -537,4 +537,66 @@ describe('Manifest Content', () => {
|
||||
expect(safariManifest.background.persistent).toBe(expected);
|
||||
},
|
||||
);
|
||||
|
||||
describe('versions', () => {
|
||||
it.each([
|
||||
['chrome', 3] as const,
|
||||
['safari', 2] as const,
|
||||
['edge', 3] as const,
|
||||
])(
|
||||
'should include version_name on %s when it needs simplified',
|
||||
async (browser, manifestVersion) => {
|
||||
const project = new TestProject({
|
||||
version: '1.0.0-alpha1',
|
||||
});
|
||||
|
||||
await project.build({ browser, manifestVersion });
|
||||
const manifest = await project.getOutputManifest(
|
||||
`.output/${browser}-mv${manifestVersion}/manifest.json`,
|
||||
);
|
||||
|
||||
expect(manifest.version).toBe('1.0.0');
|
||||
expect(manifest.version_name).toBe('1.0.0-alpha1');
|
||||
},
|
||||
);
|
||||
|
||||
it.each([['firefox', 2] as const])(
|
||||
"should not include a version_name on %s because the browser doesn't support it",
|
||||
async (browser, manifestVersion) => {
|
||||
const project = new TestProject({
|
||||
version: '1.0.0-alpha1',
|
||||
});
|
||||
|
||||
await project.build({ browser, manifestVersion });
|
||||
const manifest = await project.getOutputManifest(
|
||||
`.output/${browser}-mv${manifestVersion}/manifest.json`,
|
||||
);
|
||||
|
||||
expect(manifest.version).toBe('1.0.0');
|
||||
expect(manifest.version_name).toBeUndefined();
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
['chrome', 3] as const,
|
||||
['firefox', 2] as const,
|
||||
['safari', 3] as const,
|
||||
['edge', 3] as const,
|
||||
])(
|
||||
'should not include the version_name if it is equal to version',
|
||||
async (browser, manifestVersion) => {
|
||||
const project = new TestProject({
|
||||
version: '1.0.0.1',
|
||||
});
|
||||
|
||||
await project.build({ browser, manifestVersion });
|
||||
const manifest = await project.getOutputManifest(
|
||||
`.output/${browser}-mv${manifestVersion}/manifest.json`,
|
||||
);
|
||||
|
||||
expect(manifest.version).toBe('1.0.0.1');
|
||||
expect(manifest.version_name).toBeUndefined();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('Output Directory Structure', () => {
|
||||
expect(await project.serializeOutput()).toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\"}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\"}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ describe('Output Directory Structure', () => {
|
||||
================================================================================
|
||||
.output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":[\\"*://*/*\\"],\\"css\\":[\\"content-scripts/one.css\\",\\"content-scripts/two.css\\"],\\"js\\":[\\"content-scripts/one.js\\",\\"content-scripts/two.js\\"]}]}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":[\\"*://*/*\\"],\\"css\\":[\\"content-scripts/one.css\\",\\"content-scripts/two.css\\"],\\"js\\":[\\"content-scripts/one.js\\",\\"content-scripts/two.js\\"]}]}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -96,7 +96,7 @@ describe('Output Directory Structure', () => {
|
||||
================================================================================
|
||||
.output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":[\\"*://*/*\\"],\\"js\\":[\\"content-scripts/overlay-one.js\\"]}]}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":[\\"*://*/*\\"],\\"js\\":[\\"content-scripts/overlay-one.js\\"]}]}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -172,7 +172,10 @@ describe('Output Directory Structure', () => {
|
||||
'entrypoints/background.js',
|
||||
`export default defineBackground(() => {});`,
|
||||
);
|
||||
project.addFile('entrypoints/unlisted.js', ``);
|
||||
project.addFile(
|
||||
'entrypoints/unlisted.js',
|
||||
`export default defineUnlistedScript(() => {})`,
|
||||
);
|
||||
project.addFile(
|
||||
'entrypoints/content.js',
|
||||
`export default defineContentScript({
|
||||
@@ -192,10 +195,10 @@ describe('Output Directory Structure', () => {
|
||||
|
||||
expect(await project.serializeFile('.output/chrome-mv3/manifest.json'))
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"background\\":{\\"service_worker\\":\\"background.js\\"},\\"content_scripts\\":[{\\"matches\\":[\\"*://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]},{\\"matches\\":[\\"*://*.duckduckgo.com/*\\"],\\"js\\":[\\"content-scripts/named.js\\"]}]}"
|
||||
`);
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"background\\":{\\"service_worker\\":\\"background.js\\"},\\"content_scripts\\":[{\\"matches\\":[\\"*://*.google.com/*\\"],\\"js\\":[\\"content-scripts/content.js\\"]},{\\"matches\\":[\\"*://*.duckduckgo.com/*\\"],\\"js\\":[\\"content-scripts/named.js\\"]}]}"
|
||||
`);
|
||||
expect(await project.fileExists('.output/chrome-mv3/background.js'));
|
||||
expect(
|
||||
await project.fileExists('.output/chrome-mv3/content-scripts/content.js'),
|
||||
|
||||
@@ -35,9 +35,9 @@ describe('React', () => {
|
||||
).toBe(true);
|
||||
expect(await project.serializeFile('.output/chrome-mv3/manifest.json'))
|
||||
.toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"content_scripts\\":[{\\"matches\\":\\"<all_urls>\\",\\"js\\":[\\"content-scripts/demo.js\\"]}]}"
|
||||
`);
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"content_scripts\\":[{\\"matches\\":\\"<all_urls>\\",\\"js\\":[\\"content-scripts/demo.js\\"]}]}"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,11 @@ describe('Remote Code', () => {
|
||||
it('should download "url:*" modules and include them in the final bundle', async () => {
|
||||
const url = 'https://code.jquery.com/jquery-3.7.1.slim.min.js';
|
||||
const project = new TestProject();
|
||||
project.addFile('entrypoints/popup.ts', `import "url:${url}"`);
|
||||
project.addFile(
|
||||
'entrypoints/popup.ts',
|
||||
`import "url:${url}"
|
||||
export default defineUnlistedScript(() => {})`,
|
||||
);
|
||||
|
||||
await project.build();
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('User Config', () => {
|
||||
================================================================================
|
||||
.output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"background\\":{\\"service_worker\\":\\"background.js\\"}}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"background\\":{\\"service_worker\\":\\"background.js\\"}}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -54,7 +54,7 @@ describe('User Config', () => {
|
||||
================================================================================
|
||||
.output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"background\\":{\\"service_worker\\":\\"background.js\\"}}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"background\\":{\\"service_worker\\":\\"background.js\\"}}"
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -82,7 +82,7 @@ describe('User Config', () => {
|
||||
expect(output).toMatchInlineSnapshot(`
|
||||
".output/chrome-mv3/manifest.json
|
||||
----------------------------------------
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"version_name\\":\\"0.0.0-test\\",\\"example_customization\\":[\\"production\\",\\"chrome\\",\\"3\\",\\"build\\"]}"
|
||||
{\\"manifest_version\\":3,\\"name\\":\\"E2E Extension\\",\\"description\\":\\"Example description\\",\\"version\\":\\"0.0.0\\",\\"example_customization\\":[\\"production\\",\\"chrome\\",\\"3\\",\\"build\\"]}"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ export class TestProject {
|
||||
{
|
||||
name: 'E2E Extension',
|
||||
description: 'Example description',
|
||||
version: '0.0.0-test',
|
||||
version: '0.0.0',
|
||||
dependencies: {
|
||||
wxt: '../../..',
|
||||
},
|
||||
|
||||
+11
-7
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.7.4",
|
||||
"version": "0.8.0",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"engines": {
|
||||
"node": ">=18.16.0",
|
||||
"node": ">=18",
|
||||
"pnpm": ">=8"
|
||||
},
|
||||
"repository": {
|
||||
@@ -44,6 +44,10 @@
|
||||
"import": "./dist/client.js",
|
||||
"types": "./dist/client.d.ts"
|
||||
},
|
||||
"./sandbox": {
|
||||
"import": "./dist/sandbox.js",
|
||||
"types": "./dist/sandbox.d.ts"
|
||||
},
|
||||
"./browser": {
|
||||
"import": "./dist/browser.js",
|
||||
"types": "./dist/browser.d.ts"
|
||||
@@ -90,7 +94,7 @@
|
||||
"prompts": "^2.4.2",
|
||||
"rollup-plugin-visualizer": "^5.9.2",
|
||||
"unimport": "^3.1.0",
|
||||
"vite": "^4.4.7",
|
||||
"vite": "^4.4.11",
|
||||
"web-ext-run": "^0.1.0",
|
||||
"webextension-polyfill": "^0.10.0",
|
||||
"zip-dir": "^2.0.0"
|
||||
@@ -99,9 +103,9 @@
|
||||
"@faker-js/faker": "^8.0.2",
|
||||
"@types/fs-extra": "^11.0.1",
|
||||
"@types/lodash.merge": "^4.6.7",
|
||||
"@types/node": "^20.4.5",
|
||||
"@types/node": "^20.8.6",
|
||||
"@types/prompts": "^2.4.4",
|
||||
"@vitest/coverage-v8": "^0.34.1",
|
||||
"@vitest/coverage-v8": "^0.34.6",
|
||||
"execa": "^7.2.0",
|
||||
"jsdom": "^22.1.0",
|
||||
"lint-staged": "^14.0.0",
|
||||
@@ -114,8 +118,8 @@
|
||||
"tsx": "^3.12.7",
|
||||
"typescript": "^5.2.2",
|
||||
"vitepress": "1.0.0-rc.10",
|
||||
"vitest": "^0.34.1",
|
||||
"vitest-mock-extended": "^1.1.4",
|
||||
"vitest": "^0.34.6",
|
||||
"vitest-mock-extended": "^1.3.1",
|
||||
"vue": "^3.3.4",
|
||||
"webextension-polyfill": "^0.10.0"
|
||||
},
|
||||
|
||||
Generated
+102
-91
@@ -84,8 +84,8 @@ importers:
|
||||
specifier: ^3.1.0
|
||||
version: 3.3.0
|
||||
vite:
|
||||
specifier: ^4.4.7
|
||||
version: 4.4.9(@types/node@20.5.9)
|
||||
specifier: ^4.4.11
|
||||
version: 4.4.11(@types/node@20.8.6)
|
||||
web-ext-run:
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0
|
||||
@@ -106,14 +106,14 @@ importers:
|
||||
specifier: ^4.6.7
|
||||
version: 4.6.7
|
||||
'@types/node':
|
||||
specifier: ^20.4.5
|
||||
version: 20.5.9
|
||||
specifier: ^20.8.6
|
||||
version: 20.8.6
|
||||
'@types/prompts':
|
||||
specifier: ^2.4.4
|
||||
version: 2.4.4
|
||||
'@vitest/coverage-v8':
|
||||
specifier: ^0.34.1
|
||||
version: 0.34.1(vitest@0.34.3)
|
||||
specifier: ^0.34.6
|
||||
version: 0.34.6(vitest@0.34.6)
|
||||
execa:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0
|
||||
@@ -149,13 +149,13 @@ importers:
|
||||
version: 5.2.2
|
||||
vitepress:
|
||||
specifier: 1.0.0-rc.10
|
||||
version: 1.0.0-rc.10(@types/node@20.5.9)
|
||||
version: 1.0.0-rc.10(@types/node@20.8.6)
|
||||
vitest:
|
||||
specifier: ^0.34.1
|
||||
version: 0.34.3(jsdom@22.1.0)
|
||||
specifier: ^0.34.6
|
||||
version: 0.34.6(jsdom@22.1.0)
|
||||
vitest-mock-extended:
|
||||
specifier: ^1.1.4
|
||||
version: 1.3.0(typescript@5.2.2)(vitest@0.34.3)
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1(typescript@5.2.2)(vitest@0.34.6)
|
||||
vue:
|
||||
specifier: ^3.3.4
|
||||
version: 3.3.4
|
||||
@@ -864,8 +864,8 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/@jest/schemas@29.6.0:
|
||||
resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==}
|
||||
/@jest/schemas@29.6.3:
|
||||
resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@sinclair/typebox': 0.27.8
|
||||
@@ -1005,7 +1005,7 @@ packages:
|
||||
resolution: {integrity: sha512-c0hrgAOVYr21EX8J0jBMXGLMgJqVf/v6yxi0dLaJboW9aQPh16Id+z6w2Tx1hm+piJOLv8xPfVKZCLfjPw/IMQ==}
|
||||
dependencies:
|
||||
'@types/jsonfile': 6.1.1
|
||||
'@types/node': 20.5.9
|
||||
'@types/node': 20.8.6
|
||||
dev: true
|
||||
|
||||
/@types/http-cache-semantics@4.0.1:
|
||||
@@ -1019,7 +1019,7 @@ packages:
|
||||
/@types/jsonfile@6.1.1:
|
||||
resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==}
|
||||
dependencies:
|
||||
'@types/node': 20.5.9
|
||||
'@types/node': 20.8.6
|
||||
dev: true
|
||||
|
||||
/@types/lodash.merge@4.6.7:
|
||||
@@ -1036,13 +1036,15 @@ packages:
|
||||
resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
|
||||
dev: false
|
||||
|
||||
/@types/node@20.5.9:
|
||||
resolution: {integrity: sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==}
|
||||
/@types/node@20.8.6:
|
||||
resolution: {integrity: sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==}
|
||||
dependencies:
|
||||
undici-types: 5.25.3
|
||||
|
||||
/@types/prompts@2.4.4:
|
||||
resolution: {integrity: sha512-p5N9uoTH76lLvSAaYSZtBCdEXzpOOufsRjnhjVSrZGXikVGHX9+cc9ERtHRV4hvBKHyZb1bg4K+56Bd2TqUn4A==}
|
||||
dependencies:
|
||||
'@types/node': 20.5.9
|
||||
'@types/node': 20.8.6
|
||||
kleur: 3.0.3
|
||||
dev: true
|
||||
|
||||
@@ -1080,8 +1082,8 @@ packages:
|
||||
resolution: {integrity: sha512-Sdg+E2F5JUbhkE1qX15QUxpyhfMFKRGJqND9nb1C0gNN4NR7kCV31/1GvNbg6Xe+m/JElJ9/lG5kepMzjGPuQw==}
|
||||
dev: false
|
||||
|
||||
/@vitest/coverage-v8@0.34.1(vitest@0.34.3):
|
||||
resolution: {integrity: sha512-lRgUwjTMr8idXEbUPSNH4jjRZJXJCVY3BqUa+LDXyJVe3pldxYMn/r0HMqatKUGTp0Kyf1j5LfFoY6kRqRp7jw==}
|
||||
/@vitest/coverage-v8@0.34.6(vitest@0.34.6):
|
||||
resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==}
|
||||
peerDependencies:
|
||||
vitest: '>=0.32.0 <1'
|
||||
dependencies:
|
||||
@@ -1096,47 +1098,47 @@ packages:
|
||||
std-env: 3.3.3
|
||||
test-exclude: 6.0.0
|
||||
v8-to-istanbul: 9.1.0
|
||||
vitest: 0.34.3(jsdom@22.1.0)
|
||||
vitest: 0.34.6(jsdom@22.1.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@vitest/expect@0.34.3:
|
||||
resolution: {integrity: sha512-F8MTXZUYRBVsYL1uoIft1HHWhwDbSzwAU9Zgh8S6WFC3YgVb4AnFV2GXO3P5Em8FjEYaZtTnQYoNwwBrlOMXgg==}
|
||||
/@vitest/expect@0.34.6:
|
||||
resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==}
|
||||
dependencies:
|
||||
'@vitest/spy': 0.34.3
|
||||
'@vitest/utils': 0.34.3
|
||||
chai: 4.3.7
|
||||
'@vitest/spy': 0.34.6
|
||||
'@vitest/utils': 0.34.6
|
||||
chai: 4.3.10
|
||||
dev: true
|
||||
|
||||
/@vitest/runner@0.34.3:
|
||||
resolution: {integrity: sha512-lYNq7N3vR57VMKMPLVvmJoiN4bqwzZ1euTW+XXYH5kzr3W/+xQG3b41xJn9ChJ3AhYOSoweu974S1V3qDcFESA==}
|
||||
/@vitest/runner@0.34.6:
|
||||
resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==}
|
||||
dependencies:
|
||||
'@vitest/utils': 0.34.3
|
||||
'@vitest/utils': 0.34.6
|
||||
p-limit: 4.0.0
|
||||
pathe: 1.1.1
|
||||
dev: true
|
||||
|
||||
/@vitest/snapshot@0.34.3:
|
||||
resolution: {integrity: sha512-QyPaE15DQwbnIBp/yNJ8lbvXTZxS00kRly0kfFgAD5EYmCbYcA+1EEyRalc93M0gosL/xHeg3lKAClIXYpmUiQ==}
|
||||
/@vitest/snapshot@0.34.6:
|
||||
resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==}
|
||||
dependencies:
|
||||
magic-string: 0.30.3
|
||||
magic-string: 0.30.2
|
||||
pathe: 1.1.1
|
||||
pretty-format: 29.6.0
|
||||
pretty-format: 29.7.0
|
||||
dev: true
|
||||
|
||||
/@vitest/spy@0.34.3:
|
||||
resolution: {integrity: sha512-N1V0RFQ6AI7CPgzBq9kzjRdPIgThC340DGjdKdPSE8r86aUSmeliTUgkTqLSgtEwWWsGfBQ+UetZWhK0BgJmkQ==}
|
||||
/@vitest/spy@0.34.6:
|
||||
resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==}
|
||||
dependencies:
|
||||
tinyspy: 2.1.1
|
||||
tinyspy: 2.2.0
|
||||
dev: true
|
||||
|
||||
/@vitest/utils@0.34.3:
|
||||
resolution: {integrity: sha512-kiSnzLG6m/tiT0XEl4U2H8JDBjFtwVlaE8I3QfGiMFR0QvnRDfYfdP3YvTBWM/6iJDAyaPY6yVQiCTUc7ZzTHA==}
|
||||
/@vitest/utils@0.34.6:
|
||||
resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==}
|
||||
dependencies:
|
||||
diff-sequences: 29.4.3
|
||||
loupe: 2.3.6
|
||||
pretty-format: 29.6.0
|
||||
diff-sequences: 29.6.3
|
||||
loupe: 2.3.7
|
||||
pretty-format: 29.7.0
|
||||
dev: true
|
||||
|
||||
/@vue/compiler-core@3.3.4:
|
||||
@@ -1616,15 +1618,15 @@ packages:
|
||||
engines: {node: '>=14.16'}
|
||||
dev: false
|
||||
|
||||
/chai@4.3.7:
|
||||
resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==}
|
||||
/chai@4.3.10:
|
||||
resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
assertion-error: 1.1.0
|
||||
check-error: 1.0.2
|
||||
check-error: 1.0.3
|
||||
deep-eql: 4.1.3
|
||||
get-func-name: 2.0.0
|
||||
loupe: 2.3.6
|
||||
get-func-name: 2.0.2
|
||||
loupe: 2.3.7
|
||||
pathval: 1.1.1
|
||||
type-detect: 4.0.8
|
||||
dev: true
|
||||
@@ -1641,8 +1643,10 @@ packages:
|
||||
resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
|
||||
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
|
||||
|
||||
/check-error@1.0.2:
|
||||
resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
|
||||
/check-error@1.0.3:
|
||||
resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
|
||||
dependencies:
|
||||
get-func-name: 2.0.2
|
||||
dev: true
|
||||
|
||||
/chokidar@3.5.3:
|
||||
@@ -1657,7 +1661,7 @@ packages:
|
||||
normalize-path: 3.0.0
|
||||
readdirp: 3.6.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
fsevents: 2.3.3
|
||||
|
||||
/chownr@2.0.0:
|
||||
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
||||
@@ -1669,7 +1673,7 @@ packages:
|
||||
engines: {node: '>=12.13.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@types/node': 20.5.9
|
||||
'@types/node': 20.8.6
|
||||
escape-string-regexp: 4.0.0
|
||||
is-wsl: 2.2.0
|
||||
lighthouse-logger: 1.4.2
|
||||
@@ -1960,8 +1964,8 @@ packages:
|
||||
resolution: {integrity: sha512-FJ9RDpf3GicEBvzI3jxc2XhHzbqD8p4ANw/1kPsFBfTvP1b7Gn/Lg1vO7R9J4IVgoMbyUmFrFGZafJ1hPZpvlg==}
|
||||
dev: false
|
||||
|
||||
/diff-sequences@29.4.3:
|
||||
resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==}
|
||||
/diff-sequences@29.6.3:
|
||||
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
@@ -2329,8 +2333,8 @@ packages:
|
||||
/fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
/fsevents@2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
/fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
@@ -2371,8 +2375,8 @@ packages:
|
||||
engines: {node: 6.* || 8.* || >= 10.*}
|
||||
dev: false
|
||||
|
||||
/get-func-name@2.0.0:
|
||||
resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
|
||||
/get-func-name@2.0.2:
|
||||
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
|
||||
dev: true
|
||||
|
||||
/get-intrinsic@1.2.1:
|
||||
@@ -3211,10 +3215,10 @@ packages:
|
||||
js-tokens: 4.0.0
|
||||
dev: false
|
||||
|
||||
/loupe@2.3.6:
|
||||
resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==}
|
||||
/loupe@2.3.7:
|
||||
resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
|
||||
dependencies:
|
||||
get-func-name: 2.0.0
|
||||
get-func-name: 2.0.2
|
||||
dev: true
|
||||
|
||||
/lowercase-keys@3.0.0:
|
||||
@@ -3393,7 +3397,7 @@ packages:
|
||||
acorn: 8.10.0
|
||||
pathe: 1.1.1
|
||||
pkg-types: 1.0.3
|
||||
ufo: 1.3.0
|
||||
ufo: 1.3.1
|
||||
|
||||
/moment@2.29.4:
|
||||
resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
|
||||
@@ -3784,11 +3788,11 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/pretty-format@29.6.0:
|
||||
resolution: {integrity: sha512-XH+D4n7Ey0iSR6PdAnBs99cWMZdGsdKrR33iUHQNr79w1szKTCIZDVdXuccAsHVwDBp0XeWPfNEoaxP9EZgRmQ==}
|
||||
/pretty-format@29.7.0:
|
||||
resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/schemas': 29.6.0
|
||||
'@jest/schemas': 29.6.3
|
||||
ansi-styles: 5.2.0
|
||||
react-is: 18.2.0
|
||||
dev: true
|
||||
@@ -4035,7 +4039,7 @@ packages:
|
||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/rollup@3.28.0:
|
||||
@@ -4043,7 +4047,7 @@ packages:
|
||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
fsevents: 2.3.3
|
||||
|
||||
/rrweb-cssom@0.6.0:
|
||||
resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
|
||||
@@ -4494,8 +4498,8 @@ packages:
|
||||
engines: {node: '>=14.0.0'}
|
||||
dev: true
|
||||
|
||||
/tinyspy@2.1.1:
|
||||
resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==}
|
||||
/tinyspy@2.2.0:
|
||||
resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
dev: true
|
||||
|
||||
@@ -4612,7 +4616,7 @@ packages:
|
||||
'@esbuild-kit/core-utils': 3.2.2
|
||||
'@esbuild-kit/esm-loader': 2.5.5
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/type-detect@4.0.8:
|
||||
@@ -4660,6 +4664,10 @@ packages:
|
||||
|
||||
/ufo@1.3.0:
|
||||
resolution: {integrity: sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw==}
|
||||
dev: false
|
||||
|
||||
/ufo@1.3.1:
|
||||
resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==}
|
||||
|
||||
/uhyphen@0.2.0:
|
||||
resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==}
|
||||
@@ -4674,6 +4682,9 @@ packages:
|
||||
which-boxed-primitive: 1.0.2
|
||||
dev: true
|
||||
|
||||
/undici-types@5.25.3:
|
||||
resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==}
|
||||
|
||||
/unimport@3.3.0:
|
||||
resolution: {integrity: sha512-3jhq3ZG5hFZzrWGDCpx83kjPzefP/EeuKkIO1T0MA4Zwj+dO/Og1mFvZ4aZ5WSDm0FVbbdVIRH1zKBG7c4wOpg==}
|
||||
dependencies:
|
||||
@@ -4775,8 +4786,8 @@ packages:
|
||||
spdx-expression-parse: 3.0.1
|
||||
dev: true
|
||||
|
||||
/vite-node@0.34.3(@types/node@20.5.9):
|
||||
resolution: {integrity: sha512-+0TzJf1g0tYXj6tR2vEyiA42OPq68QkRZCu/ERSo2PtsDJfBpDyEfuKbRvLmZqi/CgC7SCBtyC+WjTGNMRIaig==}
|
||||
/vite-node@0.34.6(@types/node@20.8.6):
|
||||
resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
|
||||
engines: {node: '>=v14.18.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@@ -4785,7 +4796,7 @@ packages:
|
||||
mlly: 1.4.2
|
||||
pathe: 1.1.1
|
||||
picocolors: 1.0.0
|
||||
vite: 4.4.9(@types/node@20.5.9)
|
||||
vite: 4.4.11(@types/node@20.8.6)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- less
|
||||
@@ -4797,8 +4808,8 @@ packages:
|
||||
- terser
|
||||
dev: true
|
||||
|
||||
/vite@4.4.9(@types/node@20.5.9):
|
||||
resolution: {integrity: sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==}
|
||||
/vite@4.4.11(@types/node@20.8.6):
|
||||
resolution: {integrity: sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -4825,14 +4836,14 @@ packages:
|
||||
terser:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/node': 20.5.9
|
||||
'@types/node': 20.8.6
|
||||
esbuild: 0.18.20
|
||||
postcss: 8.4.27
|
||||
rollup: 3.28.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
fsevents: 2.3.3
|
||||
|
||||
/vitepress@1.0.0-rc.10(@types/node@20.5.9):
|
||||
/vitepress@1.0.0-rc.10(@types/node@20.8.6):
|
||||
resolution: {integrity: sha512-+MsahIWqq5WUEmj6MR4obcKYbT7im07jZPCQPdNJExkeOSbOAJ4xypSLx88x7rvtzWHhHc5aXbOhCRvGEGjFrw==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@@ -4845,7 +4856,7 @@ packages:
|
||||
mark.js: 8.11.1
|
||||
minisearch: 6.1.0
|
||||
shiki: 0.14.3
|
||||
vite: 4.4.9(@types/node@20.5.9)
|
||||
vite: 4.4.11(@types/node@20.8.6)
|
||||
vue: 3.3.4
|
||||
transitivePeerDependencies:
|
||||
- '@algolia/client-search'
|
||||
@@ -4874,19 +4885,19 @@ packages:
|
||||
- universal-cookie
|
||||
dev: true
|
||||
|
||||
/vitest-mock-extended@1.3.0(typescript@5.2.2)(vitest@0.34.3):
|
||||
resolution: {integrity: sha512-qolbgansCq7huhmUUlHXOUYlejL86+jFkfyeoxGR9IWKhWcIjI3Ek2J9eTwIFfVzNkaTCpuJizEg9EqDJuuOkg==}
|
||||
/vitest-mock-extended@1.3.1(typescript@5.2.2)(vitest@0.34.6):
|
||||
resolution: {integrity: sha512-OpghYjh4BDuQ/Mzs3lFMQ1QRk9D8/2O9T47MLUA5eLn7K4RWIy+MfIivYOWEyxjTENjsBnzgMihDjyNalN/K0Q==}
|
||||
peerDependencies:
|
||||
typescript: 3.x || 4.x || 5.x
|
||||
vitest: '>=0.31.1'
|
||||
dependencies:
|
||||
ts-essentials: 9.3.2(typescript@5.2.2)
|
||||
typescript: 5.2.2
|
||||
vitest: 0.34.3(jsdom@22.1.0)
|
||||
vitest: 0.34.6(jsdom@22.1.0)
|
||||
dev: true
|
||||
|
||||
/vitest@0.34.3(jsdom@22.1.0):
|
||||
resolution: {integrity: sha512-7+VA5Iw4S3USYk+qwPxHl8plCMhA5rtfwMjgoQXMT7rO5ldWcdsdo3U1QD289JgglGK4WeOzgoLTsGFu6VISyQ==}
|
||||
/vitest@0.34.6(jsdom@22.1.0):
|
||||
resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==}
|
||||
engines: {node: '>=v14.18.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -4918,16 +4929,16 @@ packages:
|
||||
dependencies:
|
||||
'@types/chai': 4.3.5
|
||||
'@types/chai-subset': 1.3.3
|
||||
'@types/node': 20.5.9
|
||||
'@vitest/expect': 0.34.3
|
||||
'@vitest/runner': 0.34.3
|
||||
'@vitest/snapshot': 0.34.3
|
||||
'@vitest/spy': 0.34.3
|
||||
'@vitest/utils': 0.34.3
|
||||
'@types/node': 20.8.6
|
||||
'@vitest/expect': 0.34.6
|
||||
'@vitest/runner': 0.34.6
|
||||
'@vitest/snapshot': 0.34.6
|
||||
'@vitest/spy': 0.34.6
|
||||
'@vitest/utils': 0.34.6
|
||||
acorn: 8.10.0
|
||||
acorn-walk: 8.2.0
|
||||
cac: 6.7.14
|
||||
chai: 4.3.7
|
||||
chai: 4.3.10
|
||||
debug: 4.3.4
|
||||
jsdom: 22.1.0
|
||||
local-pkg: 0.4.3
|
||||
@@ -4938,8 +4949,8 @@ packages:
|
||||
strip-literal: 1.3.0
|
||||
tinybench: 2.5.0
|
||||
tinypool: 0.7.0
|
||||
vite: 4.4.9(@types/node@20.5.9)
|
||||
vite-node: 0.34.3(@types/node@20.5.9)
|
||||
vite: 4.4.11(@types/node@20.8.6)
|
||||
vite-node: 0.34.6(@types/node@20.8.6)
|
||||
why-is-node-running: 2.2.2
|
||||
transitivePeerDependencies:
|
||||
- less
|
||||
|
||||
+8
-1
@@ -10,7 +10,7 @@ const spinner = ora('Building WXT').start();
|
||||
|
||||
const startTime = Date.now();
|
||||
const outDir = 'dist';
|
||||
const virtualEntrypoints = ['background', 'content-script'];
|
||||
const virtualEntrypoints = ['background', 'content-script', 'unlisted-script'];
|
||||
|
||||
await fs.rm(outDir, { recursive: true, force: true });
|
||||
|
||||
@@ -48,6 +48,13 @@ await Promise.all([
|
||||
silent: true,
|
||||
external: ['vite'],
|
||||
}),
|
||||
tsup.build({
|
||||
entry: { sandbox: 'src/client/sandbox/index.ts' },
|
||||
format: ['esm'],
|
||||
sourcemap: 'inline',
|
||||
dts: true,
|
||||
silent: true,
|
||||
}),
|
||||
...virtualEntrypoints.map((entryName) =>
|
||||
tsup.build({
|
||||
entry: {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { defineBackground } from '../defineBackground';
|
||||
import { BackgroundDefinition } from '../../core/types';
|
||||
|
||||
describe('defineBackground', () => {
|
||||
it('should return the object definition when given an object', () => {
|
||||
const definition: BackgroundDefinition = {
|
||||
include: [''],
|
||||
persistent: false,
|
||||
main: vi.fn(),
|
||||
};
|
||||
|
||||
const actual = defineBackground(definition);
|
||||
|
||||
expect(actual).toEqual(definition);
|
||||
});
|
||||
|
||||
it('should return the object definition when given a main function', () => {
|
||||
const main = vi.fn();
|
||||
|
||||
const actual = defineBackground(main);
|
||||
|
||||
expect(actual).toEqual({ main });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { defineContentScript } from '../defineContentScript';
|
||||
import { ContentScriptDefinition } from '../../core/types';
|
||||
|
||||
describe('defineContentScript', () => {
|
||||
it('should return the object passed in', () => {
|
||||
const definition: ContentScriptDefinition = {
|
||||
matches: [],
|
||||
include: [''],
|
||||
main: vi.fn(),
|
||||
};
|
||||
|
||||
const actual = defineContentScript(definition);
|
||||
|
||||
expect(actual).toEqual(definition);
|
||||
});
|
||||
});
|
||||
@@ -1,12 +1,12 @@
|
||||
import { BackgroundScriptDefintition } from '..';
|
||||
import { BackgroundDefinition } from '..';
|
||||
|
||||
export function defineBackground(main: () => void): BackgroundScriptDefintition;
|
||||
export function defineBackground(main: () => void): BackgroundDefinition;
|
||||
export function defineBackground(
|
||||
definition: BackgroundScriptDefintition,
|
||||
): BackgroundScriptDefintition;
|
||||
definition: BackgroundDefinition,
|
||||
): BackgroundDefinition;
|
||||
export function defineBackground(
|
||||
arg: (() => void) | BackgroundScriptDefintition,
|
||||
): BackgroundScriptDefintition {
|
||||
arg: (() => void) | BackgroundDefinition,
|
||||
): BackgroundDefinition {
|
||||
if (typeof arg === 'function') return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { defineUnlistedScript } from '../defineUnlistedScript';
|
||||
import { UnlistedScriptDefinition } from '../../../core/types';
|
||||
|
||||
describe('defineUnlistedScript', () => {
|
||||
it('should return the object definition when given an object', () => {
|
||||
const definition: UnlistedScriptDefinition = {
|
||||
include: [''],
|
||||
main: vi.fn(),
|
||||
};
|
||||
|
||||
const actual = defineUnlistedScript(definition);
|
||||
|
||||
expect(actual).toEqual(definition);
|
||||
});
|
||||
|
||||
it('should return the object definition when given a main function', () => {
|
||||
const main = vi.fn();
|
||||
|
||||
const actual = defineUnlistedScript(main);
|
||||
|
||||
expect(actual).toEqual({ main });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { UnlistedScriptDefinition } from '../../core/types';
|
||||
|
||||
export function defineUnlistedScript(
|
||||
main: () => void,
|
||||
): UnlistedScriptDefinition;
|
||||
export function defineUnlistedScript(
|
||||
definition: UnlistedScriptDefinition,
|
||||
): UnlistedScriptDefinition;
|
||||
export function defineUnlistedScript(
|
||||
arg: (() => void) | UnlistedScriptDefinition,
|
||||
): UnlistedScriptDefinition {
|
||||
if (typeof arg === 'function') return { main: arg };
|
||||
return arg;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './defineUnlistedScript';
|
||||
@@ -37,6 +37,6 @@ try {
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error('The background script crashed on startup!');
|
||||
logger.error('The background crashed on startup!');
|
||||
throw err;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ import { ContentScriptContext } from '../utils/ContentScriptContext';
|
||||
|
||||
await main(ctx);
|
||||
} catch (err) {
|
||||
logger.error('The content script crashed on startup!', err);
|
||||
logger.error(
|
||||
`The content script "${__ENTRYPOINT__}" crashed on startup!`,
|
||||
err,
|
||||
);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import definition from 'virtual:user-unlisted-script';
|
||||
import { logger } from '../utils/logger';
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
await definition.main();
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
`The unlisted script "${__ENTRYPOINT__}" crashed on startup!`,
|
||||
err,
|
||||
);
|
||||
}
|
||||
})();
|
||||
+6
-1
@@ -6,7 +6,7 @@ declare module '*?raw' {
|
||||
}
|
||||
|
||||
declare module 'virtual:user-background' {
|
||||
const definition: import('../../').BackgroundScriptDefintition;
|
||||
const definition: import('../../').BackgroundDefinition;
|
||||
export default definition;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@ declare module 'virtual:user-content-script' {
|
||||
export default definition;
|
||||
}
|
||||
|
||||
declare module 'virtual:user-unlisted-script' {
|
||||
const definition: import('../../').UnlistedScriptDefinition;
|
||||
export default definition;
|
||||
}
|
||||
|
||||
// Globals defined by the vite-plugins/devServerGlobals.ts and utils/globals.ts
|
||||
declare const __COMMAND__: 'build' | 'serve';
|
||||
declare const __DEV_SERVER_PROTOCOL__: string;
|
||||
|
||||
@@ -261,6 +261,43 @@ describe('findEntrypoints', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it.each<[string, Omit<GenericEntrypoint, 'options'>]>([
|
||||
[
|
||||
'injected.ts',
|
||||
{
|
||||
type: 'unlisted-script',
|
||||
name: 'injected',
|
||||
inputPath: resolve(config.entrypointsDir, 'injected.ts'),
|
||||
outputDir: config.outDir,
|
||||
},
|
||||
],
|
||||
[
|
||||
'injected/index.ts',
|
||||
{
|
||||
type: 'unlisted-script',
|
||||
name: 'injected',
|
||||
inputPath: resolve(config.entrypointsDir, 'injected/index.ts'),
|
||||
outputDir: config.outDir,
|
||||
},
|
||||
],
|
||||
])(
|
||||
'should find and load unlisted-script entrypoint config from %s',
|
||||
async (path, expected) => {
|
||||
const options: GenericEntrypoint['options'] = {};
|
||||
globMock.mockResolvedValueOnce([path]);
|
||||
importEntrypointFileMock.mockResolvedValue(options);
|
||||
|
||||
const entrypoints = await findEntrypoints(config);
|
||||
|
||||
expect(entrypoints).toHaveLength(1);
|
||||
expect(entrypoints[0]).toEqual({ ...expected, options });
|
||||
expect(importEntrypointFileMock).toBeCalledWith(
|
||||
expected.inputPath,
|
||||
config,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
it.each<[string, GenericEntrypoint]>([
|
||||
// Sandbox
|
||||
[
|
||||
@@ -456,28 +493,6 @@ describe('findEntrypoints', () => {
|
||||
},
|
||||
],
|
||||
|
||||
// unlisted-script
|
||||
[
|
||||
'injected.ts',
|
||||
{
|
||||
type: 'unlisted-script',
|
||||
name: 'injected',
|
||||
inputPath: resolve(config.entrypointsDir, 'injected.ts'),
|
||||
outputDir: config.outDir,
|
||||
options: {},
|
||||
},
|
||||
],
|
||||
[
|
||||
'injected/index.ts',
|
||||
{
|
||||
type: 'unlisted-script',
|
||||
name: 'injected',
|
||||
inputPath: resolve(config.entrypointsDir, 'injected/index.ts'),
|
||||
outputDir: config.outDir,
|
||||
options: {},
|
||||
},
|
||||
],
|
||||
|
||||
// unlisted-style
|
||||
[
|
||||
'iframe.scss',
|
||||
|
||||
@@ -53,7 +53,11 @@ async function buildSingleEntrypoint(
|
||||
config: InternalConfig,
|
||||
): Promise<BuildStepOutput> {
|
||||
// Should this entrypoint be wrapped by the vite-plugins/virtualEntrypoint plugin?
|
||||
const isVirtual = ['background', 'content-script'].includes(entrypoint.type);
|
||||
const isVirtual = [
|
||||
'background',
|
||||
'content-script',
|
||||
'unlisted-script',
|
||||
].includes(entrypoint.type);
|
||||
const entry = isVirtual
|
||||
? `virtual:wxt-${entrypoint.type}?${entrypoint.inputPath}`
|
||||
: entrypoint.inputPath;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { relative, resolve } from 'path';
|
||||
import {
|
||||
BackgroundEntrypoint,
|
||||
BackgroundScriptDefintition,
|
||||
BackgroundDefinition,
|
||||
BaseEntrypointOptions,
|
||||
ContentScriptDefinition,
|
||||
ContentScriptEntrypoint,
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
InternalConfig,
|
||||
OptionsEntrypoint,
|
||||
PopupEntrypoint,
|
||||
UnlistedScriptDefinition,
|
||||
} from '../types';
|
||||
import fs from 'fs-extra';
|
||||
import { minimatch } from 'minimatch';
|
||||
@@ -74,15 +75,14 @@ export async function findEntrypoints(
|
||||
hasBackground = true;
|
||||
break;
|
||||
case 'content-script':
|
||||
entrypoint = await getContentScriptEntrypoint(
|
||||
config,
|
||||
getEntrypointName(config.entrypointsDir, path),
|
||||
path,
|
||||
);
|
||||
entrypoint = await getContentScriptEntrypoint(config, path);
|
||||
break;
|
||||
case 'unlisted-page':
|
||||
entrypoint = await getUnlistedPageEntrypoint(config, path);
|
||||
break;
|
||||
case 'unlisted-script':
|
||||
entrypoint = await getUnlistedScriptEntrypoint(config, path);
|
||||
break;
|
||||
case 'content-script-style':
|
||||
entrypoint = {
|
||||
type,
|
||||
@@ -201,12 +201,19 @@ async function getPopupEntrypoint(
|
||||
}
|
||||
}
|
||||
|
||||
const mv2KeyContent = document
|
||||
const mv2TypeContent = document
|
||||
.querySelector("meta[name='manifest.type']")
|
||||
?.getAttribute('content');
|
||||
if (mv2KeyContent) {
|
||||
if (mv2TypeContent) {
|
||||
options.mv2Key =
|
||||
mv2KeyContent === 'page_action' ? 'page_action' : 'browser_action';
|
||||
mv2TypeContent === 'page_action' ? 'page_action' : 'browser_action';
|
||||
}
|
||||
|
||||
const browserStyleContent = document
|
||||
.querySelector("meta[name='manifest.browser_style']")
|
||||
?.getAttribute('content');
|
||||
if (browserStyleContent) {
|
||||
options.browserStyle = browserStyleContent === 'true';
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -281,6 +288,35 @@ async function getUnlistedPageEntrypoint(
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path Absolute path to the script's file.
|
||||
* @param content String contents of the file at the path.
|
||||
*/
|
||||
async function getUnlistedScriptEntrypoint(
|
||||
config: InternalConfig,
|
||||
path: string,
|
||||
): Promise<GenericEntrypoint> {
|
||||
const name = getEntrypointName(config.entrypointsDir, path);
|
||||
const defaultExport = await importEntrypointFile<UnlistedScriptDefinition>(
|
||||
path,
|
||||
config,
|
||||
);
|
||||
if (defaultExport == null) {
|
||||
throw Error(
|
||||
`${name}: Default export not found, did you forget to call "export default defineUnlistedScript(...)"?`,
|
||||
);
|
||||
}
|
||||
const { main: _, ...moduleOptions } = defaultExport;
|
||||
const options: Omit<UnlistedScriptDefinition, 'main'> = moduleOptions;
|
||||
return {
|
||||
type: 'unlisted-script',
|
||||
name,
|
||||
inputPath: path,
|
||||
outputDir: config.outDir,
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path Absolute path to the background's TS file.
|
||||
*/
|
||||
@@ -288,19 +324,24 @@ async function getBackgroundEntrypoint(
|
||||
config: InternalConfig,
|
||||
path: string,
|
||||
): Promise<BackgroundEntrypoint> {
|
||||
let options: Omit<BackgroundScriptDefintition, 'main'> = {};
|
||||
const name = 'background';
|
||||
let options: Omit<BackgroundDefinition, 'main'> = {};
|
||||
if (path !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
|
||||
const defaultExport =
|
||||
await importEntrypointFile<BackgroundScriptDefintition>(path, config);
|
||||
const defaultExport = await importEntrypointFile<BackgroundDefinition>(
|
||||
path,
|
||||
config,
|
||||
);
|
||||
if (defaultExport == null) {
|
||||
throw Error('Background script does not have a default export');
|
||||
throw Error(
|
||||
`${name}: Default export not found, did you forget to call "export default defineBackground(...)"?`,
|
||||
);
|
||||
}
|
||||
const { main: _, ...moduleOptions } = defaultExport;
|
||||
options = moduleOptions;
|
||||
}
|
||||
return {
|
||||
type: 'background',
|
||||
name: 'background',
|
||||
name,
|
||||
inputPath: path,
|
||||
outputDir: config.outDir,
|
||||
options: {
|
||||
@@ -316,17 +357,19 @@ async function getBackgroundEntrypoint(
|
||||
*/
|
||||
async function getContentScriptEntrypoint(
|
||||
config: InternalConfig,
|
||||
name: string,
|
||||
path: string,
|
||||
): Promise<ContentScriptEntrypoint> {
|
||||
const name = getEntrypointName(config.entrypointsDir, path);
|
||||
const { main: _, ...options } =
|
||||
await importEntrypointFile<ContentScriptDefinition>(path, config);
|
||||
if (options == null) {
|
||||
throw Error(`Content script ${name} does not have a default export`);
|
||||
throw Error(
|
||||
`${name}: Default export not found, did you forget to call "export default defineContentScript(...)"?`,
|
||||
);
|
||||
}
|
||||
return {
|
||||
type: 'content-script',
|
||||
name: getEntrypointName(config.entrypointsDir, path),
|
||||
name,
|
||||
inputPath: path,
|
||||
outputDir: resolve(config.outDir, CONTENT_SCRIPT_OUT_DIR),
|
||||
options,
|
||||
|
||||
@@ -343,6 +343,7 @@ export interface PopupEntrypoint extends BaseEntrypoint {
|
||||
mv2Key?: 'browser_action' | 'page_action';
|
||||
defaultIcon?: Record<string, string>;
|
||||
defaultTitle?: string;
|
||||
browserStyle?: boolean;
|
||||
} & BaseEntrypointOptions;
|
||||
}
|
||||
|
||||
@@ -416,6 +417,8 @@ export interface ContentScriptDefinition extends ExcludableEntrypoint {
|
||||
* - `"manual"` - Exclude the CSS from the manifest. You are responsible for manually loading it
|
||||
* onto the page. Use `browser.runtime.getURL("content-scripts/<name>.css")` to get the file's
|
||||
* URL
|
||||
* - `"ui"` - Exclude the CSS from the manifest. CSS will be automatically added to your UI when
|
||||
* calling `createContentScriptUi`
|
||||
*
|
||||
* @default "manifest"
|
||||
*/
|
||||
@@ -426,12 +429,19 @@ export interface ContentScriptDefinition extends ExcludableEntrypoint {
|
||||
main(ctx: ContentScriptContext): void | Promise<void>;
|
||||
}
|
||||
|
||||
export interface BackgroundScriptDefintition extends ExcludableEntrypoint {
|
||||
export interface BackgroundDefinition extends ExcludableEntrypoint {
|
||||
type?: PerBrowserOption<'module'>;
|
||||
persistent?: PerBrowserOption<boolean>;
|
||||
main(): void;
|
||||
}
|
||||
|
||||
export interface UnlistedScriptDefinition extends ExcludableEntrypoint {
|
||||
/**
|
||||
* Main function executed when the unlisted script is ran.
|
||||
*/
|
||||
main(): void | Promise<void>;
|
||||
}
|
||||
|
||||
export type PerBrowserOption<T> = T | { [browser: TargetBrowser]: T };
|
||||
|
||||
export interface ExcludableEntrypoint {
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { hashContentScriptOptions } from '../content-scripts';
|
||||
import { fakeInternalConfig } from '../../../testing/fake-objects';
|
||||
|
||||
describe('Content Script Utils', () => {
|
||||
describe('hashContentScriptOptions', () => {
|
||||
it('should return a string containing all the options with defaults applied', () => {
|
||||
const hash = hashContentScriptOptions({ matches: [] });
|
||||
const hash = hashContentScriptOptions(
|
||||
{ matches: [] },
|
||||
fakeInternalConfig(),
|
||||
);
|
||||
|
||||
expect(hash).toMatchInlineSnapshot(
|
||||
'"[[\\"allFrames\\",false],[\\"excludeGlobs\\",[]],[\\"excludeMatches\\",[]],[\\"includeGlobs\\",[]],[\\"matchAboutBlank\\",false],[\\"matches\\",[]],[\\"matchOriginAsFallback\\",false],[\\"runAt\\",\\"document_idle\\"],[\\"world\\",\\"ISOLATED\\"]]"',
|
||||
'"[[\\"all_frames\\",false],[\\"exclude_globs\\",[]],[\\"exclude_matches\\",[]],[\\"include_globs\\",[]],[\\"match_about_blank\\",false],[\\"match_origin_as_fallback\\",false],[\\"matches\\",[]],[\\"run_at\\",\\"document_idle\\"],[\\"world\\",\\"ISOLATED\\"]]"',
|
||||
);
|
||||
});
|
||||
|
||||
it('should be consistent regardless of the object ordering and default values', () => {
|
||||
const hash1 = hashContentScriptOptions({
|
||||
allFrames: true,
|
||||
matches: ['*://google.com/*', '*://duckduckgo.com/*'],
|
||||
matchAboutBlank: false,
|
||||
});
|
||||
const hash2 = hashContentScriptOptions({
|
||||
matches: ['*://duckduckgo.com/*', '*://google.com/*'],
|
||||
allFrames: true,
|
||||
});
|
||||
const hash1 = hashContentScriptOptions(
|
||||
{
|
||||
allFrames: true,
|
||||
matches: ['*://google.com/*', '*://duckduckgo.com/*'],
|
||||
matchAboutBlank: false,
|
||||
},
|
||||
fakeInternalConfig(),
|
||||
);
|
||||
const hash2 = hashContentScriptOptions(
|
||||
{
|
||||
matches: ['*://duckduckgo.com/*', '*://google.com/*'],
|
||||
allFrames: true,
|
||||
},
|
||||
fakeInternalConfig(),
|
||||
);
|
||||
|
||||
expect(hash1).toBe(hash2);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { importEntrypointFile } from '../importEntrypointFile';
|
||||
import { fakeInternalConfig } from '../../../testing/fake-objects';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
const entrypointPath = (filename: string) =>
|
||||
resolve('src/core/utils/__tests__/test-entrypoints', filename);
|
||||
|
||||
const config = fakeInternalConfig({
|
||||
imports: false,
|
||||
debug: false,
|
||||
// Run inside the demo folder so that wxt is in the node_modules
|
||||
// WXT must also be built for these tests to pass
|
||||
root: 'demo',
|
||||
});
|
||||
|
||||
describe('importEntrypointFile', () => {
|
||||
it.each([
|
||||
['background.ts', { main: expect.any(Function) }],
|
||||
['content.ts', { main: expect.any(Function), matches: ['<all_urls>'] }],
|
||||
['unlisted.ts', { main: expect.any(Function) }],
|
||||
['react.tsx', { main: expect.any(Function) }],
|
||||
['with-named.ts', { main: expect.any(Function) }],
|
||||
])(
|
||||
'should return the default export of test-entrypoints/%s',
|
||||
async (file, expected) => {
|
||||
const actual = await importEntrypointFile(entrypointPath(file), config);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
},
|
||||
);
|
||||
|
||||
it('should return undefined when there is no default export', async () => {
|
||||
const actual = await importEntrypointFile(
|
||||
entrypointPath('no-default-export.ts'),
|
||||
config,
|
||||
);
|
||||
|
||||
expect(actual).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
import { defineBackground } from '../../../../client';
|
||||
|
||||
export default defineBackground({
|
||||
main() {},
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
import { defineContentScript } from '../../../../client';
|
||||
|
||||
export default defineContentScript({
|
||||
matches: ['<all_urls>'],
|
||||
main() {},
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
import { defineUnlistedScript } from '../../../../client/sandbox';
|
||||
|
||||
export default defineUnlistedScript(() => {});
|
||||
@@ -0,0 +1,3 @@
|
||||
import { defineUnlistedScript } from '../../../../client/sandbox';
|
||||
|
||||
export default defineUnlistedScript(() => {});
|
||||
@@ -0,0 +1,5 @@
|
||||
import { defineBackground } from '../../../../client';
|
||||
|
||||
export const a = {};
|
||||
|
||||
export default defineBackground(() => {});
|
||||
@@ -10,7 +10,11 @@ export function getUnimportOptions(
|
||||
const defaultOptions: Partial<UnimportOptions> = {
|
||||
debugLog: config.logger.debug,
|
||||
imports: [{ name: 'defineConfig', from: 'wxt' }],
|
||||
presets: [{ package: 'wxt/client' }, { package: 'wxt/browser' }],
|
||||
presets: [
|
||||
{ package: 'wxt/client' },
|
||||
{ package: 'wxt/browser' },
|
||||
{ package: 'wxt/sandbox' },
|
||||
],
|
||||
warn: config.logger.warn,
|
||||
dirs: ['components', 'composables', 'hooks', 'utils'],
|
||||
};
|
||||
|
||||
@@ -9,18 +9,27 @@ import { resolvePerBrowserOption } from './entrypoints';
|
||||
*/
|
||||
export function hashContentScriptOptions(
|
||||
options: ContentScriptEntrypoint['options'],
|
||||
config: InternalConfig,
|
||||
): string {
|
||||
const withDefaults: ContentScriptEntrypoint['options'] = {
|
||||
excludeGlobs: [],
|
||||
excludeMatches: [],
|
||||
includeGlobs: [],
|
||||
matchAboutBlank: false,
|
||||
matchOriginAsFallback: false,
|
||||
runAt: 'document_idle',
|
||||
allFrames: false,
|
||||
const simplifiedOptions = mapWxtOptionsToContentScript(options, config);
|
||||
|
||||
// Remove undefined fields and use defaults to generate hash
|
||||
Object.keys(simplifiedOptions).forEach((key) => {
|
||||
// @ts-expect-error: key not typed as keyof ...
|
||||
if (simplifiedOptions[key] == null) delete simplifiedOptions[key];
|
||||
});
|
||||
|
||||
const withDefaults: Manifest.ContentScript = {
|
||||
exclude_globs: [],
|
||||
exclude_matches: [],
|
||||
include_globs: [],
|
||||
match_about_blank: false,
|
||||
run_at: 'document_idle',
|
||||
all_frames: false,
|
||||
// @ts-expect-error - not in type
|
||||
match_origin_as_fallback: false,
|
||||
world: 'ISOLATED',
|
||||
// TODO: strip undefined fields from options object to improve content script grouping.
|
||||
...options,
|
||||
...simplifiedOptions,
|
||||
};
|
||||
return JSON.stringify(
|
||||
Object.entries(withDefaults)
|
||||
|
||||
@@ -237,10 +237,13 @@ async function resolveInternalViteConfig(
|
||||
internalVite.plugins.push(plugins.devHtmlPrerender(finalConfig));
|
||||
internalVite.plugins.push(plugins.unimport(finalConfig));
|
||||
internalVite.plugins.push(
|
||||
plugins.virtualEntrypoin('background', finalConfig),
|
||||
plugins.virtualEntrypoint('background', finalConfig),
|
||||
);
|
||||
internalVite.plugins.push(
|
||||
plugins.virtualEntrypoin('content-script', finalConfig),
|
||||
plugins.virtualEntrypoint('content-script', finalConfig),
|
||||
);
|
||||
internalVite.plugins.push(
|
||||
plugins.virtualEntrypoint('unlisted-script', finalConfig),
|
||||
);
|
||||
internalVite.plugins.push(plugins.devServerGlobals(finalConfig));
|
||||
internalVite.plugins.push(plugins.tsconfigPaths(finalConfig));
|
||||
|
||||
@@ -49,7 +49,6 @@ export async function importEntrypointFile<T>(
|
||||
cache: false,
|
||||
debug: config.debug,
|
||||
esmResolve: true,
|
||||
interopDefault: true,
|
||||
alias: {
|
||||
'webextension-polyfill': resolve(
|
||||
config.root,
|
||||
@@ -69,7 +68,8 @@ export async function importEntrypointFile<T>(
|
||||
});
|
||||
|
||||
try {
|
||||
return await jiti(path);
|
||||
const res = await jiti(path);
|
||||
return res.default;
|
||||
} catch (err) {
|
||||
config.logger.error(err);
|
||||
throw err;
|
||||
|
||||
@@ -60,16 +60,19 @@ export async function generateMainfest(
|
||||
): Promise<Manifest.WebExtensionManifest> {
|
||||
const pkg = await getPackageJson(config);
|
||||
|
||||
const versionName = config.manifest.version_name ?? pkg?.version;
|
||||
const version = config.manifest.version ?? simplifyVersion(pkg?.version);
|
||||
|
||||
const baseManifest: Manifest.WebExtensionManifest = {
|
||||
manifest_version: config.manifestVersion,
|
||||
name: pkg?.name,
|
||||
description: pkg?.description,
|
||||
version: pkg?.version && simplifyVersion(pkg.version),
|
||||
// Only add the version name to chromium and if the user hasn't specified a custom version.
|
||||
version,
|
||||
version_name:
|
||||
config.browser !== 'firefox' && !config.manifest.version
|
||||
? pkg?.version
|
||||
: undefined,
|
||||
// Firefox doesn't support version_name
|
||||
config.browser === 'firefox' || versionName === version
|
||||
? undefined
|
||||
: versionName,
|
||||
short_name: pkg?.shortName,
|
||||
icons: discoverIcons(buildOutput),
|
||||
};
|
||||
@@ -311,7 +314,7 @@ function addEntrypoints(
|
||||
);
|
||||
} else {
|
||||
const hashToEntrypointsMap = contentScripts.reduce((map, script) => {
|
||||
const hash = hashContentScriptOptions(script.options);
|
||||
const hash = hashContentScriptOptions(script.options, config);
|
||||
if (map.has(hash)) map.get(hash)?.push(script);
|
||||
else map.set(hash, [script]);
|
||||
return map;
|
||||
|
||||
@@ -23,6 +23,7 @@ export function removeProjectImportStatements(text: string): string {
|
||||
const noImports = removeImportStatements(text);
|
||||
|
||||
return `import { defineContentScript, defineBackground } from 'wxt/client';
|
||||
import { defineUnlistedScript } from 'wxt/sandbox';
|
||||
|
||||
${noImports}`;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { normalizePath } from '../utils/paths';
|
||||
/**
|
||||
* Wraps a user's entrypoint with a vitual version with additional logic.
|
||||
*/
|
||||
export function virtualEntrypoin(
|
||||
export function virtualEntrypoint(
|
||||
type: Entrypoint['type'],
|
||||
config: InternalConfig,
|
||||
): Plugin {
|
||||
|
||||
Reference in New Issue
Block a user