diff --git a/.cargo/config.toml b/.cargo/config.toml index 2dd5e85..b1fd65a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -8,3 +8,6 @@ build-wasm32 = "build --target wasm32-unknown-unknown" rustflags = [ "--cfg=swc_ast_unknown" ] + +[target.x86_64-pc-windows-msvc] +rustflags = ["-C", "target-feature=+crt-static"] diff --git a/.github/workflows/CI-napi.yml b/.github/workflows/CI-napi.yml new file mode 100644 index 0000000..f65a786 --- /dev/null +++ b/.github/workflows/CI-napi.yml @@ -0,0 +1,346 @@ +name: CI +env: + DEBUG: napi:* + APP_NAME: lingui-extractor-swc + MACOSX_DEPLOYMENT_TARGET: '10.13' + CARGO_INCREMENTAL: '1' +on: + # push: + # branches: + # - main + # tags-ignore: + # - '**' + # paths-ignore: + # - '**/*.md' + # - LICENSE + # - '**/*.gitignore' + # - .editorconfig + # - docs/** + pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + working-directory: ./napi-rs + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 24 + - run: corepack enable + - name: Install Rust Toolchain + uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rustfmt + - name: Install dependencies + run: yarn install + - name: Oxlint + run: yarn lint + - name: Cargo fmt + run: cargo fmt -- --check + - name: Clippy + run: cargo clippy + build: + strategy: + fail-fast: false + matrix: + settings: + - host: macos-latest + target: x86_64-apple-darwin + build: yarn build --target x86_64-apple-darwin + - host: windows-latest + build: yarn build --target x86_64-pc-windows-msvc + target: x86_64-pc-windows-msvc + # - host: windows-latest + # build: yarn build --target i686-pc-windows-msvc + # target: i686-pc-windows-msvc# + - host: ubuntu-latest + target: x86_64-unknown-linux-gnu + build: yarn build --target x86_64-unknown-linux-gnu --use-napi-cross + - host: ubuntu-latest + target: x86_64-unknown-linux-musl + build: yarn build --target x86_64-unknown-linux-musl -x + - host: macos-latest + target: aarch64-apple-darwin + build: yarn build --target aarch64-apple-darwin + - host: ubuntu-latest + target: aarch64-unknown-linux-gnu + build: yarn build --target aarch64-unknown-linux-gnu --use-napi-cross + - host: ubuntu-latest + target: aarch64-linux-android + build: yarn build --target aarch64-linux-android + - host: ubuntu-latest + target: aarch64-unknown-linux-musl + build: yarn build --target aarch64-unknown-linux-musl -x + - host: windows-latest + target: aarch64-pc-windows-msvc + build: yarn build --target aarch64-pc-windows-msvc + name: stable - ${{ matrix.settings.target }} - node@24 + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v6 + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 24 + - run: corepack enable + - name: Install Rust Toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + targets: ${{ matrix.settings.target }} + - name: Cache cargo + uses: actions/cache@v5 + with: + path: | + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ~/.napi-rs + .cargo-cache + target/ + key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} + - uses: mlugg/setup-zig@v2 + if: ${{ contains(matrix.settings.target, 'musl') }} + with: + version: 0.14.1 + - name: Install cargo-zigbuild + uses: taiki-e/install-action@v2 + if: ${{ contains(matrix.settings.target, 'musl') }} + env: + GITHUB_TOKEN: ${{ github.token }} + with: + tool: cargo-zigbuild + - name: Setup toolchain + run: ${{ matrix.settings.setup }} + if: ${{ matrix.settings.setup }} + shell: bash + - name: Install dependencies + run: yarn install + - name: Build + run: ${{ matrix.settings.build }} + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v6 + with: + name: bindings-${{ matrix.settings.target }} + + path: | + ./napi-rs/${{ env.APP_NAME }}.*.node + ./napi-rs/${{ env.APP_NAME }}.*.wasm + if-no-files-found: error + # build-freebsd: + # runs-on: ubuntu-latest + # name: Build FreeBSD + # steps: + # - uses: actions/checkout@v6 + # - name: Build + # id: build + # uses: cross-platform-actions/action@v0.32.0 + # env: + # DEBUG: napi:* + # RUSTUP_IO_THREADS: 1 + # with: + # operating_system: freebsd + # version: '15.0' + # memory: 8G + # cpu_count: 3 + # environment_variables: DEBUG RUSTUP_IO_THREADS + # shell: bash + # # language=bash + # run: | + # sudo pkg install -y -f curl node libnghttp2 npm cmake + # corepack enable + # # sudo npm install -g yarn --ignore-scripts + # curl https://sh.rustup.rs -sSf --output rustup.sh + # sh rustup.sh -y --profile minimal --default-toolchain stable + # source "$HOME/.cargo/env" + # echo "~~~~ rustc --version ~~~~" + # rustc --version + # echo "~~~~ node -v ~~~~" + # node -v + # echo "~~~~ yarn --version ~~~~" + # yarn --version + # pwd + # ls -lah + # whoami + # env + # freebsd-version + # yarn install + # yarn build + # - name: Upload artifact + # uses: actions/upload-artifact@v6 + # with: + # name: bindings-freebsd + # path: ./napi-rs/${{ env.APP_NAME }}.*.node + # if-no-files-found: error + test-macOS-windows-binding: + name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + settings: + - host: windows-latest + target: x86_64-pc-windows-msvc + architecture: x64 + - host: macos-latest + target: aarch64-apple-darwin + architecture: arm64 + - host: macos-latest + target: x86_64-apple-darwin + architecture: x64 + node: + - '22' + - '24' + runs-on: ${{ matrix.settings.host }} + steps: + - uses: actions/checkout@v6 + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node }} + architecture: ${{ matrix.settings.architecture }} + - run: corepack enable + - name: Install dependencies + run: yarn install + - name: Download artifacts + uses: actions/download-artifact@v7 + with: + name: bindings-${{ matrix.settings.target }} + path: ./napi-rs + - name: List packages + run: ls -R . + shell: bash + - name: Test bindings + run: yarn test + test-linux-binding: + name: Test ${{ matrix.target }} - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + target: + - x86_64-unknown-linux-gnu + - x86_64-unknown-linux-musl + - aarch64-unknown-linux-gnu + - aarch64-unknown-linux-musl + node: + - '22' + - '24' + runs-on: ${{ contains(matrix.target, 'aarch64') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} + steps: + - uses: actions/checkout@v6 + # - name: Setup node + # uses: actions/setup-node@v6 + # with: + # node-version: ${{ matrix.node }} + - run: corepack enable + - name: Output docker params + uses: actions/github-script@v8 + id: docker + with: + # language=javascript + script: | + const target = '${{ matrix.target }}'; + const node = '${{ matrix.node }}'; + + if (target.startsWith('aarch64')) { + core.setOutput('PLATFORM', 'linux/arm64'); + } else if (target.startsWith('armv7')) { + core.setOutput('PLATFORM', 'linux/arm/v7'); + } else { + core.setOutput('PLATFORM', 'linux/amd64'); + } + + const suffix = target.endsWith('-musl') ? 'alpine' : 'slim'; + core.setOutput('IMAGE', `node:${node}-${suffix}`) + + - name: Download artifacts + uses: actions/download-artifact@v7 + with: + name: bindings-${{ matrix.target }} + path: ./napi-rs + - name: List packages + run: ls -R . + shell: bash + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + if: ${{ contains(matrix.target, 'armv7') }} + with: + platforms: all + - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + if: ${{ contains(matrix.target, 'armv7') }} + - name: Test bindings + run: | + docker run --rm \ + -v ${{ github.workspace }}/napi-rs:/app \ + -w /app \ + --platform ${{ steps.docker.outputs.PLATFORM }} \ + ${{ steps.docker.outputs.IMAGE }} \ + sh -c "corepack enable && yarn install && yarn test" + publish: + name: Publish + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + needs: + - lint + # - build-freebsd + - test-macOS-windows-binding + - test-linux-binding + steps: + - uses: actions/checkout@v6 + - name: Setup node + uses: actions/setup-node@v6 + with: + node-version: 24 + - run: corepack enable + - name: Install dependencies + run: yarn install + - name: create npm dirs + run: yarn napi create-npm-dirs + - name: Download all artifacts + uses: actions/download-artifact@v7 + with: + path: ./napi-rs/artifacts + - name: Move artifacts + run: yarn artifacts + - name: List packages + run: ls -R ./npm + shell: bash + # - name: Publish + # run: | + # npm config set provenance true + # if git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$"; + # then + # echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + # npm publish --access public --dry-run + # elif git log -1 --pretty=%B | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+"; + # then + # echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + # npm publish --tag next --access public + # else + # echo "Not a release, skipping publish" + # fi + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + - name: Publish + run: | + echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc + npm publish --access public --dry-run + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fd05bed..338bfa8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,8 +25,8 @@ jobs: # Uses values from rust-toolchain.toml - uses: actions-rust-lang/setup-rust-toolchain@v1 - - - uses: Swatinem/rust-cache@v2 + with: + target: 'wasm32-wasip1' - name: Check formatting run: cargo fmt --check diff --git a/Cargo.lock b/Cargo.lock index d39c256..af65cab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,12 +10,14 @@ checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", + "getrandom", "once_cell", + "serde", "version_check", "zerocopy", ] @@ -35,6 +37,15 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ansi_term" version = "0.12.1" @@ -50,6 +61,12 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "ascii" version = "1.1.0" @@ -125,6 +142,43 @@ dependencies = [ "generic-array", ] +[[package]] +name = "browserslist-data" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21d369bf3fe9811518eead42e2cdf9ed9915579242864297689894c0f1089712" +dependencies = [ + "ahash", + "chrono", +] + +[[package]] +name = "browserslist-rs" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd48a6ca358df4f7000e3fb5f08738b1b91a0e5d5f862e2f77b2b14647547f5" +dependencies = [ + "ahash", + "browserslist-data", + "chrono", + "either", + "itertools", + "nom", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "bstr" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -236,6 +290,17 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "iana-time-zone", + "num-traits", + "windows-link", +] + [[package]] name = "compact_str" version = "0.7.1" @@ -249,6 +314,21 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "convert_case" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.14" @@ -258,6 +338,31 @@ dependencies = [ "libc", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-common" version = "0.1.6" @@ -268,6 +373,22 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e" +dependencies = [ + "ctor-proc-macro", + "dtor", +] + +[[package]] +name = "ctor-proc-macro" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" + [[package]] name = "darling" version = "0.20.10" @@ -303,6 +424,19 @@ dependencies = [ "syn", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -383,6 +517,27 @@ dependencies = [ "syn", ] +[[package]] +name = "dragonbox_ecma" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5577f010d4e1bb3f3c4d6081e05718eb6992cf20119cab4d3abadff198b5ae" + +[[package]] +name = "dtor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + [[package]] name = "either" version = "1.13.0" @@ -411,12 +566,30 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -442,6 +615,95 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -452,12 +714,36 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" +dependencies = [ + "aho-corasick", + "bstr", + "regex-automata", + "regex-syntax", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -474,6 +760,17 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -500,6 +797,30 @@ dependencies = [ "triomphe", ] +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "1.5.0" @@ -507,9 +828,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ "displaydoc", - "yoke", + "yoke 0.7.5", + "zerofrom", + "zerovec 0.10.4", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "serde", + "yoke 0.8.1", "zerofrom", - "zerovec", + "zerovec 0.11.5", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap 0.8.1", + "tinystr 0.8.2", + "writeable 0.6.2", + "zerovec 0.11.5", ] [[package]] @@ -519,10 +867,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "litemap 0.7.4", + "tinystr 0.7.6", + "writeable 0.5.5", + "zerovec 0.10.4", ] [[package]] @@ -534,9 +882,9 @@ dependencies = [ "displaydoc", "icu_locid", "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", + "icu_provider 1.5.0", + "tinystr 0.7.6", + "zerovec 0.10.4", ] [[package]] @@ -552,15 +900,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ "displaydoc", - "icu_collections", + "icu_collections 1.5.0", "icu_normalizer_data", - "icu_properties", - "icu_provider", + "icu_properties 1.5.1", + "icu_provider 1.5.0", "smallvec", "utf16_iter", "utf8_iter", "write16", - "zerovec", + "zerovec 0.10.4", ] [[package]] @@ -576,12 +924,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", - "icu_collections", + "icu_collections 1.5.0", "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", + "icu_properties_data 1.5.0", + "icu_provider 1.5.0", + "tinystr 0.7.6", + "zerovec 0.10.4", +] + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections 2.1.1", + "icu_locale_core", + "icu_properties_data 2.1.2", + "icu_provider 2.1.1", + "serde", + "zerotrie", + "zerovec 0.11.5", ] [[package]] @@ -590,6 +953,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + [[package]] name = "icu_provider" version = "1.5.0" @@ -600,11 +969,26 @@ dependencies = [ "icu_locid", "icu_provider_macros", "stable_deref_trait", - "tinystr", - "writeable", - "yoke", + "tinystr 0.7.6", + "writeable 0.5.5", + "yoke 0.7.5", + "zerofrom", + "zerovec 0.10.4", +] + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable 0.6.2", + "yoke 0.8.1", "zerofrom", - "zerovec", + "zerotrie", + "zerovec 0.11.5", ] [[package]] @@ -642,7 +1026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ "icu_normalizer", - "icu_properties", + "icu_properties 1.5.1", ] [[package]] @@ -659,6 +1043,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown 0.15.0", + "serde", ] [[package]] @@ -673,12 +1058,40 @@ dependencies = [ "syn", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "jsonc-parser" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d80e6d70e7911a29f3cf3f44f452df85d06f73572b494ca99a2cad3fcf8f4" +dependencies = [ + "serde_json", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -692,30 +1105,75 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] -name = "lingui_macro_plugin" +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "lingui_extractor" version = "6.0.0-next.1" dependencies = [ "data-encoding", - "once_cell", - "regex", + "lingui_macro", + "napi", + "napi-derive", "serde", "serde_json", - "sha2", "swc_core", + "swc_sourcemap", ] [[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - -[[package]] +name = "lingui_extractor_swc" +version = "0.1.0" +dependencies = [ + "anyhow", + "lingui_extractor", + "napi", + "napi-build", + "napi-derive", + "rayon", + "serde", + "serde_json", + "swc_core", +] + +[[package]] +name = "lingui_macro" +version = "6.0.0-next.1" +dependencies = [ + "data-encoding", + "once_cell", + "regex", + "serde", + "serde_json", + "sha2", + "swc_core", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] name = "litemap" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + [[package]] name = "lock_api" version = "0.4.12" @@ -732,6 +1190,15 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lru" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "matchers" version = "0.2.0" @@ -771,6 +1238,12 @@ dependencies = [ "syn", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "munge" version = "0.4.2" @@ -791,12 +1264,96 @@ dependencies = [ "syn", ] +[[package]] +name = "napi" +version = "3.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6944d0bf100571cd6e1a98a316cdca262deb6fccf8d93f5ae1502ca3fc88bd3" +dependencies = [ + "bitflags", + "ctor", + "futures", + "napi-build", + "napi-sys", + "nohash-hasher", + "rustc-hash", + "serde", + "serde_json", +] + +[[package]] +name = "napi-build" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d376940fd5b723c6893cd1ee3f33abbfd86acb1cd1ec079f3ab04a2a3bc4d3b1" + +[[package]] +name = "napi-derive" +version = "3.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c914b5e420182bfb73504e0607592cdb8e2e21437d450883077669fb72a114d" +dependencies = [ + "convert_case", + "ctor", + "napi-derive-backend", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "napi-derive-backend" +version = "5.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0864cf6a82e2cfb69067374b64c9253d7e910e5b34db833ed7495dda56ccb18" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "semver", + "syn", +] + +[[package]] +name = "napi-sys" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb602b84d7c1edae45e50bbf1374696548f36ae179dfa667f577e384bb90c2b" +dependencies = [ + "libloading", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "normpath" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a9da8c9922c35a1033d76f7272dfc2e7ee20392083d75aeea6ced23c6266578" +dependencies = [ + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -872,6 +1429,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "par-iter" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eae0176a010bb94b9a67f0eb9da0fd31410817d58850649c54f485124c9a71a" +dependencies = [ + "either", + "par-core", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -895,12 +1462,34 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "path-clean" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecba01bf2678719532c5e3059e0b5f0811273d94b397088b82e3bd0a78c78fdd" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "phf" version = "0.11.2" @@ -949,6 +1538,45 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec 0.11.5", +] + +[[package]] +name = "precomputed-map" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84350ffee5cedfabf9bee3e8825721f651da8ff79d50fe7a37cf0ca015c428ee" + +[[package]] +name = "preset_env_base" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d4639c317ff6c06bfbca5d56a763dbd599766acf7d8f1e350eab15caf219b20" +dependencies = [ + "anyhow", + "browserslist-rs", + "dashmap", + "from_variant", + "once_cell", + "rustc-hash", + "semver", + "serde", + "st-map", + "tracing", +] + [[package]] name = "pretty_assertions" version = "1.4.1" @@ -1006,12 +1634,24 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "radium" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "radix_fmt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426" + [[package]] name = "rancor" version = "0.1.0" @@ -1036,6 +1676,26 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.7" @@ -1074,6 +1734,16 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "regress" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2057b2325e68a893284d1538021ab90279adac1139957ca2a74426c6f118fb48" +dependencies = [ + "hashbrown 0.16.1", + "memchr", +] + [[package]] name = "relative-path" version = "1.9.3" @@ -1152,9 +1822,9 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "ryu-js" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad97d4ce1560a5e27cec89519dc8300d1aa6035b099821261c651486a19e44d5" +checksum = "dd29631678d6fb0903b69223673e122c32e9ae559d0960a38d574695ebc0ea15" [[package]] name = "scoped-tls" @@ -1226,6 +1896,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha2" version = "0.10.8" @@ -1264,6 +1945,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + [[package]] name = "smallvec" version = "1.13.2" @@ -1281,6 +1968,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "st-map" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8257dd592de7614be71a2342d36ba2d527ddad3f9a0c8d09d6ceed4c371531e4" +dependencies = [ + "arrayvec", + "static-map-macro", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1300,6 +1997,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "static-map-macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710e9696ef338691287aeb937ee6ffe60022f579d3c8d2fd9d58973a9a10a466" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1323,6 +2031,56 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "swc" +version = "54.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c93b0a1fc0edfcb66eb6245175c17b402c644a228c5e750b5aaa9509b48f96a7" +dependencies = [ + "anyhow", + "base64", + "bytes-str", + "dashmap", + "either", + "indexmap", + "jsonc-parser", + "napi", + "napi-derive", + "once_cell", + "par-core", + "par-iter", + "parking_lot", + "regex", + "rustc-hash", + "serde", + "serde_json", + "swc_atoms", + "swc_common", + "swc_compiler_base", + "swc_config", + "swc_ecma_ast", + "swc_ecma_codegen", + "swc_ecma_ext_transforms", + "swc_ecma_loader", + "swc_ecma_minifier", + "swc_ecma_parser", + "swc_ecma_preset_env", + "swc_ecma_transforms", + "swc_ecma_transforms_base", + "swc_ecma_transforms_compat", + "swc_ecma_transforms_optimization", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_error_reporters", + "swc_node_comments", + "swc_sourcemap", + "swc_timer", + "swc_transform_common", + "swc_visit", + "tracing", + "url", +] + [[package]] name = "swc_allocator" version = "4.0.1" @@ -1383,41 +2141,106 @@ dependencies = [ ] [[package]] -name = "swc_core" -version = "50.2.3" +name = "swc_compiler_base" +version = "47.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a4addc76896d859a57855961fd351486a900021aade516f7623969ed28958f" +checksum = "224fb0c0bbd57594892659261702903298027623156ab133005057af8e6fbc3d" dependencies = [ - "swc_allocator", + "anyhow", + "base64", + "bytes-str", + "napi", + "napi-derive", + "once_cell", + "pathdiff", + "rustc-hash", + "serde", + "serde_json", "swc_atoms", "swc_common", + "swc_config", "swc_ecma_ast", + "swc_ecma_codegen", + "swc_ecma_minifier", "swc_ecma_parser", - "swc_ecma_transforms_base", - "swc_ecma_transforms_testing", - "swc_ecma_utils", "swc_ecma_visit", - "swc_plugin", - "swc_plugin_macro", - "swc_plugin_proxy", - "swc_transform_common", - "vergen", + "swc_sourcemap", + "swc_timer", ] [[package]] -name = "swc_ecma_ast" -version = "19.0.0" +name = "swc_config" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "724195600825cbdd2a899d5473d2ce1f24ae418bff1231f160ecf38a3bc81f46" +checksum = "72e90b52ee734ded867104612218101722ad87ff4cf74fe30383bd244a533f97" dependencies = [ - "bitflags", - "cbor4ii", - "is-macro", - "num-bigint", + "anyhow", + "bytes-str", + "dashmap", + "globset", + "indexmap", "once_cell", - "phf", + "regex", + "regress", "rustc-hash", - "string_enum", + "serde", + "serde_json", + "swc_config_macro", + "swc_sourcemap", +] + +[[package]] +name = "swc_config_macro" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b416e8ce6de17dc5ea496e10c7012b35bbc0e3fef38d2e065eed936490db0b3" +dependencies = [ + "proc-macro2", + "quote", + "swc_macros_common", + "syn", +] + +[[package]] +name = "swc_core" +version = "56.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98e364864dc10de940b04a8e2b60ea2d2d512b1aa1e940651e128446fe35d71" +dependencies = [ + "swc", + "swc_allocator", + "swc_atoms", + "swc_common", + "swc_config", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_testing", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_nodejs_common", + "swc_plugin", + "swc_plugin_macro", + "swc_plugin_proxy", + "swc_transform_common", + "vergen", +] + +[[package]] +name = "swc_ecma_ast" +version = "20.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252124d0d786aa2338860701a067c93488747dfadbfedb16ac78f386e16a0ac4" +dependencies = [ + "bitflags", + "cbor4ii", + "is-macro", + "num-bigint", + "once_cell", + "phf", + "rustc-hash", + "serde", + "string_enum", "swc_atoms", "swc_common", "swc_visit", @@ -1426,100 +2249,588 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "21.0.0" +version = "23.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56116de786118dce35e90b612a1f4d952116dd2728ecb197c8064cfccf527baf" +dependencies = [ + "ascii", + "compact_str", + "dragonbox_ecma", + "memchr", + "num-bigint", + "once_cell", + "regex", + "rustc-hash", + "serde", + "swc_allocator", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_codegen_macros", + "tracing", +] + +[[package]] +name = "swc_ecma_codegen_macros" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e276dc62c0a2625a560397827989c82a93fd545fcf6f7faec0935a82cc4ddbb8" +dependencies = [ + "proc-macro2", + "swc_macros_common", + "syn", +] + +[[package]] +name = "swc_ecma_compat_bugfixes" +version = "41.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06666c745fc486f1237e552a370e2f1d703d3a78a4d58e3c286d8c1a8834875" +dependencies = [ + "rustc-hash", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_compat_es2015", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_trace_macro", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_common" +version = "32.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9acb3c0cd3f8102af5021b6e666d5c2dfe2c0c78c9ccb35e8ed8ed79fad2d4c4" +dependencies = [ + "swc_common", + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_utils", +] + +[[package]] +name = "swc_ecma_compat_es2015" +version = "41.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f34c347e38ce9ed1cc6b7bad12e459e5ffec861e6dd195fbbb5d325c4750792f" +dependencies = [ + "arrayvec", + "indexmap", + "is-macro", + "rustc-hash", + "serde", + "serde_derive", + "smallvec", + "swc_atoms", + "swc_common", + "swc_config", + "swc_ecma_ast", + "swc_ecma_compat_common", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_transforms_classes", + "swc_ecma_transforms_macros", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_trace_macro", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_es2016" +version = "37.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a031de2780845fa3e8b45c2fd7c43cd14ce01239917262739a32db0233b6e6d" +dependencies = [ + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_es2017" +version = "37.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ca488aa5f09dc20f27cf2d6b43241c99ef80006ce5fa7469636222bee3b8251" +dependencies = [ + "serde", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_es2018" +version = "38.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1814e16a1ab0242461c0beeab8686d8334f9ffa94618ccdda5dc0e3b98ceeee7" +dependencies = [ + "serde", + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_es2019" +version = "37.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1540e2d0910fad216450be4af5d460ee86a2dabafbfa8414f8845f3139209a" +dependencies = [ + "swc_common", + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_es2020" +version = "39.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589d4655c12f0bc3072b8514be3c46d0c50cfc8eced3b6453cb051b1bae1e09e" +dependencies = [ + "serde", + "swc_common", + "swc_ecma_ast", + "swc_ecma_compat_es2022", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_es2021" +version = "37.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdd8220e7a2148f0bb8e1f756718f66d0c6e4a7a42212e591ec9c009a8fc720" +dependencies = [ + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_es2022" +version = "39.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f48a3678e283bee646b4b96c4e6d90e3d4354f3f483ae6da79e7693d1fd68d5" +dependencies = [ + "rustc-hash", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_transforms_base", + "swc_ecma_transforms_classes", + "swc_ecma_transforms_macros", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_trace_macro", + "tracing", +] + +[[package]] +name = "swc_ecma_compat_regexp" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c267d92e58db3f3c00cf3f7e93ee72391f5cc2d9a5877db63ca95d7495a535" +dependencies = [ + "icu_properties 2.1.2", + "swc_ecma_regexp_ast", + "swc_ecma_regexp_visit", +] + +[[package]] +name = "swc_ecma_ext_transforms" +version = "26.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a6aed670f87cde675f40dcd0ff5196f3cec9b2bc7e6fed12adf5b808f18eb69" +dependencies = [ + "phf", + "swc_common", + "swc_ecma_ast", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_hooks" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9adff1f01550ef653e262ad709a2914d3dd6cfd559aea2e28eeeab8f895981" +dependencies = [ + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_loader" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b36b38399698e77c3d63838c2e32e40df0d5e55e489bef529a77a349a722c7a" +dependencies = [ + "anyhow", + "dashmap", + "lru", + "normpath", + "once_cell", + "parking_lot", + "path-clean", + "pathdiff", + "rustc-hash", + "serde", + "serde_json", + "swc_atoms", + "swc_common", + "tracing", +] + +[[package]] +name = "swc_ecma_minifier" +version = "44.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d62a924e6d201251cf10c94eb88bb88404aa9b24312d05622140202818159e4" +dependencies = [ + "arrayvec", + "bitflags", + "indexmap", + "num-bigint", + "num_cpus", + "once_cell", + "par-core", + "par-iter", + "parking_lot", + "phf", + "radix_fmt", + "rustc-hash", + "ryu-js", + "serde", + "serde_json", + "swc_atoms", + "swc_common", + "swc_config", + "swc_ecma_ast", + "swc_ecma_codegen", + "swc_ecma_hooks", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_transforms_optimization", + "swc_ecma_usage_analyzer", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_timer", + "tracing", +] + +[[package]] +name = "swc_ecma_parser" +version = "33.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d237cf212d1f3ff5c0cf6ab5070f0ed4d624a0ab032ac4f0451675d31890e71" +dependencies = [ + "bitflags", + "either", + "num-bigint", + "phf", + "rustc-hash", + "seq-macro", + "serde", + "smartstring", + "stacker", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "tracing", +] + +[[package]] +name = "swc_ecma_preset_env" +version = "47.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c35d01f1b0d11bd915ff4757e1c9b045b287c5b6970f90b54eb9f3b638252d15" +dependencies = [ + "anyhow", + "foldhash 0.1.5", + "indexmap", + "once_cell", + "precomputed-map", + "preset_env_base", + "rustc-hash", + "serde", + "serde_json", + "string_enum", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transformer", + "swc_ecma_transforms", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_regexp" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb1c912d1f73009546bc8271feb40a2371f148fcde6a4b6f4973a1ce167bc07" +dependencies = [ + "phf", + "rustc-hash", + "swc_atoms", + "swc_common", + "swc_ecma_regexp_ast", + "swc_ecma_regexp_common", + "swc_ecma_regexp_visit", + "unicode-id-start", +] + +[[package]] +name = "swc_ecma_regexp_ast" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568b408134ad2e201cd48db4d1ed7bed40abbec6e242fb8492a066834f674b11" +dependencies = [ + "bitflags", + "is-macro", + "swc_atoms", + "swc_common", + "swc_ecma_regexp_common", +] + +[[package]] +name = "swc_ecma_regexp_common" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a0a09a9e4dc09c97f07273695bd4b58e46b99dbb0cb788ce0dad2a181eb1e94" + +[[package]] +name = "swc_ecma_regexp_visit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258ea946dddb367af135b8255c6ddd0b86a066f3d3c7d4bca2e624b77cd1b51f" +dependencies = [ + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_regexp_ast", + "swc_visit", +] + +[[package]] +name = "swc_ecma_testing" +version = "19.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177244625cdecd268a07534c3b087f7f263604dd40f3ec7c7a984ca95351b632" +dependencies = [ + "anyhow", + "hex", + "sha2", + "testing", + "tracing", +] + +[[package]] +name = "swc_ecma_transformer" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6175f7560a1b3cdc5231f0a608cf132ffcca8c4977c7f7410bbca8ccfb6bc09a" +dependencies = [ + "rustc-hash", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_compat_regexp", + "swc_ecma_hooks", + "swc_ecma_regexp", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", + "tracing", +] + +[[package]] +name = "swc_ecma_transforms" +version = "46.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1eab738b6e8f9385aad8d143e7750134e503c48ba620e0bc27aabaec3822a16" +dependencies = [ + "par-core", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_transforms_compat", + "swc_ecma_transforms_optimization", + "swc_ecma_transforms_proposal", + "swc_ecma_transforms_react", + "swc_ecma_transforms_typescript", + "swc_ecma_utils", +] + +[[package]] +name = "swc_ecma_transforms_base" +version = "36.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf93abf3dc6d2b21a2a29c62b0197cd270b6105a483236ecba91993f895204e" +dependencies = [ + "better_scoped_tls", + "indexmap", + "once_cell", + "par-core", + "phf", + "rustc-hash", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_utils", + "swc_ecma_visit", + "tracing", +] + +[[package]] +name = "swc_ecma_transforms_classes" +version = "36.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3567a1a95c2f6d5f7c3ca59051cf099c5ac54cf8f293bcfb43b385477b9f80a9" +dependencies = [ + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_transforms_compat" +version = "42.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c77d9d21345ca986ae3b5ff1a4fa3607b15b07ed397506e6dba32e867cf40fd" +checksum = "e472acb6e92135ab42646a41086ee8c81576b9e0e964b483ac6c504319b9d861" dependencies = [ - "ascii", - "compact_str", - "memchr", - "num-bigint", - "once_cell", - "regex", - "rustc-hash", - "ryu-js", + "indexmap", + "par-core", "serde", - "swc_allocator", "swc_atoms", "swc_common", "swc_ecma_ast", - "swc_ecma_codegen_macros", - "swc_sourcemap", + "swc_ecma_compat_bugfixes", + "swc_ecma_compat_common", + "swc_ecma_compat_es2015", + "swc_ecma_compat_es2016", + "swc_ecma_compat_es2017", + "swc_ecma_compat_es2018", + "swc_ecma_compat_es2019", + "swc_ecma_compat_es2020", + "swc_ecma_compat_es2021", + "swc_ecma_compat_es2022", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", "tracing", ] [[package]] -name = "swc_ecma_codegen_macros" -version = "2.0.2" +name = "swc_ecma_transforms_macros" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e276dc62c0a2625a560397827989c82a93fd545fcf6f7faec0935a82cc4ddbb8" +checksum = "bc777288799bf6786e5200325a56e4fbabba590264a4a48a0c70b16ad0cf5cd8" dependencies = [ "proc-macro2", + "quote", "swc_macros_common", "syn", ] [[package]] -name = "swc_ecma_parser" -version = "29.0.2" +name = "swc_ecma_transforms_optimization" +version = "38.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63984b544fe1d8f66e9ce616e57429bb878572fcf1504851ef9d9f4f5260e2b" +checksum = "ab76533e9da38c8f13ca1a9d0a6edd6b3de328a281441aee9810281e1b7ba4e9" dependencies = [ - "bitflags", - "either", - "num-bigint", - "phf", + "bytes-str", + "dashmap", + "indexmap", + "once_cell", + "par-core", + "petgraph", "rustc-hash", - "seq-macro", - "serde", - "smartstring", - "stacker", + "serde_json", "swc_atoms", "swc_common", "swc_ecma_ast", + "swc_ecma_parser", + "swc_ecma_transforms_base", + "swc_ecma_utils", + "swc_ecma_visit", "tracing", ] [[package]] -name = "swc_ecma_testing" -version = "19.0.0" +name = "swc_ecma_transforms_proposal" +version = "36.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177244625cdecd268a07534c3b087f7f263604dd40f3ec7c7a984ca95351b632" +checksum = "55c6aac75098d237a4311922e69e587355089e7ae880d237e037c10275f27e8d" dependencies = [ - "anyhow", - "hex", - "sha2", - "testing", - "tracing", + "either", + "rustc-hash", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_transforms_classes", + "swc_ecma_utils", + "swc_ecma_visit", ] [[package]] -name = "swc_ecma_transforms_base" -version = "32.0.0" +name = "swc_ecma_transforms_react" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "499486ed875ba49af2f36d0d809f61ce6e42943a3aa1d97f592d96f10fe734cc" +checksum = "06920cb2277974a0000f58fb7a70d23f2419dddd53de0d5de8db014a9a1163f9" dependencies = [ - "better_scoped_tls", + "base64", + "bytes-str", "indexmap", "once_cell", - "par-core", - "phf", "rustc-hash", "serde", + "sha1", + "string_enum", "swc_atoms", "swc_common", + "swc_config", "swc_ecma_ast", + "swc_ecma_hooks", "swc_ecma_parser", + "swc_ecma_transforms_base", "swc_ecma_utils", "swc_ecma_visit", - "tracing", ] [[package]] name = "swc_ecma_transforms_testing" -version = "35.0.0" +version = "40.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ec7851260522b2864983caa3fc7004ebb080842f49ee49a5461b779277378d" +checksum = "994b87d7c96e973c324efdc1e68ee58ceca319d1416b6a7fd63157f45e72a493" dependencies = [ "ansi_term", "anyhow", @@ -1541,18 +2852,54 @@ dependencies = [ "testing", ] +[[package]] +name = "swc_ecma_transforms_typescript" +version = "40.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1f479758dfdefc5f1af7df222c13c1521b176489aba4dc6d13c3e21739f6473" +dependencies = [ + "bytes-str", + "rustc-hash", + "serde", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_transforms_base", + "swc_ecma_transforms_react", + "swc_ecma_utils", + "swc_ecma_visit", +] + +[[package]] +name = "swc_ecma_usage_analyzer" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7aec80849cab609d92af5dd2670f18fc760f7029beb11beebcef3fed9ba3466" +dependencies = [ + "bitflags", + "indexmap", + "rustc-hash", + "swc_atoms", + "swc_common", + "swc_ecma_ast", + "swc_ecma_utils", + "swc_ecma_visit", + "swc_timer", + "tracing", +] + [[package]] name = "swc_ecma_utils" -version = "25.0.0" +version = "26.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd5ee449d21110a271e73d0a9f7640a8854a62cb0e2cb0c9db3445383598e21" +checksum = "3669c1d92ba315caff5a80df76141367acf61b2d846231a1960e25be65a20fbd" dependencies = [ + "dragonbox_ecma", "indexmap", "num_cpus", "once_cell", "par-core", "rustc-hash", - "ryu-js", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -1562,9 +2909,9 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "19.0.0" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69d63f7f704a2ec937edef90a3eba1f64602eceb60c8deb260c01131f680e8b" +checksum = "e971a258717db3dc8939c38410d8b8cb8126f1b05b9758672daa7cae3e0248c2" dependencies = [ "new_debug_unreachable", "num-bigint", @@ -1610,6 +2957,31 @@ dependencies = [ "syn", ] +[[package]] +name = "swc_node_comments" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e110f3d5684e9c087450ee522d4b8ba68fd91964992984032cc00194a212cde4" +dependencies = [ + "dashmap", + "rustc-hash", + "swc_atoms", + "swc_common", +] + +[[package]] +name = "swc_nodejs_common" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d48ec32365dba9a371950ce298483c3b714bd441878acea233711d66698863e" +dependencies = [ + "anyhow", + "napi", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "swc_plugin" version = "1.0.1" @@ -1632,9 +3004,9 @@ dependencies = [ [[package]] name = "swc_plugin_proxy" -version = "19.0.0" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f976dc63cd8b1916f265ee7d2647c28a85b433640099a5bf07153346dedffda" +checksum = "e78e1a9d26be495289cb07b9d73222f92f60b74d47904169d3ce4977600ec11e" dependencies = [ "better_scoped_tls", "cbor4ii", @@ -1664,6 +3036,15 @@ dependencies = [ "url", ] +[[package]] +name = "swc_timer" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db06b46cc832f7cf83c2ce21905fc465d01443a2bdccf63644383e1f5847532" +dependencies = [ + "tracing", +] + [[package]] name = "swc_trace_macro" version = "2.0.2" @@ -1830,7 +3211,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", - "zerovec", + "zerovec 0.10.4", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec 0.11.5", ] [[package]] @@ -1943,6 +3334,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + [[package]] name = "unicode-width" version = "0.1.14" @@ -2027,6 +3424,60 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2058,6 +3509,65 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -2140,6 +3650,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + [[package]] name = "write16" version = "1.0.0" @@ -2152,6 +3668,12 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + [[package]] name = "wyz" version = "0.5.1" @@ -2175,7 +3697,18 @@ checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", - "yoke-derive", + "yoke-derive 0.7.5", + "zerofrom", +] + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive 0.8.1", "zerofrom", ] @@ -2191,20 +3724,32 @@ dependencies = [ "synstructure", ] +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -2232,15 +3777,38 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke 0.8.1", + "zerofrom", +] + [[package]] name = "zerovec" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ - "yoke", + "yoke 0.7.5", + "zerofrom", + "zerovec-derive 0.10.3", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "serde", + "yoke 0.8.1", "zerofrom", - "zerovec-derive", + "zerovec-derive 0.11.2", ] [[package]] @@ -2253,3 +3821,14 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index b21cce2..56c62bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,14 @@ -[package] -name = "lingui_macro_plugin" +[workspace] +members = [ + "crates/*", + "napi-rs", +] +resolver = "2" + +[workspace.package] version = "6.0.0-next.1" edition = "2021" -[lib] -crate-type = ["cdylib", 'rlib'] - [profile.release] # This removes more dead code codegen-units = 1 @@ -15,22 +18,5 @@ opt-level = "s" # Optimize for performance, this is default so you don't need to specify it # opt-level = "z" -[dependencies] -data-encoding = "2.3.3" -sha2 = "0.10.8" -serde = "1.0.207" -serde_json = "1.0.125" -regex = "1.10.6" -once_cell = "1.19.0" -swc_core = { version = "50.2.3", features = [ - "ecma_plugin_transform", - "ecma_utils", - "ecma_visit", - "ecma_ast", - "ecma_parser", - "common", - "testing_transform", -] } -# .cargo/config defines few alias to build plugin. -# cargo build-wasi generates wasm-wasi32 binary -# cargo build-wasm32 generates wasm32-unknown-unknown binary. +[workspace.dependencies] +swc_core = { version = "56.0.0", default-features = false } diff --git a/rust-toolchain.toml b/___rust-toolchain.toml similarity index 70% rename from rust-toolchain.toml rename to ___rust-toolchain.toml index ab31454..a3d8165 100644 --- a/rust-toolchain.toml +++ b/___rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.85" +channel = "nightly-2025-05-06" targets = ["wasm32-wasip1"] components = ["rustfmt", "clippy"] diff --git a/crates/lingui_extractor/Cargo.toml b/crates/lingui_extractor/Cargo.toml new file mode 100644 index 0000000..fe78ee4 --- /dev/null +++ b/crates/lingui_extractor/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "lingui_extractor" +version.workspace = true +edition.workspace = true + +[lib] +crate-type = ["rlib"] + +[dependencies] +napi-derive = { version = "3.0.0", features = ["type-def"] } +napi = "3.8.3" +lingui_macro = { path = "../lingui_macro" } +data-encoding = "2.3.3" +serde = { version = "1.0.207", features = ["derive"] } +serde_json = "1.0.125" +swc_sourcemap = "9.3.4" +swc_core = { version = "56.0.0", features = [ + "ecma_ast", + "ecma_parser", + "ecma_visit", + "common" +] } diff --git a/crates/lingui_extractor/src/lib.rs b/crates/lingui_extractor/src/lib.rs new file mode 100644 index 0000000..842e9b6 --- /dev/null +++ b/crates/lingui_extractor/src/lib.rs @@ -0,0 +1,5 @@ +mod message_extractor; +mod message_extractor_visitor; + +pub use message_extractor::{extract_messages, ExtractorOptions}; +pub use message_extractor_visitor::{ExtractedMessage, ExtractionResult}; diff --git a/crates/lingui_extractor/src/message_extractor.rs b/crates/lingui_extractor/src/message_extractor.rs new file mode 100644 index 0000000..1a5e86c --- /dev/null +++ b/crates/lingui_extractor/src/message_extractor.rs @@ -0,0 +1,128 @@ +use crate::message_extractor_visitor::{ExtractionResult, MessageExtractorVisitor}; +use data_encoding::BASE64; +use lingui_macro::{LinguiMacroFolder, LinguiOptions}; +use serde::{Deserialize, Serialize}; +use std::rc::Rc; +use std::sync::Arc; +use swc_core::common::{Globals, Mark, GLOBALS}; +use swc_core::ecma::transforms::base::resolver; +use swc_core::{ + common::{ + comments::{Comments, SingleThreadedComments}, + sync::Lrc, + FileName, SourceMap, + }, + ecma::{ + ast::*, + parser::{Parser, StringInput, Syntax}, + visit::VisitWith, + }, +}; +use swc_sourcemap as sourcemap; + +/// Extract inline source map from source code +/// Looks for sourceMappingURL comments with inline base64 data +fn extract_inline_sourcemap(source_code: &str) -> Option { + // get_compiler().transform() + // Look for sourceMappingURL comment (typically at the end of the file) + let source_mapping_prefix = "sourceMappingURL="; + + // Search for the comment in the source code + if let Some(idx) = source_code.rfind(source_mapping_prefix) { + let url_part = &source_code[idx + source_mapping_prefix.len()..]; + + // Find the end of the URL (typically end of line or end of file) + let url = url_part.lines().next().unwrap_or(url_part).trim(); + + // Check if it's an inline base64 data URL + if url.starts_with("data:application/json;base64,") { + // Extract the base64 content + if let Some(base64_start) = url.find("base64,") { + let base64_content = &url[base64_start + "base64,".len()..].trim(); + + // Decode base64 + if let Ok(decoded) = BASE64.decode(base64_content.as_bytes()) { + // Parse the source map + if let Ok(source_map) = sourcemap::SourceMap::from_slice(&decoded) { + return Some(source_map); + } + } + } + } + } + + None +} + +#[derive(Default, Clone, Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ExtractorOptions { + pub parser: Syntax, +} + +/// Extract messages from source code +pub fn extract_messages( + source_code: &str, + filename: &str, + options: &ExtractorOptions, +) -> Result> { + let source_map = Lrc::new(SourceMap::default()); + + let source_file = source_map.new_source_file( + Arc::new(FileName::Custom(filename.to_string())), + source_code.to_string(), + ); + + let comments = Rc::new(SingleThreadedComments::default()); + + let mut parser = Parser::new( + options.parser, + StringInput::from(&*source_file), + Some(&comments), + ); + + let module = parser + .parse_module() + .map_err(|e| format!("Parse error: {:?}", e))?; + + let program = Program::Module(module); + + // Extract inline source map if present + let inline_source_map = extract_inline_sourcemap(source_code); + + // Extract messages directly from parsed module + let mut extractor_visitor = MessageExtractorVisitor::new( + source_map.clone(), + &comments as &dyn Comments, + inline_source_map, + ); + + let lingui_macro = LinguiMacroFolder::new( + LinguiOptions { + strip_non_essential_fields: false, + ..Default::default() + }, + Some(&comments as &dyn Comments), + ); + + let globals = Globals::default(); + + GLOBALS.set(&globals, || { + let unresolved_mark = Mark::new(); + let top_level_mark = Mark::new(); + + program + .apply(&mut resolver( + unresolved_mark, + top_level_mark, + options.parser.typescript(), + )) + .apply(swc_core::ecma::visit::fold_pass(lingui_macro)) + .visit_with(&mut extractor_visitor); + }); + + Ok(ExtractionResult { + messages: extractor_visitor.messages, + warnings: extractor_visitor.warnings, + }) +} diff --git a/crates/lingui_extractor/src/message_extractor_visitor.rs b/crates/lingui_extractor/src/message_extractor_visitor.rs new file mode 100644 index 0000000..1515739 --- /dev/null +++ b/crates/lingui_extractor/src/message_extractor_visitor.rs @@ -0,0 +1,549 @@ +use napi_derive::napi; +use serde::Serialize; +use std::collections::BTreeMap; +use std::sync::Arc as Lrc; +use swc_core::common::comments::Comments; +use swc_core::common::source_map::SmallPos; +use swc_core::common::{SourceMap, SourceMapper, Span, Spanned}; +use swc_core::ecma::ast::{ + BinaryOp, CallExpr, Callee, Expr, JSXAttrName, JSXAttrOrSpread, JSXAttrValue, JSXElement, + JSXElementName, JSXExpr, Lit, MemberProp, ObjectLit, Prop, PropName, PropOrSpread, Str, +}; +use swc_core::ecma::visit::{Visit, VisitWith}; +use swc_sourcemap as sourcemap; + +/// Represents the location where a message was found +#[napi(object)] +#[derive(Debug, Clone, Serialize)] +pub struct Origin { + pub filename: String, + pub line: u32, + pub column: Option, +} + +/// A message extracted from source code +#[napi(object)] +#[derive(Debug, Clone, Serialize)] +pub struct ExtractedMessage { + pub id: String, + pub message: Option, + pub context: Option, + pub comment: Option, + pub placeholders: BTreeMap, + pub origin: Option, +} + +/// Internal structure for building messages +#[derive(Debug, Default)] +struct RawMessage { + id: Option, + message: Option, + comment: Option, + context: Option, + placeholders: Option>, +} + +/// Result of message extraction containing messages and any warnings +#[napi(object)] +#[derive(Debug)] +pub struct ExtractionResult { + pub messages: Vec, + pub warnings: Vec, +} + +const I18N_OBJECT: &str = "i18n"; + +/// Check if a node has a specific leading comment +fn has_comment(comments: &dyn Comments, span: Span, comment_text: &str) -> bool { + if let Some(leading) = comments.get_leading(span.lo) { + return leading.iter().any(|c| c.text.trim() == comment_text); + } + false +} + +/// Check if a node has the lingui-extract-ignore comment +fn has_ignore_comment(comments: &dyn Comments, span: Span) -> bool { + has_comment(comments, span, "lingui-extract-ignore") +} + +/// Check if a node has the i18n marker comment +fn has_i18n_comment(comments: &dyn Comments, span: Span) -> bool { + has_comment(comments, span, "i18n") +} + +/// Extract text from an expression (handles strings, concatenation, template literals) +fn get_text_from_expression( + expr: &Expr, + emit_error_on_variable: bool, + warnings: &mut Vec, +) -> Option { + match expr { + Expr::Lit(Lit::Str(s)) => Some(s.value.to_string_lossy().into_owned()), + + Expr::Bin(bin_expr) if bin_expr.op == BinaryOp::Add => { + let left = get_text_from_expression(&bin_expr.left, emit_error_on_variable, warnings); + let right = get_text_from_expression(&bin_expr.right, emit_error_on_variable, warnings); + + left.zip(right) + .map(|(left, right)| format!("{left}{right}")) + } + + Expr::Tpl(tpl) => { + if tpl.quasis.len() > 1 { + warnings + .push("Could not extract from template literal with expressions.".to_string()); + return None; + } + + tpl.quasis + .first() + .and_then(|q| q.cooked.as_ref().map(|s| s.to_string_lossy().into_owned())) + } + + _ => { + if emit_error_on_variable { + warnings.push("Only strings or template literals could be extracted.".to_string()); + } + None + } + } +} + +/// Convert a values object expression to placeholders HashMap +fn values_object_to_placeholders( + obj: &ObjectLit, + warnings: &mut Vec, +) -> BTreeMap { + let mut placeholders = BTreeMap::new(); + + for (i, prop) in obj.props.iter().enumerate() { + if let PropOrSpread::Prop(prop) = prop { + if let Prop::KeyValue(kv) = &**prop { + let name = match &kv.key { + PropName::Ident(id) => Some(id.sym.to_string()), + PropName::Str(s) => Some(s.value.to_string_lossy().into_owned()), + PropName::Num(n) => Some(n.value.to_string()), + _ => { + warnings.push(format!( + "Could not extract values to placeholders. The key #{i} has unsupported syntax", + )); + None + } + }; + + if let Some(name) = name { + placeholders.insert(name, kv.value.span()); + } + } + } + } + + placeholders +} + +/// Extract message properties from an object expression +fn extract_from_object_expression(obj: &ObjectLit, warnings: &mut Vec) -> RawMessage { + let mut raw_msg = RawMessage::default(); + + let text_keys = ["id", "message", "comment", "context"]; + + for prop in &obj.props { + if let PropOrSpread::Prop(prop) = prop { + if let Prop::KeyValue(kv) = &**prop { + if let PropName::Ident(key_ident) = &kv.key { + let key_name = key_ident.sym.as_ref(); + + if key_name == "values" { + if let Expr::Object(obj_expr) = &*kv.value { + raw_msg.placeholders = + Some(values_object_to_placeholders(obj_expr, warnings)); + } + } else if text_keys.contains(&key_name) { + let text = get_text_from_expression(&kv.value, true, warnings); + + match key_name { + "id" => raw_msg.id = text, + "message" => raw_msg.message = text, + "comment" => raw_msg.comment = text, + "context" => raw_msg.context = text, + _ => {} + } + } + } + } + } + } + + raw_msg +} + +/// Visitor for extracting messages from AST +pub struct MessageExtractorVisitor<'a> { + pub messages: Vec, + pub warnings: Vec, + source_map: Lrc, + comments: &'a dyn Comments, + input_source_map: Option, +} + +impl<'a> MessageExtractorVisitor<'a> { + pub fn new( + source_map: Lrc, + comments: &'a dyn Comments, + inline_source_map: Option, + ) -> Self { + Self { + messages: Vec::new(), + warnings: Vec::new(), + source_map, + comments, + input_source_map: inline_source_map, + } + } + + /// Collect a message and add it to the list + fn collect_message(&mut self, raw: RawMessage, span: Span) { + // Prevent from adding undefined msgid + if raw.id.is_none() { + return; + } + + // Extract line and column from span using SourceMap + let loc = self.source_map.lookup_char_pos(span.lo); + + // Check if column is valid (not a synthetic/dummy position from macros) + // Synthetic spans often have very large column values that would overflow + let col = if loc.col.0 < 1000000 { + Some(loc.col.to_usize() + 1) // Convert to 1-based + } else { + None // Invalid/synthetic column, omit it + }; + + let filename = self.source_map.span_to_filename(span).to_string(); + + // Try to resolve original location using inline source map if available + let origin = self + .input_source_map + .as_ref() + .and_then(|source_map| { + // Source maps are 0-based, so we need to convert from 1-based line + let line = if loc.line > 0 { loc.line - 1 } else { 0 }; + let column = loc.col.to_usize(); + + // Look up the token in the source map + let token = source_map.lookup_token(line as u32, column as u32)?; + + // Get the original source filename + let original_file = source_map + .get_source(token.get_src_id()) + .map(|s| s.to_string()) + .unwrap_or_else(|| filename.clone()); + + // Source map line/column are 0-based, convert to 1-based + Some(Origin { + filename: original_file, + line: (token.get_src_line() + 1), + column: Some(token.get_src_col() + 1), + }) + }) + .or_else(|| { + // Fallback if token not found in source map or no source map + Some(Origin { + filename: filename.clone(), + line: loc.line as u32, + column: col.map(|c| c as u32), + }) + }); + + self.messages.push(ExtractedMessage { + id: raw.id.unwrap(), + message: raw.message, + context: raw.context, + comment: raw.comment, + placeholders: raw + .placeholders + .map(|placeholders| { + // map placeholders spans to snippets + placeholders + .into_iter() + .filter_map(|(key, span)| { + self.source_map + .span_to_snippet(span) + .ok() + .map(|snippet| (key, snippet)) + }) + .collect() + }) + .unwrap_or_default(), + origin, + }); + } + + /// Check if a JSX element is a Trans component from @lingui/react + fn is_trans_component(&self, el: &JSXElement) -> bool { + // For now, we check if the name is "Trans" + // In a full implementation, we would track imports + if let JSXElementName::Ident(ident) = &el.opening.name { + ident.sym.as_ref() == "Trans" + } else { + false + } + } + + /// Check if a callee is an i18n method (_ or t) + fn is_i18n_method(&self, callee: &Callee) -> bool { + if let Callee::Expr(expr) = callee { + if let Expr::Member(member) = &**expr { + // Check if property is _ or t + let is_underscore_or_t = match &member.prop { + MemberProp::Ident(id) => id.sym.as_ref() == "_" || id.sym.as_ref() == "t", + _ => false, + }; + + if !is_underscore_or_t { + return false; + } + + // Check if object is i18n or ends with .i18n + match &*member.obj { + Expr::Ident(id) if id.sym.as_ref() == I18N_OBJECT => return true, + Expr::Member(inner_member) => { + if let MemberProp::Ident(id) = &inner_member.prop { + return id.sym.as_ref() == I18N_OBJECT; + } + } + _ => {} + } + } + } + false + } + + /// Extract from a message descriptor (object expression with i18n comment) + fn extract_from_message_descriptor(&mut self, obj: &ObjectLit, span: Span) { + let raw = extract_from_object_expression(obj, &mut self.warnings); + + if raw.id.is_none() { + let loc = self.source_map.span_to_string(span); + self.warnings + .push(format!("{loc}: Missing message ID, skipping.")); + return; + } + + self.collect_message(raw, span); + } +} + +impl<'a> Visit for MessageExtractorVisitor<'a> { + fn visit_call_expr(&mut self, call: &CallExpr) { + // Check for ignore comment + if has_ignore_comment(self.comments, call.span) { + call.visit_children_with(self); + return; + } + + // Check if this is i18n._ or i18n.t + if !self.is_i18n_method(&call.callee) { + call.visit_children_with(self); + return; + } + + let first_arg = call.args.first(); + if first_arg.is_none() { + call.visit_children_with(self); + return; + } + + let first_arg = &first_arg.unwrap().expr; + + // Skip if first argument has i18n comment (will be processed by ObjectExpression visitor) + if has_i18n_comment(self.comments, first_arg.span()) { + call.visit_children_with(self); + return; + } + + // Check if first argument is an object expression + if let Expr::Object(obj) = &**first_arg { + self.extract_from_message_descriptor(obj, call.span); + call.visit_children_with(self); + return; + } + + // Otherwise, extract id from first argument + let id = get_text_from_expression( + first_arg, + false, // Don't emit error on variable + &mut self.warnings, + ); + + if id.is_none() { + call.visit_children_with(self); + return; + } + + let mut raw = RawMessage { + id, + ..Default::default() + }; + + // Extract placeholders from second argument if it's an object + if let Some(second_arg) = call.args.get(1) { + if let Expr::Object(obj) = &*second_arg.expr { + // self.source_map. + raw.placeholders = Some(values_object_to_placeholders(obj, &mut self.warnings)); + } + } + + // Merge with third argument if it's an object (message descriptor) + if let Some(third_arg) = call.args.get(2) { + if let Expr::Object(obj) = &*third_arg.expr { + let descriptor = extract_from_object_expression(obj, &mut self.warnings); + + // Merge properties (keeping existing id) + if descriptor.message.is_some() { + raw.message = descriptor.message; + } + if descriptor.comment.is_some() { + raw.comment = descriptor.comment; + } + if descriptor.context.is_some() { + raw.context = descriptor.context; + } + } + } + + self.collect_message(raw, call.span); + call.visit_children_with(self); + } + + fn visit_jsx_element(&mut self, el: &JSXElement) { + // Check if this is a Trans component + if !self.is_trans_component(el) { + el.visit_children_with(self); + return; + } + + // Check for spread attribute with i18n comment + for attr in &el.opening.attrs { + if let JSXAttrOrSpread::SpreadElement(spread) = attr { + if has_i18n_comment(self.comments, spread.expr.span()) { + el.visit_children_with(self); + return; + } + } + } + + // Extract props from attributes + let mut raw = RawMessage::default(); + + for attr in &el.opening.attrs { + if let JSXAttrOrSpread::JSXAttr(jsx_attr) = attr { + if let JSXAttrName::Ident(name_ident) = &jsx_attr.name { + let key = name_ident.sym.as_ref(); + + match key { + "id" | "message" | "comment" | "context" => { + let value = match &jsx_attr.value { + Some(JSXAttrValue::Str(s)) => { + Some(s.value.to_string_lossy().into_owned()) + } + Some(JSXAttrValue::JSXExprContainer(container)) => { + if let JSXExpr::Expr(expr) = &container.expr { + if let Expr::Lit(Lit::Str(s)) = &**expr { + Some(s.value.to_string_lossy().into_owned()) + } else { + None + } + } else { + None + } + } + _ => None, + }; + + if let Some(v) = value { + match key { + "id" => raw.id = Some(v), + "message" => raw.message = Some(v), + "comment" => raw.comment = Some(v), + "context" => raw.context = Some(v), + _ => {} + } + } + } + "values" => { + if let Some(JSXAttrValue::JSXExprContainer(container)) = &jsx_attr.value + { + if let JSXExpr::Expr(expr) = &container.expr { + if let Expr::Object(obj) = &**expr { + raw.placeholders = Some(values_object_to_placeholders( + obj, + &mut self.warnings, + )); + } + } + } + } + _ => {} + } + } + } + } + + // Check if id is missing + if raw.id.is_none() { + // Check if there's an id prop at all + let has_id_prop = el.opening.attrs.iter().any(|attr| { + if let JSXAttrOrSpread::JSXAttr(jsx_attr) = attr { + if let JSXAttrName::Ident(name_ident) = &jsx_attr.name { + return name_ident.sym.as_ref() == "id"; + } + } + false + }); + + // Only warn if there's no id prop or if the id value is a literal but empty + if !has_id_prop { + let loc = self.source_map.span_to_string(el.span); + self.warnings + .push(format!("{loc}: Missing message ID, skipping.")); + } + el.visit_children_with(self); + return; + } + + self.collect_message(raw, el.span); + el.visit_children_with(self); + } + + fn visit_object_lit(&mut self, obj: &ObjectLit) { + // Check for i18n comment + if has_i18n_comment(self.comments, obj.span) { + self.extract_from_message_descriptor(obj, obj.span); + } + + obj.visit_children_with(self); + } + + fn visit_str(&mut self, s: &Str) { + // Check for i18n comment + if !has_i18n_comment(self.comments, s.span) { + return; + } + + let id = s.value.to_string_lossy().into_owned(); + + if id.is_empty() { + self.warnings + .push("Empty StringLiteral, skipping.".to_string()); + return; + } + + let raw = RawMessage { + id: Some(id), + ..Default::default() + }; + + self.collect_message(raw, s.span); + } +} diff --git a/crates/lingui_extractor/tests/__snapshots__/js-call-expression.js.json b/crates/lingui_extractor/tests/__snapshots__/js-call-expression.js.json new file mode 100644 index 0000000..425f5df --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/js-call-expression.js.json @@ -0,0 +1,100 @@ +[ + { + "id": "Message", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-call-expression.js", + "line": 1, + "column": 13 + } + }, + { + "id": "Description", + "message": null, + "context": null, + "comment": "description", + "placeholders": {}, + "origin": { + "filename": "js-call-expression.js", + "line": 3, + "column": 25 + } + }, + { + "id": "ID", + "message": "Message with id", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-call-expression.js", + "line": 5, + "column": 16 + } + }, + { + "id": "Values {param}", + "message": null, + "context": null, + "comment": null, + "placeholders": { + "param": "param" + }, + "origin": { + "filename": "js-call-expression.js", + "line": 7, + "column": 20 + } + }, + { + "id": "Some id", + "message": null, + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-call-expression.js", + "line": 9, + "column": 21 + } + }, + { + "id": "my.id", + "message": "My Id Message", + "context": null, + "comment": "My comment", + "placeholders": {}, + "origin": { + "filename": "js-call-expression.js", + "line": 12, + "column": 1 + } + }, + { + "id": "Aliased Message", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-call-expression.js", + "line": 19, + "column": 1 + } + }, + { + "id": "my.id", + "message": "My Id Message", + "context": null, + "comment": "My comment", + "placeholders": {}, + "origin": { + "filename": "js-call-expression.js", + "line": 22, + "column": 1 + } + } +] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/__snapshots__/js-message-descriptor.js.json b/crates/lingui_extractor/tests/__snapshots__/js-message-descriptor.js.json new file mode 100644 index 0000000..fff1bd9 --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/js-message-descriptor.js.json @@ -0,0 +1,78 @@ +[ + { + "id": "Message", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-message-descriptor.js", + "line": 1, + "column": 22 + } + }, + { + "id": "Description", + "message": null, + "context": null, + "comment": "description", + "placeholders": {}, + "origin": { + "filename": "js-message-descriptor.js", + "line": 3, + "column": 34 + } + }, + { + "id": "ID", + "message": "Message with id", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-message-descriptor.js", + "line": 5, + "column": 25 + } + }, + { + "id": "Values {param} {0} {name} {value}", + "message": null, + "context": null, + "comment": null, + "placeholders": { + "0": "user.getName()", + "param": "param", + "value": "user\n ? user.name\n : null" + }, + "origin": { + "filename": "js-message-descriptor.js", + "line": 7, + "column": 29 + } + }, + { + "id": "Values {param} {0}", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-message-descriptor.js", + "line": 23, + "column": 30 + } + }, + { + "id": "Some id", + "message": null, + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-message-descriptor.js", + "line": 25, + "column": 30 + } + } +] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/__snapshots__/js-with-macros.js.json b/crates/lingui_extractor/tests/__snapshots__/js-with-macros.js.json new file mode 100644 index 0000000..d38d69a --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/js-with-macros.js.json @@ -0,0 +1,186 @@ +[ + { + "id": "xDAtGP", + "message": "Message", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 4, + "column": 2 + } + }, + { + "id": "xDAtGP", + "message": "Message", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 6, + "column": 15 + } + }, + { + "id": "Nu4oKW", + "message": "Description", + "context": null, + "comment": "description", + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 8, + "column": 25 + } + }, + { + "id": "ID", + "message": "Message with id", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 13, + "column": 16 + } + }, + { + "id": "QCVtWw", + "message": "Values {param}", + "context": null, + "comment": null, + "placeholders": { + "param": "param" + }, + "origin": { + "filename": "js-with-macros.js", + "line": 18, + "column": 21 + } + }, + { + "id": "ID Some", + "message": "Message with id some", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 20, + "column": 19 + } + }, + { + "id": "Backtick", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 25, + "column": 27 + } + }, + { + "id": "Some ID", + "message": null, + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 29, + "column": 25 + } + }, + { + "id": "Some other ID", + "message": null, + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 34, + "column": 25 + } + }, + { + "id": "Some ID", + "message": null, + "context": "Context2", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 39, + "column": 34 + } + }, + { + "id": "Some ID", + "message": null, + "context": "Context2", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 44, + "column": 28 + } + }, + { + "id": "sD7MQ4", + "message": "TplLiteral", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 49, + "column": 29 + } + }, + { + "id": "VO4BJY", + "message": "[useLingui]: TplLiteral", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 54, + "column": 4 + } + }, + { + "id": "ZxxjOE", + "message": "[useLingui]: Text {0, plural, offset:1 =0 {No books} =1 {1 book} other {# books}}", + "context": null, + "comment": null, + "placeholders": { + "0": "users.length" + }, + "origin": { + "filename": "js-with-macros.js", + "line": 57, + "column": 14 + } + }, + { + "id": "AZczQP", + "message": "Some ID", + "context": "Context2", + "comment": "This is a comment for a message", + "placeholders": {}, + "origin": { + "filename": "js-with-macros.js", + "line": 65, + "column": 36 + } + } +] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/__snapshots__/jsx-with-macros.js.json b/crates/lingui_extractor/tests/__snapshots__/jsx-with-macros.js.json new file mode 100644 index 0000000..cd92a6c --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/jsx-with-macros.js.json @@ -0,0 +1,90 @@ +[ + { + "id": "d1Kdl3", + "message": "Hi, my name is {name}", + "context": null, + "comment": null, + "placeholders": { + "name": "name" + }, + "origin": { + "filename": "jsx-with-macros.js", + "line": 4, + "column": 8 + } + }, + { + "id": "YikuIL", + "message": "Some message", + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-with-macros.js", + "line": 5, + "column": 28 + } + }, + { + "id": "LBCs5C", + "message": "Some other message", + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-with-macros.js", + "line": 6, + "column": 28 + } + }, + { + "id": "ru2rzr", + "message": "Some message", + "context": "Context2", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-with-macros.js", + "line": 7, + "column": 28 + } + }, + { + "id": "MHrjPM", + "message": "Title", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-with-macros.js", + "line": 8, + "column": 16 + } + }, + { + "id": "esnaQO", + "message": "{count, plural, one {# book} other {# books}}", + "context": null, + "comment": null, + "placeholders": { + "count": "count" + }, + "origin": { + "filename": "jsx-with-macros.js", + "line": 10, + "column": 17 + } + }, + { + "id": "TFdOtc", + "message": "Some message with comment", + "context": null, + "comment": "This is comment", + "placeholders": {}, + "origin": { + "filename": "jsx-with-macros.js", + "line": 15, + "column": 35 + } + } +] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/__snapshots__/jsx-without-macros.js.json b/crates/lingui_extractor/tests/__snapshots__/jsx-without-macros.js.json new file mode 100644 index 0000000..7570aeb --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/jsx-without-macros.js.json @@ -0,0 +1,86 @@ +[ + { + "id": "msg.hello", + "message": null, + "context": null, + "comment": "Description", + "placeholders": {}, + "origin": { + "filename": "jsx-without-macros.js", + "line": 5, + "column": 2 + } + }, + { + "id": "msg.context", + "message": null, + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-without-macros.js", + "line": 6, + "column": 2 + } + }, + { + "id": "msg.notcontext", + "message": null, + "context": "Context1", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-without-macros.js", + "line": 7, + "column": 2 + } + }, + { + "id": "msg.context", + "message": null, + "context": "Context2", + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-without-macros.js", + "line": 8, + "column": 2 + } + }, + { + "id": "msg.default", + "message": "Hello World", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-without-macros.js", + "line": 9, + "column": 2 + } + }, + { + "id": "msg.default", + "message": "Hello World", + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-without-macros.js", + "line": 10, + "column": 2 + } + }, + { + "id": "Hi, my name is <0>{name}", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "jsx-without-macros.js", + "line": 11, + "column": 2 + } + } +] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/__snapshots__/jsx-without-trans.js.json b/crates/lingui_extractor/tests/__snapshots__/jsx-without-trans.js.json new file mode 100644 index 0000000..d576235 --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/jsx-without-trans.js.json @@ -0,0 +1,30 @@ +[ + { + "id": "esnaQO", + "message": "{count, plural, one {# book} other {# books}}", + "context": null, + "comment": null, + "placeholders": { + "count": "count" + }, + "origin": { + "filename": "jsx-without-trans.js", + "line": 2, + "column": 16 + } + }, + { + "id": "8qNz-K", + "message": "{count, plural, one {# book} other {# books}}", + "context": "Some context", + "comment": null, + "placeholders": { + "count": "count" + }, + "origin": { + "filename": "jsx-without-trans.js", + "line": 3, + "column": 16 + } + } +] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/__snapshots__/with-sourcemaps.js.json b/crates/lingui_extractor/tests/__snapshots__/with-sourcemaps.js.json new file mode 100644 index 0000000..d764830 --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/with-sourcemaps.js.json @@ -0,0 +1,38 @@ +[ + { + "id": "Message from file a.jsx", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "../a.jsx", + "line": 1, + "column": 1 + } + }, + { + "id": "Message from file b.jsx", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "../b.jsx", + "line": 1, + "column": 1 + } + }, + { + "id": "Message from file c.jsx", + "message": null, + "context": null, + "comment": null, + "placeholders": {}, + "origin": { + "filename": "../c.jsx", + "line": 1, + "column": 1 + } + } +] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/__snapshots__/without-lingui.js.json b/crates/lingui_extractor/tests/__snapshots__/without-lingui.js.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/crates/lingui_extractor/tests/__snapshots__/without-lingui.js.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/crates/lingui_extractor/tests/fixtures/js-call-expression.js b/crates/lingui_extractor/tests/fixtures/js-call-expression.js new file mode 100644 index 0000000..19bc697 --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/js-call-expression.js @@ -0,0 +1,26 @@ +const msg = i18n._("Message") + +const withDescription = i18n._("Description", {}, { comment: "description" }) + +const withId = i18n._("ID", {}, { message: "Message with id" }) + +const withValues = i18n._("Values {param}", { param: param }) + +const withContext = i18n._("Some id", {}, { context: "Context1" }) + +// from message descriptor +i18n._({ + id: "my.id", + message: "My Id Message", + comment: "My comment", +}) + +// support alias +i18n.t("Aliased Message") + +// from message descriptor +i18n.t({ + id: "my.id", + message: "My Id Message", + comment: "My comment", +}) diff --git a/crates/lingui_extractor/tests/fixtures/js-message-descriptor.js b/crates/lingui_extractor/tests/fixtures/js-message-descriptor.js new file mode 100644 index 0000000..3761efc --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/js-message-descriptor.js @@ -0,0 +1,25 @@ +const msg = /*i18n*/ { id: "Message" } + +const withDescription = /*i18n*/ { id: "Description", comment: "description" } + +const withId = /*i18n*/ { id: "ID", message: "Message with id" } + +const withValues = /*i18n*/ { + id: "Values {param} {0} {name} {value}", + values: { + param: param, + 0: user.getName(), + ["name"]: "foo", + // prettier-ignore + value: user + ? user.name + : null, + }, +} +/** + * With values passed as variable + */ +const values = {} +const withValues2 = /*i18n*/ { id: "Values {param} {0}", values } + +const withContext = /*i18n*/ { id: "Some id", context: "Context1" } diff --git a/crates/lingui_extractor/tests/fixtures/js-with-macros.js b/crates/lingui_extractor/tests/fixtures/js-with-macros.js new file mode 100644 index 0000000..3a5df0c --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/js-with-macros.js @@ -0,0 +1,69 @@ +import {t, defineMessage, msg, plural} from "@lingui/core/macro" +import {useLingui} from "@lingui/react/macro" + +t`Message` + +const msg1 = t`Message` + +const withDescription = defineMessage({ + message: "Description", + comment: "description", +}) + +const withId = defineMessage({ + id: "ID", + message: "Message with id", +}) + +const withValues = t`Values ${param}` + +const withTId = t({ + id: "ID Some", + message: "Message with id some", +}) + +const withTIdBacktick = t({ + id: `Backtick`, +}) + +const tWithContextA = t({ + id: "Some ID", + context: "Context1", +}) + +const tWithContextB = t({ + id: "Some other ID", + context: "Context1", +}) + +const defineMessageWithContext = defineMessage({ + id: "Some ID", + context: "Context2", +}) + +const defineMessageAlias = msg({ + id: "Some ID", + context: "Context2", +}) + +const defineMessageAlias2 = msg`TplLiteral` + +function MyComponent() { + const {t} = useLingui() + + t`[useLingui]: TplLiteral` + + // macro nesting + const a = t`[useLingui]: Text ${plural(users.length, { + offset: 1, + 0: "No books", + 1: "1 book", + other: "# books", + })}` +} + +const defineMessageWithAllFields = msg({ + message: "Some ID", + context: "Context2", + comment: "This is a comment for a message" +}) diff --git a/crates/lingui_extractor/tests/fixtures/jsx-with-macros.js b/crates/lingui_extractor/tests/fixtures/jsx-with-macros.js new file mode 100644 index 0000000..99f7262 --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/jsx-with-macros.js @@ -0,0 +1,16 @@ +import {Trans} from "@lingui/react/macro"; +import {t, plural} from "@lingui/core/macro"; + +Hi, my name is {name} +;Some message +;Some other message +;Some message +; +; +;Some message with comment + diff --git a/crates/lingui_extractor/tests/fixtures/jsx-without-macros.js b/crates/lingui_extractor/tests/fixtures/jsx-without-macros.js new file mode 100644 index 0000000..5a91b7e --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/jsx-without-macros.js @@ -0,0 +1,12 @@ +import { Trans } from "@lingui/react" + +; + +; +; +; +; +; +; +; + diff --git a/crates/lingui_extractor/tests/fixtures/jsx-without-trans.js b/crates/lingui_extractor/tests/fixtures/jsx-without-trans.js new file mode 100644 index 0000000..6a6d0ee --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/jsx-without-trans.js @@ -0,0 +1,3 @@ +import { Plural } from "@lingui/react/macro" +; +; diff --git a/crates/lingui_extractor/tests/fixtures/with-sourcemaps.js b/crates/lingui_extractor/tests/fixtures/with-sourcemaps.js new file mode 100644 index 0000000..e2f060e --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/with-sourcemaps.js @@ -0,0 +1,12 @@ +"use strict"; +(() => { + // a.jsx + i18n.t("Message from file a.jsx"); + + // b.jsx + i18n.t("Message from file b.jsx"); + + // c.jsx + i18n.t("Message from file c.jsx"); +})(); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vYS5qc3giLCAiLi4vYi5qc3giLCAiLi4vYy5qc3giXSwKICAic291cmNlc0NvbnRlbnQiOiBbImkxOG4udCgnTWVzc2FnZSBmcm9tIGZpbGUgYS5qc3gnKVxuIiwgImkxOG4udCgnTWVzc2FnZSBmcm9tIGZpbGUgYi5qc3gnKVxuIiwgImkxOG4udCgnTWVzc2FnZSBmcm9tIGZpbGUgYy5qc3gnKVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7O0FBQUEsT0FBSyxFQUFFLHlCQUF5Qjs7O0FDQWhDLE9BQUssRUFBRSx5QkFBeUI7OztBQ0FoQyxPQUFLLEVBQUUseUJBQXlCOyIsCiAgIm5hbWVzIjogW10KfQo= diff --git a/crates/lingui_extractor/tests/fixtures/without-lingui.js b/crates/lingui_extractor/tests/fixtures/without-lingui.js new file mode 100644 index 0000000..16aa895 --- /dev/null +++ b/crates/lingui_extractor/tests/fixtures/without-lingui.js @@ -0,0 +1,7 @@ +import { Select } from "awesome-form-lib" +import { Trans } from "awesome-animation-lib" + +; + Displaced element + +;