Compare commits
257 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 279be8deb7 | |||
| 7366d8aab7 | |||
| a7ab409d48 | |||
| 9dea0cf3ae | |||
| 50d7c1ec80 | |||
| f32cdafdf6 | |||
| 2e2272d07a | |||
| 27ffff7e0a | |||
| 305cebe0d0 | |||
| 4602a068f8 | |||
| 3a947d72c6 | |||
| 1940e3530f | |||
| dd549dc686 | |||
| 3417bd3ed2 | |||
| 9470d2b696 | |||
| f523a7d31d | |||
| ea4c2b035b | |||
| c5bfba837f | |||
| c5ad957b25 | |||
| cc849e7cea | |||
| 22428da54d | |||
| f6071f7e2d | |||
| 08e8560865 | |||
| 75f01db543 | |||
| 5a028d2551 | |||
| 07a4ba8bc5 | |||
| f84921f735 | |||
| 872494e490 | |||
| d0848b0be5 | |||
| c848956777 | |||
| 296997d10e | |||
| ffdb22238c | |||
| a63c320403 | |||
| aa86ed78a3 | |||
| 19456ec855 | |||
| 2c57840c44 | |||
| 26b7927f62 | |||
| d4267af725 | |||
| 16a2aedcd0 | |||
| 755f04f777 | |||
| cf9539ddab | |||
| 99d558f33c | |||
| 1fe073004b | |||
| 6ae5fb5edb | |||
| 3a3953edf6 | |||
| c8e788eaf8 | |||
| 088a44496d | |||
| 60a57c5abc | |||
| 482466bbbf | |||
| 65deb7317b | |||
| 00ae061822 | |||
| 9bd7fc1bd5 | |||
| 98ddb83f1d | |||
| 6dd8b9d072 | |||
| 1e3482a878 | |||
| 734846843f | |||
| f1eac66494 | |||
| b4c3280f58 | |||
| b2f2998767 | |||
| 720eb93c67 | |||
| cdf8611e0b | |||
| 905d797b65 | |||
| 6ca8ccc332 | |||
| 76496e8865 | |||
| f38fec8588 | |||
| 4351ac9657 | |||
| f3834ac0e2 | |||
| 48891a7ca5 | |||
| 3b6a4aa635 | |||
| b20f0471c2 | |||
| 0f9e66e1e8 | |||
| 6fb4cee43f | |||
| 0e8afbbf56 | |||
| 83decf7bf5 | |||
| 5c77cf23b8 | |||
| 606fd3164c | |||
| 71308d0d6f | |||
| 8bbea7cda4 | |||
| a87d3e4809 | |||
| 1f3db58254 | |||
| 43f6c06271 | |||
| 04ae542b13 | |||
| f97c81df0d | |||
| b7b3fc53eb | |||
| 4b44fb849d | |||
| 5d0a266e9c | |||
| 24667861db | |||
| 25cc403886 | |||
| 923312c482 | |||
| adeef6eb73 | |||
| 6f84d45960 | |||
| 938c25cab4 | |||
| 0404637da8 | |||
| 98d95e4b7f | |||
| 2687a35781 | |||
| 886dae28fa | |||
| 8c9bc8cdbc | |||
| 5414a0aa34 | |||
| 223cf8613b | |||
| 4f1776befc | |||
| 38473b9f6c | |||
| 41b428c75f | |||
| d8d754658f | |||
| e52ebf1d53 | |||
| 535c7a5f92 | |||
| 99b2bd784a | |||
| 31ebf966fd | |||
| 6036c6e8e0 | |||
| 597151b5dd | |||
| 29aeaed223 | |||
| edf87952c7 | |||
| 78f8434a06 | |||
| 7eaccad683 | |||
| bfa9c1e1c8 | |||
| a2d6577579 | |||
| 0e8191488f | |||
| a1510bb081 | |||
| 1eaca30f97 | |||
| bc79987ed5 | |||
| 36a501506e | |||
| e1d47f5f63 | |||
| 7faa9b5a64 | |||
| 295bee708c | |||
| 9e917481c4 | |||
| c5a8b9fb3d | |||
| 3f4e32f8da | |||
| f630098f1d | |||
| 608d6e2b54 | |||
| fad5ab6c44 | |||
| d4cb7997fe | |||
| 28364b8be1 | |||
| d28a5c7d5e | |||
| df707aef4c | |||
| 77af2e58ec | |||
| f738e56337 | |||
| f2fe2584e0 | |||
| 02673ae017 | |||
| 8dd294a163 | |||
| 469e735d53 | |||
| b02001796e | |||
| 0d4d2fdd7e | |||
| b65e5446fa | |||
| f75fe3ce5b | |||
| 59ba2712cf | |||
| fefe601541 | |||
| 7291c60413 | |||
| bb679102b1 | |||
| 16027c8971 | |||
| 84405a33e3 | |||
| bdf795c3f2 | |||
| ab73084bb5 | |||
| e9fb4c5414 | |||
| bc54f525e4 | |||
| 9170159bc1 | |||
| fa657a0366 | |||
| 24920ddd52 | |||
| eb0b372113 | |||
| 8f5f4f674e | |||
| 38c1dae9c7 | |||
| f92bcd1d14 | |||
| df09b86d23 | |||
| bd5cfa10ad | |||
| 94914dd1ad | |||
| dfbb58a2f1 | |||
| 54a1c3576f | |||
| 9ddf73b4fe | |||
| 4ceec1a6ab | |||
| ba314d7434 | |||
| 55fed67067 | |||
| 852390092e | |||
| 067be3fed3 | |||
| 1aecdbb71c | |||
| d8e517cb7b | |||
| 9da5b4cacc | |||
| 84af32242b | |||
| 7a81472407 | |||
| 9399d8df42 | |||
| 459f73fd5c | |||
| c1c3d3b7c5 | |||
| 380a9630e5 | |||
| 984568e00c | |||
| 5fefd8e083 | |||
| a6eef643f6 | |||
| a01928e010 | |||
| d901db2316 | |||
| fdda812078 | |||
| 7c59e9d5b5 | |||
| c9b0c4da34 | |||
| 9f214141b4 | |||
| 4638e90f02 | |||
| d1c50ab6f8 | |||
| 489aa0ffd8 | |||
| ebcc605961 | |||
| bb630049d5 | |||
| 39321adfe1 | |||
| ea2b8df906 | |||
| 74a9b1aef4 | |||
| 8b3e35de94 | |||
| 9d4724fa99 | |||
| a8379cbd80 | |||
| bdfb6c5a84 | |||
| 87414d7137 | |||
| f9d0b64d7a | |||
| 97918710bd | |||
| ac340b3f1e | |||
| a2097e148b | |||
| 190be7f732 | |||
| 0333ce5c46 | |||
| 47df623fd4 | |||
| c609efbd9a | |||
| c8cd41a833 | |||
| 02a0110091 | |||
| 6c572c56a3 | |||
| 2db516ef3b | |||
| 9f3787cd95 | |||
| 5511943237 | |||
| 626838eba6 | |||
| 587328f54c | |||
| 1aa88b1fb6 | |||
| e7db119545 | |||
| da79536456 | |||
| aaaff43731 | |||
| 5d77142758 | |||
| 586ea0002b | |||
| e642d6fe76 | |||
| 7148f288d5 | |||
| 40abf3fb5b | |||
| adea6c7177 | |||
| 96a307e99f | |||
| f0201f72ef | |||
| 0b1b677b3d | |||
| b1dcec86cd | |||
| 7c783fe565 | |||
| 9a0207d7cf | |||
| 1b0e047d6b | |||
| 7ab3c7e5d9 | |||
| 9ece49d226 | |||
| 1272e2ec74 | |||
| db16602018 | |||
| 5c202805b9 | |||
| bfc8866b69 | |||
| 9aedc29289 | |||
| e1f3d75ac4 | |||
| 030f23d2e9 | |||
| 6be9a4e71b | |||
| eb0bffb5dd | |||
| 240bbb3676 | |||
| 7d25110a6e | |||
| 598eea703b | |||
| 8793f7bff4 | |||
| c1b3911622 | |||
| b0bf05109d | |||
| d9cb0ebcc8 | |||
| 1eda21f63f | |||
| f2dbcde124 | |||
| 60f00db2c5 | |||
| a9332453fc |
@@ -4,12 +4,10 @@ description: Install PNPM, Node, and dependencies
|
||||
inputs:
|
||||
install:
|
||||
default: 'true'
|
||||
type: boolean
|
||||
description: Whether or not to run 'pnpm install'
|
||||
|
||||
installArgs:
|
||||
default: ''
|
||||
type: string
|
||||
description: Additional args to append to "pnpm install"
|
||||
|
||||
runs:
|
||||
@@ -17,12 +15,12 @@ runs:
|
||||
|
||||
steps:
|
||||
- name: 🛠️ Setup PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@f2b2b233b538f500472c7274c7012f57857d8ce0 # v4.1.0
|
||||
|
||||
- name: 🛠️ Setup NodeJS
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||
with:
|
||||
node-version: 18
|
||||
node-version: 20
|
||||
cache: pnpm
|
||||
|
||||
- name: 📦 Install Dependencies
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
name: 🔔 Notify Unreleased Commits
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 20 * * 1' # Weekly at 8 PM UTC (3 PM CT)
|
||||
|
||||
jobs:
|
||||
notify:
|
||||
runs-on: ubuntu-22.04
|
||||
if: github.repository_owner == 'wxt-dev'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: List Commits
|
||||
id: list-commits
|
||||
run: |
|
||||
./scripts/list-unreleased-commits.sh > summary.txt
|
||||
|
||||
- name: Discord notification
|
||||
run: |
|
||||
PAYLOAD=$(jq -n --arg content "${{ env.MESSAGE }}" '{"content": $content}')
|
||||
curl -X POST \
|
||||
-F "payload_json=${PAYLOAD}" \
|
||||
-F "file1=@summary.txt" \
|
||||
$DISCORD_WEBHOOK
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_UNRELEASED_COMMITS }}
|
||||
MESSAGE: |
|
||||
If a package needs released, please [run the workflow](<https://github.com/wxt-dev/wxt/actions/workflows/release.yml>).
|
||||
|
||||
Before running, consider:
|
||||
- Are there any breaking changes? If so, prepare a list of breaking changes and update the changelog and release notes after the release.
|
||||
- Are there any PRs open that we wait to release after they're merged?
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
if: ${{ github.repository == 'wxt-dev/wxt' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Post Thank You Comment
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
env:
|
||||
comment: Thanks for helping make WXT better!
|
||||
with:
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# Only fetch the config file from the repository
|
||||
sparse-checkout-cone-mode: false
|
||||
|
||||
@@ -23,13 +23,13 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
|
||||
with:
|
||||
registry: https://${{ secrets.DOCKER_REGISTRY_HOSTNAME }}
|
||||
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
|
||||
|
||||
@@ -31,16 +31,18 @@ jobs:
|
||||
|
||||
publish:
|
||||
name: Publish
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: write
|
||||
contents: write # Push version changes
|
||||
id-token: write # OIDC for NPM publishing
|
||||
needs:
|
||||
- validate
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ssh-key: ${{ secrets.DEPLOY_KEY }} # https://github.com/sbellone/release-workflow-example
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -60,9 +62,9 @@ jobs:
|
||||
- name: Publish to NPM
|
||||
working-directory: packages/${{ inputs.package }}
|
||||
run: |
|
||||
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > ~/.npmrc
|
||||
pnpm build
|
||||
pnpm publish
|
||||
pnpm pack
|
||||
sudo npm i -g npm@latest
|
||||
/usr/local/bin/npm publish *.tgz
|
||||
|
||||
- name: Create GitHub release
|
||||
run: pnpm tsx scripts/create-github-release.ts ${{ inputs.package }}
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
@@ -11,11 +11,15 @@ jobs:
|
||||
sync:
|
||||
name: 'Sync with @types/chrome'
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'wxt-dev'
|
||||
permissions:
|
||||
contents: write
|
||||
contents: write # Push version changes
|
||||
id-token: write # OIDC for NPM publishing
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -32,15 +36,16 @@ jobs:
|
||||
|
||||
- name: Commit Changes
|
||||
id: commit
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
commit_message: 'fix: Upgrade `@wxt-dev/browser` to latest `@types/chrome` version'
|
||||
|
||||
- name: Publish Package
|
||||
- name: Publish to NPM
|
||||
if: steps.commit.outputs.changes_detected == 'true'
|
||||
working-directory: packages/browser
|
||||
run: |
|
||||
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > ~/.npmrc
|
||||
pnpm publish
|
||||
pnpm pack
|
||||
sudo npm i -g npm@latest
|
||||
/usr/local/bin/npm publish *.tgz
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -55,39 +55,41 @@ jobs:
|
||||
working-directory: packages/wxt-demo
|
||||
|
||||
tests:
|
||||
name: Tests
|
||||
runs-on: ubuntu-22.04
|
||||
name: Tests (${{ matrix.title }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- title: 'Linux'
|
||||
os: ubuntu-22.04
|
||||
coverage: true
|
||||
- title: 'Windows'
|
||||
os: windows-latest
|
||||
coverage: false
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@3d267786b128fe76c2f16a390aa2448b815359f3 # v2.1.2
|
||||
|
||||
- name: Run Tests
|
||||
run: pnpm test:coverage -- --reporter=default --reporter=hanging-process
|
||||
if: ${{ ! matrix.coverage }}
|
||||
run: pnpm test
|
||||
|
||||
- name: Run Tests (Coverage)
|
||||
if: matrix.coverage
|
||||
run: pnpm test:coverage --reporter=default --reporter=hanging-process
|
||||
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v5
|
||||
if: matrix.coverage
|
||||
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
windows-tests:
|
||||
name: Windows Tests
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
- name: Run Tests
|
||||
run: pnpm test
|
||||
|
||||
template:
|
||||
name: Template
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -102,7 +104,7 @@ jobs:
|
||||
- vue
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup
|
||||
@@ -31,12 +31,12 @@ jobs:
|
||||
pnpm dlx wxt@latest --version
|
||||
|
||||
- name: Record VHS
|
||||
uses: charmbracelet/vhs-action@v2.1.0
|
||||
uses: charmbracelet/vhs-action@59641cdc7fadf3978db65eb8c6937ea2752f4ec3 # v2.1.0
|
||||
with:
|
||||
path: 'docs/tapes/init-demo.tape'
|
||||
|
||||
- name: Save recorded GIF
|
||||
uses: stefanzweifel/git-auto-commit-action@v5
|
||||
uses: stefanzweifel/git-auto-commit-action@04702edda442b2e678b25b537cec683a1493fcb9 # v7.1.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/DavidAnson/markdownlint/refs/heads/main/schema/markdownlint-config-schema.json",
|
||||
"line-length": false,
|
||||
"no-inline-html": false,
|
||||
"first-line-heading": false
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
node_modules
|
||||
.git
|
||||
.output
|
||||
dist
|
||||
|
||||
# Generated files
|
||||
packages/wxt/README.md
|
||||
packages/*/CHANGELOG.md
|
||||
docs/api
|
||||
Vendored
+2
-1
@@ -10,5 +10,6 @@
|
||||
// Additional guidelines for Copilot
|
||||
"github.copilot.chat.codeGeneration.instructions": [
|
||||
{ "file": "CONTRIBUTING.md" }
|
||||
]
|
||||
],
|
||||
"oxc.enable": true
|
||||
}
|
||||
|
||||
+4
-4
@@ -60,7 +60,7 @@ representative at an online or offline event.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
aaronklinker1@gmail.com.
|
||||
<aaronklinker1@gmail.com>.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
@@ -116,7 +116,7 @@ the community.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
<https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
@@ -124,5 +124,5 @@ enforcement ladder](https://github.com/mozilla/diversity).
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
<https://www.contributor-covenant.org/faq>. Translations are available at
|
||||
<https://www.contributor-covenant.org/translations>.
|
||||
|
||||
+42
-6
@@ -6,6 +6,19 @@ If you are changing the docs or fixing a bug, feel free to fork and open a PR.
|
||||
|
||||
If you want to add a new feature, please create an issue or discussion first so we can decide if the feature is inline with the vision for WXT.
|
||||
|
||||
## WXT's Vision
|
||||
|
||||
WXT is two things:
|
||||
|
||||
1. A build tool
|
||||
2. A set of runtime utilities
|
||||
|
||||
The long term goal of WXT is provide an opinionated build tool that keeps WXT projects standard, while providing light-weight runtime utils that simplify a lot of the boilerplate/overhead when setting up a new extension.
|
||||
|
||||
I also want to provide a way for developers to use either one of those two things independently, and not require them to use both. This is why all of WXT's runtime utils are shipped as their own NPM packages, most of them not bundled inside the core `wxt` package. If you just want to use the packages, they're availalbe, and if you just want to use WXT's built tool, you don't have to import any of WXT's utilities, you can use your own.
|
||||
|
||||
> The few runtime utils shipped inside WXT are things that should be used by 90% of extensions. That said, they're also legacy utils left in from before I started creating separate NPM packages, and in the future, they may be removed from the core package.
|
||||
|
||||
## Conventional Commits
|
||||
|
||||
This project uses [Conventional Commit format](https://www.conventionalcommits.org/en/v1.0.0/) to automatically generate a changelog and better understand the changes in the project
|
||||
@@ -20,6 +33,19 @@ Here are some examples of conventional commit messages:
|
||||
|
||||
The title of your pull request should follow the [conventional commit format](#conventional-commits). When a pull request is merged to the main branch, all changes are going to be squashed into a single commit. The message of this commit will be the title of the pull request. And for every release, the commit messages are used to generate the changelog.
|
||||
|
||||
## Breaking Changes Policy
|
||||
|
||||
A quick word on WXT's breaking changes policy. I am willing to make breaking changes, but they have to be for a good enough reason - they have to make WXT better as a whole, they can't be based on one opinion.
|
||||
|
||||
Breaking changes also require a major release. Major releases have happened once or twice a year, so after you merge your PR, you'll have to wait a little bit before it is released.
|
||||
|
||||
To make a breaking change:
|
||||
|
||||
1. Make sure you're PR is targeting the `major` branch
|
||||
2. Add `!` after the conventional commit type (`fix!: ...`, `feat!: ...`, `chore!: ...`, etc) to indicate that it is a breaking change
|
||||
3. At the top of the PR, provide documentation that will inform developers about the breaking change, why it was done, and how to migrate their extension so nothing breaks.
|
||||
- This documentation will be put ["Upgrading WXT"](https://wxt.dev/guide/resources/upgrading.html) page in the docs, read through previous breaking change docs for an idea of what is required.
|
||||
|
||||
## Setup
|
||||
|
||||
WXT uses `pnpm`, so make sure you have it installed.
|
||||
@@ -146,17 +172,21 @@ Releases are done with GitHub actions:
|
||||
|
||||
## Upgrading Dependencies
|
||||
|
||||
Use [`taze`](https://www.npmjs.com/package/taze) to upgrade dependencies throughout the entire monorepo.
|
||||
WXT has custom rules around what dependencies can be upgraded. Use the `scripts/upgrade-deps.ts` script to upgrade dependencies and follow these rules.
|
||||
|
||||
```sh
|
||||
pnpm dlx taze -r
|
||||
pnpm tsx scripts/upgrade-deps.ts
|
||||
```
|
||||
|
||||
Configuration is in [`taze.config.ts`](./taze.config.ts).
|
||||
To see all the options, run:
|
||||
|
||||
```sh
|
||||
pnpm tsx scripts/upgrade-deps.ts --help
|
||||
```
|
||||
|
||||
## Install Unreleased Versions
|
||||
|
||||
This repo uses https://pkg.pr.new to publish versions of all it's packages for almost every commit. You can install them via:
|
||||
This repo uses <https://pkg.pr.new> to publish versions of all it's packages for almost every commit. You can install them via:
|
||||
|
||||
```sh
|
||||
npm i https://pkg.pr.new/[package-name]@[ref]
|
||||
@@ -177,10 +207,16 @@ npm i https://pkg.pr.new/@wxt-dev/module-react@426f907
|
||||
|
||||
## Blog Posts
|
||||
|
||||
Anyone is welcome to submit a blog post on https://wxt.dev/blog!
|
||||
Anyone is welcome to submit a blog post on <https://wxt.dev/blog>!
|
||||
|
||||
> [!NOTE]
|
||||
> Before starting on a blog post, please message Aaron on Discord or start a discussion on GitHub to get permission to write about a topic, but most topics are welcome: Major version updates, tutorials, etc.
|
||||
|
||||
- **English only**: Blog posts should be written in English. Unfortunately, our maintainers doesn't have the bandwidth right now to translate our docs, let alone blog posts. Sorry 😓
|
||||
- **English only**: Blog posts should be written in English. Unfortunately, our maintainers don't have the bandwidth right now to translate our docs, let alone blog posts. Sorry 😓
|
||||
- **AI**: Please only use AI to translate or proof-read your blog post. Don't generate the whole thing... We don't want to publish that.
|
||||
|
||||
## Become a Maintainer
|
||||
|
||||
If you're interested in becoming a maintainer, send an email to Aaron at <aaronklinker1@gmail.com> with your github username saying you're interested. The process is very informal, I will add you quickly if you've contributed code or answered questions and helped out the community!
|
||||
|
||||
Maintainers don't have to just write code - they can manage issues, answer questsions, review PRs, organize and prioritize work - there's lots of ways for you to help out.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# Maintainers
|
||||
|
||||
A couple of things for you to consider before merging a PR or giving the go-ahead on a feature proposal.
|
||||
|
||||
## Be picky about new features and packages
|
||||
|
||||
We are responsible for maintaining them and fixing related bugs after the PR is merged. The community can always release their own WXT modules or packages, not everything needs to be built into WXT.
|
||||
|
||||
## Prefer standards over customization
|
||||
|
||||
Don't merge PRs that just add another way to do something, like [this one](https://github.com/wxt-dev/wxt/pull/2053#issuecomment-3857010196).
|
||||
|
||||
WXT is opinionated, if you have questions about what is WXT's opinion or we need to create a new one, create an issue and @ me to discuss.
|
||||
|
||||
## PRs should be small and targeted
|
||||
|
||||
A PR should make one change. They should not make any unrelated changes outside of accomplishing the one thing. This makes PRs easier to review and they get merged more quickly - a win-win for everyone.
|
||||
|
||||
## `@wxt-dev/*` packages are separate
|
||||
|
||||
We can't make changes to these packages assuming people are using them only with WXT. For example, I almost missed [this PR](https://github.com/wxt-dev/wxt/pull/2049#issuecomment-3861251599).
|
||||
|
||||
I want these packages to be usable on their own so if people don't like WXT's build tool, they can still use our other awesome packages.
|
||||
|
||||
## Minimize dependencies
|
||||
|
||||
I don't like how heavy lots of frameworks are. It's unavoidable to a certain extent, but if you can do something without another dependency, try to.
|
||||
|
||||
If you need a dependency, look for one with zero dependencies and that's respectable.
|
||||
|
||||
## Look at milestones
|
||||
|
||||
I've organized WXT's long term plans into [milestones](https://github.com/wxt-dev/wxt/milestones), check those out to get an idea of my priorities for some of the larger features.
|
||||
|
||||
## Require tests
|
||||
|
||||
If someone opens a PR to fix a bug but doesn't include tests, don't merge the PR. Tests are required to prevent regressions and maintain a codebase long term.
|
||||
|
||||
## Ask for reproductions for bugs
|
||||
|
||||
You don't need to triage bugs if someone doesn't give you enough information. You can always ask for a repo with a reproduction or wait for more details.
|
||||
|
||||
If there's not an easy way to reproduce a bug, you're wasting your time triaging it. Just be mindful of your own time!
|
||||
|
||||
Here's an example of how to ask for a reproduction: <https://github.com/wxt-dev/wxt/issues/2064#issuecomment-3862579110>. You could be more blunt than this.
|
||||
|
||||
## Add yourself as a code owner
|
||||
|
||||
If you want to be responsible for a specific package or directory, add yourself to the [`.github/CODEOWNERS`](https://github.com/wxt-dev/wxt/blob/main/.github/CODEOWNERS) file to get added as a reviewer to PRs automatically. You can also add yourself to the default list to be added as a reviewer on all PRs.
|
||||
@@ -1,50 +1,32 @@
|
||||
<h1 align="center">
|
||||
<img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo">
|
||||
<span>WXT</span>
|
||||
</h1>
|
||||
<div align="center">
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="npm version" src="https://img.shields.io/npm/v/wxt?labelColor=black&color=%234fa048"></a>
|
||||
<span> </span>
|
||||
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="downloads" src="https://img.shields.io/npm/dm/wxt?labelColor=black&color=%234fa048"></a>
|
||||
<span> </span>
|
||||
<a href="https://github.com/wxt-dev/wxt/blob/main/LICENSE" target="_blank"><img alt="license | MIT" src="https://img.shields.io/npm/l/wxt?labelColor=black&color=%234fa048"></a>
|
||||
<span> </span>
|
||||
<a href="https://codecov.io/github/wxt-dev/wxt" target="_blank"><img alt="coverage" src="https://img.shields.io/codecov/c/github/wxt-dev/wxt?labelColor=black&color=%234fa048"></a>
|
||||
</p>
|
||||
# <img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo"> WXT
|
||||
|
||||
<p align="center">
|
||||
<span>Next-gen framework for developing web extensions.</span>
|
||||
<br/>
|
||||
<span>⚡</span>
|
||||
<br/>
|
||||
<q><i>It's like Nuxt, but for Web Extensions</i></q>
|
||||
</p>
|
||||
[](https://www.npmjs.com/package/wxt)
|
||||
[](https://www.npmjs.com/package/wxt)
|
||||
[](https://github.com/wxt-dev/wxt/blob/main/LICENSE)
|
||||
[](https://codecov.io/github/wxt-dev/wxt)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://wxt.dev/guide/installation.html" target="_blank">Get Started</a>
|
||||
•
|
||||
<a href="https://wxt.dev/api/config.html" target="_blank">Configuration</a>
|
||||
•
|
||||
<a href="https://wxt.dev/examples.html" target="_blank">Examples</a>
|
||||
•
|
||||
<a href="https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md" target="_blank">Changelog</a>
|
||||
•
|
||||
<a href="https://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
|
||||
</p>
|
||||
Next-gen framework for developing web extensions.<br/>⚡<br/><q><i>It's like Nuxt, but for Web Extensions</i></q>
|
||||
|
||||
[Get Started](https://wxt.dev/guide/installation.html) •
|
||||
[Configuration](https://wxt.dev/api/config.html) •
|
||||
[Examples](https://wxt.dev/examples.html) •
|
||||
[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md) •
|
||||
[Discord](https://discord.gg/ZFsZqGery9)
|
||||
|
||||
</div>
|
||||
|
||||

|
||||
|
||||
## Demo
|
||||
|
||||
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
|
||||
<https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94>
|
||||
|
||||
## Quick Start
|
||||
|
||||
Bootstrap a new project:
|
||||
|
||||
<!-- automd:pm-x version="latest" name="wxt" args="init" -->
|
||||
|
||||
```sh
|
||||
# npm
|
||||
npx wxt@latest init
|
||||
@@ -56,8 +38,6 @@ pnpm dlx wxt@latest init
|
||||
bunx wxt@latest init
|
||||
```
|
||||
|
||||
<!-- /automd -->
|
||||
|
||||
Or see the [installation guide](https://wxt.dev/guide/installation.html) to get started with WXT.
|
||||
|
||||
## Features
|
||||
@@ -79,17 +59,11 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
|
||||
|
||||
WXT is a [MIT-licensed](https://github.com/wxt-dev/wxt/blob/main/LICENSE) open source project with its ongoing development made possible entirely by the support of these awesome backers. If you'd like to join them, please consider [sponsoring WXT's development](https://github.com/sponsors/wxt-dev).
|
||||
|
||||
<a href="https://github.com/sponsors/wxt-dev"><img alt="WXT Sponsors" src="https://raw.githubusercontent.com/wxt-dev/static/refs/heads/main/sponsorkit/sponsors.svg"></a>
|
||||
[](https://github.com/sponsors/wxt-dev)
|
||||
|
||||
## Contributors
|
||||
|
||||
<!-- automd:contributors author="aklinker1" license="MIT" github="wxt-dev/wxt" -->
|
||||
|
||||
Published under the [MIT](https://github.com/wxt-dev/wxt/blob/main/LICENSE) license.
|
||||
Made by [@aklinker1](https://github.com/aklinker1) and [community](https://github.com/wxt-dev/wxt/graphs/contributors) 💛
|
||||
<br><br>
|
||||
<a href="https://github.com/wxt-dev/wxt/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=wxt-dev/wxt" />
|
||||
</a>
|
||||
|
||||
<!-- /automd -->
|
||||
[](https://github.com/wxt-dev/wxt/graphs/contributors)
|
||||
|
||||
@@ -4,7 +4,7 @@ import useListExtensionDetails, {
|
||||
ChromeExtension,
|
||||
} from '../composables/useListExtensionDetails';
|
||||
|
||||
// Add extension IDs here. Order doesn't matter, will be sorted by a combination of weekly active users and rating.
|
||||
// Add extension IDs to end of the list. On the website, extensions will be sorted by a combination of weekly active users and rating.
|
||||
// Change the commit message or PR title to: "docs: Added "[extension name]" to the homepage"
|
||||
const chromeExtensionIds = [
|
||||
'ocfdgncpifmegplaglcnglhioflaimkd', // GitHub: Better Line Counts
|
||||
@@ -85,6 +85,38 @@ const chromeExtensionIds = [
|
||||
'edkhpdceeinkcacjdgebjehipmnbomce', // NZBDonkey - The ultimate NZB file download tool
|
||||
'cckggnbnimdbbpmdinkkgbbncopbloob', // WeChat Markdown Editor(微信 Markdown 编辑器)
|
||||
'jcblcjolcojmfopefcighfmkkefbaofg', // Tab Grab
|
||||
'eehmoikadcijkapfjocnhjclpbaindlb', // BrowserLens - https://browserlens.com/
|
||||
'hfhellofkjebbchcdffmicekjdomkcmc', // Epic Games Library Extension
|
||||
'gknigcbhlammoakmmdddkblknanpjiac', // Zen Analytics Pixel Tracker - zapt.web.app
|
||||
'cnklededohhcbmjjdlbjdkkihkgoggol', // Crypto Pulse - Compose your newtab with nature images, widgets & realtime Crypto Price & Bitcoin RSS.
|
||||
'miponnamafdenpgjemkknimgjfibicdc', // Youtube Video Scheduler
|
||||
'nhmbcmalgpkjbomhlhgdicanmkkaajmg', // Chatslator: Livestream Chat Translator
|
||||
'mbamjfdjbcdgpopfnkkmlohadbbnplhm', // 公众号阅读增强器 - https://wxreader.honwhy.wang
|
||||
'hannhecbnjnnbbafffmogdlnajpcomek', // 토탐정
|
||||
'ehboaofjncodknjkngdggmpdinhdoijp', // 2FAS Pass - https://2fas.com/
|
||||
'hnjamiaoicaepbkhdoknhhcedjdocpkd', // Quick Prompt - https://github.com/wenyuanw/quick-prompt
|
||||
'kacblhilkacgfnkjfodalohcnllcgmjd', // Add QR Code Generator Icon Back To Address Bar
|
||||
'fkbdlogfdjmpfepbbbjcgcfbgbcfcnne', // Piwik PRO Tracking Helper
|
||||
'nkbikckldmljjiiajklecmgmajgapbfl', // PIPX - Take Control of Picture-in-Picture, Automatically
|
||||
'hgppdobcpkfkmiegekaglonjajeojmdd', // Browsely - AI-powered browser extension
|
||||
'ehmoihnjgkdimihkhokkmfjdgomohjgm', // Filmbudd Pro - Simple, private – and synced ratings and watch notes across all your devices
|
||||
'alglchohmdikgdjhafiicilegegieafa', // MultiField CopyCat - Copy, Paste & Autofill Web Forms Instantly
|
||||
'aamihahiiogceidpbnfgehacgiecephe', // ChatSight - Add Table of Contents to ChatGPT
|
||||
'cndibmoanboadcifjkjbdpjgfedanolh', // BetterCampus (prev. BetterCanvas)
|
||||
'hinfimgacobnellbncbcpdlpaapcofaa', // Leetcode Fonts - Change fonts in leetcode effortlessly
|
||||
'kbkbfefhhabpkibojinapkkgciiacggg', // TranslateManga - Manga Translator & Manga Tracker
|
||||
'emeakbgdecgmdjgegnejpppcnkcnoaen', // SiteData - Free Website Traffic Checker & Reverse AdSense Tool
|
||||
'gpnckbhgpnjciklpoehkmligeaebigaa', // Livestream Chat Reader - Text-to-Speech for YouTube/Twitch chat
|
||||
'fjlalaedpfcojcfpkgkglbjjbbkofgnl', // ChatGPT Token Counter - Count tokens in real time on chatgpt conversation
|
||||
'fbgblmjbeebanackldpbmpacppflgmlj', // LinuxDo Scripts - 为 linux.do 用户提供了一些增强功能
|
||||
'dfacnjidgbagicaekenjgclfnhdnjjdi', // Zen Virtual Piano - https://zen-piano.web.app/
|
||||
'naeibcegmgpofimedkmfgjgphfhfhlab', // Crypto Pulse price tracker - https://get-crypto-pulse.web.app/
|
||||
'ffglckbhfbfmdkefdmjbhpnffkcmlhdh', // Redirect Web - Automatically redirect pages or open them in another app
|
||||
'eglpfhbhmelampoihamjomgkeobgdofl', // Capture It - Capture & Edit Screenshots
|
||||
'jmghclbfbbapimhbgnpffbimphlpolnm', // Teams Chat Exporter
|
||||
'jdcppdokgfbnhiacbeplahgnciahnhck', // Lofi BGM Player - Free lofi focus music for work & study
|
||||
'cgpmbiiagnehkikhcbnhiagfomajncpa', // Margin - Annotate and highlight any webpage, with your notes saved to the decentralized AT Protocol.
|
||||
'mfjdonmgmgcijagclnkfhmjiblbfjaid', // KeyFloat - Floating multilingual keyboard with native key mappings, drag, dark mode, sounds, and dynamic layouts for macOS & Windows
|
||||
];
|
||||
|
||||
const { data, err, isLoading } = useListExtensionDetails(chromeExtensionIds);
|
||||
|
||||
@@ -35,6 +35,9 @@ export default function (ids: string[]) {
|
||||
query,
|
||||
variables: { ids },
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then(async (res) => {
|
||||
isLoading.value = false;
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
import { Feed } from 'feed';
|
||||
import { writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import llmstxt from 'vitepress-plugin-llms';
|
||||
|
||||
const origin = 'https://wxt.dev';
|
||||
|
||||
@@ -71,6 +72,7 @@ export default defineConfig({
|
||||
vite: {
|
||||
clearScreen: false,
|
||||
plugins: [
|
||||
llmstxt(),
|
||||
groupIconVitePlugin({
|
||||
customIcon: {
|
||||
'wxt.config.ts': localIconLoader(
|
||||
|
||||
@@ -8,16 +8,6 @@ outline: deep
|
||||
|
||||
During development, WXT uses [`web-ext` by Mozilla](https://www.npmjs.com/package/web-ext) to automatically open a browser window with your extension installed.
|
||||
|
||||
:::danger
|
||||
Chrome 137 removed support for the `--load-extension` CLI flag, which WXT relied on to open the browser with an extension installed. So this feature will not work for Chrome.
|
||||
|
||||
You have two options:
|
||||
|
||||
1. Install [Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (which still supports the `--load-extension` flag) and [point the `chrome` binary to it](#set-browser-binaries), or
|
||||
2. [Disable this feature](#disable-opening-browser) and manually load your extension
|
||||
|
||||
:::
|
||||
|
||||
## Config Files
|
||||
|
||||
You can configure browser startup in 3 places:
|
||||
@@ -42,6 +32,8 @@ You can configure browser startup in 3 places:
|
||||
To set or customize the browser opened during development:
|
||||
|
||||
```ts [web-ext.config.ts]
|
||||
import { defineWebExtConfig } from 'wxt';
|
||||
|
||||
export default defineWebExtConfig({
|
||||
binaries: {
|
||||
chrome: '/path/to/chrome-beta', // Use Chrome Beta instead of regular Chrome
|
||||
@@ -51,6 +43,18 @@ export default defineWebExtConfig({
|
||||
});
|
||||
```
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
webExt: {
|
||||
binaries: {
|
||||
chrome: '/path/to/chrome-beta', // Use Chrome Beta instead of regular Chrome
|
||||
firefox: 'firefoxdeveloperedition', // Use Firefox Developer Edition instead of regular Firefox
|
||||
edge: '/path/to/edge', // Open MS Edge when running "wxt -b edge"
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
By default, WXT will try to automatically discover where Chrome/Firefox are installed. However, if you have chrome installed in a non-standard location, you need to set it manually as shown above.
|
||||
|
||||
### Persist Data
|
||||
@@ -59,11 +63,13 @@ By default, to keep from modifying your browser's existing profiles, `web-ext` c
|
||||
|
||||
Right now, Chromium based browsers are the only browsers that support overriding this behavior and persisting data when running the `dev` script multiple times.
|
||||
|
||||
To persist data, set the `--user-data-dir` flag:
|
||||
To persist data, set the `--user-data-dir` flag in any of the config files mentioned above:
|
||||
|
||||
:::code-group
|
||||
|
||||
```ts [Mac/Linux]
|
||||
import { defineWebExtConfig } from 'wxt';
|
||||
|
||||
export default defineWebExtConfig({
|
||||
chromiumArgs: ['--user-data-dir=./.wxt/chrome-data'],
|
||||
});
|
||||
@@ -71,6 +77,7 @@ export default defineWebExtConfig({
|
||||
|
||||
```ts [Windows]
|
||||
import { resolve } from 'node:path';
|
||||
import { defineWebExtConfig } from 'wxt';
|
||||
|
||||
export default defineWebExtConfig({
|
||||
// On Windows, the path must be absolute
|
||||
@@ -92,7 +99,30 @@ You can use any directory you'd like for `--user-data-dir`, the examples above c
|
||||
If you prefer to load the extension into your browser manually, you can disable the auto-open behavior:
|
||||
|
||||
```ts [web-ext.config.ts]
|
||||
import { defineWebExtConfig } from 'wxt';
|
||||
|
||||
export default defineWebExtConfig({
|
||||
disabled: true,
|
||||
});
|
||||
```
|
||||
|
||||
### Enabling Chrome Features
|
||||
|
||||
Some APIs are disabled in Chrome during development because of the default flags `web-ext` uses to launch Chrome, like the [Prompt API](https://developer.chrome.com/docs/ai/prompt-api).
|
||||
|
||||
If your extension depends on new features or services, you can enable them via `chromiumArgs`:
|
||||
|
||||
```ts
|
||||
import { defineWebExtConfig } from 'wxt';
|
||||
|
||||
export default defineWebExtConfig({
|
||||
chromiumArgs: [
|
||||
// For example, this flag enables the Prompt API
|
||||
'--disable-features=DisableLoadExtensionCommandLineSwitch',
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
There is no comprehensive list of what feature flags enable what APIs and services.
|
||||
|
||||
Alternatively, if you can't find a flag that enables a feature you're looking for, [disable the opening the browser during development](#disable-opening-browser) and use your regular chrome profile for development.
|
||||
|
||||
@@ -10,7 +10,7 @@ WXT does several pre-processing steps to try and prevent errors during this proc
|
||||
2. Use `@webext-core/fake-browser` to create a fake version of the `chrome` and `browser` globals expected by extensions.
|
||||
3. Pre-process the JS/TS code, stripping out the `main` function then tree-shaking unused code from the file
|
||||
|
||||
However, this process is not perfect. It doesn't setup all the globals found in the browser and the APIs may behave differently. As such, **_you should avoid using browser or extension APIs outside the `main` function of your entrypoints!_**
|
||||
However, this process is not perfect. It doesn't setup all the globals found in the browser and the APIs may behave differently. As such, **_you should avoid using browser or extension APIs outside the `main` function of your entrypoints!_** See [Entrypoint Limitations](/guide/essentials/extension-apis#entrypoint-limitations) for more details.
|
||||
|
||||
:::tip
|
||||
If you're running into errors while importing entrypoints, run `wxt prepare --debug` to see more details about this process. When debugging, WXT will print out the pre-processed code to help you identify issues.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
WXT supports [dotenv files the same way as Vite](https://vite.dev/guide/env-and-mode.html#env-files). Create any of the following files:
|
||||
|
||||
```
|
||||
```plaintext
|
||||
.env
|
||||
.env.local
|
||||
.env.[mode]
|
||||
@@ -65,7 +65,6 @@ To use environment variables in the manifest, you need to use the function synta
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
extensionApi: 'chrome',
|
||||
modules: ['@wxt-dev/module-vue'],
|
||||
manifest: { // [!code --]
|
||||
oauth2: { // [!code --]
|
||||
@@ -81,3 +80,16 @@ export default defineConfig({
|
||||
```
|
||||
|
||||
WXT can't load your `.env` files until after the config file has been loaded. So by using the function syntax for `manifest`, it defers creating the object until after the `.env` files are loaded into the process.
|
||||
|
||||
Note that Vite's runtime environment variables, like `import.meta.env.DEV`, will not be defined. Instead, access the `mode` like this:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
manifest: ({ mode }) => {
|
||||
const isDev = mode === 'development';
|
||||
console.log('Is development mode:', isDev);
|
||||
|
||||
// ...
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -11,7 +11,7 @@ export default defineConfig({
|
||||
hooks: {
|
||||
'build:manifestGenerated': (wxt, manifest) => {
|
||||
if (wxt.config.mode === 'development') {
|
||||
manifest.title += ' (DEV)';
|
||||
manifest.name += ' (DEV)';
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -20,6 +20,8 @@ export default defineConfig({
|
||||
|
||||
Most hooks provide the `wxt` object as the first argument. It contains the resolved config and other info about the current build. The other arguments can be modified by reference to change different parts of the build system.
|
||||
|
||||
You can find the [list of all available hooks](/api/reference/wxt/interfaces/WxtHooks) in the API reference.
|
||||
|
||||
Putting one-off hooks like this in your config file is simple, but if you find yourself writing lots of hooks, you should extract them into [WXT Modules](/guide/essentials/wxt-modules) instead.
|
||||
|
||||
## Execution Order
|
||||
@@ -32,7 +34,7 @@ Because hooks can be defined in multiple places, including [WXT Modules](/guide/
|
||||
|
||||
To see the order for your project, run `wxt prepare --debug` flag and search for the "Hook execution order":
|
||||
|
||||
```
|
||||
```plaintext
|
||||
⚙ Hook execution order:
|
||||
⚙ 1. wxt:built-in:unimport
|
||||
⚙ 2. src/modules/auto-icons.ts
|
||||
@@ -50,7 +52,9 @@ Changing execution order is simple:
|
||||
📄 0.my-module.ts
|
||||
📄 1.another-module.ts
|
||||
```
|
||||
|
||||
- If you need to run an NPM module after user modules, just make it a user module and prefix the filename with a number!
|
||||
|
||||
```ts
|
||||
// modules/2.i18n.ts
|
||||
export { default } from '@wxt-dev/i18n/module';
|
||||
|
||||
@@ -128,7 +128,7 @@ If a version is not present in your `package.json`, it defaults to `"0.0.0"`.
|
||||
|
||||
WXT automatically discovers your extension's icon by looking at files in the `public/` directory:
|
||||
|
||||
```
|
||||
```plaintext
|
||||
public/
|
||||
├─ icon-16.png
|
||||
├─ icon-24.png
|
||||
@@ -235,6 +235,7 @@ If you want to use the `activeTab` permission or the `browser.action.onClicked`
|
||||
|
||||
1. Delete the [Popup entrypoint](/guide/essentials/entrypoints#popup) if it exists
|
||||
2. Add the `action` key to your manifest:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
manifest: {
|
||||
|
||||
@@ -20,7 +20,7 @@ export default defineAppConfig({
|
||||
```
|
||||
|
||||
:::warning
|
||||
This file is committed to the repo, so don't put any secrets here. Instead, use [Environment Variables](#environment-variables)
|
||||
This file is committed to the repo, so don't put any secrets here. Instead, use [Environment Variables](/guide/essentials/config/environment-variables)
|
||||
:::
|
||||
|
||||
To access runtime config, WXT provides the `useAppConfig` function:
|
||||
|
||||
@@ -19,7 +19,7 @@ export default defineContentScript({
|
||||
|
||||
This object is responsible for tracking whether or not the content script's context is "invalidated". Most browsers, by default, do not stop content scripts if the extension is uninstalled, updated, or disabled. When this happens, content scripts start reporting this error:
|
||||
|
||||
```
|
||||
```plaintext
|
||||
Error: Extension context invalidated.
|
||||
```
|
||||
|
||||
@@ -76,6 +76,7 @@ To create a standalone content script that only includes a CSS file:
|
||||
|
||||
1. Create the CSS file: `entrypoints/example.content.css`
|
||||
2. Use the `build:manifestGenerated` hook to add the content script to the manifest:
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
hooks: {
|
||||
@@ -210,9 +211,7 @@ export default defineContentScript({
|
||||
anchor: 'body',
|
||||
onMount: (container) => {
|
||||
// Create the Svelte app inside the UI container
|
||||
mount(App, {
|
||||
target: container,
|
||||
});
|
||||
return mount(App, { target: container });
|
||||
},
|
||||
onRemove: (app) => {
|
||||
// Destroy the app when the UI is removed
|
||||
@@ -395,11 +394,9 @@ export default defineContentScript({
|
||||
anchor: 'body',
|
||||
onMount: (container) => {
|
||||
// Create the Svelte app inside the UI container
|
||||
mount(App, {
|
||||
target: container,
|
||||
});
|
||||
return mount(App, { target: container });
|
||||
},
|
||||
onRemove: () => {
|
||||
onRemove: (app) => {
|
||||
// Destroy the app when the UI is removed
|
||||
unmount(app);
|
||||
},
|
||||
@@ -459,6 +456,7 @@ If you don't need to run your UI in the same frame as the content script, you ca
|
||||
WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/utils/content-script-ui/iframe/functions/createIframeUi), which simplifies setting up the IFrame.
|
||||
|
||||
1. Create an HTML page that will be loaded into your IFrame:
|
||||
|
||||
```html
|
||||
<!-- entrypoints/example-iframe.html -->
|
||||
<!doctype html>
|
||||
@@ -473,7 +471,9 @@ WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/utils/cont
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
1. Add the page to the manifest's `web_accessible_resources`:
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
manifest: {
|
||||
@@ -486,6 +486,7 @@ WXT provides a helper function, [`createIframeUi`](/api/reference/wxt/utils/cont
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
1. Create and mount the IFrame:
|
||||
|
||||
```ts
|
||||
@@ -590,6 +591,76 @@ For MV3, `injectScript` is synchronous and the injected script will be evaluated
|
||||
However for MV2, `injectScript` has to `fetch` the script's text content and create an inline `<script>` block. This means for MV2, your script is injected asynchronously and it will not be evaluated at the same time as your content script's `run_at`.
|
||||
:::
|
||||
|
||||
The `script` element can be modified just before it is added to the DOM by using the `modifyScript` option. This can be used to e.g. modify `script.async`/`script.defer`, add event listeners to the element, or pass data to the script via `script.dataset`. An example:
|
||||
|
||||
```ts
|
||||
// entrypoints/example.content.ts
|
||||
export default defineContentScript({
|
||||
matches: ['*://*/*'],
|
||||
async main() {
|
||||
await injectScript('/example-main-world.js', {
|
||||
modifyScript(script) {
|
||||
script.dataset['greeting'] = 'Hello there';
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
// entrypoints/example-main-world.ts
|
||||
export default defineUnlistedScript(() => {
|
||||
console.log(document.currentScript?.dataset['greeting']);
|
||||
});
|
||||
```
|
||||
|
||||
`injectScript` returns the created script element. It can be used to e.g. send messages to the script in the form of custom events. The script can add an event listener for them via `document.currentScript`. An example of bidirectional communication:
|
||||
|
||||
```ts
|
||||
// entrypoints/example.content.ts
|
||||
export default defineContentScript({
|
||||
matches: ['*://*/*'],
|
||||
async main() {
|
||||
const { script } = await injectScript('/example-main-world.js', {
|
||||
modifyScript(script) {
|
||||
// Add a listener before the injected script is loaded.
|
||||
script.addEventListener('from-injected-script', (event) => {
|
||||
if (event instanceof CustomEvent) {
|
||||
console.log(`${event.type}:`, event.detail);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Send an event after the injected script is loaded.
|
||||
script.dispatchEvent(
|
||||
new CustomEvent('from-content-script', {
|
||||
detail: 'General Kenobi',
|
||||
}),
|
||||
);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
// entrypoints/example-main-world.ts
|
||||
export default defineUnlistedScript(() => {
|
||||
const script = document.currentScript;
|
||||
|
||||
script?.addEventListener('from-content-script', (event) => {
|
||||
if (event instanceof CustomEvent) {
|
||||
console.log(`${event.type}:`, event.detail);
|
||||
}
|
||||
});
|
||||
|
||||
script?.dispatchEvent(
|
||||
new CustomEvent('from-injected-script', {
|
||||
detail: 'Hello there',
|
||||
}),
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
## Mounting UI to dynamic element
|
||||
|
||||
In many cases, you may need to mount a UI to a DOM element that does not exist at the time the web page is initially loaded. To handle this, use the `autoMount` API to automatically mount the UI when the target element appears dynamically and unmount it when the element disappears. In WXT, the `anchor` option is used to target the element, enabling automatic mounting and unmounting based on its appearance and removal.
|
||||
|
||||
@@ -300,14 +300,14 @@ When defining content script entrypoints, keep in mind that WXT will import this
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```ts
|
||||
browser.runtime.onMessage.addListener((message) => { // [!code --]
|
||||
// ... // [!code --]
|
||||
}); // [!code --]
|
||||
const container = document.createElement('div'); // [!code --]
|
||||
document.body.append(container); // [!code --]
|
||||
|
||||
export default defineBackground(() => {
|
||||
browser.runtime.onMessage.addListener((message) => { // [!code ++]
|
||||
// ... // [!code ++]
|
||||
}); // [!code ++]
|
||||
export default defineContentScript({
|
||||
main: function () {
|
||||
const container = document.createElement('div'); // [!code ++]
|
||||
document.body.append(container); // [!code ++]
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -470,6 +470,19 @@ When you define a Newtab entrypoint, WXT will automatically update the manifest
|
||||
/>
|
||||
<meta name="manifest.type" content="page_action|browser_action" />
|
||||
<meta name="manifest.browser_style" content="true|false" />
|
||||
<!-- Firefox only: where to place the action button -->
|
||||
<meta
|
||||
name="manifest.default_area"
|
||||
content="navbar|menupanel|tabstrip|personaltoolbar"
|
||||
/>
|
||||
<!-- Firefox only: icons for light/dark themes -->
|
||||
<meta
|
||||
name="manifest.theme_icons"
|
||||
content="[
|
||||
{ light: '/icon-light-16.png', dark: '/icon-dark-16.png', size: 16 },
|
||||
{ light: '/icon-light-32.png', dark: '/icon-dark-32.png', size: 32 }
|
||||
]"
|
||||
/>
|
||||
|
||||
<!-- Set include/exclude if the page should be removed from some builds -->
|
||||
<meta name="manifest.include" content="['chrome', ...]" />
|
||||
@@ -580,7 +593,7 @@ body {
|
||||
}
|
||||
```
|
||||
|
||||
Follow Vite's guide to setup your preprocessor of choice: https://vitejs.dev/guide/features.html#css-pre-processors
|
||||
Follow Vite's guide to setup your preprocessor of choice: <https://vitejs.dev/guide/features.html#css-pre-processors>
|
||||
|
||||
CSS entrypoints are always unlisted. To add CSS to a content script, see the [Content Script](/guide/essentials/content-scripts#css) docs.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# ES Modules
|
||||
|
||||
You source code should always be written as ESM. However, you have some control whether an entrypoint is bundled as ESM.
|
||||
Your source code should always be written as ESM. However, you have some control whether an entrypoint is bundled as ESM.
|
||||
|
||||
## HTML Pages <Badge type="warning" text="≥0.0.1" />
|
||||
|
||||
|
||||
@@ -75,3 +75,63 @@ Alternatively, if you're trying to use similar APIs under different names (to su
|
||||
//
|
||||
});
|
||||
```
|
||||
|
||||
## Entrypoint Limitations
|
||||
|
||||
Because WXT imports your entrypoint files into a NodeJS, non-extension environment, the `chrome`/`browser` variables provided to extensions by the browser **will not be available**.
|
||||
|
||||
To prevent some basic errors, WXT polyfills these globals with the same in-memory, fake implementation it uses for testing: [`@webext-core/fake-browser`](https://webext-core.aklinker1.io/fake-browser/installation/). However, not all the APIs have been implemented.
|
||||
|
||||
So it is extremely important to NEVER use `browser.*` extension APIs outside the main function of any JS/TS entrypoints (background, content scripts, and unlisted scripts). If you do, you'll see an error like this:
|
||||
|
||||
```plaintext
|
||||
✖ Command failed after 440 ms
|
||||
|
||||
ERROR Browser.action.onClicked.addListener not implemented.
|
||||
```
|
||||
|
||||
The fix is simple, just move your API usage into the entrypoint's main function:
|
||||
|
||||
:::code-group
|
||||
|
||||
```ts [background.ts]
|
||||
browser.action.onClicked.addListener(() => {
|
||||
/* ... */
|
||||
}); // [!code --]
|
||||
|
||||
export default defineBackground(() => {
|
||||
browser.action.onClicked.addListener(() => {
|
||||
/* ... */
|
||||
}); // [!code ++]
|
||||
});
|
||||
```
|
||||
|
||||
```ts [content.ts]
|
||||
browser.runtime.onMessage.addListener(() => {
|
||||
/* ... */
|
||||
}); // [!code --]
|
||||
|
||||
export default defineContentScript({
|
||||
main() {
|
||||
browser.runtime.onMessage.addListener(() => {
|
||||
/* ... */
|
||||
}); // [!code ++]
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```ts [unlisted.ts]
|
||||
browser.runtime.onMessage.addListener(() => {
|
||||
/* ... */
|
||||
}); // [!code --]
|
||||
|
||||
export default defineUnlistedScript(() => {
|
||||
browser.runtime.onMessage.addListener(() => {
|
||||
/* ... */
|
||||
}); // [!code ++]
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Read [Entrypoint Loaders](/guide/essentials/config/entrypoint-loaders) for more technical details about this limitation.
|
||||
|
||||
@@ -9,6 +9,7 @@ This page discusses how to setup internationalization using the vanilla `browser
|
||||
## Usage
|
||||
|
||||
1. Add `default_locale` to your manifest:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
manifest: {
|
||||
@@ -16,11 +17,12 @@ This page discusses how to setup internationalization using the vanilla `browser
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
2. Create `messages.json` files in the `public/` directory:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
📂 {srcDir}/
|
||||
📂 {rootDir}/
|
||||
📂 public/
|
||||
📂 _locales/
|
||||
📂 en/
|
||||
@@ -41,9 +43,11 @@ This page discusses how to setup internationalization using the vanilla `browser
|
||||
```
|
||||
|
||||
3. Get the translation:
|
||||
|
||||
```ts
|
||||
browser.i18n.getMessage('helloWorld');
|
||||
```
|
||||
|
||||
4. _Optional_: Add translations for extension name and description:
|
||||
|
||||
```json
|
||||
|
||||
@@ -72,13 +72,13 @@ jobs:
|
||||
submit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 22
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
|
||||
@@ -62,6 +62,7 @@ Here are some examples:
|
||||
```
|
||||
|
||||
- HTML file only built for all targets other than `chrome`:
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
@@ -9,7 +9,7 @@ WXT provides first class support for Vitest for unit testing:
|
||||
```ts
|
||||
// vitest.config.ts
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import { WxtVitest } from 'wxt/testing';
|
||||
import { WxtVitest } from 'wxt/testing/vitest-plugin';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [WxtVitest()],
|
||||
@@ -36,7 +36,7 @@ This example demonstrates that you don't have to mock `browser.storage` (used by
|
||||
|
||||
```ts
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { fakeBrowser } from 'wxt/testing';
|
||||
import { fakeBrowser } from 'wxt/testing/fake-browser';
|
||||
|
||||
const accountStorage = storage.defineItem<Account>('local:account');
|
||||
|
||||
@@ -105,4 +105,4 @@ To use a different framework, you will likely have to disable auto-imports, setu
|
||||
|
||||
It is possible to do, but will require a bit more setup. Refer to Vitest's setup for an example of how to setup a test environment:
|
||||
|
||||
https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts
|
||||
<https://github.com/wxt-dev/wxt/blob/main/packages/wxt/src/testing/wxt-vitest-plugin.ts>
|
||||
|
||||
@@ -9,18 +9,23 @@ WXT provides a "module system" that let's you run code at different steps in the
|
||||
There are two ways to add a module to your project:
|
||||
|
||||
1. **NPM**: install an NPM package, like [`@wxt-dev/auto-icons`](https://www.npmjs.com/package/@wxt-dev/auto-icons) and add it to your config:
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
modules: ['@wxt-dev/auto-icons'],
|
||||
});
|
||||
```
|
||||
|
||||
> Searching for ["wxt module"](https://www.npmjs.com/search?q=wxt%20module) on NPM is a good way to find published WXT modules.
|
||||
|
||||
2. **Local**: add a file to your project's `modules/` directory:
|
||||
```
|
||||
|
||||
```plaintext
|
||||
<rootDir>/
|
||||
modules/
|
||||
my-module.ts
|
||||
```
|
||||
|
||||
> To learn more about writing your own modules, read the [Writing Modules](/guide/essentials/wxt-modules) docs.
|
||||
|
||||
## Module Options
|
||||
@@ -61,7 +66,7 @@ Each module's setup function is executed after the `wxt.config.ts` file is loade
|
||||
|
||||
Refer to the [API reference](/api/reference/wxt/interfaces/Wxt) for a complete list of properties and functions available.
|
||||
|
||||
Also to make sure and read about all the [hooks that are available](https://wxt.dev/api/reference/wxt/interfaces/WxtHooks) - they are essential to writing modules.
|
||||
Also make sure to read about [all the hooks that are available](/api/reference/wxt/interfaces/WxtHooks) - they are essential to writing modules.
|
||||
|
||||
### Recipes
|
||||
|
||||
|
||||
@@ -45,47 +45,63 @@ Once you've run the `dev` command, continue to [Next Steps](#next-steps)!
|
||||
|
||||
1. Create a new project
|
||||
:::code-group
|
||||
|
||||
```sh [PNPM]
|
||||
cd my-project
|
||||
pnpm init
|
||||
```
|
||||
|
||||
```sh [Bun]
|
||||
cd my-project
|
||||
bun init
|
||||
```
|
||||
|
||||
```sh [NPM]
|
||||
cd my-project
|
||||
npm init
|
||||
```
|
||||
|
||||
```sh [Yarn]
|
||||
cd my-project
|
||||
yarn init
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
2. Install WXT:
|
||||
:::code-group
|
||||
|
||||
```sh [PNPM]
|
||||
pnpm i -D wxt
|
||||
```
|
||||
|
||||
```sh [Bun]
|
||||
bun i -D wxt
|
||||
```
|
||||
|
||||
```sh [NPM]
|
||||
npm i -D wxt
|
||||
```
|
||||
|
||||
```sh [Yarn]
|
||||
yarn add --dev wxt
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
3. Add an entrypoint, `my-project/entrypoints/background.ts`:
|
||||
:::code-group
|
||||
|
||||
```ts
|
||||
export default defineBackground(() => {
|
||||
console.log('Hello world!');
|
||||
});
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
4. Add scripts to your `package.json`:
|
||||
|
||||
```json [package.json]
|
||||
{
|
||||
"scripts": {
|
||||
@@ -99,20 +115,26 @@ Once you've run the `dev` command, continue to [Next Steps](#next-steps)!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
5. Run your extension in dev mode
|
||||
:::code-group
|
||||
|
||||
```sh [PNPM]
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
```sh [Bun]
|
||||
bun run dev
|
||||
```
|
||||
|
||||
```sh [NPM]
|
||||
npm run dev
|
||||
```
|
||||
|
||||
```sh [Yarn]
|
||||
yarn dev
|
||||
```
|
||||
|
||||
:::
|
||||
WXT will automatically open a browser window with your extension installed.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Welcome to WXT!
|
||||
# Welcome to WXT
|
||||
|
||||
WXT is a modern, open-source framework for building web extensions. Inspired by Nuxt, its goals are to:
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ This page is dedicated to all the awesome people how have made something for WXT
|
||||
## Blog Posts
|
||||
|
||||
- [Building Modern Cross Browser Web Extensions](https://aabidk.dev/tags/wxt/) by Aabid ([@aabidk20](https://github.com/aabidk20))
|
||||
- [Building Browser Extensions with WXT](https://rxliuli.com/blog/browser-extension-dev-01-introduction-to-basic-concepts/) by rxliuli ([@rxliuli](https://github.com/rxliuli))
|
||||
|
||||
## NPM Packages
|
||||
|
||||
|
||||
+43
-10
@@ -20,13 +20,13 @@ await chrome.scripting.getRegisteredContentScripts();
|
||||
|
||||
## How do I disable opening the browser automatically during development?
|
||||
|
||||
See https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser
|
||||
See <https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser>
|
||||
|
||||
## How do I stay logged into a website during development?
|
||||
|
||||
See https://wxt.dev/guide/essentials/config/browser-startup.html#persist-data
|
||||
See <https://wxt.dev/guide/essentials/config/browser-startup.html#persist-data>
|
||||
|
||||
## My component library doesn't work in content scripts!
|
||||
## My component library doesn't work in content scripts
|
||||
|
||||
This is usually caused by one of two things (or both) when using `createShadowRootUi`:
|
||||
|
||||
@@ -36,7 +36,6 @@ This is usually caused by one of two things (or both) when using `createShadowRo
|
||||
Some component libraries manually add CSS to the page by adding a `<style>` or `<link>` element. They place this element in the document's `<head>` by default. This causes your styles to be placed outside the `ShadowRoot` and it's isolation blocks the styles from being applied to your UI.
|
||||
|
||||
When a library does this, **you need to tell the library where to put its styles**. Here's the documentation for a few popular component libraries:
|
||||
|
||||
- Ant Design: [`StyleProvider`](https://ant.design/docs/react/compatible-style#shadow-dom-usage)
|
||||
- Mantine: [`MantineProvider#getRootElement` and `MantineProvider#cssVariablesSelector`](https://mantine.dev/theming/mantine-provider/)
|
||||
|
||||
@@ -165,13 +164,17 @@ Both issues have the same cause: the library puts something outside the `ShadowR
|
||||
|
||||
Both issues have the same fix: tell the library to put elements inside the `ShadowRoot`, not outside it. See the details above for more information and example fixes for each problem.
|
||||
|
||||
## Does WXT provide docs for LLMs?
|
||||
|
||||
Yes, WXT's documentation provides markdown files based on the [the /llms.txt proposal](https://llmstxt.org/).
|
||||
|
||||
## Is there an LLM trained on WXT's docs that I chat with?
|
||||
|
||||
Yes! There's a "Ask AI" button in the bottom right of the page, try it out! Or visit https://knowledge.wxt.dev/ for a fullscreen experience.
|
||||
Yes! There's a "Ask AI" button in the bottom right of the page, try it out! Or visit <https://knowledge.wxt.dev/> for a fullscreen experience.
|
||||
|
||||
Additionally, if you want to train your own model or provide context to your editor, you can use the LLM knowledge files hosted by the site:
|
||||
|
||||
https://wxt.dev/knowledge/index.json
|
||||
<https://wxt.dev/knowledge/index.json>
|
||||
|
||||
You don't need to crawl the entire website, these files already contain all the relevant docs for training a LLM on WXT. But feel free to crawl it and generate your own files if you want!
|
||||
|
||||
@@ -179,11 +182,41 @@ You don't need to crawl the entire website, these files already contain all the
|
||||
|
||||
To run the WXT dev server in a devcontainer, but load the dev build of your extension in your browser:
|
||||
|
||||
1. **Bind-mount your project directory to your host**
|
||||
1. **Bind-mount your project directory to your host**
|
||||
If you're using VS Code, you can open your project folder with the `Dev Containers: Open Folder in Container...` command. This keeps the folder synchronized between your host and the devcontainer, ensuring that the extension `dist` directory remains accessible from the host.
|
||||
|
||||
2. **Disable auto-opening the browser**
|
||||
WXT automatically opens your browser during development, but since you're running inside a container, it won't be able to access it. Follow the instructions [here](https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser) to disable browser auto-opening in your `wxt.config.ts`.
|
||||
2. **Disable auto-opening the browser**
|
||||
WXT automatically opens your browser during development, but since you're running inside a container, it won't be able to access it. Follow [the guide here](https://wxt.dev/guide/essentials/config/browser-startup.html#disable-opening-browser) to disable browser auto-opening in your `wxt.config.ts`.
|
||||
|
||||
3. **Tell WXT to listen on all network interfaces**
|
||||
3. **Tell WXT to listen on all network interfaces**
|
||||
To enable hot-reloading, your extension has to connect to the WXT dev server running inside your container. WXT will only listen on `localhost` by default, which prevents connections from outside the devcontainer. To fix this you can instruct WXT to listen on all interfaces with `wxt --host 0.0.0.0`.
|
||||
|
||||
## How do I use the new Prompt API in Chrome?
|
||||
|
||||
The service responsible for the [Prompt API](https://developer.chrome.com/docs/ai/prompt-api) is not enabled by default if you let WXT open the browser during dev mode. When checking `LanguageModel.availability`, you will always receive "unavailable".
|
||||
|
||||
You have two options:
|
||||
|
||||
1. Pass the `--disable-features=DisableLoadExtensionCommandLineSwitch` feature flag to enable the service in the browser WXT opens:
|
||||
|
||||
```ts
|
||||
// wxt.config.ts
|
||||
export default defineConfig({
|
||||
webExt: {
|
||||
chromiumArgs: [
|
||||
'--disable-features=DisableLoadExtensionCommandLineSwitch',
|
||||
],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
2. Disable the runner and install your extension in your regular chrome profile manually:
|
||||
|
||||
```ts
|
||||
// wxt.config.ts
|
||||
export default defineConfig({
|
||||
webExt: {
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -15,6 +15,11 @@ cd path/to/your/project
|
||||
pnpm dlx wxt@latest init example-wxt --template vanilla
|
||||
```
|
||||
|
||||
:::tip
|
||||
We recommend reviewing [project structure](/guide/essentials/project-structure.md) before you get started.
|
||||
You can customize directory names in `wxt.config.ts` to match your project's needs.
|
||||
:::
|
||||
|
||||
In general, you'll need to:
|
||||
|
||||
 <input type="checkbox" /> Install `wxt`<br />
|
||||
|
||||
@@ -9,14 +9,18 @@ outline: deep
|
||||
To upgrade WXT to the latest major version:
|
||||
|
||||
1. Install it, skipping scripts so `wxt prepare` doesn't run - it will probably throw an error after a major version change (we'll run it later).
|
||||
|
||||
```sh
|
||||
pnpm i wxt@latest --ignore-scripts
|
||||
```
|
||||
|
||||
2. Follow the upgrade steps below to fix any breaking changes.
|
||||
3. Run `wxt prepare`. It should succeed and type errors will go away afterwords.
|
||||
|
||||
```sh
|
||||
pnpm wxt prepare
|
||||
```
|
||||
|
||||
4. Manually test to make sure both dev mode and production builds work.
|
||||
|
||||
For minor or patch version updates, there are no special steps. Just update it with your package manager:
|
||||
@@ -44,19 +48,36 @@ Read through all the changes once before updating your code.
|
||||
WXT's `browser` no longer uses the `webextension-polyfill`!
|
||||
|
||||
:::details Why?
|
||||
See https://github.com/wxt-dev/wxt/issues/784
|
||||
See <https://github.com/wxt-dev/wxt/issues/784>
|
||||
:::
|
||||
|
||||
To upgrade, you have two options:
|
||||
|
||||
1. **Stop using the polyfill** - No changes necessary, though you may want to do some manual testing to make sure everything continues to work. None of the early testers of this feature reported any runtime issues once they stopped using the polyfill.
|
||||
- If you're already using `extensionApi: "chrome"`, then you don't need to test anything! You're already using the same `browser` object v0.20 provides by default.
|
||||
1. **Stop using the polyfill**
|
||||
- If you're already using `extensionApi: "chrome"`, then you're not using the polyfill and there is nothing to change!
|
||||
- Otherwise there is only one change: `browser.runtime.onMessage` no longer supports using promises to return a response:
|
||||
|
||||
```ts
|
||||
browser.runtime.onMessage.addListener(async () => { // [!code --]
|
||||
const res = await someAsyncWork(); // [!code --]
|
||||
return res; // [!code --]
|
||||
browser.runtime.onMessage.addListener(async (_message, _sender, sendResponse) => { // [!code ++]
|
||||
someAsyncWork().then((res) => { // [!code ++]
|
||||
sendResponse(res); // [!code ++]
|
||||
}); // [!code ++]
|
||||
return true; // [!code ++]
|
||||
});
|
||||
```
|
||||
|
||||
2. **Continue using the polyfill** - If you want to keep using the polyfill, you can! One less thing to worry about during this upgrade.
|
||||
- Install `webextension-polyfill` and WXT's [new polyfill module](https://www.npmjs.com/package/@wxt-dev/webextension-polyfill):
|
||||
|
||||
```sh
|
||||
pnpm i webextension-polyfill @wxt-dev/webextension-polyfill
|
||||
```
|
||||
|
||||
- Add the WXT module to your config:
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
modules: ['@wxt-dev/webextension-polyfill'],
|
||||
@@ -106,9 +127,9 @@ The default location for the `public/` and `modules/` directories have changed t
|
||||
|
||||
- If you follow the default folder structure, you don't need to make any changes.
|
||||
- If you set a custom `srcDir`, you have two options:
|
||||
1. Move the your `public/` and `modules/` directories to the project root:
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
1. Move the your `public/` and `modules/` directories to the project root:
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
📂 {rootDir}/
|
||||
📁 modules/ <!-- [!code ++] -->
|
||||
📁 public/ <!-- [!code ++] -->
|
||||
@@ -121,14 +142,16 @@ The default location for the `public/` and `modules/` directories have changed t
|
||||
📄 app.config.ts
|
||||
📄 wxt.config.ts
|
||||
```
|
||||
2. Keep the folders in the same place and update your project config:
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
srcDir: 'src',
|
||||
publicDir: 'src/public', // [!code ++]
|
||||
modulesDir: 'src/modules', // [!code ++]
|
||||
});
|
||||
```
|
||||
|
||||
2. Keep the folders in the same place and update your project config:
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
srcDir: 'src',
|
||||
publicDir: 'src/public', // [!code ++]
|
||||
modulesDir: 'src/modules', // [!code ++]
|
||||
});
|
||||
```
|
||||
|
||||
### Import Path Changes and `#imports`
|
||||
|
||||
@@ -230,6 +253,7 @@ If you've previously loaded the extension into your browser manually for develop
|
||||
### Deprecated APIs Removed
|
||||
|
||||
- `entrypointLoader` option: WXT now uses `vite-node` for importing entrypoints during the build process.
|
||||
<!-- markdownlint-disable-next-line MD051 -->
|
||||
> This was deprecated in v0.19.0, see the [v0.19 section](#v0-18-5-rarr-v0-19-0) for migration steps.
|
||||
- `transformManifest` option: Use the `build:manifestGenerated` hook to transform the manifest instead:
|
||||
<!-- prettier-ignore -->
|
||||
@@ -251,6 +275,7 @@ If you've previously loaded the extension into your browser manually for develop
|
||||
To improve consistency with the `web-ext.config.ts` filename, the "runner" API and config options have been renamed. You can continue using the old names, but they have been deprecated and will be removed in a future version:
|
||||
|
||||
1. The `runner` option has been renamed to `webExt`:
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
runner: { // [!code --]
|
||||
@@ -259,12 +284,16 @@ To improve consistency with the `web-ext.config.ts` filename, the "runner" API a
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
2. `defineRunnerConfig` has been renamed to `defineWebExtConfig`:
|
||||
|
||||
```ts [web-ext.config.ts]
|
||||
import { defineRunnerConfig } from 'wxt'; // [!code --]
|
||||
import { defineWebExtConfig } from 'wxt'; // [!code ++]
|
||||
```
|
||||
|
||||
3. The `ExtensionRunnerConfig` type has been renamed to `WebExtConfig`
|
||||
|
||||
```ts
|
||||
import type { ExtensionRunnerConfig } from 'wxt'; // [!code --]
|
||||
import type { WebExtConfig } from 'wxt'; // [!code ++]
|
||||
@@ -342,7 +371,7 @@ WXT no longer ships with Common JS support. If you're using CJS, here's your mig
|
||||
1. Add [`"type": "module"`](https://nodejs.org/api/packages.html#type) to your `package.json`.
|
||||
2. Change the file extension of any `.js` files that use CJS syntax to `.cjs`, or update them to use EMS syntax.
|
||||
|
||||
Vite also provides steps for migrating to ESM. Check them out for more details: https://vitejs.dev/guide/migration#deprecate-cjs-node-api
|
||||
Vite also provides steps for migrating to ESM. Check them out for more details: <https://vitejs.dev/guide/migration#deprecate-cjs-node-api>
|
||||
|
||||
## v0.18.0 → v0.18.5
|
||||
|
||||
@@ -357,11 +386,13 @@ If you already have `<srcDir>/modules` or `<srcDir>/Modules` directory, `wxt pre
|
||||
You have two options:
|
||||
|
||||
1. [Recommended] Keep your files where they are and tell WXT to look in a different folder:
|
||||
|
||||
```ts [wxt.config.ts]
|
||||
export default defineConfig({
|
||||
modulesDir: 'wxt-modules', // defaults to "modules"
|
||||
});
|
||||
```
|
||||
|
||||
2. Rename your `modules` directory to something else.
|
||||
|
||||
## v0.17.0 → v0.18.0
|
||||
@@ -415,7 +446,7 @@ item.watch((newValue: number, oldValue: number) => { // [!code ++]
|
||||
|
||||
JS entrypoints in the output directory have been moved. Unless you're doing some kind of post-build work referencing files, you don't have to make any changes.
|
||||
|
||||
```
|
||||
```plaintext
|
||||
.output/
|
||||
<target>/
|
||||
chunks/
|
||||
@@ -445,7 +476,7 @@ export default defineConfig({
|
||||
|
||||
### Renamed Undocumented Constants
|
||||
|
||||
Renamed undocumented constants for detecting the build config at runtime in [#380](https://github.com/wxt-dev/wxt/pull/380). Now documented here: https://wxt.dev/guide/multiple-browsers.html#runtime
|
||||
Renamed undocumented constants for detecting the build config at runtime in [#380](https://github.com/wxt-dev/wxt/pull/380). Now documented here: <https://wxt.dev/guide/multiple-browsers.html#runtime>
|
||||
|
||||
- `__BROWSER__` → `import.meta.env.BROWSER`
|
||||
- `__COMMAND__` → `import.meta.env.COMMAND`
|
||||
@@ -472,7 +503,7 @@ Renamed undocumented constants for detecting the build config at runtime in [#38
|
||||
|
||||
### New `wxt/storage` APIs
|
||||
|
||||
`wxt/storage` no longer relies on [`unstorage`](https://www.npmjs.com/package/unstorage). Some `unstorage` APIs, like `prefixStorage`, have been removed, while others, like `snapshot`, are methods on the new `storage` object. Most of the standard usage remains the same. See https://wxt.dev/guide/storage and https://wxt.dev/api/reference/wxt/storage/ for more details ([#300](https://github.com/wxt-dev/wxt/pull/300))
|
||||
`wxt/storage` no longer relies on [`unstorage`](https://www.npmjs.com/package/unstorage). Some `unstorage` APIs, like `prefixStorage`, have been removed, while others, like `snapshot`, are methods on the new `storage` object. Most of the standard usage remains the same. See <https://wxt.dev/guide/storage> and <https://wxt.dev/api/reference/wxt/storage/> for more details ([#300](https://github.com/wxt-dev/wxt/pull/300))
|
||||
|
||||
## v0.11.0 → v0.12.0
|
||||
|
||||
@@ -482,6 +513,7 @@ Renamed undocumented constants for detecting the build config at runtime in [#38
|
||||
|
||||
- If you use auto-imports, no changes are required.
|
||||
- If you have disabled auto-imports, you'll need to manually update your import statements:
|
||||
|
||||
```ts
|
||||
import { defineBackground, defineContentScript } from 'wxt/client'; // [!code --]
|
||||
import { defineBackground, defineContentScript } from 'wxt/sandbox'; // [!code ++]
|
||||
|
||||
+25
-31
@@ -4,46 +4,51 @@
|
||||
"engines": {
|
||||
"node": ">=18.20.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.10.0",
|
||||
"packageManager": "pnpm@10.29.2+sha512.bef43fa759d91fd2da4b319a5a0d13ef7a45bb985a3d7342058470f9d2051a3ba8674e629672654686ef9443ad13a82da2beb9eeb3e0221c87b8154fff9d74b8",
|
||||
"scripts": {
|
||||
"check": "check && pnpm -r --sequential run check",
|
||||
"test": "pnpm -r --sequential run test run",
|
||||
"test:coverage": "pnpm -r --sequential run test:coverage",
|
||||
"prepare": "simple-git-hooks",
|
||||
"prepublish": "pnpm -s build",
|
||||
"docs:gen": "typedoc --options docs/typedoc.json",
|
||||
"docs:dev": "pnpm -s docs:gen && vitepress dev docs",
|
||||
"docs:build": "pnpm -s docs:gen && vitepress build docs",
|
||||
"docs:preview": "pnpm -s docs:gen && vitepress preview docs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/buildc": "^1.1.4",
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@commitlint/config-conventional": "^19.8.0",
|
||||
"@commitlint/types": "^19.8.0",
|
||||
"@aklinker1/buildc": "^1.1.6",
|
||||
"@aklinker1/check": "^2.2.0",
|
||||
"@commitlint/config-conventional": "^20.4.1",
|
||||
"@commitlint/types": "^20.4.0",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@vitest/coverage-v8": "^3.1.2",
|
||||
"changelogen": "^0.6.1",
|
||||
"@types/semver": "^7.7.1",
|
||||
"@vitest/coverage-v8": "^4.0.18",
|
||||
"changelogen": "^0.6.2",
|
||||
"consola": "^3.4.2",
|
||||
"fast-glob": "^3.3.3",
|
||||
"feed": "^4.2.2",
|
||||
"fs-extra": "^11.3.0",
|
||||
"lint-staged": "^15.5.1",
|
||||
"feed": "^5.2.0",
|
||||
"fs-extra": "^11.3.3",
|
||||
"lint-staged": "^16.2.7",
|
||||
"markdown-it-footnote": "^4.0.0",
|
||||
"nano-spawn": "^0.2.0",
|
||||
"prettier": "^3.5.3",
|
||||
"simple-git-hooks": "^2.13.0",
|
||||
"tsx": "4.19.4",
|
||||
"markdownlint-cli": "^0.47.0",
|
||||
"nano-spawn": "^2.0.0",
|
||||
"p-map": "^7.0.4",
|
||||
"prettier": "^3.8.1",
|
||||
"semver": "^7.7.4",
|
||||
"simple-git-hooks": "^2.13.1",
|
||||
"tsdown": "^0.20.3",
|
||||
"tsx": "4.21.0",
|
||||
"typedoc": "^0.25.4",
|
||||
"typedoc-plugin-frontmatter": "^1.3.0",
|
||||
"typedoc-plugin-frontmatter": "^1.3.1",
|
||||
"typedoc-plugin-markdown": "4.0.0-next.23",
|
||||
"typedoc-vitepress-theme": "1.0.0-next.3",
|
||||
"typescript": "^5.8.3",
|
||||
"vitepress": "^1.6.3",
|
||||
"typescript": "^5.9.3",
|
||||
"vitepress": "^1.6.4",
|
||||
"vitepress-knowledge": "^0.4.1",
|
||||
"vitepress-plugin-group-icons": "^1.5.2",
|
||||
"vitepress-plugin-group-icons": "^1.7.1",
|
||||
"vitepress-plugin-llms": "^1.11.0",
|
||||
"vitest-mock-extended": "^3.1.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue": "^3.5.27",
|
||||
"wxt": "workspace:*"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
@@ -51,16 +56,5 @@
|
||||
},
|
||||
"lint-staged": {
|
||||
"*": "prettier --ignore-unknown --write"
|
||||
},
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
"ignoreMissing": [
|
||||
"@algolia/client-search",
|
||||
"search-insights"
|
||||
]
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"markdown-it-footnote": "patches/markdown-it-footnote.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,61 @@
|
||||
# Changelog
|
||||
|
||||
## v0.5.2
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/analytics-v0.5.1...analytics-v0.5.2)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Normalize path for createAnalytics of analytics/index.ts ([#2013](https://github.com/wxt-dev/wxt/pull/2013))
|
||||
- Allow custom API URL in Google Analytics 4 provider options ([#1653](https://github.com/wxt-dev/wxt/pull/1653))
|
||||
|
||||
### 💅 Refactors
|
||||
|
||||
- Code cleanup in analytics package ([#2084](https://github.com/wxt-dev/wxt/pull/2084))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Fix other type error after `chrome` types update ([31ebf966](https://github.com/wxt-dev/wxt/commit/31ebf966))
|
||||
- Upgrade dev and non-major prod dependencies ([#2000](https://github.com/wxt-dev/wxt/pull/2000))
|
||||
- Use `tsdown` to build packages ([#2006](https://github.com/wxt-dev/wxt/pull/2006))
|
||||
- Move script-only dev dependencies to top-level `package.json` ([#2007](https://github.com/wxt-dev/wxt/pull/2007))
|
||||
- Update dependencies ([#2069](https://github.com/wxt-dev/wxt/pull/2069))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Honwhy Wang <honwhy.wang@gmail.com>
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
|
||||
|
||||
## v0.5.1
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/analytics-v0.5.0...analytics-v0.5.1)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Integrate latest measurement protocol changes ([#1767](https://github.com/wxt-dev/wxt/pull/1767))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Use `@wxt-dev/browser` instead of `@types/chrome` ([#1645](https://github.com/wxt-dev/wxt/pull/1645))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
- Change browser workspace dependency to `^` ([c7335add](https://github.com/wxt-dev/wxt/commit/c7335add))
|
||||
- Fix auto-fixable `markdownlint` errors ([#1710](https://github.com/wxt-dev/wxt/pull/1710))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Tanishq-aggarwal ([@tanishq-aggarwal](https://github.com/tanishq-aggarwal))
|
||||
|
||||
## v0.5.0
|
||||
|
||||
[⚠️ breaking changes](https://wxt.dev/guide/resources/upgrading.html) • [compare changes](https://github.com/wxt-dev/wxt/compare/analytics-v0.4.1...analytics-v0.5.0)
|
||||
|
||||
### 🩹 Fixes
|
||||
@@ -9,4 +64,4 @@
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
@@ -10,15 +10,19 @@ Report analytics events from your web extension extension.
|
||||
## Install With WXT
|
||||
|
||||
1. Install the NPM package:
|
||||
|
||||
```bash
|
||||
pnpm i @wxt-dev/analytics
|
||||
```
|
||||
|
||||
2. In your `wxt.config.ts`, add the WXT module:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
modules: ['@wxt-dev/analytics/module'],
|
||||
});
|
||||
```
|
||||
|
||||
3. In your `<srcDir>/app.config.ts`, add a provider:
|
||||
|
||||
```ts
|
||||
@@ -49,9 +53,11 @@ Report analytics events from your web extension extension.
|
||||
## Install Without WXT
|
||||
|
||||
1. Install the NPM package:
|
||||
|
||||
```bash
|
||||
pnpm i @wxt-dev/analytics
|
||||
```
|
||||
|
||||
2. Create an `analytics` instance:
|
||||
|
||||
```ts
|
||||
@@ -66,10 +72,12 @@ Report analytics events from your web extension extension.
|
||||
```
|
||||
|
||||
3. Import your analytics module in the background to initialize the message listener:
|
||||
|
||||
```ts
|
||||
// background.ts
|
||||
import './utils/analytics';
|
||||
```
|
||||
|
||||
4. Then use your `analytics` instance to report events:
|
||||
|
||||
```ts
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
// Build module and plugins
|
||||
export default defineBuildConfig({
|
||||
rootDir: resolve(__dirname, 'modules/analytics'),
|
||||
outDir: resolve(__dirname, 'dist'),
|
||||
entries: [
|
||||
{ input: 'index.ts', name: 'module' },
|
||||
{ input: 'client.ts', name: 'index' },
|
||||
'background-plugin.ts',
|
||||
'types.ts',
|
||||
'providers/google-analytics-4.ts',
|
||||
'providers/umami.ts',
|
||||
],
|
||||
externals: ['#analytics'],
|
||||
replace: {
|
||||
'import.meta.env.NPM': 'true',
|
||||
},
|
||||
declaration: true,
|
||||
});
|
||||
@@ -13,6 +13,22 @@ import { browser } from '@wxt-dev/browser';
|
||||
|
||||
const ANALYTICS_PORT = '@wxt-dev/analytics';
|
||||
|
||||
const INTERACTIVE_TAGS = new Set([
|
||||
'A',
|
||||
'BUTTON',
|
||||
'INPUT',
|
||||
'SELECT',
|
||||
'TEXTAREA',
|
||||
]);
|
||||
const INTERACTIVE_ROLES = new Set([
|
||||
'button',
|
||||
'link',
|
||||
'checkbox',
|
||||
'menuitem',
|
||||
'tab',
|
||||
'radio',
|
||||
]);
|
||||
|
||||
export function createAnalytics(config?: AnalyticsConfig): Analytics {
|
||||
if (!browser?.runtime?.id)
|
||||
throw Error(
|
||||
@@ -62,8 +78,8 @@ function createBackgroundAnalytics(
|
||||
|
||||
const getBackgroundMeta = () => ({
|
||||
timestamp: Date.now(),
|
||||
// Don't track sessions for the background, it can be running
|
||||
// indefinitely, and will inflate session duration stats.
|
||||
// Don't track sessions for the background, it can be running indefinitely
|
||||
// and will inflate session duration stats.
|
||||
sessionId: undefined,
|
||||
language: navigator.language,
|
||||
referrer: undefined,
|
||||
@@ -75,7 +91,7 @@ function createBackgroundAnalytics(
|
||||
const getBaseEvent = async (
|
||||
meta: AnalyticsEventMetadata,
|
||||
): Promise<BaseAnalyticsEvent> => {
|
||||
const platform = await platformInfo;
|
||||
const { arch, os } = await platformInfo;
|
||||
return {
|
||||
meta,
|
||||
user: {
|
||||
@@ -84,8 +100,8 @@ function createBackgroundAnalytics(
|
||||
version: config?.version ?? manifest.version_name ?? manifest.version,
|
||||
wxtMode: import.meta.env.MODE,
|
||||
wxtBrowser: import.meta.env.BROWSER,
|
||||
arch: platform.arch,
|
||||
os: platform.os,
|
||||
arch,
|
||||
os,
|
||||
browser: userAgent.browser.name,
|
||||
browserVersion: userAgent.browser.version,
|
||||
...(await userProperties),
|
||||
@@ -253,27 +269,12 @@ function defineStorageItem<T>(
|
||||
): AnalyticsStorageItem<T> {
|
||||
return {
|
||||
getValue: async () =>
|
||||
(await browser.storage.local.get(key))[key] ?? defaultValue,
|
||||
(await browser.storage.local.get<Record<string, any>>(key))[key] ??
|
||||
defaultValue,
|
||||
setValue: (newValue) => browser.storage.local.set({ [key]: newValue }),
|
||||
};
|
||||
}
|
||||
|
||||
const INTERACTIVE_TAGS = new Set([
|
||||
'A',
|
||||
'BUTTON',
|
||||
'INPUT',
|
||||
'SELECT',
|
||||
'TEXTAREA',
|
||||
]);
|
||||
const INTERACTIVE_ROLES = new Set([
|
||||
'button',
|
||||
'link',
|
||||
'checkbox',
|
||||
'menuitem',
|
||||
'tab',
|
||||
'radio',
|
||||
]);
|
||||
|
||||
export function defineAnalyticsProvider<T = never>(
|
||||
definition: (
|
||||
/** The analytics object. */
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from 'wxt/modules';
|
||||
import { relative, resolve } from 'node:path';
|
||||
import type { AnalyticsConfig } from './types';
|
||||
import { normalizePath } from 'wxt';
|
||||
|
||||
declare module 'wxt/utils/define-app-config' {
|
||||
export interface WxtAppConfig {
|
||||
@@ -22,10 +23,10 @@ export default defineWxtModule({
|
||||
// Paths
|
||||
const wxtAnalyticsFolder = resolve(wxt.config.wxtDir, 'analytics');
|
||||
const wxtAnalyticsIndex = resolve(wxtAnalyticsFolder, 'index.ts');
|
||||
const clientModuleId = import.meta.env.NPM
|
||||
const clientModuleId = process.env.NPM
|
||||
? '@wxt-dev/analytics'
|
||||
: resolve(wxt.config.modulesDir, 'analytics/client');
|
||||
const pluginModuleId = import.meta.env.NPM
|
||||
const pluginModuleId = process.env.NPM
|
||||
? '@wxt-dev/analytics/background-plugin'
|
||||
: resolve(wxt.config.modulesDir, 'analytics/background-plugin');
|
||||
|
||||
@@ -38,17 +39,15 @@ export default defineWxtModule({
|
||||
});
|
||||
|
||||
// Generate #analytics module
|
||||
const wxtAnalyticsCode = [
|
||||
`import { createAnalytics } from '${
|
||||
import.meta.env.NPM
|
||||
? clientModuleId
|
||||
: relative(wxtAnalyticsFolder, clientModuleId)
|
||||
}';`,
|
||||
`import { useAppConfig } from '#imports';`,
|
||||
``,
|
||||
`export const analytics = createAnalytics(useAppConfig().analytics);`,
|
||||
``,
|
||||
].join('\n');
|
||||
const wxtAnalyticsCode = `import { createAnalytics } from '${
|
||||
process.env.NPM
|
||||
? clientModuleId
|
||||
: normalizePath(relative(wxtAnalyticsFolder, clientModuleId))
|
||||
}';
|
||||
import { useAppConfig } from '#imports';
|
||||
|
||||
export const analytics = createAnalytics(useAppConfig().analytics);
|
||||
`;
|
||||
addAlias(wxt, '#analytics', wxtAnalyticsIndex);
|
||||
wxt.hook('prepare:types', async (_, entries) => {
|
||||
entries.push({
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { BaseAnalyticsEvent } from '../types';
|
||||
const DEFAULT_ENGAGEMENT_TIME_IN_MSEC = 100;
|
||||
|
||||
export interface GoogleAnalytics4ProviderOptions {
|
||||
apiUrl?: string;
|
||||
apiSecret: string;
|
||||
measurementId: string;
|
||||
}
|
||||
@@ -18,7 +19,7 @@ export const googleAnalytics4 =
|
||||
): Promise<void> => {
|
||||
const url = new URL(
|
||||
config?.debug ? '/debug/mp/collect' : '/mp/collect',
|
||||
'https://www.google-analytics.com',
|
||||
options.apiUrl ?? 'https://www.google-analytics.com',
|
||||
);
|
||||
if (options.apiSecret)
|
||||
url.searchParams.set('api_secret', options.apiSecret);
|
||||
@@ -46,6 +47,7 @@ export const googleAnalytics4 =
|
||||
ad_personalization: 'DENIED',
|
||||
},
|
||||
user_properties: mappedUserProperties,
|
||||
user_agent: navigator.userAgent,
|
||||
events: [
|
||||
{
|
||||
name: eventName,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wxt-dev/analytics",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.2",
|
||||
"description": "Add analytics to your web extension",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
},
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
@@ -43,7 +43,7 @@
|
||||
"dev": "buildc --deps-only -- wxt",
|
||||
"dev:build": "buildc --deps-only -- wxt build",
|
||||
"check": "pnpm build && check",
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"prepack": "pnpm -s build",
|
||||
"prepare": "buildc --deps-only -- wxt prepare"
|
||||
},
|
||||
@@ -51,11 +51,9 @@
|
||||
"wxt": ">=0.20.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"wxt": "workspace:*"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
export default defineConfig({
|
||||
entry: {
|
||||
index: './modules/analytics/client.ts',
|
||||
module: './modules/analytics/index.ts',
|
||||
'background-plugin': './modules/analytics/background-plugin.ts',
|
||||
types: './modules/analytics/types.ts',
|
||||
'providers/google-analytics-4':
|
||||
'./modules/analytics/providers/google-analytics-4.ts',
|
||||
'providers/umami': './modules/analytics/providers/umami.ts',
|
||||
},
|
||||
external: ['#analytics'],
|
||||
define: {
|
||||
'process.env.NPM': 'true',
|
||||
},
|
||||
});
|
||||
@@ -1,5 +1,37 @@
|
||||
# Changelog
|
||||
|
||||
## v1.1.0
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/auto-icons-v1.0.2...auto-icons-v1.1.0)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Add overlay option for dev icons ([#1825](https://github.com/wxt-dev/wxt/pull/1825))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Rewrite and restructure the documentation website ([#933](https://github.com/wxt-dev/wxt/pull/933))
|
||||
- Use full URLs in README so they work on the docs site ([d20793d5](https://github.com/wxt-dev/wxt/commit/d20793d5))
|
||||
- Add SVG compatibility note ([#1830](https://github.com/wxt-dev/wxt/pull/1830))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Add `oxlint` for linting ([#947](https://github.com/wxt-dev/wxt/pull/947))
|
||||
- **deps:** Bump sharp from 0.33.4 to 0.33.5 ([#959](https://github.com/wxt-dev/wxt/pull/959))
|
||||
- Upgrade all non-major dependencies ([#1040](https://github.com/wxt-dev/wxt/pull/1040))
|
||||
- **deps:** Upgrade all non-major dependencies ([#1164](https://github.com/wxt-dev/wxt/pull/1164))
|
||||
- **deps:** Bump dev and non-breaking major dependencies ([#1167](https://github.com/wxt-dev/wxt/pull/1167))
|
||||
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
|
||||
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Typed SIGTERM ([@typed-sigterm](https://github.com/typed-sigterm))
|
||||
- Kuba ([@zizzfizzix](https://github.com/zizzfizzix))
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
|
||||
## v1.0.2
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/auto-icons-v1.0.1...auto-icons-v1.0.2)
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
## Features
|
||||
|
||||
- Generate extension icons with the correct sizes
|
||||
- Make the icon greyscale during development
|
||||
- Make the icon greyscale or include a visible overlay during development
|
||||
- SVG is supported
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"version": "1.0.2",
|
||||
"version": "1.1.0",
|
||||
"type": "module",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
@@ -38,7 +38,7 @@
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"check": "pnpm build && check"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -46,15 +46,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"defu": "^6.1.4",
|
||||
"fs-extra": "^11.3.0",
|
||||
"sharp": "^0.34.1"
|
||||
"fs-extra": "^11.3.3",
|
||||
"sharp": "^0.34.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"oxlint": "^0.16.8",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"oxlint": "^1.43.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { defineWxtModule } from 'wxt/modules';
|
||||
import { resolve, relative } from 'node:path';
|
||||
import defu from 'defu';
|
||||
import sharp from 'sharp';
|
||||
import { ensureDir, exists } from 'fs-extra';
|
||||
import { ensureDir, pathExists } from 'fs-extra';
|
||||
|
||||
export default defineWxtModule<AutoIconsOptions>({
|
||||
name: '@wxt-dev/auto-icons',
|
||||
@@ -14,17 +14,30 @@ export default defineWxtModule<AutoIconsOptions>({
|
||||
{
|
||||
enabled: true,
|
||||
baseIconPath: resolve(wxt.config.srcDir, 'assets/icon.png'),
|
||||
grayscaleOnDevelopment: true,
|
||||
developmentIndicator: 'grayscale',
|
||||
sizes: [128, 48, 32, 16],
|
||||
},
|
||||
);
|
||||
|
||||
// Backward compatibility for the deprecated option
|
||||
if (options?.grayscaleOnDevelopment !== undefined) {
|
||||
wxt.logger.warn(
|
||||
'`[auto-icons]` "grayscaleOnDevelopment" is deprecated. Use "developmentIndicator" instead.',
|
||||
);
|
||||
|
||||
if (options?.developmentIndicator === undefined) {
|
||||
parsedOptions.developmentIndicator = options!.grayscaleOnDevelopment
|
||||
? 'grayscale'
|
||||
: false;
|
||||
}
|
||||
}
|
||||
|
||||
const resolvedPath = resolve(wxt.config.srcDir, parsedOptions.baseIconPath);
|
||||
|
||||
if (!parsedOptions.enabled)
|
||||
return wxt.logger.warn(`\`[auto-icons]\` ${this.name} disabled`);
|
||||
|
||||
if (!(await exists(resolvedPath))) {
|
||||
if (!(await pathExists(resolvedPath))) {
|
||||
return wxt.logger.warn(
|
||||
`\`[auto-icons]\` Skipping icon generation, no base icon found at ${relative(process.cwd(), resolvedPath)}`,
|
||||
);
|
||||
@@ -42,21 +55,44 @@ export default defineWxtModule<AutoIconsOptions>({
|
||||
});
|
||||
|
||||
wxt.hooks.hook('build:done', async (wxt, output) => {
|
||||
const image = sharp(resolvedPath).png();
|
||||
|
||||
if (
|
||||
wxt.config.mode === 'development' &&
|
||||
parsedOptions.grayscaleOnDevelopment
|
||||
) {
|
||||
image.grayscale();
|
||||
}
|
||||
|
||||
const outputFolder = wxt.config.outDir;
|
||||
|
||||
for (const size of parsedOptions.sizes) {
|
||||
const resized = image.resize(size);
|
||||
const resizedImage = sharp(resolvedPath).resize(size).png();
|
||||
|
||||
if (wxt.config.mode === 'development') {
|
||||
if (parsedOptions.developmentIndicator === 'grayscale') {
|
||||
resizedImage.grayscale();
|
||||
} else if (parsedOptions.developmentIndicator === 'overlay') {
|
||||
// Helper to build an overlay that places a yellow rectangle at the bottom
|
||||
// of the icon with the text "DEV" in black. The overlay has the same
|
||||
// dimensions as the icon so we can composite it with default gravity.
|
||||
const buildDevOverlay = (size: number) => {
|
||||
const rectHeight = Math.round(size * 0.5);
|
||||
const fontSize = Math.round(size * 0.35);
|
||||
|
||||
return Buffer.from(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="${size - rectHeight}" width="${size}" height="${rectHeight}" fill="#ffff00" />
|
||||
<text x="${size / 2}" y="${size - rectHeight / 2}" font-family="Arial, Helvetica, sans-serif" font-size="${fontSize}" font-weight="bold" fill="black" text-anchor="middle" dominant-baseline="middle">DEV</text>
|
||||
</svg>`);
|
||||
};
|
||||
const overlayBuffer = await sharp(buildDevOverlay(size))
|
||||
.png()
|
||||
.toBuffer();
|
||||
|
||||
resizedImage.composite([
|
||||
{
|
||||
input: overlayBuffer,
|
||||
left: 0,
|
||||
top: 0,
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
ensureDir(resolve(outputFolder, 'icons'));
|
||||
await resized.toFile(resolve(outputFolder, `icons/${size}.png`));
|
||||
await resizedImage.toFile(resolve(outputFolder, `icons/${size}.png`));
|
||||
|
||||
output.publicAssets.push({
|
||||
type: 'asset',
|
||||
@@ -89,9 +125,20 @@ export interface AutoIconsOptions {
|
||||
* @default "<srcDir>/assets/icon.png"
|
||||
*/
|
||||
baseIconPath?: string;
|
||||
/**
|
||||
* Apply a visual indicator to the icon when running in development mode.
|
||||
*
|
||||
* "grayscale" converts the icon to grayscale.
|
||||
* "overlay" covers the bottom half with a yellow rectangle and writes "DEV" in black text.
|
||||
* Set to `false` to disable any indicator.
|
||||
*
|
||||
* @default "grayscale"
|
||||
*/
|
||||
developmentIndicator?: 'grayscale' | 'overlay' | false;
|
||||
/**
|
||||
* Grayscale the image when in development mode to indicate development
|
||||
* @default true
|
||||
* @deprecated Use `developmentIndicator` instead
|
||||
*/
|
||||
grayscaleOnDevelopment?: boolean;
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@wxt-dev/browser",
|
||||
"description": "Provides a cross-browser API for using extension APIs and types based on @types/chrome",
|
||||
"version": "0.0.326",
|
||||
"version": "0.1.36",
|
||||
"type": "module",
|
||||
"main": "src/index.mjs",
|
||||
"types": "src/index.d.ts",
|
||||
@@ -23,12 +23,11 @@
|
||||
"src"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/chrome": "0.0.326",
|
||||
"fs-extra": "^11.3.0",
|
||||
"nano-spawn": "^0.2.0",
|
||||
"tsx": "4.19.4",
|
||||
"typescript": "^5.8.3",
|
||||
"vitest": "^3.1.2"
|
||||
"@types/chrome": "0.1.36",
|
||||
"fs-extra": "^11.3.3",
|
||||
"nano-spawn": "^2.0.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/filesystem": "*",
|
||||
|
||||
@@ -60,9 +60,7 @@ for (const { file, srcPath, destPath } of declarationFileMapping) {
|
||||
|
||||
// Done!
|
||||
|
||||
console.log(
|
||||
'\x1b[32m✔\x1b[0m Done in ' + performance.now().toFixed(0) + ' ms',
|
||||
);
|
||||
console.log('\x1b[32m✔\x1b[0m Done in ' + performance.now().toFixed(0) + ' ms');
|
||||
|
||||
// Transformations
|
||||
|
||||
|
||||
@@ -5,19 +5,19 @@ import { browser, type Browser } from '../index';
|
||||
describe('browser', () => {
|
||||
describe('types', () => {
|
||||
it('should provide types via the Browser import', () => {
|
||||
expectTypeOf<Browser.runtime.MessageSender>().toMatchTypeOf<chrome.runtime.MessageSender>();
|
||||
expectTypeOf<Browser.storage.AreaName>().toMatchTypeOf<chrome.storage.AreaName>();
|
||||
expectTypeOf<Browser.i18n.LanguageDetectionResult>().toMatchTypeOf<chrome.i18n.LanguageDetectionResult>();
|
||||
expectTypeOf<Browser.runtime.MessageSender>().toEqualTypeOf<chrome.runtime.MessageSender>();
|
||||
expectTypeOf<Browser.storage.AreaName>().toEqualTypeOf<chrome.storage.AreaName>();
|
||||
expectTypeOf<Browser.i18n.LanguageDetectionResult>().toEqualTypeOf<chrome.i18n.LanguageDetectionResult>();
|
||||
});
|
||||
|
||||
it('should provide values via the browser import', () => {
|
||||
expectTypeOf(browser.runtime.id).toMatchTypeOf<string>();
|
||||
expectTypeOf(browser.runtime.id).toEqualTypeOf<string>();
|
||||
expectTypeOf(
|
||||
browser.storage.local,
|
||||
).toMatchTypeOf<Browser.storage.StorageArea>();
|
||||
).toEqualTypeOf<Browser.storage.LocalStorageArea>();
|
||||
expectTypeOf(
|
||||
browser.i18n.detectLanguage('Hello, world!'),
|
||||
).resolves.toMatchTypeOf<chrome.i18n.LanguageDetectionResult>();
|
||||
browser.i18n.detectLanguage,
|
||||
).returns.resolves.toEqualTypeOf<chrome.i18n.LanguageDetectionResult>();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+4443
-5051
File diff suppressed because it is too large
Load Diff
@@ -24,10 +24,9 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/chrome": "{{chromeTypesVersion}}",
|
||||
"fs-extra": "^11.3.0",
|
||||
"nano-spawn": "^0.2.0",
|
||||
"tsx": "4.19.4",
|
||||
"typescript": "^5.8.3",
|
||||
"vitest": "^3.1.2"
|
||||
"fs-extra": "^11.3.3",
|
||||
"nano-spawn": "^2.0.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.18"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
1. Simple messages file format
|
||||
2. Plural form support
|
||||
3. Integrates with the [I18n Ally VS Code extension](#vscode)
|
||||
3. Integrates with the [I18n Ally VS Code extension](#vs-code)
|
||||
|
||||
It also provides several benefits over other non-web extension specific i18n packages:
|
||||
|
||||
@@ -81,7 +81,7 @@ And you're done! Using WXT, you get type-safety out of the box.
|
||||
|
||||
> [!NOTE]
|
||||
> For the best DX, you should to integrate `@wxt-dev/i18n` into your build process. This enables:
|
||||
|
||||
>
|
||||
> 1. Plural forms
|
||||
> 2. Simple messages file format
|
||||
> 3. Type safety
|
||||
|
||||
@@ -21,13 +21,13 @@
|
||||
"license": "MIT",
|
||||
"funding": "https://github.com/sponsors/wxt-dev",
|
||||
"scripts": {
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"check": "buildc --deps-only -- check",
|
||||
"test": "buildc --deps-only -- vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@wxt-dev/browser": "workspace:^",
|
||||
"chokidar": "^4.0.3",
|
||||
"chokidar": "^5.0.0",
|
||||
"confbox": "^0.1.8 || ^0.2.2",
|
||||
"fast-glob": "^3.3.3"
|
||||
},
|
||||
@@ -40,19 +40,17 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@types/node": "^20.17.6",
|
||||
"oxlint": "^0.16.8",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"vitest": "^3.1.2",
|
||||
"vitest-plugin-random-seed": "^1.1.1",
|
||||
"oxlint": "^1.43.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.18",
|
||||
"vitest-plugin-random-seed": "^1.1.2",
|
||||
"wxt": "workspace:*"
|
||||
},
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
|
||||
@@ -44,7 +44,7 @@ export default defineWxtModule<I18nOptions>({
|
||||
options ?? {};
|
||||
|
||||
const getLocalizationFiles = async () => {
|
||||
const files = await glob('*.{json,json5,yml,yaml,toml}', {
|
||||
const files = await glob('*.{json,json5,jsonc,yml,yaml,toml}', {
|
||||
cwd: localesDir,
|
||||
absolute: true,
|
||||
});
|
||||
@@ -88,7 +88,7 @@ export default defineWxtModule<I18nOptions>({
|
||||
)!;
|
||||
if (defaultLocaleFile == null) {
|
||||
throw Error(
|
||||
`\`[i18n]\` Required localization file does not exist: \`<localesDir>/${wxt.config.manifest.default_locale}.{json|json5|yml|yaml|toml}\``,
|
||||
`\`[i18n]\` Required localization file does not exist: \`<localesDir>/${wxt.config.manifest.default_locale}.{json|json5|jsonc|yml|yaml|toml}\``,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
const entry = ['src/index.ts', 'src/build.ts', 'src/module.ts'];
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
entry,
|
||||
},
|
||||
{
|
||||
entry,
|
||||
format: 'cjs',
|
||||
},
|
||||
]);
|
||||
@@ -1,5 +1,43 @@
|
||||
# Changelog
|
||||
|
||||
## v1.1.5
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.4...module-react-v1.1.5)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps:** Support @vitejs/plugin-react@5 ([9170159b](https://github.com/wxt-dev/wxt/commit/9170159b))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
|
||||
## v1.1.4
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.3...module-react-v1.1.4)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Add support for WXT v0.20.0 ([c9dca022](https://github.com/wxt-dev/wxt/commit/c9dca022))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
|
||||
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
|
||||
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
|
||||
- **deps:** Upgrade to Vite 6 and related dependencies ([#1496](https://github.com/wxt-dev/wxt/pull/1496))
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
- **deps:** Update all dependencies ([#1648](https://github.com/wxt-dev/wxt/pull/1648))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Okinea Dev <hi@okinea.dev>
|
||||
|
||||
## v1.1.3
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-react-v1.1.2...module-react-v1.1.3)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
export default defineBuildConfig({
|
||||
rootDir: resolve(__dirname, 'modules'),
|
||||
outDir: resolve(__dirname, 'dist'),
|
||||
entries: [{ input: 'react.ts', name: 'index' }],
|
||||
rollup: {
|
||||
emitCJS: true,
|
||||
},
|
||||
declaration: true,
|
||||
});
|
||||
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"funding": "https://github.com/sponsors/wxt-dev",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.5",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
@@ -41,24 +41,22 @@
|
||||
"scripts": {
|
||||
"dev": "wxt",
|
||||
"check": "pnpm build && check",
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"prepare": "buildc --deps-only -- wxt prepare"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.19.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-react": "^4.4.1"
|
||||
"@vitejs/plugin-react": "^4.4.1 || ^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.3",
|
||||
"publint": "^0.3.12",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"@types/react": "^19.2.13",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"publint": "^0.3.17",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"typescript": "^5.9.3",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
const entry = {
|
||||
index: './modules/react.ts',
|
||||
};
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
entry,
|
||||
},
|
||||
{
|
||||
entry,
|
||||
format: 'cjs',
|
||||
},
|
||||
]);
|
||||
@@ -1,5 +1,33 @@
|
||||
# Changelog
|
||||
|
||||
## v1.1.4
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-solid-v1.1.3...module-solid-v1.1.4)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Add support for WXT v0.20.0 ([c9dca022](https://github.com/wxt-dev/wxt/commit/c9dca022))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps-dev:** Bump solid-js from 1.9.3 to 1.9.4 ([#1391](https://github.com/wxt-dev/wxt/pull/1391))
|
||||
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
|
||||
- **deps:** Bump vite-plugin-solid from 2.10.2 to 2.11.6 ([#1491](https://github.com/wxt-dev/wxt/pull/1491))
|
||||
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
|
||||
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
|
||||
- **deps:** Upgrade to Vite 6 and related dependencies ([#1496](https://github.com/wxt-dev/wxt/pull/1496))
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
- **deps:** Update all dependencies ([#1648](https://github.com/wxt-dev/wxt/pull/1648))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Okinea Dev <hi@okinea.dev>
|
||||
|
||||
## v1.1.3
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-solid-v1.1.2...module-solid-v1.1.3)
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
export default defineBuildConfig({
|
||||
rootDir: resolve(__dirname, 'modules'),
|
||||
outDir: resolve(__dirname, 'dist'),
|
||||
entries: [{ input: 'solid.ts', name: 'index' }],
|
||||
rollup: {
|
||||
emitCJS: true,
|
||||
},
|
||||
declaration: true,
|
||||
});
|
||||
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"funding": "https://github.com/sponsors/wxt-dev",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
@@ -41,21 +41,19 @@
|
||||
"scripts": {
|
||||
"dev": "wxt",
|
||||
"check": "pnpm build && check",
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"prepare": "buildc --deps-only -- wxt prepare"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.19.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"vite-plugin-solid": "^2.11.6"
|
||||
"vite-plugin-solid": "^2.11.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"publint": "^0.3.12",
|
||||
"solid-js": "^1.9.6",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"publint": "^0.3.17",
|
||||
"solid-js": "^1.9.11",
|
||||
"typescript": "^5.9.3",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
const entry = {
|
||||
index: './modules/solid.ts',
|
||||
};
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
entry,
|
||||
},
|
||||
{
|
||||
entry,
|
||||
format: 'cjs',
|
||||
},
|
||||
]);
|
||||
@@ -1,5 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## v2.0.4
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-svelte-v2.0.3...module-svelte-v2.0.4)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Add support for @sveltejs/vite-plugin-svelte@6 ([459f73fd](https://github.com/wxt-dev/wxt/commit/459f73fd))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
|
||||
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
|
||||
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Okinea Dev <hi@okinea.dev>
|
||||
|
||||
## v2.0.3
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-svelte-v2.0.2...module-svelte-v2.0.3)
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"funding": "https://github.com/sponsors/wxt-dev",
|
||||
"version": "2.0.3",
|
||||
"version": "2.0.4",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
@@ -39,7 +39,7 @@
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"check": "pnpm build && check"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -47,13 +47,11 @@
|
||||
"svelte": ">=5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0 || ^5.0.0"
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0 || ^5.0.0 || ^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
const entry = {
|
||||
index: './src/index.ts',
|
||||
};
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
entry,
|
||||
},
|
||||
{
|
||||
entry,
|
||||
format: 'cjs',
|
||||
},
|
||||
]);
|
||||
@@ -1,5 +1,27 @@
|
||||
# Changelog
|
||||
|
||||
## v1.0.3
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-vue-v1.0.2...module-vue-v1.0.3)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Add funding links to `package.json` files ([#1446](https://github.com/wxt-dev/wxt/pull/1446))
|
||||
- Use PNPM 10's new catelog feature ([#1493](https://github.com/wxt-dev/wxt/pull/1493))
|
||||
- Move production dependencies to PNPM 10 catelog ([#1494](https://github.com/wxt-dev/wxt/pull/1494))
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
- Wxt & @wxt-dev/module-vue support Vite 7 ([#1771](https://github.com/wxt-dev/wxt/pull/1771))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Ayu ([@ayu-exorcist](https://github.com/ayu-exorcist))
|
||||
- Okinea Dev <hi@okinea.dev>
|
||||
|
||||
## v1.0.2
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/module-vue-v1.0.1...module-vue-v1.0.2)
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"funding": "https://github.com/sponsors/wxt-dev",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"type": "module",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
@@ -39,20 +39,18 @@
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"check": "pnpm build && check"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"wxt": ">=0.19.16"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vitejs/plugin-vue": "^5.2.3"
|
||||
"@vitejs/plugin-vue": "^5.2.3 || ^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
const entry = {
|
||||
index: './src/index.ts',
|
||||
};
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
entry,
|
||||
},
|
||||
{
|
||||
entry,
|
||||
format: 'cjs',
|
||||
},
|
||||
]);
|
||||
@@ -0,0 +1,33 @@
|
||||
# Changelog
|
||||
|
||||
## v0.1.2
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/runner-v0.1.1...runner-v0.1.2)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- **config:** Add browser path for Zen via Homebrew ([#1813](https://github.com/wxt-dev/wxt/pull/1813))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Improve Chrome path search ([#1823](https://github.com/wxt-dev/wxt/pull/1823))
|
||||
- **paths:** Add browser paths for Arc & Dia on macos ([#1814](https://github.com/wxt-dev/wxt/pull/1814))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Fix auto-fixable `markdownlint` errors ([#1710](https://github.com/wxt-dev/wxt/pull/1710))
|
||||
- Manually fix markdownlint errors ([#1711](https://github.com/wxt-dev/wxt/pull/1711))
|
||||
- **deps:** Upgrade oxlint from 0.16.8 to 1.14.0 ([a01928e0](https://github.com/wxt-dev/wxt/commit/a01928e0))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Sam Carlton ([@ThatGuySam](https://github.com/ThatGuySam))
|
||||
- Alexander Kachkaev <alexander@kachkaev.ru>
|
||||
|
||||
## v0.1.1
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/runner-v0.1.0...runner-v0.1.1)
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
Programmatically open a browser and install a web extension from a local directory.
|
||||
|
||||
###### With WXT
|
||||
## Usage
|
||||
|
||||
### With WXT
|
||||
|
||||
> [!WARNING]
|
||||
> This package is intended to replace [`web-ext`](https://github.com/mozilla/web-ext) in the future, but it is not ready at the moment. Once it's ready for testing in WXT, more details will be added here.
|
||||
@@ -16,7 +18,7 @@ export default defineRunnerConfig({
|
||||
});
|
||||
```
|
||||
|
||||
###### JS API
|
||||
### JS API
|
||||
|
||||
```ts
|
||||
import { run } from '@wxt-dev/runner';
|
||||
@@ -92,7 +94,7 @@ await run({
|
||||
|
||||
These presets configure different flags for different operating systems when spawning the browser process.
|
||||
|
||||
If you want to customize your data persistence beyond what these presets define, [you can override the browser flags yourself](#Arguments) to configure persistence.
|
||||
If you want to customize your data persistence beyond what these presets define, [you can override the browser flags yourself](#arguments) to configure persistence.
|
||||
|
||||
### Browser Binaries
|
||||
|
||||
@@ -153,7 +155,7 @@ To see debug logs, set the `DEBUG` env var to `"@wxt-dev/runner"`. This will pri
|
||||
<details>
|
||||
<summary>Example debug output</summary>
|
||||
|
||||
```
|
||||
```plaintext
|
||||
@wxt-dev/runner:options User options: { extensionDir: 'demo-extension', target: undefined }
|
||||
@wxt-dev/runner:options Resolved options: {
|
||||
browserBinary: '/usr/bin/chromium',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@wxt-dev/runner",
|
||||
"description": "Launch Chrome and Firefox with a web extension installed",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.2",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -24,21 +24,17 @@
|
||||
"check": "pnpm build && check",
|
||||
"test": "buildc --deps-only -- vitest",
|
||||
"dev": "tsx --trace-warnings dev.ts",
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"prepublishOnly": "pnpm build"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"oxlint": "^0.16.8",
|
||||
"publint": "^0.3.12",
|
||||
"tsx": "4.19.4",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"vitest": "^3.1.2"
|
||||
"oxlint": "^1.43.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.18"
|
||||
},
|
||||
"main": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
"types": "dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
export type BrowserPlatform = 'windows' | 'mac' | 'linux';
|
||||
|
||||
export type KnownTarget =
|
||||
| 'arc'
|
||||
| 'chromium'
|
||||
| 'chrome'
|
||||
| 'chrome-beta'
|
||||
| 'chrome-dev'
|
||||
| 'chrome-canary'
|
||||
| 'dia'
|
||||
| 'edge'
|
||||
| 'edge-beta'
|
||||
| 'edge-dev'
|
||||
@@ -21,6 +23,11 @@ export const KNOWN_BROWSER_PATHS: Record<
|
||||
> = {
|
||||
// Chromium based targets
|
||||
|
||||
arc: {
|
||||
mac: ['/Applications/Arc.app/Contents/MacOS/Arc'],
|
||||
linux: [],
|
||||
windows: [],
|
||||
},
|
||||
chromium: {
|
||||
mac: [],
|
||||
linux: [
|
||||
@@ -30,7 +37,10 @@ export const KNOWN_BROWSER_PATHS: Record<
|
||||
windows: [],
|
||||
},
|
||||
chrome: {
|
||||
mac: ['/Applications/Chrome.app/Contents/MacOS/Google Chrome'],
|
||||
mac: [
|
||||
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
||||
'/Applications/Chrome.app/Contents/MacOS/Google Chrome',
|
||||
],
|
||||
linux: [],
|
||||
windows: ['C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'],
|
||||
},
|
||||
@@ -42,6 +52,7 @@ export const KNOWN_BROWSER_PATHS: Record<
|
||||
'chrome-canary': {
|
||||
mac: [
|
||||
'/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
|
||||
'/Applications/Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
|
||||
],
|
||||
linux: [],
|
||||
windows: [],
|
||||
@@ -51,6 +62,11 @@ export const KNOWN_BROWSER_PATHS: Record<
|
||||
linux: [],
|
||||
windows: [],
|
||||
},
|
||||
dia: {
|
||||
mac: ['/Applications/Dia.app/Contents/MacOS/Dia'],
|
||||
linux: [],
|
||||
windows: [],
|
||||
},
|
||||
edge: {
|
||||
mac: [],
|
||||
linux: [],
|
||||
@@ -96,7 +112,12 @@ export const KNOWN_BROWSER_PATHS: Record<
|
||||
windows: [],
|
||||
},
|
||||
zen: {
|
||||
mac: ['/Applications/Zen Browser.app/Contents/MacOS/zen'],
|
||||
mac: [
|
||||
'/Applications/Zen Browser.app/Contents/MacOS/zen',
|
||||
// Homebrew Cask
|
||||
// https://github.com/Homebrew/homebrew-cask/blob/main/Casks/z/zen.rb#L23C13-L23C19
|
||||
'/Applications/Zen.app/Contents/MacOS/zen',
|
||||
],
|
||||
linux: [],
|
||||
windows: [],
|
||||
},
|
||||
@@ -107,10 +128,12 @@ export const KNOWN_BROWSER_PATHS: Record<
|
||||
*/
|
||||
export const FALLBACK_TARGETS: Partial<Record<KnownTarget, KnownTarget[]>> = {
|
||||
chrome: [
|
||||
'arc',
|
||||
'chromium',
|
||||
'chrome-canary',
|
||||
'chrome-beta',
|
||||
'chrome-dev',
|
||||
'dia',
|
||||
'edge',
|
||||
'edge-canary',
|
||||
'edge-beta',
|
||||
|
||||
@@ -114,7 +114,7 @@ async function findBrowserBinary(target: string): Promise<string | undefined> {
|
||||
for (const target of targets) {
|
||||
const potentialPaths = KNOWN_BROWSER_PATHS[target]?.[platform] ?? [];
|
||||
for (const path of potentialPaths) {
|
||||
if (await exists(path)) return path;
|
||||
if (await pathExists(path)) return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,7 +207,7 @@ function deduplicateArgs(
|
||||
return args;
|
||||
}
|
||||
|
||||
async function exists(path: string): Promise<boolean> {
|
||||
async function pathExists(path: string): Promise<boolean> {
|
||||
try {
|
||||
await open(path, 'r');
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,92 @@
|
||||
# Changelog
|
||||
|
||||
## v1.2.7
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.6...storage-v1.2.7)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Add another `defineItem` signature when `init` function is passed ([#1909](https://github.com/wxt-dev/wxt/pull/1909))
|
||||
- **storage:** Set version number on init ([#1996](https://github.com/wxt-dev/wxt/pull/1996))
|
||||
|
||||
### 💅 Refactors
|
||||
|
||||
- Code cleanup in analytics package ([#2084](https://github.com/wxt-dev/wxt/pull/2084))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Rename keys name of getMetas() to be proper ([#2105](https://github.com/wxt-dev/wxt/pull/2105))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Fix type errors after `chrome` type upgrades ([6036c6e8](https://github.com/wxt-dev/wxt/commit/6036c6e8))
|
||||
- Upgrade dev and non-major prod dependencies ([#2000](https://github.com/wxt-dev/wxt/pull/2000))
|
||||
- Use `tsdown` to build packages ([#2006](https://github.com/wxt-dev/wxt/pull/2006))
|
||||
- Move script-only dev dependencies to top-level `package.json` ([#2007](https://github.com/wxt-dev/wxt/pull/2007))
|
||||
- Update dependencies ([#2069](https://github.com/wxt-dev/wxt/pull/2069))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Willow ([@42willow](https://github.com/42willow))
|
||||
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Dan McGee <dpmcgee@gmail.com>
|
||||
|
||||
## v1.2.6
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.5...storage-v1.2.6)
|
||||
|
||||
## v1.2.5
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.4...storage-v1.2.5)
|
||||
|
||||
## v1.2.4
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.3...storage-v1.2.4)
|
||||
|
||||
## v1.2.3
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.2...storage-v1.2.3)
|
||||
|
||||
## v1.2.2
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.1...storage-v1.2.2)
|
||||
|
||||
## v1.2.1
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.2.0...storage-v1.2.1)
|
||||
|
||||
## v1.2.0
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.1.1...storage-v1.2.0)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- **storage:** Add `onMigrationComplete` callback ([#1514](https://github.com/wxt-dev/wxt/pull/1514))
|
||||
- **storage:** Add `debug` option to enable migration logs ([#1513](https://github.com/wxt-dev/wxt/pull/1513))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Fix typescript error on `defineItem` fallback ([#1601](https://github.com/wxt-dev/wxt/pull/1601))
|
||||
- Use `@wxt-dev/browser` instead of `@types/chrome` ([#1645](https://github.com/wxt-dev/wxt/pull/1645))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps:** Update all dependencies ([#1568](https://github.com/wxt-dev/wxt/pull/1568))
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
- Change browser workspace dependency to `^` ([c7335add](https://github.com/wxt-dev/wxt/commit/c7335add))
|
||||
- **deps:** Upgrade oxlint from 0.16.8 to 1.14.0 ([a01928e0](https://github.com/wxt-dev/wxt/commit/a01928e0))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Anh71me ([@iyume](https://github.com/iyume))
|
||||
- Ergou <ma2808203259@hotmail.com>
|
||||
|
||||
## v1.1.1
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/storage-v1.1.0...storage-v1.1.1)
|
||||
@@ -69,4 +156,4 @@ It's still shipped inside WXT and accessible via `wxt/storage`, but now:
|
||||
|
||||
[Read the docs](https://wxt.dev/storage.html) for more details.
|
||||
|
||||
> This is apart of the v1.0 initiative for WXT.
|
||||
> This is apart of the v1.0 initiative for WXT.
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@wxt-dev/storage",
|
||||
"description": "Web extension storage API provided by WXT, supports all browsers.",
|
||||
"version": "1.1.1",
|
||||
"version": "1.2.7",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -25,7 +25,7 @@
|
||||
"license": "MIT",
|
||||
"funding": "https://github.com/sponsors/wxt-dev",
|
||||
"scripts": {
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"check": "buildc --deps-only -- check",
|
||||
"test": "buildc --deps-only -- vitest"
|
||||
},
|
||||
@@ -35,16 +35,14 @@
|
||||
"dequal": "^2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@webext-core/fake-browser": "^1.3.2",
|
||||
"oxlint": "^0.16.8",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"vitest": "^3.1.2"
|
||||
"@webext-core/fake-browser": "^1.3.4",
|
||||
"oxlint": "^1.43.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"vitest": "^4.0.18"
|
||||
},
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
|
||||
@@ -706,6 +706,47 @@ describe('Storage Utils', () => {
|
||||
expect(migrateToV3).toBeCalledWith(4);
|
||||
});
|
||||
|
||||
it('should set the version without running migrations for empty storage items', async () => {
|
||||
const migrate = vi.fn((n: number) => n * 2);
|
||||
|
||||
const item = storage.defineItem<number>('local:key', {
|
||||
init: () => 1,
|
||||
version: 2,
|
||||
migrations: {
|
||||
2: migrate,
|
||||
},
|
||||
});
|
||||
const value = await item.getValue();
|
||||
const meta = await item.getMeta();
|
||||
|
||||
expect(value).toEqual(1);
|
||||
expect(meta).toEqual({ v: 2 });
|
||||
expect(migrate).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
it('should set the version and run migrations if a storage value already exists and v2 is added', async () => {
|
||||
const key = 'local:key';
|
||||
|
||||
// Mimic as if an initial value was set by a previous version. We expect
|
||||
// this value to be migrated and doubled to V2.
|
||||
await storage.setItem(key, 1);
|
||||
|
||||
const migrate = vi.fn((n: number) => n * 2);
|
||||
const item = storage.defineItem<number>(key, {
|
||||
init: () => 1,
|
||||
version: 2,
|
||||
migrations: {
|
||||
2: migrate,
|
||||
},
|
||||
});
|
||||
const value = await item.getValue();
|
||||
const meta = await item.getMeta();
|
||||
|
||||
expect(value).toEqual(2);
|
||||
expect(meta).toEqual({ v: 2 });
|
||||
expect(migrate).toBeCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should call onMigrationComplete callback function if defined', async () => {
|
||||
await fakeBrowser.storage.local.set({
|
||||
count: 2,
|
||||
@@ -1315,6 +1356,18 @@ describe('Storage Utils', () => {
|
||||
});
|
||||
expectTypeOf(item).toEqualTypeOf<WxtStorageItem<number | null, {}>>();
|
||||
});
|
||||
|
||||
it('should define a non-null value when options are passed with a non-null init function', () => {
|
||||
const item = storage.defineItem(`local:test`, {
|
||||
init: () => 123,
|
||||
});
|
||||
expectTypeOf(item).toEqualTypeOf<WxtStorageItem<number, {}>>();
|
||||
|
||||
const item2 = storage.defineItem(`local:test`, {
|
||||
init: () => Promise.resolve(123),
|
||||
});
|
||||
expectTypeOf(item2).toEqualTypeOf<WxtStorageItem<number, {}>>();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+146
-23
@@ -17,6 +17,7 @@ function createStorage(): WxtStorage {
|
||||
sync: createDriver('sync'),
|
||||
managed: createDriver('managed'),
|
||||
};
|
||||
|
||||
const getDriver = (area: StorageArea) => {
|
||||
const driver = drivers[area];
|
||||
if (driver == null) {
|
||||
@@ -25,14 +26,17 @@ function createStorage(): WxtStorage {
|
||||
}
|
||||
return driver;
|
||||
};
|
||||
|
||||
const resolveKey = (key: StorageItemKey) => {
|
||||
const deliminatorIndex = key.indexOf(':');
|
||||
const driverArea = key.substring(0, deliminatorIndex) as StorageArea;
|
||||
|
||||
const driverKey = key.substring(deliminatorIndex + 1);
|
||||
if (driverKey == null)
|
||||
if (driverKey == null) {
|
||||
throw Error(
|
||||
`Storage key should be in the form of "area:key", but received "${key}"`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
driverArea,
|
||||
@@ -40,17 +44,23 @@ function createStorage(): WxtStorage {
|
||||
driver: getDriver(driverArea),
|
||||
};
|
||||
};
|
||||
|
||||
const getMetaKey = (key: string) => key + '$';
|
||||
|
||||
const mergeMeta = (oldMeta: any, newMeta: any): any => {
|
||||
const newFields = { ...oldMeta };
|
||||
|
||||
Object.entries(newMeta).forEach(([key, value]) => {
|
||||
if (value == null) delete newFields[key];
|
||||
else newFields[key] = value;
|
||||
});
|
||||
|
||||
return newFields;
|
||||
};
|
||||
|
||||
const getValueOrFallback = (value: any, fallback: any) =>
|
||||
value ?? fallback ?? null;
|
||||
|
||||
const getMetaValue = (properties: any) =>
|
||||
typeof properties === 'object' && !Array.isArray(properties)
|
||||
? properties
|
||||
@@ -64,11 +74,13 @@ function createStorage(): WxtStorage {
|
||||
const res = await driver.getItem<any>(driverKey);
|
||||
return getValueOrFallback(res, opts?.fallback ?? opts?.defaultValue);
|
||||
};
|
||||
|
||||
const getMeta = async (driver: WxtStorageDriver, driverKey: string) => {
|
||||
const metaKey = getMetaKey(driverKey);
|
||||
const res = await driver.getItem<any>(metaKey);
|
||||
return getMetaValue(res);
|
||||
};
|
||||
|
||||
const setItem = async (
|
||||
driver: WxtStorageDriver,
|
||||
driverKey: string,
|
||||
@@ -76,6 +88,7 @@ function createStorage(): WxtStorage {
|
||||
) => {
|
||||
await driver.setItem(driverKey, value ?? null);
|
||||
};
|
||||
|
||||
const setMeta = async (
|
||||
driver: WxtStorageDriver,
|
||||
driverKey: string,
|
||||
@@ -85,23 +98,27 @@ function createStorage(): WxtStorage {
|
||||
const existingFields = getMetaValue(await driver.getItem(metaKey));
|
||||
await driver.setItem(metaKey, mergeMeta(existingFields, properties));
|
||||
};
|
||||
|
||||
const removeItem = async (
|
||||
driver: WxtStorageDriver,
|
||||
driverKey: string,
|
||||
opts: RemoveItemOptions | undefined,
|
||||
) => {
|
||||
await driver.removeItem(driverKey);
|
||||
|
||||
if (opts?.removeMeta) {
|
||||
const metaKey = getMetaKey(driverKey);
|
||||
await driver.removeItem(metaKey);
|
||||
}
|
||||
};
|
||||
|
||||
const removeMeta = async (
|
||||
driver: WxtStorageDriver,
|
||||
driverKey: string,
|
||||
properties: string | string[] | undefined,
|
||||
) => {
|
||||
const metaKey = getMetaKey(driverKey);
|
||||
|
||||
if (properties == null) {
|
||||
await driver.removeItem(metaKey);
|
||||
} else {
|
||||
@@ -110,19 +127,19 @@ function createStorage(): WxtStorage {
|
||||
await driver.setItem(metaKey, newFields);
|
||||
}
|
||||
};
|
||||
|
||||
const watch = (
|
||||
driver: WxtStorageDriver,
|
||||
driverKey: string,
|
||||
cb: WatchCallback<any>,
|
||||
) => {
|
||||
return driver.watch(driverKey, cb);
|
||||
};
|
||||
) => driver.watch(driverKey, cb);
|
||||
|
||||
const storage: WxtStorage = {
|
||||
return {
|
||||
getItem: async (key, opts) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
return await getItem(driver, driverKey, opts);
|
||||
},
|
||||
|
||||
getItems: async (keys) => {
|
||||
const areaToKeyMap = new Map<StorageArea, string[]>();
|
||||
const keyToOptsMap = new Map<string, GetItemOptions<any> | undefined>();
|
||||
@@ -131,6 +148,7 @@ function createStorage(): WxtStorage {
|
||||
keys.forEach((key) => {
|
||||
let keyStr: StorageItemKey;
|
||||
let opts: GetItemOptions<any> | undefined;
|
||||
|
||||
if (typeof key === 'string') {
|
||||
// key: string
|
||||
keyStr = key;
|
||||
@@ -143,9 +161,11 @@ function createStorage(): WxtStorage {
|
||||
keyStr = key.key;
|
||||
opts = key.options;
|
||||
}
|
||||
|
||||
orderedKeys.push(keyStr);
|
||||
const { driverArea, driverKey } = resolveKey(keyStr);
|
||||
const areaKeys = areaToKeyMap.get(driverArea) ?? [];
|
||||
|
||||
areaToKeyMap.set(driverArea, areaKeys.concat(driverKey));
|
||||
keyToOptsMap.set(keyStr, opts);
|
||||
});
|
||||
@@ -154,6 +174,7 @@ function createStorage(): WxtStorage {
|
||||
await Promise.all(
|
||||
Array.from(areaToKeyMap.entries()).map(async ([driverArea, keys]) => {
|
||||
const driverResults = await drivers[driverArea].getItems(keys);
|
||||
|
||||
driverResults.forEach((driverResult) => {
|
||||
const key = `${driverArea}:${driverResult.key}` as StorageItemKey;
|
||||
const opts = keyToOptsMap.get(key);
|
||||
@@ -161,6 +182,7 @@ function createStorage(): WxtStorage {
|
||||
driverResult.value,
|
||||
opts?.fallback ?? opts?.defaultValue,
|
||||
);
|
||||
|
||||
resultsMap.set(key, value);
|
||||
});
|
||||
}),
|
||||
@@ -171,14 +193,17 @@ function createStorage(): WxtStorage {
|
||||
value: resultsMap.get(key),
|
||||
}));
|
||||
},
|
||||
|
||||
getMeta: async (key) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
return await getMeta(driver, driverKey);
|
||||
},
|
||||
|
||||
getMetas: async (args) => {
|
||||
const keys = args.map((arg) => {
|
||||
const key = typeof arg === 'string' ? arg : arg.key;
|
||||
const { driverArea, driverKey } = resolveKey(key);
|
||||
|
||||
return {
|
||||
key,
|
||||
driverArea,
|
||||
@@ -186,6 +211,7 @@ function createStorage(): WxtStorage {
|
||||
driverMetaKey: getMetaKey(driverKey),
|
||||
};
|
||||
});
|
||||
|
||||
const areaToDriverMetaKeysMap = keys.reduce<
|
||||
Partial<Record<StorageArea, (typeof keys)[number][]>>
|
||||
>((map, key) => {
|
||||
@@ -211,10 +237,12 @@ function createStorage(): WxtStorage {
|
||||
meta: resultsMap[key.key],
|
||||
}));
|
||||
},
|
||||
|
||||
setItem: async (key, value) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
await setItem(driver, driverKey, value);
|
||||
},
|
||||
|
||||
setItems: async (items) => {
|
||||
const areaToKeyValueMap: Partial<
|
||||
Record<StorageArea, Array<{ key: string; value: any }>>
|
||||
@@ -229,6 +257,7 @@ function createStorage(): WxtStorage {
|
||||
value: item.value,
|
||||
});
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
Object.entries(areaToKeyValueMap).map(async ([driverArea, values]) => {
|
||||
const driver = getDriver(driverArea as StorageArea);
|
||||
@@ -236,10 +265,12 @@ function createStorage(): WxtStorage {
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
||||
setMeta: async (key, properties) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
await setMeta(driver, driverKey, properties);
|
||||
},
|
||||
|
||||
setMetas: async (items) => {
|
||||
const areaToMetaUpdatesMap: Partial<
|
||||
Record<StorageArea, { key: string; properties: any }[]>
|
||||
@@ -278,16 +309,19 @@ function createStorage(): WxtStorage {
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
removeItem: async (key, opts) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
await removeItem(driver, driverKey, opts);
|
||||
},
|
||||
|
||||
removeItems: async (keys) => {
|
||||
const areaToKeysMap: Partial<Record<StorageArea, string[]>> = {};
|
||||
|
||||
keys.forEach((key) => {
|
||||
let keyStr: StorageItemKey;
|
||||
let opts: RemoveItemOptions | undefined;
|
||||
|
||||
if (typeof key === 'string') {
|
||||
// key: string
|
||||
keyStr = key;
|
||||
@@ -303,9 +337,11 @@ function createStorage(): WxtStorage {
|
||||
keyStr = key.key;
|
||||
opts = key.options;
|
||||
}
|
||||
|
||||
const { driverArea, driverKey } = resolveKey(keyStr);
|
||||
areaToKeysMap[driverArea] ??= [];
|
||||
areaToKeysMap[driverArea].push(driverKey);
|
||||
|
||||
if (opts?.removeMeta) {
|
||||
areaToKeysMap[driverArea].push(getMetaKey(driverKey));
|
||||
}
|
||||
@@ -318,36 +354,45 @@ function createStorage(): WxtStorage {
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
||||
clear: async (base) => {
|
||||
const driver = getDriver(base);
|
||||
await driver.clear();
|
||||
},
|
||||
|
||||
removeMeta: async (key, properties) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
await removeMeta(driver, driverKey, properties);
|
||||
},
|
||||
|
||||
snapshot: async (base, opts) => {
|
||||
const driver = getDriver(base);
|
||||
const data = await driver.snapshot();
|
||||
|
||||
opts?.excludeKeys?.forEach((key) => {
|
||||
delete data[key];
|
||||
delete data[getMetaKey(key)];
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
restoreSnapshot: async (base, data) => {
|
||||
const driver = getDriver(base);
|
||||
await driver.restoreSnapshot(data);
|
||||
},
|
||||
|
||||
watch: (key, cb) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
return watch(driver, driverKey, cb);
|
||||
},
|
||||
|
||||
unwatch() {
|
||||
Object.values(drivers).forEach((driver) => {
|
||||
driver.unwatch();
|
||||
});
|
||||
},
|
||||
|
||||
defineItem: (key, opts?: WxtStorageItemOptions<any>) => {
|
||||
const { driver, driverKey } = resolveKey(key);
|
||||
|
||||
@@ -357,12 +402,14 @@ function createStorage(): WxtStorage {
|
||||
onMigrationComplete,
|
||||
debug = false,
|
||||
} = opts ?? {};
|
||||
|
||||
if (targetVersion < 1) {
|
||||
throw Error(
|
||||
'Storage item version cannot be less than 1. Initial versions should be set to 1, not 0.',
|
||||
);
|
||||
}
|
||||
const migrate = async () => {
|
||||
|
||||
const migrate: WxtStorageItem<any, any>['migrate'] = async () => {
|
||||
const driverMetaKey = getMetaKey(driverKey);
|
||||
const [{ value }, { value: meta }] = await driver.getItems([
|
||||
driverKey,
|
||||
@@ -376,11 +423,12 @@ function createStorage(): WxtStorage {
|
||||
`Version downgrade detected (v${currentVersion} -> v${targetVersion}) for "${key}"`,
|
||||
);
|
||||
}
|
||||
|
||||
if (currentVersion === targetVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (debug === true) {
|
||||
if (debug) {
|
||||
console.debug(
|
||||
`[@wxt-dev/storage] Running storage migration for ${key}: v${currentVersion} -> v${targetVersion}`,
|
||||
);
|
||||
@@ -395,7 +443,7 @@ function createStorage(): WxtStorage {
|
||||
migratedValue =
|
||||
(await migrations?.[migrateToVersion]?.(migratedValue)) ??
|
||||
migratedValue;
|
||||
if (debug === true) {
|
||||
if (debug) {
|
||||
console.debug(
|
||||
`[@wxt-dev/storage] Storage migration processed for version: v${migrateToVersion}`,
|
||||
);
|
||||
@@ -411,14 +459,16 @@ function createStorage(): WxtStorage {
|
||||
{ key: driverMetaKey, value: { ...meta, v: targetVersion } },
|
||||
]);
|
||||
|
||||
if (debug === true) {
|
||||
if (debug) {
|
||||
console.debug(
|
||||
`[@wxt-dev/storage] Storage migration completed for ${key} v${targetVersion}`,
|
||||
{ migratedValue },
|
||||
);
|
||||
}
|
||||
|
||||
onMigrationComplete?.(migratedValue, targetVersion);
|
||||
};
|
||||
|
||||
const migrationsDone =
|
||||
opts?.migrations == null
|
||||
? Promise.resolve()
|
||||
@@ -441,6 +491,9 @@ function createStorage(): WxtStorage {
|
||||
|
||||
const newValue = await opts.init();
|
||||
await driver.setItem<any>(driverKey, newValue);
|
||||
if (value == null && targetVersion > 1) {
|
||||
await setMeta(driver, driverKey, { v: targetVersion });
|
||||
}
|
||||
return newValue;
|
||||
});
|
||||
|
||||
@@ -449,62 +502,75 @@ function createStorage(): WxtStorage {
|
||||
|
||||
return {
|
||||
key,
|
||||
|
||||
get defaultValue() {
|
||||
return getFallback();
|
||||
},
|
||||
get fallback() {
|
||||
return getFallback();
|
||||
},
|
||||
|
||||
getValue: async () => {
|
||||
await migrationsDone;
|
||||
|
||||
if (opts?.init) {
|
||||
return await getOrInitValue();
|
||||
} else {
|
||||
return await getItem(driver, driverKey, opts);
|
||||
}
|
||||
},
|
||||
|
||||
getMeta: async () => {
|
||||
await migrationsDone;
|
||||
|
||||
return await getMeta(driver, driverKey);
|
||||
},
|
||||
|
||||
setValue: async (value) => {
|
||||
await migrationsDone;
|
||||
|
||||
return await setItem(driver, driverKey, value);
|
||||
},
|
||||
|
||||
setMeta: async (properties) => {
|
||||
await migrationsDone;
|
||||
|
||||
return await setMeta(driver, driverKey, properties);
|
||||
},
|
||||
|
||||
removeValue: async (opts) => {
|
||||
await migrationsDone;
|
||||
|
||||
return await removeItem(driver, driverKey, opts);
|
||||
},
|
||||
|
||||
removeMeta: async (properties) => {
|
||||
await migrationsDone;
|
||||
|
||||
return await removeMeta(driver, driverKey, properties);
|
||||
},
|
||||
|
||||
watch: (cb) =>
|
||||
watch(driver, driverKey, (newValue, oldValue) =>
|
||||
cb(newValue ?? getFallback(), oldValue ?? getFallback()),
|
||||
),
|
||||
|
||||
migrate,
|
||||
};
|
||||
},
|
||||
};
|
||||
return storage;
|
||||
}
|
||||
|
||||
function createDriver(storageArea: StorageArea): WxtStorageDriver {
|
||||
const getStorageArea = () => {
|
||||
if (browser.runtime == null) {
|
||||
throw Error(
|
||||
[
|
||||
"'wxt/storage' must be loaded in a web extension environment",
|
||||
'\n - If thrown during a build, see https://github.com/wxt-dev/wxt/issues/371',
|
||||
" - If thrown during tests, mock 'wxt/browser' correctly. See https://wxt.dev/guide/go-further/testing.html\n",
|
||||
].join('\n'),
|
||||
);
|
||||
throw Error(`'wxt/storage' must be loaded in a web extension environment
|
||||
|
||||
- If thrown during a build, see https://github.com/wxt-dev/wxt/issues/371
|
||||
- If thrown during tests, mock 'wxt/browser' correctly. See https://wxt.dev/guide/go-further/testing.html
|
||||
`);
|
||||
}
|
||||
|
||||
if (browser.storage == null) {
|
||||
throw Error(
|
||||
"You must add the 'storage' permission to your manifest to use 'wxt/storage'",
|
||||
@@ -514,18 +580,23 @@ function createDriver(storageArea: StorageArea): WxtStorageDriver {
|
||||
const area = browser.storage[storageArea];
|
||||
if (area == null)
|
||||
throw Error(`"browser.storage.${storageArea}" is undefined`);
|
||||
|
||||
return area;
|
||||
};
|
||||
|
||||
const watchListeners = new Set<(changes: StorageAreaChanges) => void>();
|
||||
|
||||
return {
|
||||
getItem: async (key) => {
|
||||
const res = await getStorageArea().get(key);
|
||||
const res = await getStorageArea().get<Record<string, any>>(key);
|
||||
return res[key];
|
||||
},
|
||||
|
||||
getItems: async (keys) => {
|
||||
const result = await getStorageArea().get(keys);
|
||||
return keys.map((key) => ({ key, value: result[key] ?? null }));
|
||||
},
|
||||
|
||||
setItem: async (key, value) => {
|
||||
if (value == null) {
|
||||
await getStorageArea().remove(key);
|
||||
@@ -533,6 +604,7 @@ function createDriver(storageArea: StorageArea): WxtStorageDriver {
|
||||
await getStorageArea().set({ [key]: value });
|
||||
}
|
||||
},
|
||||
|
||||
setItems: async (values) => {
|
||||
const map = values.reduce<Record<string, unknown>>(
|
||||
(map, { key, value }) => {
|
||||
@@ -541,37 +613,51 @@ function createDriver(storageArea: StorageArea): WxtStorageDriver {
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
await getStorageArea().set(map);
|
||||
},
|
||||
|
||||
removeItem: async (key) => {
|
||||
await getStorageArea().remove(key);
|
||||
},
|
||||
|
||||
removeItems: async (keys) => {
|
||||
await getStorageArea().remove(keys);
|
||||
},
|
||||
|
||||
clear: async () => {
|
||||
await getStorageArea().clear();
|
||||
},
|
||||
|
||||
snapshot: async () => {
|
||||
return await getStorageArea().get();
|
||||
},
|
||||
|
||||
restoreSnapshot: async (data) => {
|
||||
await getStorageArea().set(data);
|
||||
},
|
||||
|
||||
watch(key, cb) {
|
||||
const listener = (changes: StorageAreaChanges) => {
|
||||
const change = changes[key];
|
||||
if (change == null) return;
|
||||
if (dequal(change.newValue, change.oldValue)) return;
|
||||
const change = changes[key] as {
|
||||
newValue?: any;
|
||||
oldValue?: any | null;
|
||||
} | null;
|
||||
|
||||
if (change == null || dequal(change.newValue, change.oldValue)) return;
|
||||
|
||||
cb(change.newValue ?? null, change.oldValue ?? null);
|
||||
};
|
||||
|
||||
getStorageArea().onChanged.addListener(listener);
|
||||
watchListeners.add(listener);
|
||||
|
||||
return () => {
|
||||
getStorageArea().onChanged.removeListener(listener);
|
||||
watchListeners.delete(listener);
|
||||
};
|
||||
},
|
||||
|
||||
unwatch() {
|
||||
watchListeners.forEach((listener) => {
|
||||
getStorageArea().onChanged.removeListener(listener);
|
||||
@@ -612,6 +698,7 @@ export interface WxtStorage {
|
||||
| { key: StorageItemKey; options?: GetItemOptions<any> }
|
||||
>,
|
||||
): Promise<Array<{ key: StorageItemKey; value: any }>>;
|
||||
|
||||
/**
|
||||
* Return an object containing metadata about the key. Object is stored at `key + "$"`. If value
|
||||
* is not an object, it returns an empty object.
|
||||
@@ -620,15 +707,17 @@ export interface WxtStorage {
|
||||
* await storage.getMeta("local:installDate");
|
||||
*/
|
||||
getMeta<T extends Record<string, unknown>>(key: StorageItemKey): Promise<T>;
|
||||
|
||||
/**
|
||||
* Get the metadata of multiple storage items.
|
||||
*
|
||||
* @param items List of keys or items to get the metadata of.
|
||||
* @param keys List of keys or items to get the metadata of.
|
||||
* @returns An array containing storage keys and their metadata.
|
||||
*/
|
||||
getMetas(
|
||||
keys: Array<StorageItemKey | WxtStorageItem<any, any>>,
|
||||
): Promise<Array<{ key: StorageItemKey; meta: any }>>;
|
||||
|
||||
/**
|
||||
* Set a value in storage. Setting a value to `null` or `undefined` is equivalent to calling
|
||||
* `removeItem`.
|
||||
@@ -637,6 +726,7 @@ export interface WxtStorage {
|
||||
* await storage.setItem<number>("local:installDate", Date.now());
|
||||
*/
|
||||
setItem<T>(key: StorageItemKey, value: T | null): Promise<void>;
|
||||
|
||||
/**
|
||||
* Set multiple values in storage. If a value is set to `null` or `undefined`, the key is removed.
|
||||
*
|
||||
@@ -652,6 +742,7 @@ export interface WxtStorage {
|
||||
| { item: WxtStorageItem<any, any>; value: any }
|
||||
>,
|
||||
): Promise<void>;
|
||||
|
||||
/**
|
||||
* Sets metadata properties. If some properties are already set, but are not included in the
|
||||
* `properties` parameter, they will not be removed.
|
||||
@@ -663,10 +754,11 @@ export interface WxtStorage {
|
||||
key: StorageItemKey,
|
||||
properties: T | null,
|
||||
): Promise<void>;
|
||||
|
||||
/**
|
||||
* Set the metadata of multiple storage items.
|
||||
*
|
||||
* @param items List of storage keys or items and metadata to set for each.
|
||||
* @param metas List of storage keys or items and metadata to set for each.
|
||||
*/
|
||||
setMetas(
|
||||
metas: Array<
|
||||
@@ -674,6 +766,7 @@ export interface WxtStorage {
|
||||
| { item: WxtStorageItem<any, any>; meta: Record<string, any> }
|
||||
>,
|
||||
): Promise<void>;
|
||||
|
||||
/**
|
||||
* Removes an item from storage.
|
||||
*
|
||||
@@ -681,6 +774,7 @@ export interface WxtStorage {
|
||||
* await storage.removeItem("local:installDate");
|
||||
*/
|
||||
removeItem(key: StorageItemKey, opts?: RemoveItemOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Remove a list of keys from storage.
|
||||
*/
|
||||
@@ -712,6 +806,7 @@ export interface WxtStorage {
|
||||
key: StorageItemKey,
|
||||
properties?: string | string[],
|
||||
): Promise<void>;
|
||||
|
||||
/**
|
||||
* Return all the items in storage.
|
||||
*/
|
||||
@@ -719,15 +814,18 @@ export interface WxtStorage {
|
||||
base: StorageArea,
|
||||
opts?: SnapshotOptions,
|
||||
): Promise<Record<string, unknown>>;
|
||||
|
||||
/**
|
||||
* Restores the results of `snapshot`. If new properties have been saved since the snapshot, they are
|
||||
* not overridden. Only values existing in the snapshot are overridden.
|
||||
*/
|
||||
restoreSnapshot(base: StorageArea, data: any): Promise<void>;
|
||||
|
||||
/**
|
||||
* Watch for changes to a specific key in storage.
|
||||
*/
|
||||
watch<T>(key: StorageItemKey, cb: WatchCallback<T | null>): Unwatch;
|
||||
|
||||
/**
|
||||
* Remove all watch listeners.
|
||||
*/
|
||||
@@ -749,6 +847,12 @@ export interface WxtStorage {
|
||||
key: StorageItemKey,
|
||||
options: WxtStorageItemOptions<TValue> & { defaultValue: TValue },
|
||||
): WxtStorageItem<TValue, TMetadata>;
|
||||
defineItem<TValue, TMetadata extends Record<string, unknown> = {}>(
|
||||
key: StorageItemKey,
|
||||
options: WxtStorageItemOptions<TValue> & {
|
||||
init: () => TValue | Promise<TValue>;
|
||||
},
|
||||
): WxtStorageItem<TValue, TMetadata>;
|
||||
defineItem<TValue, TMetadata extends Record<string, unknown> = {}>(
|
||||
key: StorageItemKey,
|
||||
options: WxtStorageItemOptions<TValue>,
|
||||
@@ -777,42 +881,52 @@ export interface WxtStorageItem<
|
||||
* The storage key passed when creating the storage item.
|
||||
*/
|
||||
key: StorageItemKey;
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to fallback, use it instead.
|
||||
*/
|
||||
defaultValue: TValue;
|
||||
|
||||
/**
|
||||
* The value provided by the `fallback` option.
|
||||
*/
|
||||
fallback: TValue;
|
||||
|
||||
/**
|
||||
* Get the latest value from storage.
|
||||
*/
|
||||
getValue(): Promise<TValue>;
|
||||
|
||||
/**
|
||||
* Get metadata.
|
||||
*/
|
||||
getMeta(): Promise<NullablePartial<TMetadata>>;
|
||||
|
||||
/**
|
||||
* Set the value in storage.
|
||||
*/
|
||||
setValue(value: TValue): Promise<void>;
|
||||
|
||||
/**
|
||||
* Set metadata properties.
|
||||
*/
|
||||
setMeta(properties: NullablePartial<TMetadata>): Promise<void>;
|
||||
|
||||
/**
|
||||
* Remove the value from storage.
|
||||
*/
|
||||
removeValue(opts?: RemoveItemOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Remove all metadata or certain properties from metadata.
|
||||
*/
|
||||
removeMeta(properties?: string[]): Promise<void>;
|
||||
|
||||
/**
|
||||
* Listen for changes to the value in storage.
|
||||
*/
|
||||
watch(cb: WatchCallback<TValue>): Unwatch;
|
||||
|
||||
/**
|
||||
* If there are migrations defined on the storage item, migrate to the latest version.
|
||||
*
|
||||
@@ -830,6 +944,7 @@ export interface GetItemOptions<T> {
|
||||
* @deprecated Renamed to `fallback`, use it instead.
|
||||
*/
|
||||
defaultValue?: T;
|
||||
|
||||
/**
|
||||
* Default value returned when `getItem` would otherwise return `null`.
|
||||
*/
|
||||
@@ -858,10 +973,12 @@ export interface WxtStorageItemOptions<T> {
|
||||
* @deprecated Renamed to `fallback`, use it instead.
|
||||
*/
|
||||
defaultValue?: T;
|
||||
|
||||
/**
|
||||
* Default value returned when `getValue` would otherwise return `null`.
|
||||
*/
|
||||
fallback?: T;
|
||||
|
||||
/**
|
||||
* If passed, a value in storage will be initialized immediately after
|
||||
* defining the storage item. This function returns the value that will be
|
||||
@@ -869,20 +986,24 @@ export interface WxtStorageItemOptions<T> {
|
||||
* already exist.
|
||||
*/
|
||||
init?: () => T | Promise<T>;
|
||||
|
||||
/**
|
||||
* Provide a version number for the storage item to enable migrations. When changing the version
|
||||
* in the future, migration functions will be ran on application startup.
|
||||
*/
|
||||
version?: number;
|
||||
|
||||
/**
|
||||
* A map of version numbers to the functions used to migrate the data to that version.
|
||||
*/
|
||||
migrations?: Record<number, (oldValue: any) => any>;
|
||||
|
||||
/**
|
||||
* Print debug logs, such as migration process.
|
||||
* @default false
|
||||
*/
|
||||
debug?: boolean;
|
||||
|
||||
/**
|
||||
* A callback function that runs on migration complete.
|
||||
*/
|
||||
@@ -900,10 +1021,12 @@ export type StorageAreaChanges = {
|
||||
type NullablePartial<T> = {
|
||||
[key in keyof T]+?: T[key] | undefined | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback called when a value in storage is changed.
|
||||
*/
|
||||
export type WatchCallback<T> = (newValue: T, oldValue: T) => void;
|
||||
|
||||
/**
|
||||
* Call to remove a watch listener
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
@@ -32,7 +32,7 @@
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"check": "buildc --deps-only -- check"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -40,11 +40,9 @@
|
||||
"wxt": ">=0.19.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"oxlint": "^0.16.8",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"oxlint": "^1.43.0",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"unocss": "^0.64.0 || ^0.65.0 || ^65.0.0 || ^66.0.0",
|
||||
"wxt": "workspace:*"
|
||||
},
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
export default defineBuildConfig({
|
||||
rootDir: resolve(__dirname, 'modules/webextension-polyfill'),
|
||||
outDir: resolve(__dirname, 'dist'),
|
||||
entries: [
|
||||
{ input: 'index.ts', name: 'index' },
|
||||
{ input: 'browser.ts', name: 'browser' },
|
||||
],
|
||||
replace: {
|
||||
'process.env.NPM': 'true',
|
||||
},
|
||||
declaration: true,
|
||||
});
|
||||
@@ -20,7 +20,7 @@
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"types": "./dist/index.d.mts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
@@ -37,7 +37,7 @@
|
||||
"scripts": {
|
||||
"dev": "wxt",
|
||||
"check": "pnpm build && check",
|
||||
"build": "buildc -- unbuild",
|
||||
"build": "buildc -- tsdown",
|
||||
"prepare": "buildc --deps-only -- wxt prepare"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -45,11 +45,9 @@
|
||||
"wxt": ">=0.20.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aklinker1/check": "2.0.0",
|
||||
"@types/webextension-polyfill": "^0.12.3",
|
||||
"publint": "^0.3.12",
|
||||
"typescript": "^5.8.3",
|
||||
"unbuild": "^3.5.0",
|
||||
"@types/webextension-polyfill": "^0.12.4",
|
||||
"publint": "^0.3.17",
|
||||
"typescript": "^5.9.3",
|
||||
"webextension-polyfill": "^0.12.0",
|
||||
"wxt": "workspace:*"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { defineConfig } from 'tsdown';
|
||||
|
||||
export default defineConfig({
|
||||
entry: {
|
||||
index: 'modules/webextension-polyfill/index.ts',
|
||||
browser: 'modules/webextension-polyfill/browser.ts',
|
||||
},
|
||||
define: {
|
||||
'process.env.NPM': 'true',
|
||||
},
|
||||
});
|
||||
@@ -18,19 +18,19 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@wxt-dev/i18n": "workspace:*",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0"
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.3",
|
||||
"@types/react": "^19.2.13",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@wxt-dev/auto-icons": "workspace:*",
|
||||
"@wxt-dev/unocss": "workspace:*",
|
||||
"sass": "^1.87.0",
|
||||
"typescript": "^5.8.3",
|
||||
"sass": "^1.97.3",
|
||||
"typescript": "^5.9.3",
|
||||
"unocss": "^0.64.0 || ^0.65.0 || ^65.0.0 || ^66.0.0",
|
||||
"vitest": "^3.1.2",
|
||||
"vitest-plugin-random-seed": "^1.1.1",
|
||||
"vitest": "^4.0.18",
|
||||
"vitest-plugin-random-seed": "^1.1.2",
|
||||
"wxt": "workspace:*"
|
||||
},
|
||||
"buildc": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { defineConfig } from 'wxt';
|
||||
import { presetUno } from 'unocss';
|
||||
import { presetWind3 } from 'unocss';
|
||||
|
||||
export default defineConfig({
|
||||
srcDir: 'src',
|
||||
@@ -53,7 +53,7 @@ export default defineConfig({
|
||||
],
|
||||
},
|
||||
},
|
||||
presets: [presetUno()],
|
||||
presets: [presetWind3()],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,5 +1,296 @@
|
||||
# Changelog
|
||||
|
||||
## v0.20.17
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.16...wxt-v0.20.17)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Update left-over CJS require of `publish-browser-extension` to ESM ([#2120](https://github.com/wxt-dev/wxt/pull/2120))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
|
||||
## v0.20.16
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.15...wxt-v0.20.16)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Revert "rename `name` to `names` prop of `rollup` to fix deprecated warning " ([#2106](https://github.com/wxt-dev/wxt/pull/2106))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Speed up E2E tests by skipping `pnpm install` when possible ([#2113](https://github.com/wxt-dev/wxt/pull/2113))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
|
||||
## v0.20.15
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.14...wxt-v0.20.15)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Export `normalizePath` from `wxt` module ([#2080](https://github.com/wxt-dev/wxt/pull/2080))
|
||||
- **popup:** Add Firefox `default_area` and `theme_icons` support ([#2097](https://github.com/wxt-dev/wxt/pull/2097))
|
||||
- Add log `--level` cli option ([#1973](https://github.com/wxt-dev/wxt/pull/1973))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Content script is incorrectly invalidated when injected multiple times ([#2035](https://github.com/wxt-dev/wxt/pull/2035))
|
||||
- Use `uiContainer` to apply position when creating shadow root ui ([#2036](https://github.com/wxt-dev/wxt/pull/2036))
|
||||
- Make `ExtensionRunner#closeBrowser` optional ([#2092](https://github.com/wxt-dev/wxt/pull/2092))
|
||||
- Rename `name` to `names` prop of `rollup` to fix deprecated warning ([#2106](https://github.com/wxt-dev/wxt/pull/2106))
|
||||
|
||||
### 💅 Refactors
|
||||
|
||||
- Standardize file existence checks to `pathExists` ([#2083](https://github.com/wxt-dev/wxt/pull/2083))
|
||||
- Cleanup esm ([#1950](https://github.com/wxt-dev/wxt/pull/1950))
|
||||
- `async`/`await` cleanup ([#2088](https://github.com/wxt-dev/wxt/pull/2088))
|
||||
- Cleanup unnecssary checks ([#2089](https://github.com/wxt-dev/wxt/pull/2089))
|
||||
- Simplify import paths ([#2093](https://github.com/wxt-dev/wxt/pull/2093))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Fix JSDoc ([6ae5fb5e](https://github.com/wxt-dev/wxt/commit/6ae5fb5e))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Cleanup comment line lengths ([#2090](https://github.com/wxt-dev/wxt/pull/2090))
|
||||
- Cleanup `@ts-*` comments ([#2094](https://github.com/wxt-dev/wxt/pull/2094))
|
||||
- Update JSDoc to use `@internal` ([#2091](https://github.com/wxt-dev/wxt/pull/2091))
|
||||
- Fix typos ([#2086](https://github.com/wxt-dev/wxt/pull/2086))
|
||||
- Remove unused code ([#2087](https://github.com/wxt-dev/wxt/pull/2087))
|
||||
- Simplify imports of `cli/__tests__/index.ts` ([#2104](https://github.com/wxt-dev/wxt/pull/2104))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Nick Doan ([@nickbar01234](https://github.com/nickbar01234))
|
||||
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Wotan-allfather <wotan-ai@proton.me>
|
||||
- Namu ([@namuorg](https://github.com/namuorg))
|
||||
- Eli ([@lishaduck](https://github.com/lishaduck))
|
||||
|
||||
## v0.20.14
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.13...wxt-v0.20.14)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Add `onBeforeMount` callback to `createIframeUi` options ([#1899](https://github.com/wxt-dev/wxt/pull/1899))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Remove failing test ([6fb4cee4](https://github.com/wxt-dev/wxt/commit/6fb4cee4))
|
||||
- Rename and make firefoxPrefs in web-ext.config.ts work ([#2068](https://github.com/wxt-dev/wxt/pull/2068))
|
||||
- **content-script-context:** Handle undefined browser.runtime ([#2042](https://github.com/wxt-dev/wxt/pull/2042))
|
||||
- `MaxListenersExceededWarning` ([#2058](https://github.com/wxt-dev/wxt/pull/2058))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Fix alignment of 2 last comments of regex patterns ([#2012](https://github.com/wxt-dev/wxt/pull/2012))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Use `tsdown` to build packages ([#2006](https://github.com/wxt-dev/wxt/pull/2006))
|
||||
- Move script-only dev dependencies to top-level `package.json` ([#2007](https://github.com/wxt-dev/wxt/pull/2007))
|
||||
- Update dependencies ([#2069](https://github.com/wxt-dev/wxt/pull/2069))
|
||||
- Upgrade major deps ([#2070](https://github.com/wxt-dev/wxt/pull/2070))
|
||||
- Refresh lockfile and upgrade subdependencies ([#2071](https://github.com/wxt-dev/wxt/pull/2071))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Dareka ([@darekadareka](https://github.com/darekadareka))
|
||||
- Mark ([@mjfaga](https://github.com/mjfaga))
|
||||
- ariasuni ([@ariasuni](https://github.com/ariasuni))
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
|
||||
- Bohuslavsemenov ([@bohuslavsemenov](https://github.com/bohuslavsemenov))
|
||||
|
||||
## v0.20.13
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.12...wxt-v0.20.13)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Remove script element immediately in injectScript ([#1761](https://github.com/wxt-dev/wxt/pull/1761))
|
||||
- Add `modifyScript` option to `injectScript` ([#1762](https://github.com/wxt-dev/wxt/pull/1762))
|
||||
- Make `injectScript` return the created script element ([#1838](https://github.com/wxt-dev/wxt/pull/1838))
|
||||
- Support `.wxtrc` config file ([#1833](https://github.com/wxt-dev/wxt/pull/1833))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Make `injectScript` wait until script is actually loaded ([#1763](https://github.com/wxt-dev/wxt/pull/1763))
|
||||
- Don't return promises from unlisted scripts that do not have an async `main` function ([#1907](https://github.com/wxt-dev/wxt/pull/1907))
|
||||
|
||||
### 💅 Refactors
|
||||
|
||||
- Use `script.text` instead of `innerHTML` in `injectScript` ([#1764](https://github.com/wxt-dev/wxt/pull/1764))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Rxliuli ([@rxliuli](https://github.com/rxliuli))
|
||||
- Sebastian Landwehr <info@sebastianlandwehr.com>
|
||||
- Johan Kiviniemi ([@ion1](https://github.com/ion1))
|
||||
|
||||
## v0.20.12
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.11...wxt-v0.20.12)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Remove `data-wxt-*` attributes ([#1913](https://github.com/wxt-dev/wxt/pull/1913))
|
||||
- Default to using `use_dynamic_url: true` for content script css files ([#1993](https://github.com/wxt-dev/wxt/pull/1993))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Wxt normal logs are drowned by `dotenv@17.0.0` ads ([#1883](https://github.com/wxt-dev/wxt/pull/1883))
|
||||
- Optimize `splitShadowRootCss` ([#1934](https://github.com/wxt-dev/wxt/pull/1934))
|
||||
- `wxt prepare` fails with the error "__vite_ssr_exportName__ is not defined" when using Vite 7 ([#1884](https://github.com/wxt-dev/wxt/pull/1884))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Use `linkedom` a test instead of `happy-dom` ([#1957](https://github.com/wxt-dev/wxt/pull/1957))
|
||||
- Add support for `vite-node` v5 ([#2001](https://github.com/wxt-dev/wxt/pull/2001))
|
||||
- Upgrade dev and non-major prod dependencies ([#2000](https://github.com/wxt-dev/wxt/pull/2000))
|
||||
- **dev-deps:** Upgrade `happy-dom` to address CVE-2025-61927 ([#2002](https://github.com/wxt-dev/wxt/pull/2002))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Jaguar Zhou ([@aiktb](https://github.com/aiktb))
|
||||
- Alexander Harding <noreply@harding.dev>
|
||||
- Florian Kühne ([@ZerGo0](https://github.com/ZerGo0))
|
||||
|
||||
## v0.20.11
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.10...wxt-v0.20.11)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Split `wxt/testing` into separate modules to fix issues with `jsdom` and `happy-dom` ([#1844](https://github.com/wxt-dev/wxt/pull/1844))
|
||||
- `input_components` is supported by mv3 ([#1881](https://github.com/wxt-dev/wxt/pull/1881))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps:** Upgrade project subdependencies ([#1882](https://github.com/wxt-dev/wxt/pull/1882))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Qijia Liu <liumeo@pku.edu.cn>
|
||||
- Marcellino Ornelas ([@marcellino-ornelas](https://github.com/marcellino-ornelas))
|
||||
|
||||
## v0.20.10
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.9...wxt-v0.20.10)
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps:** Upgrade non-breaking production dependencies ([#1877](https://github.com/wxt-dev/wxt/pull/1877))
|
||||
- **deps:** Upgrade web-ext-run to support CDP ([#1879](https://github.com/wxt-dev/wxt/pull/1879))
|
||||
- **deps:** `publish-browser-extension` upgrade ([#1880](https://github.com/wxt-dev/wxt/pull/1880))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
|
||||
## v0.20.9
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.8...wxt-v0.20.9)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- **types:** Use TType for DocumentEventMap key in ctx.addEventListener ([#1863](https://github.com/wxt-dev/wxt/pull/1863))
|
||||
- Prevent Unlisted CSS from being excluded in the build when using CSS preprocessor ([#1590](https://github.com/wxt-dev/wxt/pull/1590))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- **deps:** Upgrade oxlint from 0.16.8 to 1.14.0 ([a01928e0](https://github.com/wxt-dev/wxt/commit/a01928e0))
|
||||
- **deps:** Upgrade typescript from 5.8.3 to 5.9.2 ([a6eef643](https://github.com/wxt-dev/wxt/commit/a6eef643))
|
||||
- Upgrade nano-spawn to v1 ([5fefd8e0](https://github.com/wxt-dev/wxt/commit/5fefd8e0))
|
||||
- Upgrade faker to v10 ([984568e0](https://github.com/wxt-dev/wxt/commit/984568e0))
|
||||
- Upgrade dotenv to v17.2.2 ([380a9630](https://github.com/wxt-dev/wxt/commit/380a9630))
|
||||
- Upgrade happy-dom to v18.0.1 ([c1c3d3b7](https://github.com/wxt-dev/wxt/commit/c1c3d3b7))
|
||||
- Create script for managing dependency upgrades ([#1875](https://github.com/wxt-dev/wxt/pull/1875))
|
||||
- **deps:** Upgrade all dev dependencies ([#1876](https://github.com/wxt-dev/wxt/pull/1876))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Kim Gyeongjae ([@PortalCube](https://github.com/PortalCube))
|
||||
- Atomie CHEN <atomic_cwh@163.com>
|
||||
|
||||
## v0.20.8
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.7...wxt-v0.20.8)
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Support http server websocket inside containers ([#1707](https://github.com/wxt-dev/wxt/pull/1707))
|
||||
- Recreating keyboardShortcuts interface on file changes. ([#1465](https://github.com/wxt-dev/wxt/pull/1465))
|
||||
- Fix bad regex from #1707 ([#1712](https://github.com/wxt-dev/wxt/pull/1712), [#1707](https://github.com/wxt-dev/wxt/issues/1707))
|
||||
- Fix bundle variable assignment error with `rolldown-vite` ([#1715](https://github.com/wxt-dev/wxt/pull/1715))
|
||||
- Support negation patterns when including/excluding files from ZIP files ([#1517](https://github.com/wxt-dev/wxt/pull/1517))
|
||||
- **rolldown-compat:** Only apply footer to content and unlisted scripts via plugin ([#1793](https://github.com/wxt-dev/wxt/pull/1793))
|
||||
- Init project should allow the .git folder to exist ([#1731](https://github.com/wxt-dev/wxt/pull/1731))
|
||||
- Adding missing chromiumPort parameter in web-ext.ts to enable fixed port debugging ([#1818](https://github.com/wxt-dev/wxt/pull/1818))
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Fix API reference sidebar by naming new module ([eb0bffb5](https://github.com/wxt-dev/wxt/commit/eb0bffb5))
|
||||
- Update JSDoc with ways to cancel timeouts and intervals set by content script context ([030f23d2](https://github.com/wxt-dev/wxt/commit/030f23d2))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Fix auto-fixable `markdownlint` errors ([#1710](https://github.com/wxt-dev/wxt/pull/1710))
|
||||
- Remove automd ([7d25110a](https://github.com/wxt-dev/wxt/commit/7d25110a))
|
||||
- Wxt & @wxt-dev/module-vue support Vite 7 ([#1771](https://github.com/wxt-dev/wxt/pull/1771))
|
||||
- Fix type error ([0333ce5c](https://github.com/wxt-dev/wxt/commit/0333ce5c))
|
||||
|
||||
### 🤖 CI
|
||||
|
||||
- Use matrix for test jobs ([#1708](https://github.com/wxt-dev/wxt/pull/1708))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Sylva <sylvain.lavabre@live.fr>
|
||||
- Btea ([@btea](https://github.com/btea))
|
||||
- Patryk Kuniczak ([@PatrykKuniczak](https://github.com/PatrykKuniczak))
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Ayu ([@ayu-exorcist](https://github.com/ayu-exorcist))
|
||||
- Nishu ([@nishu-murmu](https://github.com/nishu-murmu))
|
||||
|
||||
## v0.20.7
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.6...wxt-v0.20.7)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Add `@font-face` to be processed by `splitShadowRootCss` ([#1635](https://github.com/wxt-dev/wxt/pull/1635))
|
||||
- Add DisableLoadExtensionCommandLineSwitch flag to Chromium runner ([#1698](https://github.com/wxt-dev/wxt/pull/1698))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Improve CSS reset inside shadow roots ([da5cd325](https://github.com/wxt-dev/wxt/commit/da5cd325))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Stop using PNPM catalog ([#1644](https://github.com/wxt-dev/wxt/pull/1644))
|
||||
- Upgrade `@aklinker1/check` to v2 ([#1647](https://github.com/wxt-dev/wxt/pull/1647))
|
||||
- **deps:** Update all dependencies ([#1648](https://github.com/wxt-dev/wxt/pull/1648))
|
||||
- Change browser workspace dependency to `^` ([c7335add](https://github.com/wxt-dev/wxt/commit/c7335add))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Richard Lee ([@dlackty](https://github.com/dlackty))
|
||||
- Aaron ([@aklinker1](https://github.com/aklinker1))
|
||||
- Seaders ([@seaders](https://github.com/seaders))
|
||||
|
||||
## v0.20.6
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.20.5...wxt-v0.20.6)
|
||||
|
||||
+18
-44
@@ -1,51 +1,33 @@
|
||||
<!-- DO NOT EDIT, THIS FILE WAS GENERATED BY '../../scripts/generate-readmes.sh' -->
|
||||
<h1 align="center">
|
||||
<img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo">
|
||||
<span>WXT</span>
|
||||
</h1>
|
||||
<div align="center">
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="npm version" src="https://img.shields.io/npm/v/wxt?labelColor=black&color=%234fa048"></a>
|
||||
<span> </span>
|
||||
<a href="https://www.npmjs.com/package/wxt" target="_blank"><img alt="downloads" src="https://img.shields.io/npm/dm/wxt?labelColor=black&color=%234fa048"></a>
|
||||
<span> </span>
|
||||
<a href="https://github.com/wxt-dev/wxt/blob/main/LICENSE" target="_blank"><img alt="license | MIT" src="https://img.shields.io/npm/l/wxt?labelColor=black&color=%234fa048"></a>
|
||||
<span> </span>
|
||||
<a href="https://codecov.io/github/wxt-dev/wxt" target="_blank"><img alt="coverage" src="https://img.shields.io/codecov/c/github/wxt-dev/wxt?labelColor=black&color=%234fa048"></a>
|
||||
</p>
|
||||
# <img align="top" width="44" src="https://raw.githubusercontent.com/wxt-dev/wxt/HEAD/docs/public/hero-logo.svg" alt="WXT Logo"> WXT
|
||||
|
||||
<p align="center">
|
||||
<span>Next-gen framework for developing web extensions.</span>
|
||||
<br/>
|
||||
<span>⚡</span>
|
||||
<br/>
|
||||
<q><i>It's like Nuxt, but for Web Extensions</i></q>
|
||||
</p>
|
||||
[](https://www.npmjs.com/package/wxt)
|
||||
[](https://www.npmjs.com/package/wxt)
|
||||
[](https://github.com/wxt-dev/wxt/blob/main/LICENSE)
|
||||
[](https://codecov.io/github/wxt-dev/wxt)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://wxt.dev/guide/installation.html" target="_blank">Get Started</a>
|
||||
•
|
||||
<a href="https://wxt.dev/api/config.html" target="_blank">Configuration</a>
|
||||
•
|
||||
<a href="https://wxt.dev/examples.html" target="_blank">Examples</a>
|
||||
•
|
||||
<a href="https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md" target="_blank">Changelog</a>
|
||||
•
|
||||
<a href="https://discord.gg/ZFsZqGery9" target="_blank">Discord</a>
|
||||
</p>
|
||||
Next-gen framework for developing web extensions.<br/>⚡<br/><q><i>It's like Nuxt, but for Web Extensions</i></q>
|
||||
|
||||
[Get Started](https://wxt.dev/guide/installation.html) •
|
||||
[Configuration](https://wxt.dev/api/config.html) •
|
||||
[Examples](https://wxt.dev/examples.html) •
|
||||
[Changelog](https://github.com/wxt-dev/wxt/blob/main/packages/wxt/CHANGELOG.md) •
|
||||
[Discord](https://discord.gg/ZFsZqGery9)
|
||||
|
||||
</div>
|
||||
|
||||

|
||||
|
||||
## Demo
|
||||
|
||||
https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94
|
||||
<https://github.com/wxt-dev/wxt/assets/10101283/4d678939-1bdb-495c-9c36-3aa281d84c94>
|
||||
|
||||
## Quick Start
|
||||
|
||||
Bootstrap a new project:
|
||||
|
||||
<!-- automd:pm-x version="latest" name="wxt" args="init" -->
|
||||
|
||||
```sh
|
||||
# npm
|
||||
npx wxt@latest init
|
||||
@@ -57,8 +39,6 @@ pnpm dlx wxt@latest init
|
||||
bunx wxt@latest init
|
||||
```
|
||||
|
||||
<!-- /automd -->
|
||||
|
||||
Or see the [installation guide](https://wxt.dev/guide/installation.html) to get started with WXT.
|
||||
|
||||
## Features
|
||||
@@ -80,17 +60,11 @@ Or see the [installation guide](https://wxt.dev/guide/installation.html) to get
|
||||
|
||||
WXT is a [MIT-licensed](https://github.com/wxt-dev/wxt/blob/main/LICENSE) open source project with its ongoing development made possible entirely by the support of these awesome backers. If you'd like to join them, please consider [sponsoring WXT's development](https://github.com/sponsors/wxt-dev).
|
||||
|
||||
<a href="https://github.com/sponsors/wxt-dev"><img alt="WXT Sponsors" src="https://raw.githubusercontent.com/wxt-dev/static/refs/heads/main/sponsorkit/sponsors.svg"></a>
|
||||
[](https://github.com/sponsors/wxt-dev)
|
||||
|
||||
## Contributors
|
||||
|
||||
<!-- automd:contributors author="aklinker1" license="MIT" github="wxt-dev/wxt" -->
|
||||
|
||||
Published under the [MIT](https://github.com/wxt-dev/wxt/blob/main/LICENSE) license.
|
||||
Made by [@aklinker1](https://github.com/aklinker1) and [community](https://github.com/wxt-dev/wxt/graphs/contributors) 💛
|
||||
<br><br>
|
||||
<a href="https://github.com/wxt-dev/wxt/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=wxt-dev/wxt" />
|
||||
</a>
|
||||
|
||||
<!-- /automd -->
|
||||
[](https://github.com/wxt-dev/wxt/graphs/contributors)
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@
|
||||
* `publish-browser-extension` as a direct dependency (like for PNPM, which doesn't link
|
||||
* sub-dependency binaries to "node_modules/.bin")
|
||||
*/
|
||||
require('publish-browser-extension/cli');
|
||||
import 'publish-browser-extension/cli';
|
||||
@@ -1,46 +0,0 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
import { version, exports } from './package.json';
|
||||
import { readFile, writeFile } from 'fs/promises';
|
||||
import {
|
||||
virtualEntrypointModuleNames,
|
||||
virtualModuleNames,
|
||||
} from './src/core/utils/virtual-modules';
|
||||
|
||||
export default defineBuildConfig([
|
||||
// Non-virtual modules can be transpiled with mkdist
|
||||
{
|
||||
entries: [
|
||||
{
|
||||
builder: 'mkdist',
|
||||
input: 'src',
|
||||
pattern: ['**/*', '!**/__tests__', '!**/*.md', '!virtual', '!@types'],
|
||||
declaration: true,
|
||||
},
|
||||
],
|
||||
hooks: {
|
||||
async 'build:done'() {
|
||||
// Replace any template variables in output files
|
||||
await replaceVars('dist/version.mjs', { version });
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Virtual modules must be bundled individually
|
||||
...virtualModuleNames.map((moduleName) => ({
|
||||
entries: [`src/virtual/${moduleName}.ts`],
|
||||
externals: [
|
||||
...virtualEntrypointModuleNames.map((name) => `virtual:user-${name}`),
|
||||
'virtual:wxt-plugins',
|
||||
'virtual:app-config',
|
||||
...Object.keys(exports).map((path) => 'wxt' + path.slice(1)), // ./utils/storage => wxt/utils/storage
|
||||
],
|
||||
})),
|
||||
]);
|
||||
|
||||
async function replaceVars(file: string, vars: Record<string, string>) {
|
||||
let text = await readFile(file, 'utf8');
|
||||
Object.entries(vars).forEach(([name, value]) => {
|
||||
text = text.replaceAll(`{{${name}}}`, value);
|
||||
});
|
||||
await writeFile(file, text, 'utf8');
|
||||
}
|
||||
@@ -30,8 +30,8 @@ describe('Analysis', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(await project.fileExists('stats.html')).toBe(true);
|
||||
expect(await project.fileExists('.output/chrome-mv3/stats-0.json')).toBe(
|
||||
expect(await project.pathExists('stats.html')).toBe(true);
|
||||
expect(await project.pathExists('.output/chrome-mv3/stats-0.json')).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
@@ -52,9 +52,9 @@ describe('Analysis', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(await project.fileExists('stats.html')).toBe(true);
|
||||
expect(await project.fileExists('stats-0.json')).toBe(true);
|
||||
expect(await project.fileExists('stats-1.json')).toBe(true);
|
||||
expect(await project.pathExists('stats.html')).toBe(true);
|
||||
expect(await project.pathExists('stats-0.json')).toBe(true);
|
||||
expect(await project.pathExists('stats-1.json')).toBe(true);
|
||||
});
|
||||
|
||||
it('should support customizing the stats output directory', async () => {
|
||||
@@ -73,7 +73,7 @@ describe('Analysis', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(await project.fileExists('stats/bundle.html')).toBe(true);
|
||||
expect(await project.pathExists('stats/bundle.html')).toBe(true);
|
||||
});
|
||||
|
||||
it('should place artifacts next to the custom output file', async () => {
|
||||
@@ -93,9 +93,9 @@ describe('Analysis', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(await project.fileExists('stats/bundle.html')).toBe(true);
|
||||
expect(await project.fileExists('stats/bundle-0.json')).toBe(true);
|
||||
expect(await project.fileExists('stats/bundle-1.json')).toBe(true);
|
||||
expect(await project.pathExists('stats/bundle.html')).toBe(true);
|
||||
expect(await project.pathExists('stats/bundle-0.json')).toBe(true);
|
||||
expect(await project.pathExists('stats/bundle-1.json')).toBe(true);
|
||||
});
|
||||
|
||||
it('should open the stats in the browser when requested', async () => {
|
||||
|
||||
@@ -17,22 +17,22 @@ describe('Auto Imports', () => {
|
||||
// Generated by wxt
|
||||
export {}
|
||||
declare global {
|
||||
const ContentScriptContext: typeof import('wxt/utils/content-script-context')['ContentScriptContext']
|
||||
const InvalidMatchPattern: typeof import('wxt/utils/match-patterns')['InvalidMatchPattern']
|
||||
const MatchPattern: typeof import('wxt/utils/match-patterns')['MatchPattern']
|
||||
const browser: typeof import('wxt/browser')['browser']
|
||||
const createIframeUi: typeof import('wxt/utils/content-script-ui/iframe')['createIframeUi']
|
||||
const createIntegratedUi: typeof import('wxt/utils/content-script-ui/integrated')['createIntegratedUi']
|
||||
const createShadowRootUi: typeof import('wxt/utils/content-script-ui/shadow-root')['createShadowRootUi']
|
||||
const defineAppConfig: typeof import('wxt/utils/define-app-config')['defineAppConfig']
|
||||
const defineBackground: typeof import('wxt/utils/define-background')['defineBackground']
|
||||
const defineContentScript: typeof import('wxt/utils/define-content-script')['defineContentScript']
|
||||
const defineUnlistedScript: typeof import('wxt/utils/define-unlisted-script')['defineUnlistedScript']
|
||||
const defineWxtPlugin: typeof import('wxt/utils/define-wxt-plugin')['defineWxtPlugin']
|
||||
const fakeBrowser: typeof import('wxt/testing')['fakeBrowser']
|
||||
const injectScript: typeof import('wxt/utils/inject-script')['injectScript']
|
||||
const storage: typeof import('wxt/utils/storage')['storage']
|
||||
const useAppConfig: typeof import('wxt/utils/app-config')['useAppConfig']
|
||||
const ContentScriptContext: typeof import('wxt/utils/content-script-context').ContentScriptContext
|
||||
const InvalidMatchPattern: typeof import('wxt/utils/match-patterns').InvalidMatchPattern
|
||||
const MatchPattern: typeof import('wxt/utils/match-patterns').MatchPattern
|
||||
const browser: typeof import('wxt/browser').browser
|
||||
const createIframeUi: typeof import('wxt/utils/content-script-ui/iframe').createIframeUi
|
||||
const createIntegratedUi: typeof import('wxt/utils/content-script-ui/integrated').createIntegratedUi
|
||||
const createShadowRootUi: typeof import('wxt/utils/content-script-ui/shadow-root').createShadowRootUi
|
||||
const defineAppConfig: typeof import('wxt/utils/define-app-config').defineAppConfig
|
||||
const defineBackground: typeof import('wxt/utils/define-background').defineBackground
|
||||
const defineContentScript: typeof import('wxt/utils/define-content-script').defineContentScript
|
||||
const defineUnlistedScript: typeof import('wxt/utils/define-unlisted-script').defineUnlistedScript
|
||||
const defineWxtPlugin: typeof import('wxt/utils/define-wxt-plugin').defineWxtPlugin
|
||||
const fakeBrowser: typeof import('wxt/testing').fakeBrowser
|
||||
const injectScript: typeof import('wxt/utils/inject-script').injectScript
|
||||
const storage: typeof import('wxt/utils/storage').storage
|
||||
const useAppConfig: typeof import('wxt/utils/app-config').useAppConfig
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
@@ -142,7 +142,7 @@ describe('Auto Imports', () => {
|
||||
|
||||
await project.prepare();
|
||||
|
||||
expect(await project.fileExists('.wxt/types/imports.d.ts')).toBe(false);
|
||||
expect(await project.pathExists('.wxt/types/imports.d.ts')).toBe(false);
|
||||
});
|
||||
|
||||
it('should only include imports-module.d.ts in the the project', async () => {
|
||||
@@ -280,24 +280,10 @@ describe('Auto Imports', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(await project.fileExists('.wxt/eslint-auto-imports.mjs')).toBe(
|
||||
expect(await project.pathExists('.wxt/eslint-auto-imports.mjs')).toBe(
|
||||
false,
|
||||
);
|
||||
expect(await project.fileExists('.wxt/eslintrc-auto-import.json')).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('should NOT output an ESlint config file by default', async () => {
|
||||
const project = new TestProject();
|
||||
project.addFile('entrypoints/popup.html', `<html></html>`);
|
||||
|
||||
await project.prepare();
|
||||
|
||||
expect(await project.fileExists('.wxt/eslint-auto-imports.mjs')).toBe(
|
||||
false,
|
||||
);
|
||||
expect(await project.fileExists('.wxt/eslintrc-auto-import.json')).toBe(
|
||||
expect(await project.pathExists('.wxt/eslintrc-auto-import.json')).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -77,7 +77,7 @@ describe('Module Helpers', () => {
|
||||
|
||||
await project.build(config);
|
||||
|
||||
expect(await project.fileExists('.output/chrome-mv3/injected.js')).toBe(
|
||||
expect(await project.pathExists('.output/chrome-mv3/injected.js')).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
@@ -118,10 +118,10 @@ describe('Module Helpers', () => {
|
||||
fileName: 'module.txt',
|
||||
});
|
||||
await expect(
|
||||
project.fileExists('.output/chrome-mv3/module.txt'),
|
||||
project.pathExists('.output/chrome-mv3/module.txt'),
|
||||
).resolves.toBe(true);
|
||||
await expect(
|
||||
project.fileExists('.output/chrome-mv3/example/generated.txt'),
|
||||
project.pathExists('.output/chrome-mv3/example/generated.txt'),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
|
||||
@@ -298,7 +298,7 @@ describe('Module Helpers', () => {
|
||||
|
||||
await expect(
|
||||
project.serializeFile('.wxt/types/imports.d.ts'),
|
||||
).resolves.toContain("const ref: typeof import('vue')['ref']");
|
||||
).resolves.toContain("const ref: typeof import('vue').ref");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user