[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug Report 🐛\nabout: Did something not work as expected?\n---\n\n## 🐛 Bug description\nDescribe your issue in detail.\n\n#### 🤔 Expected Behavior\nWhat should have happened?\n\n#### 👟 Steps to reproduce\nClear steps describing how to reproduce the issue, including commands and flags run. If you are seeing an error, please include the full error message and stack trace.\n\n#### 🌍 Your environment\nInclude the relevant details of your environment.\nwasm-pack version:\nrustc version:"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature Request 💡\nabout: Suggest a new idea for wasm-pack\n---\n\n## 💡 Feature description\nBrief explanation of the requested feature.\n\n#### 💻 Basic example\nInclude a basic code example if possible. Omit this section if not applicable."
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Make sure these boxes are checked! 📦✅\n\n- [ ] You have the latest version of `rustfmt` installed\n```bash\n$ rustup component add rustfmt\n```\n- [ ] You ran `cargo fmt` on the code base before submitting\n- [ ] You reference which issue is being closed in the PR text\n\n✨✨ 😄 Thanks so much for contributing to wasm-pack! 😄 ✨✨\n"
  },
  {
    "path": ".github/workflows/approve.yml",
    "content": "name: Automatic Approve\npermissions:\n  contents: read\n  pull-requests: write\non:\n  schedule: \n    - cron: \"0 0 * * *\"\n  workflow_dispatch:\njobs:\n  automatic-approve:\n    name: Automatic Approve\n    runs-on: ubuntu-latest\n    steps:\n      - name: Automatic Approve\n        uses: mheap/automatic-approve-action@v1.1.0\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n          workflows: \"test.yml\"\n"
  },
  {
    "path": ".github/workflows/book.yml",
    "content": "name: Build and deploy documentation book\n\non:\n  push:\n  pull_request:    \n\njobs:\n  book:\n    permissions:\n      contents: write\n    name: Build and deploy book\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v3\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          toolchain: stable\n\n      - name: Cache dependencies\n        uses: actions/cache@v3\n        env:\n          cache-name: cache-mdbook\n        with:\n          path: |\n            ~/.cargo/.crates.toml\n            ~/.cargo/.crates2.json\n            ~/.cargo/bin\n            ~/.cargo/registry/index\n            ~/.cargo/registry/cache\n          key: ${{ runner.os }}-build-${{ env.cache-name }}-0.3 }}\n\n      - name: Install mdbook\n        run: |\n          (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)\n          (test -x $HOME/.cargo/bin/mdbook || cargo install --vers \"^0.4\" mdbook)\n          cargo install-update -a\n\n      - name: Build book\n        run: |\n          mdbook --version\n          (cd docs && mv _theme theme && mdbook build)\n          rustc ./docs/_installer/build-installer.rs\n          ./build-installer\n\n      - name: Deploy book\n        uses: JamesIves/github-pages-deploy-action@v4.4.1\n        if: ${{ github.ref == 'refs/heads/master' }}\n        with:\n          branch: gh-pages\n          folder: docs\n          token: ${{ secrets.GITHUB_TOKEN }}\n          single-commit: true\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "on:\n  push:\n    tags:\n      - 'v*' # Run when tag matches v*, i.e. v1.0, v20.15.10\n\nname: Release\npermissions:\n  contents: read\n\nenv:\n  RELEASE_BIN: wasm-pack\n  RELEASE_DIR: artifacts\n  GITHUB_REF: '${{ github.ref }}'\n  WINDOWS_TARGET: x86_64-pc-windows-msvc\n  MACOS_AMD64_TARGET: x86_64-apple-darwin\n  MACOS_ARM64_TARGET: aarch64-apple-darwin\n  LINUX_AMD64_TARGET: x86_64-unknown-linux-musl\n  LINUX_ARM64_TARGET: aarch64-unknown-linux-musl\n\n  # Space separated paths to include in the archive.\n  RELEASE_ADDS: README.md LICENSE-APACHE LICENSE-MIT\n\njobs:\n  build:\n    name: Build artifacts\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        include:\n          - target: x86_64-unknown-linux-musl\n            os: ubuntu-latest\n            rust: stable\n          - target: aarch64-unknown-linux-musl\n            os: ubuntu-latest\n            rust: stable\n          - target: x86_64-apple-darwin\n            os: macos-latest\n            rust: stable\n          - target: aarch64-apple-darwin\n            os: macos-latest\n            rust: stable\n          - target: x86_64-pc-windows-msvc\n            os: windows-latest\n            rust: stable\n\n    steps:\n      - uses: actions/checkout@v3\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          toolchain: ${{ matrix.rust }}\n          targets: wasm32-unknown-unknown\n\n      - name: Query version number\n        id: get_version\n        shell: bash\n        run: |\n          echo \"using version tag ${GITHUB_REF:10}\"\n          echo ::set-output name=version::\"${GITHUB_REF:10}\"\n\n      - name: Install C compilation tooling (Linux)\n        if: matrix.os == 'ubuntu-latest'\n        run: |\n          sudo apt-get update -y\n          sudo apt-get install clang gcc-aarch64-linux-gnu musl-tools -y\n\n      - name: Install p7zip (MacOS)\n        if: matrix.os == 'macos-latest'\n        run: brew install p7zip\n\n      - name: Add rustup target\n        run: rustup target add ${{ matrix.target }}\n\n      - uses: taiki-e/install-action@v2\n        with:\n          tool: cross\n\n      - name: Build\n        run: cross build --release --target ${{ matrix.target }}\n\n      - name: Set RUSTFLAGS (Windows)\n        if: matrix.os == 'windows-latest'\n        run: echo \"RUSTFLAGS=-Ctarget-feature=+crt-static\" >> $GITHUB_ENV\n\n      - name: Create artifact directory\n        run: |\n          mkdir ${{ env.RELEASE_DIR }}\n          mkdir -p ${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }}\n\n      - name: Move binaries (Linux/MacOS)\n        if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'\n        run: |\n          mv ./target/${{ matrix.target }}/release/${{ env.RELEASE_BIN }} ${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }}/${{ env.RELEASE_BIN }}\n          mv ${{ env.RELEASE_ADDS }} ./${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }}\n\n      - name: Move binaries (Windows)\n        if: matrix.os == 'windows-latest'\n        shell: bash\n        run: |\n          cp ./target/${{ matrix.target }}/release/${{ env.RELEASE_BIN }}.exe ./${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }}/${{ env.RELEASE_BIN }}.exe\n          cp ./target/${{ matrix.target }}/release/${{ env.RELEASE_BIN }}.exe wasm-pack-init.exe\n          mv ${{ env.RELEASE_ADDS }} ./${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }}\n          mv wasm-pack-init.exe ${{ env.RELEASE_DIR }}\n\n      - name: Create tarball\n        shell: bash\n        run: 7z a -ttar -so -an ./${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }} | 7z a -si ./${{ env.RELEASE_DIR }}/${{ env.RELEASE_BIN }}-${{ steps.get_version.outputs.VERSION }}-${{ matrix.target }}.tar.gz\n\n      - name: Upload Zip\n        uses: actions/upload-artifact@v4\n        with:\n          name: ${{ matrix.target }}\n          path: ./${{ env.RELEASE_DIR }}\n\n  release:\n    name: GitHub Release\n    needs: build\n    permissions:\n      contents: write\n    runs-on: ubuntu-latest\n    steps:\n      - name: Query version number\n        id: get_version\n        shell: bash\n        run: |\n          echo \"using version tag ${GITHUB_REF:10}\"\n          echo ::set-output name=version::\"${GITHUB_REF:10}\"\n\n      - name: Create Release\n        id: create_release\n        uses: actions/create-release@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          tag_name: ${{ steps.get_version.outputs.VERSION }}\n          release_name: ${{ steps.get_version.outputs.VERSION }}\n\n      - name: Download Linux amd64 tarball\n        uses: actions/download-artifact@v4.1.7\n        with:\n          name: ${{ env.LINUX_AMD64_TARGET }}\n\n      - name: Download Linux arm64 tarball\n        uses: actions/download-artifact@v4.1.7\n        with:\n          name: ${{ env.LINUX_ARM64_TARGET }}\n\n      - name: Download Windows tarball\n        uses: actions/download-artifact@v4.1.7\n        with:\n          name: ${{ env.WINDOWS_TARGET }}\n\n      - name: Download ARM64 MacOS tarball\n        uses: actions/download-artifact@v4.1.7\n        with:\n          name: ${{ env.MACOS_ARM64_TARGET }}\n      - name: Download AMD64 MacOS tarball\n        uses: actions/download-artifact@v4.1.7\n        with:\n          name: ${{ env.MACOS_AMD64_TARGET }}\n\n      - name: Release Linux amd64 tarball\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.LINUX_AMD64_TARGET }}.tar.gz\n          asset_content_type: application/gzip\n          asset_name: wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.LINUX_AMD64_TARGET }}.tar.gz\n\n      - name: Release Linux arm64 tarball\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.LINUX_ARM64_TARGET }}.tar.gz\n          asset_content_type: application/gzip\n          asset_name: wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.LINUX_ARM64_TARGET }}.tar.gz\n\n      - name: Release Windows tarball\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.WINDOWS_TARGET }}.tar.gz\n          asset_content_type: application/gzip\n          asset_name: wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.WINDOWS_TARGET }}.tar.gz\n\n      - name: Release Windows init exe\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./wasm-pack-init.exe\n          asset_content_type: application/vnd.microsoft.portable-executable\n          asset_name: wasm-pack-init.exe\n\n      - name: Release AMD64 MacOS tarball\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.MACOS_AMD64_TARGET }}.tar.gz\n          asset_content_type: application/gzip\n          asset_name: wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.MACOS_AMD64_TARGET }}.tar.gz\n      - name: Release ARM64 MacOS tarball\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.MACOS_ARM64_TARGET }}.tar.gz\n          asset_content_type: application/gzip\n          asset_name: wasm-pack-${{ steps.get_version.outputs.VERSION }}-${{ env.MACOS_ARM64_TARGET }}.tar.gz\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Tests\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\njobs:\n  test:\n    name: Test\n    permissions:\n      contents: read\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        build: [linux-stable, macos-stable, windows-stable]\n        include:\n          - build: linux-stable\n            os: ubuntu-latest\n            rust: stable\n          - build: macos-stable\n            os: macos-latest\n            rust: stable\n          - build: windows-stable\n            os: windows-latest\n            rust: stable\n    steps:\n      - uses: actions/checkout@v4\n      - uses: nanasess/setup-chromedriver@master\n      - if: matrix.os == 'macos-latest'\n        run: brew install --cask firefox\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          toolchain: ${{ matrix.rust }}\n          targets: wasm32-unknown-unknown\n      - uses: actions/setup-node@v3\n      - name: Cache dependencies\n        uses: actions/cache@v4\n        with:\n          path: |\n            ~/.cargo/.crates.toml\n            ~/.cargo/.crates2.json\n            ~/.cargo/bin\n            ~/.cargo/registry/index\n            ~/.cargo/registry/cache\n            target\n          key: ${{ runner.os }}-build-${{ hashFiles('Cargo.lock') }}\n      - name: Run Tests\n        run: cargo test --all --locked\n        env:\n          RUST_BACKTRACE: 1\n      - name: Clippy\n        run: cargo clippy\n      - name: Cargo fmt\n        run: cargo fmt --all -- --check\n"
  },
  {
    "path": ".gitignore",
    "content": "target/\n**/*.rs.bk\ntests/.crates.toml\ntests/bin\n/build-installer\ndocs/book\ndocs/installer\n\n.idea\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## 🤍 Unreleased\n\n## 🌻 0.14.0\n\n- ### ✨ Features\n\n  - **Support arbitrary wasm targets (WASI support) - [RReverser], [pull/1524]**\n\n    Allows building for targets other than wasm32-unknown-unknown, enabling WASI and other custom wasm targets.\n\n    [pull/1524]: https://github.com/drager/wasm-pack/pull/1524\n    [RReverser]: https://github.com/RReverser\n\n  - **macOS ARM (aarch64-apple-darwin) build support - [kaleidawave], [pull/1529]**\n\n    Adds native Apple Silicon support in release builds and NPM package.\n\n    [pull/1529]: https://github.com/drager/wasm-pack/pull/1529\n    [kaleidawave]: https://github.com/kaleidawave\n\n  - **Allow `--split-linked-modules` flag for wasm-bindgen - [codeart1st], [pull/1443]**\n\n    [pull/1443]: https://github.com/drager/wasm-pack/pull/1443\n    [codeart1st]: https://github.com/codeart1st\n\n  - **Custom build profile support - [rafaelbeckel], [pull/1428]**\n\n    Allows using custom cargo profiles via `--profile`.\n\n    [pull/1428]: https://github.com/drager/wasm-pack/pull/1428\n    [rafaelbeckel]: https://github.com/rafaelbeckel\n\n- ### 🤕 Fixes\n\n  - **Fix NPM package download URL - [qinyuhang], [pull/1543]**\n\n    [pull/1543]: https://github.com/drager/wasm-pack/pull/1543\n    [qinyuhang]: https://github.com/qinyuhang\n\n  - **Filter build artifacts to only .wasm files - [drager], [pull/1535]**\n\n    [pull/1535]: https://github.com/drager/wasm-pack/pull/1535\n\n  - **Handle undefined VERSION in installer script - [BrianHung], [pull/1512]**\n\n    [pull/1512]: https://github.com/drager/wasm-pack/pull/1512\n    [BrianHung]: https://github.com/BrianHung\n\n  - **Fix it_gets_wasm_bindgen_version test - [mshroyer], [pull/1509]**\n\n    [pull/1509]: https://github.com/drager/wasm-pack/pull/1509\n    [mshroyer]: https://github.com/mshroyer\n\n- ### 🛠️ Maintenance\n\n  - **Update dependencies to latest versions - [drager], [pull/1536]**\n\n    [pull/1536]: https://github.com/drager/wasm-pack/pull/1536\n\n  - **Security workflow permissions fixes - [drager]**\n\n  - **Bump ring from 0.17.8 to 0.17.14 - [dependabot], [pull/1516]**\n\n    [pull/1516]: https://github.com/drager/wasm-pack/pull/1516\n\n  - **Bump brace-expansion from 1.1.11 to 1.1.12 in /npm - [dependabot], [pull/1515]**\n\n    [pull/1515]: https://github.com/drager/wasm-pack/pull/1515\n\n  - **Bump rustls from 0.23.16 to 0.23.18 - [dependabot], [pull/1451]**\n\n    [pull/1451]: https://github.com/drager/wasm-pack/pull/1451\n    [dependabot]: https://github.com/apps/dependabot\n\n  - **Fix tar vulnerability (CVE-2026-23745) in npm package**\n\n    Override tar dependency to ^7.5.3 to fix arbitrary file overwrite and symlink poisoning vulnerability ([GHSA-8qq5-rm4j-mr97]).\n\n    [GHSA-8qq5-rm4j-mr97]: https://github.com/advisories/GHSA-8qq5-rm4j-mr97\n\n  - **Fix axios vulnerabilities in npm package**\n\n    Override axios dependency to ^0.30.0 to fix SSRF/credential leakage via absolute URL and XSRF-TOKEN leakage (CSRF) vulnerabilities.\n\n- ### 📖 Documentation\n\n  - **Update documentation links to drager's repo - [yutannihilation], [pull/1513]**\n\n    [pull/1513]: https://github.com/drager/wasm-pack/pull/1513\n    [yutannihilation]: https://github.com/yutannihilation\n\n  - **Document prerequisites for webdriver tests - [mshroyer], [pull/1509]**\n\n## ☀️ 0.13.1\n\n- ### ✨ Features\n\n  - **Requests using proxy settings from env - [jjyr], [pull/1438]**\n\n    This enables ureq to use proxy settings from env, it solves lots of pain in network restricted environments.\n\n    [pull/1438]: https://github.com/rustwasm/wasm-pack/pull/1438\n    [jjyr]: https://github.com/jjyr\n\n- ### 🤕 Fixes\n\n  - **Update binary-install to v0.4.1 - [drager], [pull/1407]**\n\n    Release v0.4.0 of binary-install introduced a regression that caused failures on some platforms. This release fixes that regression.\n\n    [pull/1407]: https://github.com/rustwasm/wasm-pack/pull/1407\n    [drager]: https://github.com/drager\n\n  - ** Allow npm binary upgrades - [net], [pull/1439]**\n\n    Fixes an issue where upgrading `wasm-pack` via NPM would not update the underlying binary.\n    Previously, the binary was stored in the `binary-install` package's directory without versioning, causing version upgrades to silently fail as the old binary continued to be used.\n    The binary is now stored in `node_modules/wasm-pack/binary/`, ensuring proper version updates when upgrading the package.\n\n    **Before:** Upgrading from `0.12.1` to `0.13.0` would continue using the `0.12.1` binary\n    **After:** Each `wasm-pack` version manages its own binary, enabling proper version upgrades\n\n    [pull/1439]: https://github.com/rustwasm/wasm-pack/pull/1439\n    [net]: https://github.com/net\n\n- ### 🛠️ Maintenance\n\n  - ** Remove unmaintained dependency atty in favor of stdlib - [mariusvniekerk], [pull/1436]**\n\n    [pull/1436]: https://github.com/rustwasm/wasm-pack/pull/1436\n    [mariusvniekerk]: https://github.com/mariusvniekerk\n\n## ☀️ 0.13.0\n\n- ### ✨ Features\n\n  - **Add option to skip optimization with wasm-opt - [sisou], [pull/1321]**\n\n    This feature introduces the `--no-opt` option to wasm-pack, providing a significant improvement in build efficiency for projects requiring multiple wasm-pack executions.\n\n    [pull/1321]: https://github.com/rustwasm/wasm-pack/pull/1321\n    [sisou]: https://github.com/sisou\n\n  - **Add support geckodriver for linux-aarch64 - [EstebanBorai], [pull/1371]**\n\n    Introduces support to download Geckodriver in Linux aarch64.\n\n    [pull/1371]: https://github.com/rustwasm/wasm-pack/pull/1371\n    [EstebanBorai]: https://github.com/EstebanBorai\n\n  - **Add wasm-opt linux aarch64 condition - [dkristia], [issue/1392], [pull/1393]**\n\n    A linux aarch64 build for wasm-opt exists in the newest binaryen versions.\n\n    [issue/1392]: https://github.com/rustwasm/wasm-pack/issues/1392\n    [pull/1393]: https://github.com/rustwasm/wasm-pack/pull/1393\n    [dkristia]: https://github.com/dkristia\n\n- ### 🤕 Fixes\n\n  - **Fix passing relative paths to cargo - [dfaust], [issue/704], [issue/1156], [issue/1252], [pull/1331]**\n\n    When building a crate located in a sub-directory, relative paths, passed as extra options to cargo (like `--target-dir`), are now handled correctly.\n\n    [issue/704]: https://github.com/rustwasm/wasm-pack/issues/704\n    [issue/1156]: https://github.com/rustwasm/wasm-pack/issues/1156\n    [issue/1252]: https://github.com/rustwasm/wasm-pack/issues/1252\n    [pull/1331]: https://github.com/rustwasm/wasm-pack/pull/1331\n    [dfaust]: https://github.com/dfaust\n\n  - **Rewrite wasm_target to use target-libdir - [daidoji], [issue/1342], [pull/1343]**\n\n    Rewritten wasm_target to use target libdir from the rustc tool rather than looking through sysroot. This is to accomodate non-rustup installations.\n\n    [issue/1342]: https://github.com/rustwasm/wasm-pack/issues/1342\n    [pull/1343]: https://github.com/rustwasm/wasm-pack/pull/1343\n    [daidoji]: https://github.com/daidoji\n\n  - **Declare ES module in package.json - [gthb], [issue/1039], [pull/1061]**\n\n    In bundler mode, generate package.json with \"type\": \"module\" and use the \"main\" attribute instead of the \"module\" attribute.\n\n    This change makes the built ES module palatable to Node.js (when run with --experimental-vm-modules --experimental-wasm-modules),\n    while it remains also palatable to webpack as illustrated in webpack/webpack#14313\n    (where the pkg subfolder is generated with wasm-pack built with this change).\n    This resolves the headache of using a wasm-pack-built package in a library that one needs to both run directly in Node and include in a webpack build.\n\n    [issue/1039]: https://github.com/rustwasm/wasm-pack/issues/1039\n    [pull/1061]: https://github.com/rustwasm/wasm-pack/pull/1061\n    [gthb]: https://github.com/gthb\n\n  - **Use new chromdriver endpoint and fix CI - [Myriad-Dreamin], [kade-robertson], [issue/1315], [issue/1390], [pull/1325], [pull/1391]**\n\n    [issue/1315]: https://github.com/rustwasm/wasm-pack/issues/1315\n    [issue/1390]: https://github.com/rustwasm/wasm-pack/issues/1390\n    [pull/1325]: https://github.com/rustwasm/wasm-pack/pull/1325\n    [pull/1391]: https://github.com/rustwasm/wasm-pack/pull/1391\n    [Myriad-Dreamin]: https://github.com/Myriad-Dreamin\n    [kade-robertson]: https://github.com/kade-robertson\n\n  - **Add mingw support to npm package - [nathaniel-daniel], [issue/1354], [issue/1359], [pull/1363]**\n\n    Fixes the NPM package's platform detection for mingw.\n\n    [issue/1354]: https://github.com/rustwasm/wasm-pack/issues/1354\n    [issue/1359]: https://github.com/rustwasm/wasm-pack/issues/1359\n    [pull/1363]: https://github.com/rustwasm/wasm-pack/pull/1363\n    [nathaniel-daniel]: https://github.com/nathaniel-daniel\n\n  - **pkg-dir option for pack and publish commands - [danielronnkvist], [issue/1369], [pull/1370]**\n\n    To be able to use these commands when the output directory option to the build command isn't the default pkg.\n\n    [issue/1369]: https://github.com/rustwasm/wasm-pack/issues/1369\n    [pull/1370]: https://github.com/rustwasm/wasm-pack/pull/1370\n    [danielronnkvist]: https://github.com/danielronnkvist\n\n  - **Optimize out-dir display - [ahaoboy], [issue/1395], [pull/1396]**\n\n    Optimize out-dir display.\n\n    from:\n\n    `[INFO]: 📦 Your wasm pkg is ready to publish at /root/code/fib-wasm/fib-rs/../fib-wasm/wasm.`\n\n    to:\n\n    `[INFO]: 📦 Your wasm pkg is ready to publish at /root/code/fib-wasm/fib-wasm/wasm.`\n\n    [issue/1395]: https://github.com/rustwasm/wasm-pack/issues/1395\n    [pull/1396]: https://github.com/rustwasm/wasm-pack/pull/1396\n    [ahaoboy]: https://github.com/ahaoboy\n\n- ### 🛠️ Maintenance\n\n  - **Fix error and warnings in install script - [lucashorward], [issue/1159], [issue/1217], [issue/1283], [pull/1320]**\n\n    [issue/1159]: https://github.com/rustwasm/wasm-pack/issues/1159\n    [issue/1217]: https://github.com/rustwasm/wasm-pack/issues/1217\n    [issue/1283]: https://github.com/rustwasm/wasm-pack/issues/1283\n    [pull/1320]: https://github.com/rustwasm/wasm-pack/pull/1320\n    [lucashorward]: https://github.com/lucashorward\n\n  - **Bump follow-redirects from 1.14.9 to 1.15.6 in /npm - [dependabot], [pull/1375]**\n\n    [pull/1375]: https://github.com/rustwasm/wasm-pack/pull/1375\n\n  - **Bump rustls-webpki from 0.100.1 to 0.100.2 - [dependabot], [pull/1323]**\n\n    [pull/1341]: https://github.com/rustwasm/wasm-pack/pull/1341\n\n  - **Bump rustix from 0.37.20 to 0.37.25 - [dependabot], [pull/1341]**\n\n    [pull/1323]: https://github.com/rustwasm/wasm-pack/pull/1323\n    [dependabot]: https://github.com/apps/dependabot\n\n  - **Bump rustls from 0.21.9 to 0.21.11 - [dependabot], [pull/1385]**\n\n    [pull/1385]: https://github.com/rustwasm/wasm-pack/pull/1385\n    [dependabot]: https://github.com/apps/dependabot\n\n  - **Bump tar from 6.1.11 to 6.2.1 in /npm - [dependabot], [pull/1379]**\n\n    [pull/1379]: https://github.com/rustwasm/wasm-pack/pull/1379\n    [dependabot]: https://github.com/apps/dependabot\n\n- ### 📖 Documentation\n\n  - **Fix typo in README - [Lionelf329], [pull/1368]**\n\n    [pull/1268]: https://github.com/rustwasm/wasm-pack/pull/1368\n    [Lionelf329]: https://github.com/Lionelf329\n\n  - **Add a description of build --target deno - [puxiao], [pull/1344]**\n\n    [pull/1344]: https://github.com/rustwasm/wasm-pack/pull/1344\n    [puxiao]: https://github.com/puxiao\n\n  - **Document deno in build target - [sigmaSd], [pull/1348]**\n\n    [pull/1348]: https://github.com/rustwasm/wasm-pack/pull/1348\n    [sigmaSd]: https://github.com/sigmaSd\n\n  - **Fix local navigation backing one step too far in docs - [SamuSoft], [pull/1387]**\n\n    [pull/1387]: https://github.com/rustwasm/wasm-pack/pull/1387\n    [SamuSoft]: https://github.com/SamuSoft\n\n  - **Add --target web to quick start build command - [josephrocca], [pull/1367]**\n\n    [pull/1367]: https://github.com/rustwasm/wasm-pack/pull/1367\n    [josephrocca]: https://github.com/josephrocca\n\n## ☀️ 0.12.1\n\n- ### 🤕 Fixes\n\n  - **Restore --version command - [lynn], [issue/1301], [pull/1305]**\n\n    The --version command got lost in space in v0.12.0. It's now brought back!\n\n    [issue/1301]: https://github.com/rustwasm/wasm-pack/issues/1301\n    [pull/1305]: https://github.com/rustwasm/wasm-pack/pull/1305\n    [lynn]: https://github.com/lynn\n\n  - **Fix value parser for Option<PathBuf> - [Myriad-Dreamin], [issue/1304], [pull/1307]**\n\n    A value parser for OsString cannot parse a command line argument for Option<PathBuf>,\n    which let it failed to specify paths for pack, publish and test commands, this faulty behavior\n    was introduced in v0.12.0.\n\n    [issue/1304]: https://github.com/rustwasm/wasm-pack/issues/1304\n    [pull/1307]: https://github.com/rustwasm/wasm-pack/pull/1307\n    [Myriad-Dreamin]: https://github.com/Myriad-Dreamin\n\n## ☀️ 0.12.0\n\n- ### ✨ Features\n\n  - **Add --no-pack flag to build command - [hamza1311], [ashleygwilliams], [issue/691], [issue/811], [pull/695], [pull/1291]**\n\n    When calling wasm-pack build a user can optionally pass --no-pack and wasm-pack will build your wasm, generate js, and not build a package.json.\n\n    [issue/691]: https://github.com/rustwasm/wasm-pack/issues/691\n    [issue/811]: https://github.com/rustwasm/wasm-pack/issues/811\n    [pull/695]: https://github.com/rustwasm/wasm-pack/pull/695\n    [pull/1291]: https://github.com/rustwasm/wasm-pack/pull/1291\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n\n  - **Add wasmbindgen option: omit_default_module_path - [matthiasgeihs], [pull/1272]**\n\n    Adds an option to call wasm-bindgen with --omit_default_module_path.\n\n    [pull/1272]: https://github.com/rustwasm/wasm-pack/pull/1272\n    [matthiasgeihs]: https://github.com/matthiasgeihs\n\n- ### 🤕 Fixes\n\n  - **Add HTTP header USER-AGENT - [LeviticusNelson], [issue/1266], [pull/1285]**\n\n    We encountered some issues when we didn't send an User-Agent. This is now fixed.\n\n    [issue/1266]: https://github.com/rustwasm/wasm-pack/issues/1266\n    [pull/1285]: https://github.com/rustwasm/wasm-pack/pull/1285\n    [LeviticusNelson]: https://github.com/LeviticusNelson\n\n  - **Replace curl with ureq - [hamza1311], [issue/650], [issue/823], [issue/997], [issue/1079], [issue/1203], [issue/1234], [issue/1281], [pull/1290]**\n\n    The HTTP client is now pure Rust. Removes the dependency of openssl which have caused a lot of issues for people using wasm-pack on various distributions.\n\n    [issue/650]: https://github.com/rustwasm/wasm-pack/issues/650\n    [issue/823]: https://github.com/rustwasm/wasm-pack/issues/823\n    [issue/997]: https://github.com/rustwasm/wasm-pack/issues/997\n    [issue/1079]: https://github.com/rustwasm/wasm-pack/issues/1079\n    [issue/1203]: https://github.com/rustwasm/wasm-pack/issues/1203\n    [issue/1234]: https://github.com/rustwasm/wasm-pack/issues/1234\n    [issue/1281]: https://github.com/rustwasm/wasm-pack/issues/1281\n    [pull/1290]: https://github.com/rustwasm/wasm-pack/pull/1290\n    [hamza1311]: https://github.com/hamza1311\n\n  - **Update binary-install to 0.2.0. binary-install replaced curl with ureq - [drager]**\n\n    See [PR](https://github.com/rustwasm/binary-install/pull/24) in binary-install repo for more information.\n\n    [drager]: https://github.com/drager\n\n  - **Remove --always-auth from npm login - [EstebanBorai], [pull/1288]**\n\n    npm login doesn't support --always-auth anymore, instead it is under the adduser subcommand.\n\n    [pull/1288]: https://github.com/rustwasm/wasm-pack/pull/1288\n    [EstebanBorai]: https://github.com/EstebanBorai\n\n  - **Turn off cargo colors during log level test - [dtolnay], [pull/1294]**\n\n    [pull/1294]: https://github.com/rustwasm/wasm-pack/pull/1294\n    [dtolnay]: https://github.com/dtolnay\n\n  - **Fix getting the target-dir in wasm_bindgen_build - [tomasol], [issue/1278], [pull/1279]**\n\n    Fixes a wasm-pack panic if --target-dir was supplied (and arguments are not sorted).\n\n    [issue/1278]: https://github.com/rustwasm/wasm-pack/issues/1278\n    [pull/1279]: https://github.com/rustwasm/wasm-pack/pull/1279\n    [tomasol]: https://github.com/tomasol\n\n  - **Respect package.readme in Cargo.toml - [heaths], [issue/1215], [pull/1298], [pull/1216]**\n\n    wasm-pack now respects specifying readme=false:\n\n    ```toml\n    [package]\n    readme = false\n    ```\n\n    [issue/1215]: https://github.com/rustwasm/wasm-pack/issues/1215\n    [pull/1298]: https://github.com/rustwasm/wasm-pack/pull/1298\n    [pull/1216]: https://github.com/rustwasm/wasm-pack/pull/1216\n    [heaths]: https://github.com/heaths\n\n- ### 📖 Documentation\n\n  - **Don't hide install options behind link - [oyamauchi], [issue/355], [pull/1242]**\n\n    [issue/355]: https://github.com/rustwasm/wasm-pack/issues/355\n    [pull/1242]: https://github.com/rustwasm/wasm-pack/issues/1242\n    [oyamauchi]: https://github.com/oyamauchi\n\n- ### 🛠️ Maintenance\n\n  - **Bump cargo-generate version to 0.18.2 - [sassman], [issue/1245] [pull/1269]**\n\n    [issue/1245]: https://github.com/rustwasm/wasm-pack/issues/1245\n    [pull/1269]: https://github.com/rustwasm/wasm-pack/pull/1269\n    [sassman]: https://github.com/sassman\n\n  - **Replace unmaintained actions-rs/toolchain action in CI workflows - [striezel], [pull/1246]**\n\n    Now we are using https://github.com/dtolnay/rust-toolchain instead.\n\n    [pull/1246]: https://github.com/rustwasm/wasm-pack/pull/1246\n    [striezel]: https://github.com/striezel\n\n  - **Update several dependencies - [hamza1311], [pull/1292]**\n\n    Updated clap, toml, predicates and serial_test to their latest versions.\n\n    [pull/1292]: https://github.com/rustwasm/wasm-pack/pull/1292\n\n## 🌦️ 0.11.1\n\n- ### 🤕 Fixes\n\n  - **Fix discovery of locally installed `wasm-opt` - [Liamolucko], [issue/1247], [pull/1257]**\n\n    [issue/1247]: https://github.com/rustwasm/wasm-pack/issues/1247\n    [pull/1257]: https://github.com/rustwasm/wasm-pack/pull/1257\n    [Liamolucko]: https://github.com/Liamolucko\n\n  - **Fix wasm-pack bin script entry - [ahippler], [issue/1248], [pull/1250]**\n\n    [issue/1248]: https://github.com/rustwasm/wasm-pack/issues/1248\n    [pull/1250]: https://github.com/rustwasm/wasm-pack/pull/1250\n    [ahippler]: https://github.com/ahippler\n\n- ### 🛠️ Maintenance\n\n  - **bump openssl from 0.10.46 to 0.10.48 - [pull/1254]**\n\n    [pull/1254]: https://github.com/rustwasm/wasm-pack/pull/1254\n\n## 🌦️ 0.11.0\n\n- ### ✨ Features\n\n  - **Make Deno target available - [egfx-notifications], [issue/672], [issue/879], [pull/1117]**\n\n    [issue/672]: https://github.com/rustwasm/wasm-pack/issues/672\n    [issue/879]: https://github.com/rustwasm/wasm-pack/issues/879\n    [pull/1117]: https://github.com/rustwasm/wasm-pack/pull/1117\n    [egfx-notifications]: https://github.com/egfx-notifications\n\n  - **Add support for more platforms to installer script - [omninonsense], [issue/1064], [issue/952], [issue/1125], [pull/1122]**\n\n    This makes the installation script work on M1 macs, as well as inside docker (especially when combined with buildx) for aarch64/arm64 architectures.\n\n    [issue/1064]: https://github.com/rustwasm/wasm-pack/issues/1064\n    [issue/952]: https://github.com/rustwasm/wasm-pack/issues/952\n    [issue/1125]: https://github.com/rustwasm/wasm-pack/issues/1125\n    [pull/1122]: https://github.com/rustwasm/wasm-pack/pull/1122\n    [omninonsense]: https://github.com/omninonsense\n\n  - **Add Linux arm64 support - [nnelgxorz], [issue/1169], [pull/1170]**\n\n    [issue/1169]: https://github.com/rustwasm/wasm-pack/issues/1169\n    [pull/1170]: https://github.com/rustwasm/wasm-pack/pull/1170\n    [nnelgxorz]: https://github.com/nnelgxorz\n\n  - **Add support for workspace inheritance - [printfn], [issue/1180], [pull/1185]**\n\n    [issue/1180]: https://github.com/rustwasm/wasm-pack/issues/1180\n    [pull/1185]: https://github.com/rustwasm/wasm-pack/pull/1185\n\n- ### 🤕 Fixes\n\n  - **--target-dir as extra option is now considered as expected - [sassman], [issue/1076], [pull/1082]**\n\n    [issue/1076]: https://github.com/rustwasm/wasm-pack/issues/1076\n    [pull/1082]: https://github.com/rustwasm/wasm-pack/pull/1082\n    [sassman]: https://github.com/sassman\n\n  - **Pass through --weak-refs --reference-types flags to bindgen - [serprex], [issue/930], [pull/937]**\n\n    [issue/930]: https://github.com/rustwasm/wasm-pack/issues/930\n    [pull/937]: https://github.com/rustwasm/wasm-pack/pull/937\n    [serprex]: https://github.com/serprex\n\n  - **Fix binaryen URL and use updated binary-install to fix installation on macOS - [matheus23], [printfn], [pull/1188]**\n\n    Use the updated binary-install crate (rustwasm/binary-install#21), switches from failure to anyhow to match what binary-install uses, and fixes wasm-opt installation on macOS.\n\n    [pull/1188]: https://github.com/rustwasm/wasm-pack/pull/1188\n    [matheus23]: https://github.com/matheus23\n    [printfn]: https://github.com/printfn\n    [rustwasm/binary-install#21]: https://github.com/rustwasm/binary-install/pull/21\n\n  - **Mark snippets and the bundler target's main file as having side effects - [Liamolucko], [issue/972], [rustwasm/wasm-bindgen/3276], [pull/1224]**\n\n    [issue/972]: https://github.com/rustwasm/wasm-pack/issues/972\n    [rustwasm/wasm-bindgen/3276]: https://github.com/rustwasm/wasm-bindgen/issues/3276\n    [pull/1224]: https://github.com/rustwasm/wasm-pack/pull/1224\n    [Liamolucko]: https://github.com/Liamolucko\n\n- ### 📖 Documentation\n\n  - **Fix typos in non-rustup-setups.md - [dallasbrittany], [issue/1141], [pull/1142]**\n\n    [issue/1141]: https://github.com/rustwasm/wasm-pack/issues/1141\n    [pull/1142]: https://github.com/rustwasm/wasm-pack/issues/1141\n    [dallasbrittany]: https://github.com/dallasbrittany\n\n  - **Fix typos in considerations.md - [lhjt], [pull/1066]**\n\n    [pull/1066]: https://github.com/rustwasm/wasm-pack/pull/1066\n    [lhjt]: https://github.com/lhjt\n\n  - **Grammar and typo fixes - [helixbass], [pull/1143]**\n\n    [pull/1143]: https://github.com/rustwasm/wasm-pack/pull/1143\n    [helixbass]: https://github.com/helixbass\n\n  - **Replace two mentions of wasm-pack init with wasm-pack build in the docs - [mstange], [pull/1086]**\n\n    [pull/1086]: https://github.com/rustwasm/wasm-pack/pull/1086\n    [mstange]: https://github.com/mstange\n\n  - **Update npm installation link - [benediktwerner], [pull/1227]**\n\n    [pull/1227]: https://github.com/rustwasm/wasm-pack/pull/1227\n    [benediktwerner]: https://github.com/benediktwerner\n\n- ### 🛠️ Maintenance\n\n  - **Bump wasm-opt to version 108 - [MichaelMauderer], [issue/1135] [pull/1136]**\n\n    [pull/1136]: https://github.com/rustwasm/wasm-pack/pull/1136\n    [issue/1135]: https://github.com/rustwasm/wasm-pack/issues/1135\n    [MichaelMauderer]: https://github.com/MichaelMauderer\n\n  - **Update binary-install to v1.0.1 - [EverlastingBugstopper], [pull/1130]**\n\n    [pull/1130]: https://github.com/rustwasm/wasm-pack/pull/1130\n\n  - **Add back run.js to npm installer - [EverlastingBugstopper], [pull/1149]**\n\n    [pull/1149]: https://github.com/rustwasm/wasm-pack/pull/1149\n\n  - **Fix some typos in the codebase - [striezel], [pull/1220]**\n\n    [pull/1220]: https://github.com/rustwasm/wasm-pack/pull/1220\n    [striezel]: https://github.com/striezel\n\n  - **Update actions/checkout in GitHub Actions workflows to v3 - [striezel], [pull/1221]**\n\n    [pull/1221]: https://github.com/rustwasm/wasm-pack/pull/1221\n\n  - **Update actions/cache in GitHub Actions workflows to v3 - [striezel], [pull/1222]**\n\n    [pull/1222]: https://github.com/rustwasm/wasm-pack/pull/1222\n\n  - **Update JamesIves/github-pages-deploy-action in GHA workflow to v4.4.1 - [striezel], [pull/1223]**\n\n    [pull/1223]: https://github.com/rustwasm/wasm-pack/pull/1223\n\n## 🌦️ 0.10.3\n\n- ### 🤕 Fixes\n\n  - **Use bash to create release tarballs - [nasso], [issue/1097] [pull/1144]**\n\n    Fixes Windows installer failure due to malformatted tar.\n\n    [pull/1144]: https://github.com/rustwasm/wasm-pack/pull/1144\n    [issue/1097]: https://github.com/rustwasm/wasm-pack/issues/1097\n    [nasso]: https://github.com/nasso\n\n  - **Clean up package.json from previous runs - [main--], [issue/1110-comment] [pull/1119]**\n\n    Remove the package.json file from previous runs to avoid crashes.\n\n    [pull/1119]: https://github.com/rustwasm/wasm-pack/pull/1119\n    [issue/1110-comment]: https://github.com/rustwasm/wasm-pack/pull/1110#issuecomment-1059008962\n    [main--]: https://github.com/main--\n\n  - **Do not remove the pkg directory - [huntc], [issue/1099] [pull/1110]**\n\n    A recent change ensured that the pkg directory was removed as the first step of attempting to create it.\n    Unfortunately, this caused a problem for webpack when watching the pkg directory.\n    Webpack was unable to recover its watching and so any watch server must be restarted,\n    which is a blocker when using it. This PR and release fixes this.\n\n    [pull/1110]: https://github.com/rustwasm/wasm-pack/pull/1110\n    [issue/1099]: https://github.com/rustwasm/wasm-pack/issues/1099\n    [huntc]: https://github.com/huntc\n\n  - **Bump regex from 1.5.4 to 1.5.6 - [dependabot], [pull/1147]**\n\n    Version 1.5.5 of the regex crate fixed a security bug in the regex compiler.\n\n    [pull/1147]: https://github.com/rustwasm/wasm-pack/pull/1147\n\n  - **Bump openssl-src from 111.17.0+1.1.1m to 111.20.0+1.1.1o - [dependabot], [pull/1146]**\n\n    Bring in bug fixes from the new version of openssl-src.\n\n    [pull/1146]: https://github.com/rustwasm/wasm-pack/pull/1146\n    [dependabot]: https://github.com/apps/dependabot\n\n## 🌦️ 0.10.2\n\n- ### ✨ Features\n\n  - **Implement support for RFC 8, transitive NPM dependencies - [jpgneves], [issue/606] [pull/986]**\n\n    [pull/986]: https://github.com/rustwasm/wasm-pack/pull/986\n    [issue/606]: https://github.com/rustwasm/wasm-pack/issues/606\n    [jpgneves]: https://github.com/jpgneves\n\n- ### 🤕 Fixes\n\n  - **Add support for macos aarch64 - [d3lm], [issue/913] [pull/1088]**\n\n    This fixes aarch64 for MacOS and will download x86_64-apple-darwin.\n\n    [pull/1088]: https://github.com/rustwasm/wasm-pack/pull/1088\n    [issue/913]: https://github.com/rustwasm/wasm-pack/issues/913\n    [d3lm]: https://github.com/d3lm\n\n  - **Add linux/arm64 to release workflow - [nacardin], [issue/1064] [pull/1065]**\n\n    [pull/1065]: https://github.com/rustwasm/wasm-pack/pull/1065\n    [issue/1064]: https://github.com/rustwasm/wasm-pack/issues/1064\n    [nacardin]: https://github.com/nacardin\n\n  - **Force axios version - [drager], [pull/1094]**\n\n    Forces npm package `axios` to version `0.21.2` in order to get security fix for a security vulnerability present in axios\n    before version `0.21.2`.\n\n    [pull/1094]: https://github.com/rustwasm/wasm-pack/pull/1094\n\n- ### 📖 Documentation\n\n  - **Update docs for how to pass extra options to cargo - [FrankenApps], [issue/1059] [pull/1073]**\n\n    [FrankenApps]: https://github.com/FrankenApps\n    [pull/1073]: https://github.com/rustwasm/wasm-pack/pull/1073\n    [issue/1059]: https://github.com/rustwasm/wasm-pack/issues/1059\n\n## 🌦️ 0.10.1\n\n- ### 🤕 Fixes\n\n  - **Add exe to binary name if windows - [drager], [issue/1038] [pull/1055]**\n\n    [pull/1055]: https://github.com/rustwasm/wasm-pack/pull/1055\n    [issue/1038]: https://github.com/rustwasm/wasm-pack/issues/1038\n\n## 🌦️ 0.10.0\n\n- ### ✨ Features\n\n  - **Added keywords - [lucashorward], [issue/707] [pull/838]**\n\n    `package.json` files usually contain a keywords array so that npm can make searching easier.\n    This PR extracts keywords from `Cargo.toml` and puts them into `package.json`.\n\n    [lucashorward]: https://github.com/lucashorward\n    [pull/838]: https://github.com/rustwasm/wasm-pack/pull/838\n    [issue/707]: https://github.com/rustwasm/wasm-pack/issues/707\n\n- ### 🤕 Fixes\n\n  - **Update binary-install to get fix for axios security vulnerability - [simlay], [Rizary], [issue/958] [pull/973] [pull/1012]**\n\n    Updates `binary-install` npm package to version `^0.1.0` in order to get security fix for a security vulnerability in axios.\n\n    [simlay]: https://github.com/simlay\n    [rizary]: https://github.com/Rizary\n    [pull/973]: https://github.com/rustwasm/wasm-pack/pull/973\n    [pull/1012]: https://github.com/rustwasm/wasm-pack/pull/1012\n    [issue/958]: https://github.com/rustwasm/wasm-pack/issues/958\n\n  - **Fix cargo-generate installation - [bradyjoslin], [issue/975] [issue/907] [pull/983]**\n\n    `wasm-pack new hello-wasm` didn't work due to a bad link when trying to install `cargo-generate`.\n\n    This PR points the installation to the correct place and makes `wasm-pack new` working again!\n\n    [bradyjoslin]: https://github.com/bradyjoslin\n    [pull/983]: https://github.com/rustwasm/wasm-pack/pull/983\n    [issue/975]: https://github.com/rustwasm/wasm-pack/issues/975\n    [issue/907]: https://github.com/rustwasm/wasm-pack/issues/907\n\n  - **Pass through extra options when building tests - [azriel91], [issue/698] [pull/851]**\n\n    `wasm-pack test` accepts extra options to pass through to `cargo` when running tests.\n    Under the hood, this runs `cargo build` before `cargo test`, and the additional options were only passed through to the `test` command. This meant that crates that enabled native features by default could not be built using `wasm-pack`, as it would attempt to build tests for the `wasm32-unknown-unknown` target with the native features enabled.\n\n    This PR passes through the extra options to `cargo` when building the tests as well.\n\n    [azriel91]: https://github.com/azriel91\n    [pull/851]: https://github.com/rustwasm/wasm-pack/pull/851\n    [issue/698]: https://github.com/rustwasm/wasm-pack/issues/698\n\n  - **Corrected files included in package.json for bundler / no target - [lucashorward], [issue/837] [pull/839]**\n\n    `wasm-pack build` and `wasm-pack build --target bundler` generates a \\_bg.js file, but it was not added to the `package.json`.\n    The file that is added, \\*.js will however reference the \\_bg.js, so when the package was distributed (both through pack or publish) it is not usable.\n\n    This PR includes that \\_bg.js file in `package.json`.\n\n    [pull/839]: https://github.com/rustwasm/wasm-pack/pull/839\n    [issue/837]: https://github.com/rustwasm/wasm-pack/issues/837\n\n  - **Find the main package if multiple packages have the same name - [ghost], [pull/830]**\n\n    If there were 2 packages with the same name, `wasm-pack` would sometimes use the wrong one and errored.\n\n    [ghost]: https://github.com/ghost\n    [pull/830]: https://github.com/rustwasm/wasm-pack/pull/830\n    [issue/829]: https://github.com/rustwasm/wasm-pack/issues/829\n\n- ### 📖 Documentation\n\n  - **Remove duplicated \"is\" in the wee_alloc tutorial- [pione30], [issue/1003] [pull/1004]**\n\n    [pione30]: https://github.com/pione30\n    [pull/1004]: https://github.com/rustwasm/wasm-pack/pull/1004\n    [issue/1003]: https://github.com/rustwasm/wasm-pack/issues/1003\n\n  - **Fix TOC links - [Swaagie], [pull/1007]**\n\n    [swaagie]: https://github.com/Swaagie\n    [pull/1007]: https://github.com/rustwasm/wasm-pack/pull/1007\n\n  - **Remove outdated TOC heading- [gthb], [pull/1011]**\n\n    [gthb]: https://github.com/gthb\n    [pull/1011]: https://github.com/rustwasm/wasm-pack/pull/1011\n\n  - **Add link to template repo - [milahu], [pull/942]**\n\n    [milahu]: https://github.com/milahu\n    [pull/942]: https://github.com/rustwasm/wasm-pack/pull/942\n\n  - **Remove greenkeeper reference - [cdvv7788], [crotwell], [issue/1001] [pull/844] [pull/1002]**\n\n    [cdvv7788]: https://github.com/cdvv7788\n    [crotwell]: https://github.com/crotwell\n    [pull/844]: https://github.com/rustwasm/wasm-pack/pull/844\n    [pull/1002]: https://github.com/rustwasm/wasm-pack/pull/1002\n    [issue/1001]: https://github.com/rustwasm/wasm-pack/issues/1001\n\n- ### 🛠️ Maintenance\n\n  - **Fix CI. Remove appveyor and travis and use Github actions - [ashleygwilliams], [drager], [issue/594] [issue/979] [pull/947]**\n\n    [pull/947]: https://github.com/rustwasm/wasm-pack/pull/947\n    [issue/594]: https://github.com/rustwasm/wasm-pack/issues/594\n    [issue/979]: https://github.com/rustwasm/wasm-pack/issues/979\n\n  - **Cargo update - [ashleygwilliams], [pull/800]**\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [pull/800]: https://github.com/rustwasm/wasm-pack/pull/800\n\n  - **Remove dirs dependency - [brightly-salty], [issue/943] [pull/944]**\n\n    [brightly-salty]: https://github.com/brightly-salty\n    [pull/944]: https://github.com/rustwasm/wasm-pack/pull/944\n    [issue/943]: https://github.com/rustwasm/wasm-pack/issues/943\n\n  - **Fix logs for uniformity - [petosorus], [issue/716] [pull/723]**\n\n    [petosorus]: https://github.com/petosorus\n    [pull/723]: https://github.com/rustwasm/wasm-pack/pull/723\n    [issue/716]: https://github.com/rustwasm/wasm-pack/issues/716\n\n  - **Fixing build error - [Pauan], [pull/841]**\n\n    [pull/841]: https://github.com/rustwasm/wasm-pack/pull/841\n\n## ☁️ 0.9.1\n\n- ### 🤕 Fixes\n\n  - **Bump binaryen to version_90 - [ashleygwilliams], [issue/781] [issue/782] [pull/687]**\n\n    Previously, wasm-pack was hardcoded to install and attempt to execute wasm-opt on every build\n    using binaryen version 78. This version had various issues on Unix/Linux and caused broken CI\n    builds for many folks (we're so sorry!).\n\n    This PR updates the binaryen version to 90, which should fix the issues folks were having.\n\n    Long-term, we'd like to create an auto-updating mechanism so that we can install and use the\n    latest release of binaryen as we do for other binaries we orchestrate.\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [pull/687]: https://github.com/rustwasm/wasm-pack/pull/687\n    [issue/782]: https://github.com/rustwasm/wasm-pack/issues/782\n    [issue/781]: https://github.com/rustwasm/wasm-pack/issues/781\n\n- ### 🛠️ Maintenance\n\n  - **Consolidate wasm-opt installation into existing binary install logic - [ashleygwilliams], [issue/685] [pull/687]**\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [pull/687]: https://github.com/rustwasm/wasm-pack/pull/687\n    [issue/685]: https://github.com/rustwasm/wasm-pack/issues/685\n\n## 🌥️ 0.9.0\n\n- ### ✨ Features\n\n  - **Adding in `--quiet` and `--log-level` flags to control the console output - [Pauan], [pull/694]**\n\n    The `--verbose` flag has long existed as a way to get more console output, but now there are two flags to get _less_ console output:\n\n    - `--quiet` will silence _all_ stdout, so only errors will be displayed.\n    - `--log-level` can be used to silence `[INFO]` or `[WARN]` output from wasm-pack.\n\n    You can cause it to display even _more_ information by using `--verbose`, or you can silence _all_ stdout by using `--quiet`.\n\n    You can also use `--log-level` to have fine-grained control over wasm-pack's log output:\n\n    - `--log-level info` is the default, it causes all messages to be logged.\n    - `--log-level warn` causes warnings and errors to be displayed, but not info.\n    - `--log-level error` causes only errors to be displayed.\n\n    These flags are global flags, so they can be used with every command, and they must come _before_ the command:\n\n    ```sh\n    wasm-pack --log-level error build\n    wasm-pack --quiet build\n    ```\n\n    [Pauan]: https://github.com/Pauan\n    [pull/694]: https://github.com/rustwasm/wasm-pack/pull/694\n\n  - **Wrap `cargo-generate` with `wasm-pack new` - [ashleygwilliams], [issue/373] [pull/623]**\n\n    One of the first steps in getting started with `wasm-pack` is to `cargo install cargo-generate` to bootstrap some project templates. This can take a while and is an extra burden on users just getting started with `wasm-pack`. `wasm-pack new` uses `cargo-generate` to bootstrap new projects, removing the need to install the tool on your own. You can read more about this feature [here](https://github.com/rustwasm/wasm-pack/blob/master/docs/src/commands/new.md).\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [pull/623]: https://github.com/rustwasm/wasm-pack/pull/623\n    [issue/373]: https://github.com/rustwasm/wasm-pack/issues/373\n\n  - **Allow `wasm-pack` to be run from subdirectories - [gameldar], [issue/620] [pull/624]**\n\n    If a crate path is not specified when running `wasm-pack` and there is no `Cargo.toml` in the current working directory, `wasm-pack` will walk up the directory structure to find a `Cargo.toml`.\n\n    [gameldar]: https://github.com/gameldar\n    [pull/624]: https://github.com/rustwasm/wasm-pack/pull/624\n    [issue/620]: https://github.com/rustwasm/wasm-pack/issues/620\n\n  - **Automatically execute `wasm-opt` on produced binaries - [alexcrichton], [issue/159] [pull/625]**\n\n    When `wasm-pack` builds binaries in released and profiling modes, it will execute `wasm-opt` on the binary, making the result smaller and more performant.\n\n    [alexcrichton]: https://github.com/alexcrichton\n    [pull/625]: https://github.com/rustwasm/wasm-pack/pull/625\n    [issue/159]: https://github.com/rustwasm/wasm-pack/issues/159\n\n  - **Helpful error message when wasm-bindgen fails because of an old version - [gameldar], [ashleygwilliams], [issue/627] [pull/633]**\n\n    `wasm-pack` will pass a `--web` flag to `wasm-bindgen` when `wasm-pack build --target web` is run. Before, if the user had an old version of `wasm-bindgen` in their dependencies, they would receive a cryptic error message. Now they will be notified that they need to update their `wasm-bindgen` dependency if they want to build for the `web` target.\n\n    [gameldar]: https://github.com/gameldar\n    [pull/633]: https://github.com/rustwasm/wasm-pack/pull/633\n    [issue/627]: https://github.com/rustwasm/wasm-pack/issues/627\n\n  - **Publish releases by tag to npm - [Tarnadas], [pull/690]**\n\n    You can now use `wasm-pack publish` to publish tagged releases with the optional `--tag` argument. You can read more about [distribution tags](https://docs.npmjs.com/cli/dist-tag) on NPM, and more about this feature in [our docs](https://github.com/Tarnadas/wasm-pack/blob/master/docs/src/commands/pack-and-publish.md#publishing-tagged-releases).\n\n    [Tarnadas]: https://github.com/Tarnadas\n    [pull/690]: https://github.com/rustwasm/wasm-pack/pull/690\n\n- ### 🤕 Fixes\n\n  - **Only use exactly v0.24.0 geckodriver on Windows - [ashleygwilliams], [issue/770] [pull/774]**\n\n    `wasm-pack test` is a great way to test your web Wasm modules- and it very nicely sets up and configures\n    the necessary browser engine drivers to do so!\n\n    For the v0.25.0 release of geckodriver, the team switched their build environment- which introduced a new\n    surprise runtime dependency, Visual C++ redistributable package, to their windows binaries. You can read\n    more about the issue here, [mozilla/geckodriver/issue/1617].\n\n    Becuase the introduction of this runtime dependency is considered a bug, and should be eventually fixed,\n    the team decided that the least invasive solution would be to hold geckodriver binaries, on Windows, at\n    v0.24.0, and to disable the auto-update logic, until the bug is fixed.\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [issue/770]: https://github.com/rustwasm/wasm-pack/issues/770\n    [pull/774]: https://github.com/rustwasm/wasm-pack/pull/774\n    [mozilla/geckodriver/issue/1617]: https://github.com/mozilla/geckodriver/issues/1617#issuecomment-532168958\n\n  - **Handle version check failures - [drager], [issue/652], [issue/653] [pull/660]**\n\n    Every day, `wasm-pack` checks the crates.io API for the latest version number and lets the user know if their installation is out of date. Now, when these API calls fail, `wasm-pack` alerts the user of the failure and waits until the next day to make another call to crates.io.\n\n    [drager]: https://github.com/drager\n    [pull/660]: https://github.com/rustwasm/wasm-pack/pull/660\n    [issue/652]: https://github.com/rustwasm/wasm-pack/issues/652\n    [issue/653]: https://github.com/rustwasm/wasm-pack/issues/653\n\n  - **Add user agent for version check - [drager], [issue/651] [pull/658]**\n\n    crates.io requires tools to set a version check `User-Agent` header when requesting the latest version. Now, when `wasm-pack` performs an API request to crates.io, it sends `User-Agent: wasm-pack/0.9.0`.\n\n    [drager]: https://github.com/drager\n    [pull/658]: https://github.com/rustwasm/wasm-pack/pull/658\n    [issue/651]: https://github.com/rustwasm/wasm-pack/issues/651\n\n  - **Remove broken link from the README - [drager], [pull/635]**\n\n    [drager]: https://github.com/drager\n    [pull/635]: https://github.com/rustwasm/wasm-pack/pull/635\n\n  - **Make `sideEffects` in generated `package.json` a boolean instead of a string - [rhysd], [pull/649]**\n\n    [rhysd]: https://github.com/rhysd\n    [pull/649]: https://github.com/rustwasm/wasm-pack/pull/649\n\n  - **Don't warn if license-file is present - [ashleygwilliams], [issue/692] [pull/693]**\n\n    Previously, `wasm-pack` would warn that the `license` field was missing if the `license-file` field was used instead. This warning is now only surfaced if both `license` and `license-field` are absent from a `Cargo.toml`.\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [pull/693]: https://github.com/rustwasm/wasm-pack/pull/693\n    [issue/692]: https://github.com/rustwasm/wasm-pack/issues/692\n\n  - **Select correct webdriver version - [MartinKavik], [issue/611] [pull/706]**\n\n    `wasm-pack` used to install a pinned version of the Chrome, Gecko, and Safari drivers. Now when a driver needs to be installed, `wasm-pack` will pull the latest version from the API and install that instead.\n\n    [MartinKavik]: https://github.com/MartinKavik\n    [pull/706]: https://github.com/rustwasm/wasm-pack/pull/706\n    [issue/611]: https://github.com/rustwasm/wasm-pack/issues/611\n\n  - **Only run node tests on `wasm-pack test --node` - [alexcrichton], [pull/630]**\n\n    [alexcrichton]: https://github.com/alexcrichton\n    [pull/630]: https://github.com/rustwasm/wasm-pack/pull/630\n\n  - **Fix npm installs for Windows Users - [EverlastingBugstopper], [issue/757] [pull/759]**\n\n    We recently published `wasm-pack` on the npm registry but forgot to test on Windows! `npm install -g wasm-pack` now works on Windows machines.\n\n    [EverlastingBugstopper]: https://github.com/EverlastingBugstopper\n    [pull/759]: https://github.com/rustwasm/wasm-pack/pull/759\n    [issue/757]: https://github.com/rustwasm/wasm-pack/issues/757\n\n  - **Clean up `cargo test` warnings - [ashleygwilliams], [issue/752] [pull/753]**\n\n    Tests now use `std::sync::Once::new()` instead of the deprecated `std::sync::ONCE_INIT`\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [pull/753]: https://github.com/rustwasm/wasm-pack/pull/753\n    [issue/752]: https://github.com/rustwasm/wasm-pack/issues/752\n\n- ### 📖 Documentation\n\n  - **Document npm installer - [drager], [issue/751] [pull/767]**\n\n    [drager]: https://github.com/drager\n    [issue/751]: https://github.com/rustwasm/wasm-pack/issues/751\n    [pull/767]: https://github.com/rustwasm/wasm-pack/pull/767\n\n  - **Update help message for `build` and `publish` subcommands - [ibaryshnikov], [issue/636] [pull/640]**\n\n    `wasm-bindgen` recently changed the default target from `browser` to `bundler` and deprecated `browser`. This change is now reflected in the help message for `wasm-pack build`.\n\n    [ibaryshnikov]: https://github.com/ibaryshnikov\n    [pull/640]: https://github.com/rustwasm/wasm-pack/pull/640\n    [issue/636]: https://github.com/rustwasm/wasm-pack/issues/636\n\n  - **Add Release Checklist - [ashleygwilliams], [issue/370] [pull/626]**\n\n    While we try to automate releases of `wasm-pack` as much as possible, there are still some manual steps that need to be completed when releasing a new version (like writing a changelog 😉). These steps now live in [`RELEASE_CHECKLIST.md`](https://github.com/rustwasm/wasm-pack/blob/master/RELEASE_CHECKLIST.md).\n\n    [ashleygwilliams]: https://github.com/ashleygwilliams\n    [pull/626]: https://github.com/rustwasm/wasm-pack/pull/626\n    [issue/370]: https://github.com/rustwasm/wasm-pack/issues/370\n\n- ### 🛠️ Maintenance\n\n  - **Ensure that `wasm-bindgen` generates move assertions - [fitzgen], [issue/677] [pull/683]**\n\n    `wasm-pack` now creates `wasm-bindgen` test fixtures that must generate move assertions for both free functions and methods.\n\n    [fitzgen]: https://github.com/fitzgen\n    [pull/683]: https://github.com/rustwasm/wasm-pack/pull/683\n    [issue/677]: https://github.com/rustwasm/wasm-pack/issues/677\n\n  - **Update `cargo_metadata` to v0.8.0 - [ThomasdenH], [pull/670]**\n\n    [ThomasdenH]: https://github.com/ThomasdenH\n    [pull/670]: https://github.com/rustwasm/wasm-pack/pull/670\n\n  - **Update `rustfmt` install snippet in PR template` - [data-pup], [issue/639] [pull/664]**\n\n    `rustfmt` is now available on Rust's stable channel so now the `wasm-pack` PR template recommends installing the stable version instead of the nightly version.\n\n    [data-pup]: https://github.com/data-pup\n    [pull/664]: https://github.com/rustwasm/wasm-pack/pull/664\n    [issue/639]: https://github.com/rustwasm/wasm-pack/issues/639\n\n## 🛠️ 0.8.1\n\n- ### 🤕 Fixes\n\n  - **Check for \"rustup\" rather than \".rustup\" when checking for wasm32 - [drager], [issue/613][pull/616]**\n\n    When we introduced support for non-rustup setups we did a check if the user was\n    using rustup or not. However, this check was too constrained and only covered\n    the most common cases, but it did not work for Docker setups.\n\n    This PR addresses that and it now covers Docker setups as well!\n    When doing this fix we also found two other small issues which this PR also addresses.\n    The first is that we did not print the helpful error message when the wasm32 target\n    was not found and the other one was that it linked to the wrong section of the documentation.\n\n    [issue/613]: https://github.com/rustwasm/wasm-pack/issues/613\n    [pull/616]: https://github.com/rustwasm/wasm-pack/pull/616\n\n## 🌤️ 0.8.0\n\n- ### ✨ Features\n\n  - **Give user's ability to customize generated filenames with `--out-name` flag - [ibaryshnikov], [issue/596] [pull/599]**\n\n    When running `wasm-pack build`, several files are generated. These files\n    are named based on the name of the crate, as per your `Cargo.toml` file.\n    Sometimes- that's not the name you'd like your files to have!\n\n    You can now specify a custom name for the generated files using a new\n    flag, `--out-name`. Given a project called `dom`, here's a comparison of\n    the default and custom generated filenames:\n\n    ```\n    wasm-pack build\n    # will produce files\n    # dom.d.ts  dom.js  dom_bg.d.ts  dom_bg.wasm  package.json  README.md\n\n     wasm-pack build --out-name index\n    # will produce files\n    # index.d.ts  index.js  index_bg.d.ts  index_bg.wasm  package.json  README.md\n    ```\n\n    [ibaryshnikov]: https://github.com/ibaryshnikov\n    [issue/596]: https://github.com/rustwasm/wasm-pack/issues/596\n    [pull/599]: https://github.com/rustwasm/wasm-pack/pull/599\n\n- ### 🤕 Fixes\n\n  - **Fix panics in `build mode --no-install` - [alexcrichton], [pull/598]**\n\n    This commit fixes the `wasm-pack build --mode no-install` command from\n    unconditionally panicking as well as `--mode force`. These steps were\n    calling an `unwrap()` on an internal `Option<T>` which was supposed to\n    be set during `step_install_wasm_bindgen`, but that step wasn't run in\n    these modes. The mode configuration of steps has been refactored\n    slightly to ensure that more steps are shared between these modes to\n    reduce duplication.\n\n    [pull/598]: https://github.com/rustwasm/wasm-pack/pull/598\n\n  - **Print unexpected panics to standard error - [drager], [issue/562] [pull/601]**\n\n    Unexpected panics are unfortunate but they're currently covered up and written\n    out to an auxiliary file. This makes panics in CI difficult to debug,\n    especially at a glance, as CI builders are likely not uploading those files.\n\n    This PR will print to standard error for unexpected panics and then let\n    `human_panic` handle panics, just like before.\n\n    [issue/562]: https://github.com/rustwasm/wasm-pack/issues/562\n    [pull/601]: https://github.com/rustwasm/wasm-pack/pull/601\n\n  - **Improve error message when `wasm32-unknown-unknown` is missing - [drager], [issue/579] [pull/602]**\n\n    For folks with non-rustup environments (which we only started supporting in\n    0.7.0!), we were giving a missing target error that was not helpful!\n\n    We've updated the error message to include more information, and we've added\n    some documentation to help explain how you can remedy the error by manually\n    installing the target on your specific rust setup- including the fact that\n    it may _not_ be possible to add the target to some setups.\n\n    Check out the docs [here](https://drager.github.io/wasm-pack/book/prerequisites/non-rustup-setups.html).\n\n    [issue/579]: https://github.com/rustwasm/wasm-pack/issues/579\n    [pull/602]: https://github.com/rustwasm/wasm-pack/pull/602\n\n- ### 📖 Documentation\n\n  - **Document `--out-dir` flag - [ashleygwilliams], [issue/592] [pull/593]**\n\n    Recently, someone asked on Discord about customizing the name of the directory\n    that contains the assets built by `wasm-pack`. We've had the `out-dir` flag for\n    a while, but it wasn't documented! Now it is.\n\n    [issue/592]: https://github.com/rustwasm/wasm-pack/issues/592\n    [pull/593]: https://github.com/rustwasm/wasm-pack/pull/593\n\n  - **Fix broken links in docs and update for template changes - [drager], [ashleygwilliams], [issue/609] [pull/612] [pull/614]**\n\n    Recently, some improvements were made to the [`wasmpack-template`]. Additionally,\n    there were some broken links in the documentation. We've updated the docs for the\n    new template and fixed the broken links!\n\n    [issue/609]: https://github.com/rustwasm/wasm-pack/issues/609\n    [pull/612]: https://github.com/rustwasm/wasm-pack/pull/612\n    [pull/614]: https://github.com/rustwasm/wasm-pack/pull/614\n\n- ### 🛠️ Maintenance\n\n  - **Move `binary-install` to its own repo - [drager], [issue/500] [pull/600]**\n\n    `binary-install` is a crate that holds the abstractions for how `wasm-pack` downloads\n    and caches pre-built binaries for the tools it wraps. It was originally part of the\n    `wasm-pack` code, then moved into a workspace as an independent crate. Now that we\n    believe it's stable, we've moved it into its own [repo](https://github.com/rustwasm/binary-install)!\n\n    [issue/500]: https://github.com/rustwasm/wasm-pack/issues/500\n    [pull/600]: https://github.com/rustwasm/wasm-pack/pull/600\n\n## 🌤️ 0.7.0\n\n- ### ✨ Features\n\n  - **Non `rustup` environment support - [drager], [pull/552]**\n\n    Before now, `wasm-pack` had a hard requirement that `rustup` had to be in the PATH. While most Rust users use\n    `rustup` there are variety reasons to have an environment that doesn't use `rustup`. With this PR, we'll now\n    support folks who are using a non-`rustup` environment!\n\n    [pull/552]: https://github.com/rustwasm/wasm-pack/pull/552\n\n  - **Improved CLI Output - [alexcrichton], [pull/547]**\n\n    It's hard to decide if this is a fix or a feature, but let's keep it positive! This PR moves `wasm-pack`'s CLI\n    output strategy closer to the desired standard we have for 1.0. This is important as it fixes many small bugs\n    that are distributed across a diveristy of terminals and difficult to test for locally.\n\n    This strategy was first introduced as a mini RFC in [issue/298], and then was discussed in a session at the Rust\n    All Hands ([notes](https://gist.github.com/fitzgen/23a62ebbd67574b9f6f72e5ac8eaeb67#file-road-to-wasm-pack-1-0-md)).\n\n    You'll notice that the spinner is gone- we eventually want to have one, but we'd like one that doesn't cause bugs!\n    If you have feedback about terminal support or an output bug, please [file an issue]! We want to hear from you!\n\n    Check out the new output in the `README` demo- or update your `wasm-pack` and take it for a spin!\n\n    [file an issue]: https://github.com/rustwasm/wasm-pack/issues/new/choose\n    [pull/547]: https://github.com/rustwasm/wasm-pack/pull/547\n    [issue/298]: https://github.com/rustwasm/wasm-pack/issues/298\n\n  - **Add support for `--target web` - [alexcrichton], [pull/567]**\n\n    Recently, `wasm-bindgen` add a new target- `web`. This new target is similar to the `no-modules` target, in that\n    it is designed to generate code that should be loaded directly in a browser, without the need of a bundler. As\n    opposed to the `no-modules` target, which produces an IIFE (Immediately Invoked Function Expression), this target\n    produces code that is an ES6 module.\n\n    You can use this target by running:\n\n    ```\n    wasm-pack build --target web\n    ```\n\n    Learn more about how to use this target by [checking out the docs!](https://drager.github.io/wasm-pack/book/commands/build.html#target)\n\n    [pull/567]: https://github.com/rustwasm/wasm-pack/pull/567\n\n  - **Support passing arbitrary arguments to `cargo test` via `wasm-pack test` - [chinedufn], [issue/525] [pull/530]**\n\n    `wasm-pack test` is an awesome command that wraps `cargo test` in a way that helps provide you some nice out of the\n    box configuration and setup. However, you may find yourself wanting to leverage the full funcationality of `cargo test`\n    by passing arguments that haven't been re-exported by the `wasm-pack test` interface.\n\n    For example, if you have a large test suite, it can be nice to simply run one test, or a subset of your tests.\n    `cargo test` supports this, however up until now, the `wasm-pack test` interface did not!\n\n    `wasm-pack test` now accepts passing and arbitrary set of arguments that it will forward along to its `cargo test` call\n    by allowing users to use `--` after any `wasm-pack test` arguments, followed by the set of arguments you'd like to pass\n    to `cargo test`.\n\n    For example:\n\n    ```\n    # Anything after `--` gets passed to the `cargo test`\n    wasm-pack test --firefox --headless -- --package my-workspace-crate my_test_name --color=always\n    ```\n\n    This will just run the `my_test_name` test and will output using color!\n\n    [See the `test` docs here!](https://rustwasm.github.io/docs/wasm-pack/commands/test.html)\n\n    [chinedufn]: https://github.com/chinedufn\n    [issue/525]: https://github.com/rustwasm/wasm-pack/issues/525\n    [pull/530]: https://github.com/rustwasm/wasm-pack/pull/530\n\n  - **Support `homepage` field of `Cargo.toml` and `package.json` - [rhysd], [pull/531]**\n\n    Both `Cargo.toml` and `package.json` support a `homepage` field that allow you to specify a website for\n    your project. We didn't support it previously (purely an accidental omission) - but now we do!\n\n    [pull/531]: https://github.com/rustwasm/wasm-pack/pull/531\n\n  - **Support `license-file` field in `Cargo.toml` - [rhysd], [pull/527]**\n\n    Sometimes, you want to provide a custom license, or specific license file that doesn't map to SPDX standard\n    licenses. In Rust/Cargo, you accomplish this by omitting the `license` field and including a `license-file`\n    field instead. You can read more about this in the [`cargo` manifest documentation].\n\n    In an npm package, this translates to `\"license\": \"SEE LICENSE IN <filename>\"` in your `package.json`. You can\n    read more about this in the [npm `package.json` documentation].\n\n    We previously only supported using SPDX standard licenses, by only supporting the `\"license\"` key in your\n    `Cargo.toml`- but now we'll allow you to leverage the `license-file` key as well, and will translate it\n    correctly into your `package.json`!\n\n    [`cargo` manifest documentation]: https://doc.rust-lang.org/cargo/reference/manifest.html\n    [npm `package.json` documentation]: https://docs.npmjs.com/files/package.json#license\n    [rhysd]: https://github.com/rhysd\n    [pull/527]: https://github.com/rustwasm/wasm-pack/pull/527\n\n- ### 🤕 Fixes\n\n  - **`wasm-pack-init (1).exe` should work - [ashleygwilliams], [issue/518] [pull/550]**\n\n    Several users noted that when downloading a new version of `wasm-pack` their browser named the executable\n    file `wasm-pack-init (1).exe`. When named this way, the file didn't show the init instructions on execution.\n    This happened because the installation logic was requiring an exact match on filename. We've loosened that\n    restriction so that the filename must _start_ with `wasm-pack-init` and will still execute files with these\n    additional, extraneous charaters in the filename. Thanks so much to [Mblkolo] and [danwilhelm] for filing the\n    issue and the excellent discussion!\n\n    [issue/518]: https://github.com/rustwasm/wasm-pack/issues/518\n    [pull/550]: https://github.com/rustwasm/wasm-pack/pull/550\n    [Mblkolo]: https://github.com/Mblkolo\n\n  - **Fix chromedriver error and message on Windows for `wasm-pack test` - [jscheffner], [issue/535] [pull/537]**\n\n    When running `wasm-pack test` on a 64-bit Windows machine, users would receive an error:\n    `geckodriver binaries are unavailable for this target`. This error message had two issues- firstly, it accidentally\n    said \"geckodriver\" instead of \"chromedriver\", secondly, it threw an error instead of using the available 32-bit\n    chromedriver distribution. Chromedriver does not do a specific disribution for Windows 64-bit!\n\n    We've fixed the error message and have also ensured that 64-bit Windows users won't encounter an error, and will\n    appropriately fallback to the 32-bit Windows chromedriver.\n\n    [jscheffner]: https://github.com/jscheffner\n    [issue/535]: https://github.com/rustwasm/wasm-pack/issues/535\n    [pull/537]: https://github.com/rustwasm/wasm-pack/pull/537\n\n  - **Correct look up location for `wasm-bindgen` when it's installed via `cargo install` - [fitzgen], [pull/504]**\n\n    Sometimes, when a `wasm-bindgen` binary is not available, or if `wasm-pack` is being run on an architecture that\n    `wasm-bindgen` doesn't produce binaries for, instead of downloading a pre-built binary, `wasm-pack` will install\n    `wasm-bindgen` using `cargo install`. This is a great and flexible back up!\n\n    However, due to the last release's recent refactor to use a global cache, we overlooked the `cargo install` case\n    and did not look for `wasm-bindgen` in the appropriate location. As a result, this led to a bug where `wasm-pack`\n    would panic.\n\n    We've fixed the lookup for the `cargo install`'d `wasm-bindgen` by moving the `cargo-install`'d version to global\n    cache location for `wasm-pack` once it's successfully built. We also eliminated the panic in favor of\n    propagating an error. Thanks for your bug reports and sorry about the mistake!\n\n    [pull/504]: https://github.com/rustwasm/wasm-pack/pull/504\n\n  - **Only print `cargo test` output the once - [fitzgen], [issue/511] [pull/521]**\n\n    Due to some technical debt and churn in the part of the codebase that handles output, we were accidentally\n    printing the output of `cargo test` twice. Now we ensure that we print it only one time!\n\n    [issue/511]: https://github.com/rustwasm/wasm-pack/issues/511\n    [pull/521]: https://github.com/rustwasm/wasm-pack/pull/521\n\n- ### 🛠️ Maintenance\n\n  - **Fix `clippy` warnings - [mstallmo], [issue/477] [pull/478]**\n\n    [`clippy`] is an awesome utilty that helps lint your Rust code for common optimizations and idioms. at the\n    beginning of `wasm-pack` development, `clippy` had not yet stablized, but it has since 1.0'd and it was\n    high time we leveraged it in `wasm-pack`. We still aren't _completely_ fixed, but we're working on it, and\n    we've already dervived a ton of value from the tool!\n\n    [`clippy`]: https://github.com/rust-lang/rust-clippy\n    [issue/477]: https://github.com/rustwasm/wasm-pack/issues/477\n    [pull/478]: https://github.com/rustwasm/wasm-pack/pull/478\n\n  - **Run `clippy` check on Travis - [drager], [pull/502]**\n\n    Now that `wasm-pack` has been clippified- we want to keep it that way! Now in addition to `cargo fmt` and\n    `cargo test`, we'll also run `cargo clippy` on all incoming PRs!\n\n    [pull/502]: https://github.com/rustwasm/wasm-pack/pull/502\n\n  - **Port tests to use `assert-cmd` - [fitzgen], [pull/522]**\n\n    [`assert_cmd`] is a great utility for testing CLI applications that is supported by the [CLI WG]. `wasm-pack`\n    development began before this library existed- so we were using a much less pleasant and efficient strategy\n    to test the CLI functionality of `wasm-pack`. Now we've ported over to using this great library!\n\n    [CLI WG]: https://www.rust-lang.org/what/cli\n    [`assert_cmd`]: https://crates.io/crates/assert_cmd\n    [pull/522]: https://github.com/rustwasm/wasm-pack/pull/522\n\n  - **Add initial tests for `binary-install` crate - [drager], [pull/517]**\n\n    In the last release, we separated some of our binary install logic into a new crate, `binary-install`.\n    However, that's about all we did... move the logic! In an effort to move the crate into true open source\n    status, [drager] has done some excellent work adding tests to the crate. This was trickier than it looked\n    and involved creating a test server! Thanks for all the efforts [drager], and the great review work [fitzgen]\n    and [lfairy]!\n\n    [pull/517]: https://github.com/rustwasm/wasm-pack/pull/517\n    [lfairy]: https://github.com/lfairy\n\n  - **Update tests `wasm-bindgen` version - [huangjj27], [issue/519] [issue/417] [pull/526]**\n\n    Our tests use fixtures that reference `wasm-bindgen` often, but the versions were not consistent or up to\n    date. As a result, the test suite leverage many version of `wasm-bindgen` which meant that they took a while\n    to run as they couldn't use the cached version of `wasm-bindgen` because the cached versions we slightly\n    different! Now they are up to date and consistent so the tests can perform better!\n\n    [pull/526]: https://github.com/rustwasm/wasm-pack/pull/526\n    [issue/519]: https://github.com/rustwasm/wasm-pack/issues/519\n    [issue/417]: https://github.com/rustwasm/wasm-pack/issues/417\n\n- ### 📖 Documentation\n\n  - **Flag gh-pages docs as unpublished - [alexcrichton] [pull/565]**\n\n    Recently, [DebugSteven] made a PR to merge all the documentation for the rustwasm toolchain into a\n    [single location]. This is going to make discovering and using tools from the entire organization easier\n    for new and seasoned folks alike. This also has the feature of displaying documentation that is related\n    to the current published version of each tool- unlike before, where the only accessible documentation was\n    for the tools at current master (which may or may not be currently published!)\n\n    If you like reading the current master's documentation- fear not, each tool will still publish the\n    documentation generated from the master branch on their individual `gh-pages`\n    ([See `wasm-pack's` master docs here]). To avoid confusion, we've added a flash message that let's you know\n    which documentation you are reading- and provides a link to documentation of the published version- just\n    in case that's what you're looking for!\n\n    [DebugSteve]: https://github.com/DebugSteven\n    [single location]: https://rustwasm.github.io/docs.html\n    [See `wasm-pack's` master docs here]: https://drager.github.io/wasm-pack/book/\n    [pull/565]: https://github.com/rustwasm/wasm-pack/pull/565\n\n  - **Add new QuickStart guide for \"Hybrid Applications with Webpack\" - [DebugSteven] [pull/536]**\n\n    Since `wasm-pack` was first published, we've focused on a workflow where a user writes a library and then\n    publishes it to npm, where anyone can use it like any npm package in their JavaScript or Node.js application.\n\n    Shortly after `wasm-pack` appeared, some RustWASM teammates created a template for a similar workflow- building\n    a RustWASM package _alongside_ an application. They did this by leveraging Webpack plugins, and it's a really\n    lovely user experience!\n\n    [This template] hasn't gotten as much attention because we've lacked a quickstart guide for folks to discover\n    and follow- now we've got one!\n\n    Check out the guide [here](https://drager.github.io/wasm-pack/book/tutorials/hybrid-applications-with-webpack/index.html)!\n\n    [This temaplte]: https://github.com/rustwasm/rust-webpack-template\n    [DebugSteven]: https://github.com/DebugSteven\n    [pull/536]: https://github.com/rustwasm/wasm-pack/pull/536\n\n  - **Add `wee_alloc` deepdive - [surma], [pull/542]**\n\n    `wee_alloc` is a useful utility that deserved more attention and explanation than our previous docs addressed.\n    This was partially because the `wasm-pack` template has an explanatory comment that helps explain its use.\n    However, for folks who don't use the template, `wee_alloc` is something important to know about- so now we have\n    given it its own section!\n\n    Check out the deepdive [here](https://drager.github.io/wasm-pack/book/tutorials/npm-browser-packages/template-deep-dive/wee_alloc.html)!\n\n    [surma]: https://github.com/surma\n    [pull/542]: https://github.com/rustwasm/wasm-pack/pull/542\n\n  - **Update prerequisite documentation - [alexcrichton], [pull/569]**\n\n    Many folks are using `wasm-pack` without publishing to npm- as a result, we've updated the documentation to\n    clearly indicate that npm is an optional requirement, only required for specific targets and workflows.\n    Additionally, since the 2018 Edition landed, `nightly` Rust is no longer a requirement. We've removed those\n    instructions and have consolidated the documentation so it is shorter and more efficient at getting you\n    started!\n\n    [pull/569]: https://github.com/rustwasm/wasm-pack/pull/569\n\n  - **Clarify what kind of account `login` adds - [killercup], [pull/539]**\n\n    Previously, when view `--help`, the command description for `login` showed:\n    `👤  Add a registry user account!` This could be confusing for folks, so now it's been updated to read:\n    `👤  Add an npm registry user account!`, which is much clearer!\n\n    [killercup]: https://github.com/killercup\n    [pull/539]: https://github.com/rustwasm/wasm-pack/pull/539\n\n  - **Wasm is a contraction, not an acronym - [fitzgen], [pull/555]**\n\n    Ever wonder how you're _actually_ supposed to refer to WebAssembly in short-form? WASM? wasm? For the pedants\n    out there, the correct usage is \"Wasm\" because Wasm is a _contraction_ of the words Web and Assembly. We've\n    updated our doucmentation to consistently refer to WebAssembly as Wasm in the shortform.\n\n    _The more you know!_\n\n    [pull/555]: https://github.com/rustwasm/wasm-pack/pull/555\n\n  - **Fix links and Rust highlightning - [drager], [issue/513] [pull/514] [pull/516]**\n\n    We had some broken links and missing Rust syntax highlighting in a few sections of the docs. This fixes that!\n\n    [issue/513]: https://github.com/rustwasm/wasm-pack/issues/513\n    [pull/514]: https://github.com/rustwasm/wasm-pack/pull/514\n    [pull/516]: https://github.com/rustwasm/wasm-pack/pull/516\n\n## 🌅 0.6.0\n\n- ### ✨ Features\n\n  - **Add three build profiles and infrastructure for their toml config - [fitzgen], [issue/153] [issue/160] [pull/440]**\n\n    When originally conceived, `wasm-pack` was exclusively a packaging and publishing tool, which naively assumed\n    that the crate author would simply run `wasm-pack` when they were ready to publish a wasm package. As a result,\n    `wasm-pack` always ran `cargo build` in `--release` mode. Since then, `wasm-pack` has grown into an integrated build\n    tool used at all stages of development, from idea conception to publishing, and as such has developed new needs.\n\n    In previous releases, we've supported a flag called `--debug` which will run `cargo build` in `dev` mode, which\n    trades faster compilation speed for a lack of optimizations. We've renamed this flag to `--dev` to match `cargo`\n    and added an additional flag, representing a third, intermediary, build profile, called `--profiling` which\n    is useful for investigating performance issues. You can see all three flags and their uses in the table below:\n\n    | Profile       | Debug Assertions | Debug Info | Optimizations | Notes                                                       |\n    | ------------- | ---------------- | ---------- | ------------- | ----------------------------------------------------------- |\n    | `--dev`       | Yes              | Yes        | No            | Useful for development and debugging.                       |\n    | `--profiling` | No               | Yes        | Yes           | Useful when profiling and investigating performance issues. |\n    | `--release`   | No               | No         | Yes           | Useful for shipping to production.                          |\n\n    The meaning of these flags will evolve as the platform grows, and always be tied to the behavior of these flags\n    in `cargo`. You can learn more about these in the [`cargo profile` documentation].\n\n    This PR also introduces a way to configure `wasm-pack` in your `Cargo.toml` file that we intend to use much more\n    in the future. As a largely convention-based tool, `wasm-pack` will never require that you configure it manually,\n    however, as our community and their projects mature alongside the tool, it became clear that allowing folks the\n    ability to drop down and configure things was something we needed to do to meet their needs.\n\n    Currently, you can only configure things related to the above-mentioned build profiles. To learn more,\n    [check out the documentation][profile-config-docs]. It leverages the `package.metadata.wasm-pack` key in your\n    `Cargo.toml`, and looks like this:\n\n    ```toml\n    # Cargo.toml\n\n    [package.metadata.wasm-pack.profile.dev.wasm-bindgen]\n    # Should we enable wasm-bindgen's debug assertions in its generated JS glue?\n    debug-js-glue = true\n    # Should wasm-bindgen demangle the symbols in the \"name\" custom section?\n    demangle-name-section = true\n    # Should we emit the DWARF debug info custom sections?\n    dwarf-debug-info = false\n    ```\n\n    As always- there are defaults for you to use, but if you love to configure (or have a project that requires it),\n    get excited, as your options have grown now and will continue to!\n\n    [profile-config-docs]: https://drager.github.io/wasm-pack/book/cargo-toml-configuration.html\n    [`cargo profile` documentation]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections\n    [issue/153]: https://github.com/rustwasm/wasm-pack/issues/153\n    [issue/160]: https://github.com/rustwasm/wasm-pack/issues/160\n    [pull/440]: https://github.com/rustwasm/wasm-pack/pull/440\n\n  - **DEPRECATION: Rename `--debug` to `--dev` to match `cargo` - [fitzgen], [pull/439]**\n\n    See the discussion of the build profiles feature above. This is a strict renaming of the previous `--debug` flag,\n    which will now warn as deprecated.\n\n    [pull/439]: https://github.com/rustwasm/wasm-pack/pull/439\n\n  - **Add an option to pass an arbitrary set of arguments to `cargo build` - [torkve], [issue/455] [pull/461]**\n\n    As an integrated build tool, `wasm-pack` orchestrates many secondary command line tools to build your package\n    in a single command. Notably, one of these tools is `cargo`. `cargo` has a wide array of features and flags, and\n    we couldn't reasonably expect to implement them all as first class features of `wasm-pack`. As a result, we've\n    created the option to allow users to pass an arbitrary number of additional flags to `wasm-pack` by appending them\n    to the `wasm-pack build` command, after passing `--`. For example:\n\n    ```\n    wasm-pack build examples/js-hello-world --mode no-install -- -Z offline\n    ```\n\n    In the above example, the flag `-Z offline` will be passed to `cargo build`. This feature is documented\n    [here][cargo opts docs].\n\n    [cargo opts docs]: https://drager.github.io/wasm-pack/book/commands/build.html#extra-options\n    [torkve]: https://github.com/torkve\n    [issue/455]: https://github.com/rustwasm/wasm-pack/issues/455\n    [pull/461]: https://github.com/rustwasm/wasm-pack/pull/461\n\n  - **Pre-build before wasm-pack publish - [csmoe], [issue/438] [pull/444]**\n\n    Previously, if you ran `wasm-pack publish` before you had successfully run `wasm-pack build`,\n    you'd receive an error that a package could not be found- because there would be no `pkg` or\n    out-directory containing a `package.json`.\n\n    In this situation, you would hope that `wasm-pack` would build your package for you when you\n    ran `wasm-pack publish`. This is slightly complicated by the fact that not everyone wants to\n    build their package to the default target or to a directory named `pkg`.\n\n    To solve this, running `wasm-pack publish` before a successful build will give you an interactive\n    prompt to build your package- allowing you to specify your out directory as well as the target you'd\n    like to build to. Check it out in the gif below:\n\n    ![pre-build publish workflow](https://user-images.githubusercontent.com/35686186/50500909-5984fe80-0a8f-11e9-9de6-43d1423b2969.gif)\n\n    [issue/438]: https://github.com/rustwasm/wasm-pack/issues/438\n    [pull/444]: https://github.com/rustwasm/wasm-pack/pull/444\n\n  - **Generate self-.gitignore as part of pkg folder - [RReverser], [pull/453]**\n\n    Since `wasm-pack` was first published, the `pkg` directory was intended to be treated as a\n    build artifact, and as such should never be published to version control. This was\n    never enforced by any assets generated by `wasm-pack`, however.\n\n    Now, when building your package, `wasm-pack` will also generate a `.gitignore` file so that the\n    `pkg`, or out-directory, will be ignored.\n\n    If you use another version control tool, you'll need to still create or edit your own ignore file-\n    pull requests to support other version control tools are welcome!\n\n    If you require editing of the generated `package.json` or add additonal assets to your package\n    before publishing, you'll want to remove the `.gitignore` file and commit to version control. We\n    intend to have a solution that makes this workflow significantly easier in upcoming releases!\n\n    [RReverser]: https://github.com/RReverser\n    [pull/453]: https://github.com/rustwasm/wasm-pack/pull/453\n\n  - **Support cargo workspaces - [fitzgen], [issue/252] [issue/305] [pull/430]**\n\n    Workspaces are a well-liked and used feature of cargo that allow you to build multiple crates\n    in a single cargo project. Because of how `wasm-pack` handled paths for `target` and out-directories,\n    we did not support cargo workspaces out of the box. Now they should work well and the feature is\n    well guarded by tests!\n\n    [issue/252]: https://github.com/rustwasm/wasm-pack/issues/252\n    [issue/305]: https://github.com/rustwasm/wasm-pack/issues/305\n    [pull/430]: https://github.com/rustwasm/wasm-pack/pull/430\n\n  - **Use a global cache for all downloaded binaries - [alexcrichton], [pull/426]**\n\n    `wasm-pack` is an integrated build tool that orchestrates several other command line tools to build\n    your wasm project for you. How `wasm-pack` does this has evolved significantly since it's early versions.\n    In the last version, a `bin` directory was created to house the tool binaries that `wasm-pack` needed to\n    build our project, but this had several limitations. Firstly, it created a `bin` directory in your project's\n    root, which could be confusing. Secondly, it meant that sharing these tools across multiple projects was\n    not possible. We did this because it gaves us the fine-grained control over the version of these tools that\n    you used.\n\n    Now, `wasm-pack` will not generate a `bin` directory, but rather will use a global cache. We retain the\n    fine-grained control over the versions of these tools that are used, but allow multiple projects that use\n    the same tools at the same versions to share the already installed asset. Your global cache will generally\n    be in your user's home directory- we use the [`dirs` crate] to determine where to place this global cache.\n    This is not currently customizable but is something we intend to look into doing!\n\n    This feature ensures that `wasm-pack` users are downloading a minimal number of binaries from the network,\n    which, for `wasm-pack` users with multiple projects, should speed up build times.\n\n    [`dirs` crate]: https://docs.rs/dirs/1.0.4/dirs/fn.cache_dir.html\n    [pull/426]: https://github.com/rustwasm/wasm-pack/pull/426\n\n- ### 🤕 Fixes\n\n  - **Fix `pack`, `login`, and `publish` for Windows users - [danwilhelm], [issue/277] [pull/489]**\n\n    Rust's behavior for spawning processes on some Windows targets introduced an interesting case where\n    Rust would fail unless the command was explicitly spawned with a prepended `cmd /c`. This failure\n    of `wasm-pack` was well noticed by our community - and thanks to the efforts of `danwilhelm` is now\n    fixed! You can read more on the background of this issue in [rust-lang/rust issue/44542].\n\n    [rust-lang/rust issue/44542]: https://github.com/rust-lang/rust/pull/44542\n    [issue/277]: https://github.com/rustwasm/wasm-pack/issues/277\n    [pull/489]: https://github.com/rustwasm/wasm-pack/pull/489\n\n  - **Validate `--target` argument - [csmoe], [issue/483] [pull/484]**\n\n    For a few releases now, `wasm-pack` has supported allowing users to specifying the target module system\n    they'd like their package built for- `browser`, `nodejs`, and `no-modules`. We did not however, validate\n    this input, and so if a user made even a slight mistake, e.g. `node`, `wasm-pack` would not catch the\n    error and would build your project using the default, `browser`. This is of course, surprising, and\n    unpleasant behavior and so now we'll error out with a message containing the supported target names.\n\n    [issue/483]: https://github.com/rustwasm/wasm-pack/issues/483\n    [pull/484]: https://github.com/rustwasm/wasm-pack/pull/484\n\n  - **Fix login - [danwilhelm], [issue/486] [pull/487]**\n\n    [danwilhelm]: https://github.com/danwilhelm\n    [issue/486]: https://github.com/rustwasm/wasm-pack/issues/486\n    [pull/487]: https://github.com/rustwasm/wasm-pack/pull/487\n\n  - **Eliminate unecessary escaping in build success terminal output - [huangjj27], [issue/390] [pull/396]**\n\n    Previously, on some systems, a successful `wasm-pack build` would print a unfortunate looking string:\n\n    ```\n    | :-) Your wasm pkg is ready to publish at \"\\\\\\\\?\\\\C:\\\\Users\\\\Ferris\\\\tmp\\\\wasm-bug\\\\pkg\".\n    ```\n\n    We've updated this to make sure the path to your project is well-formed, and most importantly,\n    human-readable.\n\n    [issue/390]: https://github.com/rustwasm/wasm-pack/issues/390\n    [pull/396]: https://github.com/rustwasm/wasm-pack/pull/396\n\n  - **Copy license file(s) to out directory - [mstallmo], [issue/407] [pull/411]**\n\n    Since `wasm-pack` was first published, we've copied over your `Cargo.toml` license definition over to\n    your `package.json`. However, we overlooked copying the actual `LICENSE` files over! Now we do!\n\n    [issue/407]: https://github.com/rustwasm/wasm-pack/issues/407\n    [pull/411]: https://github.com/rustwasm/wasm-pack/pull/411\n\n  - **Don't require cdylib crate-type for testing - [alexcrichton], [pull/442]**\n\n    `wasm-pack` was unecssarily checking `Cargo.toml` for the `cdylib` crate type during calls to `wasm-pack test`.\n    The `cdylib` output isn't necessary for the `wasm-pack test` stage because `wasm-bindgen` isn't being run over\n    a wasm file during testing. This check is now removed!\n\n    [pull/442]: https://github.com/rustwasm/wasm-pack/pull/442\n\n  - **Fix wasm-bindgen if lib is renamed via `lib.name` - [alexcrichton], [issue/339] [pull/435]**\n\n    In some circumstances, a library author may wish to specify a `name` in the `[package]` portion of their\n    `Cargo.toml`, as well as a different `name` in the `[lib]` portion, e.g.:\n\n    ```toml\n    [package]\n    name = \"hello-wasm\"\n\n    [lib]\n    name = \"wasm-lib\"\n    ```\n\n    This would cause the `wasm-bindgen` build stage of `wasm-pack` to error out because `wasm-pack` would attempt\n    to run `wasm-bindgen-cli` on a path using the `[package]` name, which wouldn't exist (because it would be using\n    the `[lib]` name). Now it works- thanks to more usage of [`cargo_metadata`] in `wasm-pack` internals!\n\n    [`cargo_metadata`]: https://crates.io/crates/cargo_metadata\n    [issue/339]: https://github.com/rustwasm/wasm-pack/issues/339\n    [pull/435]: https://github.com/rustwasm/wasm-pack/pull/435\n\n  - **Print standard error only once for failing commands - [fitzgen], [issue/422] [pull/424]**\n\n    Previously, `wasm-pack` may have printed `stderr` twice in some circumstances. This was both confusing and not\n    a pleasant experience, so now we've ensued that `wasm-pack` prints `stderr` exactly once! (It's hard enough to have\n    errors, you don't want `wasm-pack` rubbing it in, right?)\n\n    [issue/422]: https://github.com/rustwasm/wasm-pack/issues/422\n    [pull/424]: https://github.com/rustwasm/wasm-pack/pull/424\n\n  - **Add no-modules to --target flag's help text - [fitzgen], [issue/416] [pull/417]**\n\n    This is an interesting one! `fitzgen` very reasonably filed an issue asking to add `wasm-bindgen`'s\n    `--target no-modules` feature to `wasm-pack`. This was confusing as this feature was indeed already implemented,\n    and documented- BUT, notably missing from the `wasm-pack --help` text. We've fixed that now- and it was an omission\n    so glaring we definitely considered it a bug!\n\n    [issue/416]: https://github.com/rustwasm/wasm-pack/issues/416\n    [pull/417]: https://github.com/rustwasm/wasm-pack/pull/417\n\n- ### 🛠️ Maintenance\n\n  - **Replace `slog` with `log` - [alexcrichton], [issue/425] [pull/434]**\n\n    For internal maintenance reasons, as well as several end-user ones, we've migrated away from the `slog` family\n    of crates, and are now using the `log` crate plus `env_logger`. Now, `wasm-pack` won't create a `wasm-pack.log`.\n    Additionally, enabling logging will now be done through `RUST_LOG=wasm_pack` instead of `-v` flags.\n\n    [issue/425]: https://github.com/rustwasm/wasm-pack/issues/425\n    [pull/434]: https://github.com/rustwasm/wasm-pack/pull/434\n\n  - **Move binary installation to its own crate - [drager], [issue/384] [pull/415]**\n\n    In `wasm-pack 0.5.0`, we move away from `cargo install`ing many of the tools that `wasm-pack` orchestrates. Because\n    we used `cargo install`, this required an end user to sit through the compilation of each tool, which was a\n    prohibitively long time. We moved, instead, to building, and then installing, binaries of the tools. This sped up\n    build times dramatically!\n\n    This pattern has been very beneficial to `wasm-pack` and is potentially something that could be beneficial to other\n    projects! As a result, we've refactored it out into a crate and have published it as it's own crate, [`binary-install`].\n\n    [`binary-install`]: https://crates.io/crates/binary-install\n    [drager]: https://github.com/drager\n    [issue/384]: https://github.com/rustwasm/wasm-pack/issues/384\n    [pull/415]: https://github.com/rustwasm/wasm-pack/pull/415\n\n  - **Replace internal `Error` with `failure::Error` - [alexcrichton], [pull/436]**\n\n    The story of error message handling in `wasm-pack` has not been the prettiest. We originally were manually implementing\n    errors, adding the [`failure` crate] at one point, but not fully updating the entire codebase. With this PR, we are\n    nearly completely handling errors with `failure`, bringing the code into a much more maintainable and\n    pleasant-to-work-on place.\n\n    [`failure` crate]: https://crates.io/crates/failure\n    [pull/436]: https://github.com/rustwasm/wasm-pack/pull/436\n\n  - **Update `mdbook` version used by Travis - [fitzgen], [pull/433]**\n\n    [pull/433]: https://github.com/rustwasm/wasm-pack/pull/433\n\n  - **Read the `Cargo.toml` file only once - [fitzgen], [issue/25] [pull/431]**\n\n    This is a very fun one since it fixes one of the original issues filed by `ag_dubs` at the very beginning of `wasm-pack`\n    development. In a rush to implement a POC tool, `ag_dubs` noted for posterity that the `Cargo.toml` was being read\n    multiple times (twice), when it did not need to be. Thanks to `fitzgen` now it's read only once! A minor performance\n    improvement in the scheme of things, but a nice one :)\n\n    [issue/25]: https://github.com/rustwasm/wasm-pack/issues/25\n    [pull/431]: https://github.com/rustwasm/wasm-pack/pull/431\n\n  - **Use `name` field for Travis CI jobs - [fitzgen], [pull/432]**\n\n    [pull/432]: https://github.com/rustwasm/wasm-pack/pull/432\n\n  - **Add a test for build command - [huangjj27], [pull/408]**\n\n    [huangjj27]: https://github.com/huangjj27\n    [pull/408]: https://github.com/rustwasm/wasm-pack/pull/408\n\n  - **Test paths on Windows - [xmclark], [issue/380] [pull/389]**\n\n    [xmclark]: https://github.com/xmclark\n    [issue/380]: https://github.com/rustwasm/wasm-pack/issues/380\n    [pull/389]: https://github.com/rustwasm/wasm-pack/pull/389\n\n  - **Fix typo in test function name for copying the README - [mstallmo], [pull/412]**\n\n    [pull/412]: https://github.com/rustwasm/wasm-pack/pull/412\n\n- ### 📖 Documentation\n\n  - **Complete template deep dive docs - [danwilhelm], [issue/345] [issue/346] [pull/490]**\n\n    In a rush to publish a release, `ag_dubs` left some \"Coming soon!\" comments on most pages\n    of the \"Template Deep Dive\" docs. These docs help walk new users through the boilerplate\n    that using the `wasm-pack` template generates for you. Thanks so much to `danwilhem` for\n    picking this up and doing an excellent job!\n\n    [issue/345]: https://github.com/rustwasm/wasm-pack/issues/345\n    [issue/346]: https://github.com/rustwasm/wasm-pack/issues/346\n    [pull/490]: https://github.com/rustwasm/wasm-pack/pull/490\n\n  - **Minor docs updates - [fitzgen], [issue/473] [pull/485]**\n\n    [issue/473]: https://github.com/rustwasm/wasm-pack/issues/473\n    [pull/485]: https://github.com/rustwasm/wasm-pack/pull/485\n\n## 🌄 0.5.1\n\n- ### 🤕 Fixes\n\n  - **Child Process and output management - [fitzgen], [issue/287] [pull/392]**\n\n    Not exactly a \"fix\", but definitely a huge improvment in how child processes and their\n    output are handled by `wasm-pack`. Ever sat at a long prompt from `wasm-pack` and\n    wondered what was happening? No longer! Did `wasm-pack` eat your test output- no more!\n\n    [issue/287]: https://github.com/rustwasm/wasm-pack/issues/287\n    [pull/392]: https://github.com/rustwasm/wasm-pack/pull/392\n\n  - **Less scary missing field messages - [mstallmo], [issue/393] [pull/394]**\n\n    After watching a livestream of someone using `wasm-pack`, [fitzgen] noted that folks\n    seemed pretty alarmed by the loud warning about missing optional manifest fields.\n    As a result, we are now downgrading those messages from WARN to INFO, and consolidating\n    them on a single line.\n\n    [issue/393]: https://github.com/rustwasm/wasm-pack/issues/393\n    [pull/394]: https://github.com/rustwasm/wasm-pack/pull/394\n\n  - **Add `exit_status` to CLI errors - [konstin], [issue/291] [pull/387]**\n\n    We'd been hiding these- but we shouldn't have been!\n\n    [konstin]: https://github.com/konstin\n    [issue/291]: https://github.com/rustwasm/wasm-pack/issues/291\n    [pull/387]: https://github.com/rustwasm/wasm-pack/pull/387\n\n  - **Remove lingering forced nightly usage - [alexcrichton], [pull/383]**\n\n    In 0.5.0 we removed all forced nightly usage as we depend on `~1.30` which is now\n    available on both nightly and beta channels! We had a bit of a race condition with\n    that PR and the `wasm-pack test` PR, and missed a few as a result! This removes all\n    lingering forced nightly, which only affected the `wasm-pack test` command.\n\n    [pull/383]: https://github.com/rustwasm/wasm-pack/pull/383\n\n  - **Fix `wasm-bindgen-test` dependency error message - [fitzgen], [issue/377] [pull/378]**\n\n    The error message about missing the `wasm-bindgen-test` dependency errantly stated\n    that the user was missing a `wasm-bindgen` dependency! We've fixed it to correctly\n    state the missing dependency now.\n\n    [issue/377]: https://github.com/rustwasm/wasm-pack/issues/377\n    [pull/378]: https://github.com/rustwasm/wasm-pack/pull/378\n\n  - **Fix prerequisites links in docs - [fitzgen], [pull/376]**\n\n    [pull/376]: https://github.com/rustwasm/wasm-pack/pull/376\n\n- ### 🛠️ Maintenance\n\n  - **Leverage `failure::Error` consistently - [drager], [issue/280] [pull/401]**\n\n    This PR finally makes it so that `wasm-pack` is handling errors in a consistent\n    way across the codebase.\n\n    [drager]: https://github.com/drager\n    [issue/280]: https://github.com/rustwasm/wasm-pack/issues/280\n    [pull/401]: https://github.com/rustwasm/wasm-pack/pull/401\n\n## ☀️ 0.5.0\n\n- ### ✨ Features\n\n  - #### **Website!** - [ashleygwilliams], [pull/246]\n\n    We have a website now. It has the installer and links to documentation. In the future,\n    we hope to have calls to action for folks first coming to the site who are looking to\n    do specific things- these will help them find the docs and tutorials they need to.\n\n    This PR also has a complete rework of our documentation.\n\n    Check it out [here](https://drager.github.io/wasm-pack/)!\n\n  - #### 🍱 Module Support\n\n    - **BREAKING: use correct `package.json` keys for generated JavaScript - [ashleygwilliams], [issue/309] [pull/312]**\n\n      This is marked as potentially breaking because it changes the `package.json` keys that\n      are generated by the project.\n\n      Previously, we generated a JavaScript file and placed it in the `main` key, regardless\n      of what you were targeting, ES6 and Node.js alike.\n\n      We have received a lot of requests for `wasm-pack` to generate \"isomorphic\" packages,\n      that contain assets that could work on both Node.js and ES6, and this led to us\n      looking more closely at how we are using `package.json`.\n\n      With this release, we will do the following:\n\n      - `--target browser`: By default, we generate JS that is an ES6 module. We used to put\n        this in the `main` field. Now we put it in the `module` field. We also add\n        `sideEffects: false` so that bundlers that want to tree shake can.\n\n      - `--target nodejs`: This target doesn't change. We put generated JS that is a\n        CommonJS module in the `main` key.\n\n      - `--target no-modules`: This is a new target. For this target we generate bare JavaScript.\n        This code is put in a `browser` field.\n\n      You can see the structs that represent each target's expected `package.json` [here](https://github.com/rustwasm/wasm-pack/tree/master/src/manifest/npm).\n\n      Thanks so much to [bterlson] for his help in sorting this out for us!\n\n      [bterlson]: https://github.com/bterlson\n      [issue/309]: https://github.com/rustwasm/wasm-pack/issues/309\n      [pull/312]: https://github.com/rustwasm/wasm-pack/pull/312\n\n  - #### 🛠️ New Commands\n\n    - **`wasm-pack init` is now `wasm-pack build` - [csmoe], [issue/188] [pull/216]**\n\n      When this project was first conceived, we imagined it would be simply a way to package\n      up generate wasm and js and publish it to npm. Here we are at version `0.5.0` and we\n      have become much more- an integrated build tool!\n\n      As a result, the original command `init` does a lot more than that these days. We've\n      renamed the command to better reflect the work it's actually doing. `init` will still\n      work, but is deprecated now, and we will eventually remove it.\n\n      [csmoe]: https://github.com/csmoe\n      [issue/188]: https://github.com/rustwasm/wasm-pack/issues/188\n      [pull/216]: https://github.com/rustwasm/wasm-pack/pull/216\n\n    - **add new command: `wasm-pack test` - [fitzgen], [pull/271]**\n\n      This is an experimental new command that will run your tests in Node.js or a headless\n      browser using `wasm-pack test`. Check out this [tutorial](https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/index.html)\n      to learn more!\n\n      [pull/271]: https://github.com/rustwasm/wasm-pack/pull/271\n\n    - **add 2FA support to `wasm-pack publish` - [mstallmo], [issue/257] [pull/282]**\n\n      We've been wrapping the `npm login` and `npm publish` commands as `wasm-pack login`\n      and `wasm-pack publish` for a while now- but we didn't fully support two factor\n      authentication. Now we do! (Be safe out there! 2FA is good for everyone!)\n\n      [issue/257]: https://github.com/rustwasm/wasm-pack/issues/257\n      [pull/282]: https://github.com/rustwasm/wasm-pack/pull/282\n\n  - #### 🎏 New Flags\n\n    - **New target, bare JavaScript: `--target no-modules` - [ashleygwilliams], [issue/317] [pull/327]**\n\n      `wasm-bindgen` offers a `no-modules` flag that until now, we didn't support. This flag\n      produces bare, no modules JavaScript. So if that's your thing, this target is for you!\n\n      [issue/317]: https://github.com/rustwasm/wasm-pack/issues/317\n      [pull/327]: https://github.com/rustwasm/wasm-pack/pull/327\n\n    - **`--access` flag for `wasm-pack` publish - [ashleygwilliams], [issue/297] [pull/299]**\n\n      Many of our tutorials use scopes to help prevent folks from attempting to publish\n      packages that will lead to npm Registry errors because the package name already exists.\n\n      However, by default, scoped packages are assumed by the npm registry to be private, and\n      the ability to publish private packages to the npm registry is a paid feature. Worry not!\n      Now you can pass `--access public` to `wasm-pack publish` and publish scoped packages\n      publicly.\n\n      [issue/297]: https://github.com/rustwasm/wasm-pack/issues/297\n      [pull/299]: https://github.com/rustwasm/wasm-pack/pull/299\n\n  - #### ✅ New Checks\n\n    - **rustc version check - [ashleygwilliams], [issue/351] [pull/353]**\n\n      Now that we have a new fangled installer, there's a chance that folks might install `wasm-pack`\n      and not have Rust installed. Additionally, now that the features we required from the `nightly`\n      channel of Rust have moved to `beta`- we don't need to enforce `nightly`.\n\n      As of this release, we will check that your Rust version is above `1.30.0`. You can be on\n      either the `nightly` or `beta` channel and all of `wasm-pack`s calls to `cargo` will\n      respect that.\n\n      Really hate this? You can pass `--mode force` to `wasm-pack` to skip this check. I hope you know\n      what you're doing!\n\n    - **coordinating wasm-bindgen versions and installing from binaries for improved speed - [datapup], [issue/146] [pull/244] [pull/324]**\n\n      This is the true gem of this release. Have you been frustrated by how long `wasm-pack` takes to\n      run? Overusing `--mode no-install`? This is the release you're looking for.\n\n      Many releases back we realized that folks were struggling to keep the `wasm-bindgen` library\n      that their project used in sync with the `wasm-bindgen` CLI application which `wasm-pack`\n      runs for you. This became such an issue that we opted to force install `wasm-bindgen` to ensure\n      that every `wasm-pack` user had the latest version.\n\n      Like many technical solutions, this solved our original problem, but caused a new one. Now, we\n      we are forcing a `cargo install` of `wasm-bindgen` on every run, and that means downloading\n      and compiling `wasm-bindgen` everytime you want to run `wasm-pack`. That's unacceptable!\n\n      We're happy to announce that we have a pretty great solution, and several more planned for\n      future releases. As of this release, we will read your `Cargo.lock` to find the version of\n      `wasm-bindgen` you are using in your local project. We will attempt to fetch a binary version\n      of `wasm-bindgen` that matches your local version. We place that binary local to your project,\n      and use it when you run `wasm-pack build`. The next time you run `wasm-pack build` we'll use\n      that binary, instead of fetching a new one. We still fall back to `cargo install` for\n      less common architectures but this is a huge speed improvement. Check out these benchmarks!\n\n      ##### `wasm-pack` v0.4.2\n\n      ```\n      $ time wasm-pack init                   # fresh build\n      real    1m58.802s\n      user    14m49.679s\n      sys     0m24.957s\n\n      $ time wasm-pack init                   # re-build\n      real    0m56.953s\n      user    11m12.075s\n      sys     0m18.835s\n\n      $ time wasm-pack init -m no-install     # re-build with no-install\n      real    0m0.091s\n      user    0m0.052s\n      sys     0m0.042s\n      ```\n\n      ##### `wasm-pack` v0.5.0\n\n      ```\n      $ time wasm-pack build                  # fresh build\n      real    1m3.350s\n      user    3m46.912s\n      sys     0m6.057s\n\n      $ time wasm-pack build                  # re-build\n      real    0m0.230s\n      user    0m0.185s\n      sys     0m0.047s\n\n      $ time wasm-pack build -m no-install    # re-build with no-install\n      real    0m0.104s\n      user    0m0.066s\n      sys     0m0.041s\n      ```\n\n      [datapup]: https://github.com/datapup\n      [issue/146]: https://github.com/rustwasm/wasm-pack/issues/146\n      [pull/244]: https://github.com/rustwasm/wasm-pack/pull/244\n      [pull/324]: https://github.com/rustwasm/wasm-pack/pull/324\n\n    - **enforce `cargo build` with `--lib` - [ashleygwilliams], [issue/303] [pull/330]**\n\n      Right now, `wasm-pack` only works on Rust library projects. But sometimes, if you're\n      new to Rust, you might end up having a `main.rs` in your project, just by mistake.\n      Some folks ran into this and realized that it can cause issues!\n\n      As a result, we are enforcing that `cargo build` only build the library at this time.\n\n      Want to use `wasm-pack` on a binary application? We're interested in hearing from you!\n      Checkout [issue/326] and please comment! We want to support binary applicaitons in\n      the future and are always happy and curious to hear about how folks use `wasm-pack`!\n\n      [issue/326]: https://github.com/rustwasm/wasm-pack/issues/326\n      [issue/303]: https://github.com/rustwasm/wasm-pack/issues/303\n      [pull/330]: https://github.com/rustwasm/wasm-pack/pull/330\n\n  - #### Installers and Releases\n\n    - **Appveyor Windows Pre-Built binaries - [alexcrichton], [issue/147] [pull/301]**\n\n      We finally got Appveyor to publish pre-built binaries to GitHub releases.\n      Aside: I really wish there were an easier way to test and debug this stuff.\n\n      [alexcrichton]: https://github.com/alexcrichton\n      [issue/147]: https://github.com/rustwasm/wasm-pack/issues/147\n      [pull/301]: https://github.com/rustwasm/wasm-pack/pull/301\n\n    - **new experimental installer - [alexcrichton], [pull/307]**\n\n      Whew, this one is exciting. Up until now, `wasm-pack` has been distributed using\n      `cargo install`. This is not ideal for several reasons. Updating is confusing,\n      and every time it's installed the user has to wait for it to compile- right at the\n      moment they just want to hurry up and use it already.\n\n      Say hello to the new `wasm-pack` installer- we have an executable for Windows\n      and a `curl` script for \\*nix users. Not pleased with that? File an issue for your\n      preferred distribution method and we'll do our best to get it working!\n\n      This is experimental- so please try it out and file issues as you run into things!\n      You'll always be able to use `cargo install` as a backup.\n\n      Checkout the new installer [here](https://drager.github.io/wasm-pack/installer/)!\n\n      [pull/307]: https://github.com/rustwasm/wasm-pack/pull/307\n\n- ### 🛠️ Maintenance\n\n  - **testing fixture strategy improvements - [fitzgen], [pull/211] [pull/323]**\n\n    [pull/211]: https://github.com/rustwasm/wasm-pack/pull/211\n    [pull/323]: https://github.com/rustwasm/wasm-pack/pull/323\n\n  - **split testing utils into separate files - [csmoe], [issue/231] [pull/216]**\n\n    [issue/231]: https://github.com/rustwasm/wasm-pack/issues/231\n    [pull/216]: https://github.com/rustwasm/wasm-pack/pull/216\n\n  - **update dependencies - [ashleygwilliams], [issue/319] [pull/320]**\n\n    [issue/319]: https://github.com/rustwasm/wasm-pack/issues/319\n    [pull/320]: https://github.com/rustwasm/wasm-pack/pull/320\n\n- ### 📖 Documentation\n\n  - **improve readability of warnings about missing optional fields - [twilco], [pull/296]**\n\n    A little punctuation goes a long way. Error message improvement PRs are the best.\n\n    [twilco]: https://github.com/twilco\n    [pull/296]: https://github.com/rustwasm/wasm-pack/pull/296\n\n  - **update links in README - [alexcrichton], [pull/300]**\n\n    We had a real dicey documentation situation for a while. Sorry about that, and thank\n    you SO MUCH to all the folks who filed PRs to fix it.\n\n    [pull/300]: https://github.com/rustwasm/wasm-pack/pull/300\n\n  - **fix broken links in book by using relative paths - [mstallmo], [issue/325] [pull/328]**\n\n    [mstallmo]: https://github.com/mstallmo\n    [issue/325]: https://github.com/rustwasm/wasm-pack/issues/325\n    [pull/328]: https://github.com/rustwasm/wasm-pack/pull/328\n\n## ✨ 0.4.2\n\n- #### 🤕 Fixes\n\n  - **recognize `[dependencies.wasm-bindgen]` during dep check in `init` - [ashleygwilliams], [issue/221] [pull/224]**\n\n    When we originally implemented the dependency check in `wasm-pack init` we naively only checked for the\n    \"simple\" dependency declaration, `[dependencies] wasm-bindgen=\"0.2\"`. However! This is not the only way\n    to declare this dependency, and it's not the ideal way to do it if you want to specify features from the\n    crate. Now that a bunch of folks want to use `features = [\"serde-serialize\"]` we ran into a bunch of folks\n    having issues with our naive dependency checker! Thanks so much to [turboladen] for filing the very detailed\n    issue that helped us solve this quickly!\n\n    PSSSST! Curious what `features = [\"serde-serialize\"]` with `wasm-bindgen` actually does? It's awesome:\n\n    > It's possible to pass data from Rust to JS not explicitly supported in the [Feature Reference](./feature-reference.md) by serializing via [Serde](https://github.com/serde-rs/serde).\n\n    Read the [Passing arbitrary data to JS docs] to learn more!\n\n    [Passing arbitrary data to JS docs]: https://github.com/rustwasm/wasm-bindgen/blob/master/guide/src/reference/arbitrary-data-with-serde.md\n    [turboladen]: https://github.com/turboladen\n    [issue/221]: https://github.com/rustwasm/wasm-pack/issues/221\n    [pull/224]: https://github.com/rustwasm/wasm-pack/pull/224\n\n  - **improve UX of publish and pack commands - [Mackiovello], [pull/198]**\n\n    Previous to this fix, you would need to be in the parent directory of the `/pkg` dir to successfully run\n    `pack` or `publish`. This was pretty crummy! Thankfully, [Mackiovello] swooped in with a fix, that you can\n    find documented in the [pack and publish docs]!\n\n    [Mackiovello]: https://github.com/Mackiovello\n    [pull/198]: https://github.com/rustwasm/wasm-pack/pull/198\n    [pack and publish docs]: https://github.com/rustwasm/wasm-pack/blob/05e4743c22b57f4c4a1bfff1df1d2cc1a595f523/docs/pack-and-publish.md\n\n  - **use `PathBuf` instead of `String` for paths - [Mackiovello], [pull/220]**\n\n    This is mostly a maintenance PR but does fix one very small bug- depending on if you add a trailing slash to\n    a path that you pass to `init`, you might have seen an extra `/`! Now that we're using a proper Type to\n    handle this, that's much better, and in general, all the operations using paths are more robust now.\n\n    [pull/220]: https://github.com/rustwasm/wasm-pack/pull/220\n\n- #### 📖 Documentation\n\n  - **update docs and tests to eliminate no longer necessary feature flags - [ashleygwilliams], [pull/226]**\n\n    The Rust 2018 edition marches on and we are seeing feature flags drop like flies :) Instead of a whole slew\n    of feature flags, we now only need one, `#![feature(use_extern_macros)]`, and that one is also not long for\n    this world :)\n\n    [pull/226]: https://github.com/rustwasm/wasm-pack/pull/226\n\n## ⭐ 0.4.1\n\n- #### 🤕 Fixes\n\n  - **fix `files` key value for projects build for `nodejs` target - [ashleygwilliams], [issue/199] [pull/205]**\n\n    We became aware that the `files` key in `package.json` did not include the additional `_bg.js` file that\n    `wasm-bindgen` generates for projects being built for the `nodejs` target. This resulted in the file not\n    being included in the published package and resulted in a `Module Not Found` error for folks.\n\n    This was a group effort from [mciantyre] with [pull/200] and [Brooooooklyn] with [pull/197]. Thank you so\n    much for your diligence and patience while we sorted through it.\n\n    [mciantyre]: https://github.com/mciantyre\n    [Brooooooklyn]: https://github.com/Brooooooklyn\n    [issue/199]: https://github.com/rustwasm/wasm-pack/issues/199\n    [pull/205]: https://github.com/rustwasm/wasm-pack/pull/205\n    [pull/197]: https://github.com/rustwasm/wasm-pack/pull/197\n    [pull/200]: https://github.com/rustwasm/wasm-pack/pull/200\n\n- #### 🛠️ Maintenance\n\n  - **clean up `quicli` remnants - [SoryRawyer], [pull/193]**\n\n    In [v0.3.0] we removed the `quicli` dependency, however there were a few remnants\n    left behind. They are now removed!\n\n    [SoryRawyer]: https://github.com/SoryRawyer\n    [pull/193]: https://github.com/rustwasm/wasm-pack/pull/193\n    [v0.3.0]: https://github.com/rustwasm/wasm-pack/blob/master/CHANGELOG.md#-030\n\n- #### 📖 Documentation\n\n  - **DOCUMENT EVERYTHING!! and deny missing docs for all future development - [fitzgen], [pull/208]**\n\n    The `wasm-pack` team has worked hard on tutorial documentation and keeping the codebase as self-explanatory\n    as possible, but we have been slowly accruing a documentation debt. This amazing PR, landed just moments\n    before this point release and was just too good not to include. Thank you so much, [fitzgen]!\n\n    [fitzgen]: https://github.com/fitzgen\n    [pull/208]: https://github.com/rustwasm/wasm-pack/pull/208\n\n  - **fix README code example - [steveklabnik], [pull/195]**\n\n    The code example in our `README.md` was missing a critical `pub`. It's there now!\n\n    [pull/195]: https://github.com/rustwasm/wasm-pack/pull/195/files\n\n  - **fix README markup - [Hywan], [pull/202]**\n\n    There was an errant `` ` `` - it's gone now!\n\n    [Hywan]: https://github.com/Hywan\n    [pull/202]: https://github.com/rustwasm/wasm-pack/pull/202\n\n## 🌟 0.4.0\n\nThis release has a ton of awesome things in it, but the best thing is that\nalmost all of this awesome work is brought to you by a **new** contributor\nto `wasm-pack`. Welcome ya'll! We're so glad to have you!\n\n### ✨ Features\n\n- #### 🎏 New Flags\n\n  - **`--mode` flag for skipping steps when calling `init` - [ashleygwilliams], [pull/186]**\n\n    After teaching and working with `wasm-pack` for some time, it's clear that people would\n    like the flexibility to run some of the steps included in the `init` command and not others.\n    This release introduces a `--mode` flag that you can pass to `init`. The two modes currently\n    available are `skip-build` and `no-installs` and they are explained below. In the future,\n    we are looking to change the `init` interface, and potentially to split it into two commands.\n    If you have thoughts or opinions on this, please weigh in on [issue/188]!\n\n    [issue/188]: https://github.com/ashleygwilliams/wasm-pack/issues/188\n    [pull/186]: https://github.com/ashleygwilliams/wasm-pack/pull/186\n\n    - **`skip-build` mode - [kohensu], [pull/151]**\n\n      ```\n      wasm-pack init --mode skip-build\n      ```\n\n      Sometimes you want to run some of the shorter meta-data steps that\n      `wasm-pack init` does for you without all the longer build steps. Now\n      you can! Additionally, this PR was a fantastic refactor that allows even\n      more custom build configurations will be simple to implement!\n\n      [kohensu]: https://github.com/kohensu\n      [pull/151]: https://github.com/ashleygwilliams/wasm-pack/pull/151\n\n    - **`no-installs` mode - [ashleygwilliams], [pull/186]**\n\n      ```\n      wasm-pack init --mode no-installs\n      ```\n\n      Sometimes you want to run `wasm-pack` and not have it modify your global\n      env by installing stuff! Or maybe you are just in a hurry and trust your\n      env is set up correctly- now the `--mode no-install` option allows you to\n      do this.\n\n  - **`--debug` - [clanehin], [pull/127]**\n\n    ```\n    wasm-pack init --debug\n    ```\n\n    Find yourself needing to compile your Rust in `development` mode? You can now\n    pass the `--debug` flag to do so! Thanks so much to [clanehin] for filing\n    [issue/126] for this feature... and then implementing it!\n\n    [pull/127]: https://github.com/ashleygwilliams/wasm-pack/pull/127\n    [issue/126]: https://github.com/ashleygwilliams/wasm-pack/issues/126\n    [clanehin]: https://github.com/clanehin\n\n- #### ✅ New Checks\n\n  - **ensure you have `cdylib` crate type - [kendromelon], [pull/150]**\n\n    One of the biggest mistakes we've seen beginners make is forgetting to declare\n    the `cdylib` crate type in their `Cargo.toml` before running `wasm-pack init`.\n    This PR fixes that, and comes from someone who ran into this exact issue learning\n    about `wasm-pack` at [JSConfEU]! Love when it works out like this.\n\n    [JSConfEU]: https://2018.jsconf.eu/\n    [kendromelon]: https://github.com/kedromelon\n    [pull/150]: https://github.com/ashleygwilliams/wasm-pack/pull/150\n\n  - **ensure you have declared wasm-bindgen as a dep - [robertohuertasm], [pull/162]**\n\n    Another easy mistake to make is to forget to declare `wasm-bindgen` as a\n    dependency in your `Cargo.toml`. Now `wasm-pack` will check and make sure you\n    have it set before doing a bunch of long build steps :)\n\n    [robertohuertasm]: https://github.com/robertohuertasm\n    [pull/162]: https://github.com/ashleygwilliams/wasm-pack/pull/162\n\n  - **ensure you are running `nightly` - [FreeMasen], [pull/172]**\n\n    `wasm-pack` currently requires that you run it with `nightly` Rust. Now, `wasm-pack`\n    will make sure you have `nightly` installed and will ensure that `cargo build` is run\n    with `nightly`. Thanks so much to [FreeMasen] for filing [issue/171] and fixing it!\n\n    [FreeMasen]: https://github.com/FreeMasen\n    [issue/171]: https://github.com/ashleygwilliams/wasm-pack/issues/171\n    [pull/172]: https://github.com/ashleygwilliams/wasm-pack/pull/172\n\n### 🤕 Fixes\n\n- **fixed broken progress bar spinner - [migerh], [pull/164]**\n\n  Oh no! We broke the progress bar spinner in version 0.3.0. Thankfully, it's\n  fixed now- with a thoughtful refactor that also makes the underlying code\n  sounder overall.\n\n[migerh]: https://github.com/migerh\n[pull/164]: https://github.com/ashleygwilliams/wasm-pack/pull/164\n\n### 🛠️ Maintenance\n\n- **WIP bot - [ashleygwilliams] & [mgattozzi], [issue/170]**\n\n  We've got a lot of work happening on `wasm-pack` so it's good to have a bit\n  of protection from accidentally merging a Work In Progress. As a result, we\n  now have the [WIP Github App] set up on `wasm-pack`. Great suggestion [mgattozzi]!\n\n  [WIP Github App]: https://github.com/wip/app\n  [issue/170]: https://github.com/ashleygwilliams/wasm-pack/issues/170\n\n- **modularize `command.rs` - [ashleygwilliams], [pull/182]**\n\n  Thanks to the growth of `wasm-pack`, `command.rs` was getting pretty long.\n  We've broken it out into per command modules now, to help make it easier to\n  read and maintain!\n\n  [pull/182]: https://github.com/ashleygwilliams/wasm-pack/pull/182\n\n- **improve PoisonError conversion - [migerh], [pull/187]**\n\n  As part of the awesome progress bar spinner fix in [pull/164], [migerh] introduced\n  a small concern with an `unwrap` due to an outstanding need to convert `PoisonError`\n  into `wasm-pack`'s custom `Error`. Though not a critical concern, [migerh] mitigated\n  this right away by replacing `std::sync::RwLock` with the [`parking_lot` crate]!\n  This cleaned up the code even more than the previous patch!\n\n  [`parking_lot` crate]: https://github.com/Amanieu/parking_lot\n  [pull/187]: https://github.com/ashleygwilliams/wasm-pack/pull/187\n\n- **wasm category for crates.io discovery- [TomasHubelbauer], [pull/149]**\n\n  [crates.io] has [categories] to help folks discover crates, be we weren't\n  leveraging it! Now- if you explore the [`wasm` category] on [crates.io]\n  you'll see `wasm-pack`!\n\n[crates.io]: https://crates.io/\n[categories]: https://crates.io/categories\n[`wasm` category]: https://crates.io/categories/wasm\n[TomasHubelbauer]: https://github.com/TomasHubelbauer\n[pull/149]: https://github.com/ashleygwilliams/wasm-pack/pull/149\n\n- **human panic is now 1.0.0 - [spacekookie], [pull/156]**\n\n  Congrats friends! We like what you do.\n\n[pull/156]: https://github.com/ashleygwilliams/wasm-pack/pull/156\n[spacekookie]: https://github.com/spacekookie\n\n### 📖 Documentation\n\n- **cleaned up the README - [ashleygwilliams], [pull/155]**\n\n  Our `README` was struggling with a common problem- doing too much at once.\n  More specifically, it wasn't clear who the audience was, contributers or\n  end users? We've cleaned up our README and created a document specifically\n  to help contributors get up and running.\n\n[pull/155]: https://github.com/ashleygwilliams/wasm-pack/pull/155\n\n## 🌠 0.3.1\n\nBabby's first point release! Are we a real project now?\n\n### 🤕 Fixes\n\n- **fixed `init` `Is a Directory` error - [ashleygwilliams], [pull/139]**\n\n  Our new logging feature accidentally introduced a regression into 0.3.0. When\n  calling `wasm-pack init`, if a directory was not passed, a user would receive\n  a \"Is a Directory\" Error. Sorry about that! Thanks to [jbolila] for filing\n  [issue/136]!\n\n[pull/139]: https://github.com/ashleygwilliams/wasm-pack/pull/139\n[issue/136]: https://github.com/ashleygwilliams/wasm-pack/issues/136\n[jbolila]: https://github.com/jbolila\n\n- **typescript files were not included in published package - [danreeves], [pull/138]**\n\n  Generating Typescript type files by default was a pretty rad feature in\n  0.3.0 but we accidentally forgot to ensure they were included in the\n  published package. Thanks so much to [danreeves] for catching this issue\n  and fixing it for us!\n\n[danreeves]: https://github.com/danreeves\n[pull/138]: https://github.com/ashleygwilliams/wasm-pack/pull/138\n\n## 💫 0.3.0\n\n### ✨ Features\n\n- **Logging - [mgattozzi], [pull/134]**\n\n  Up until now, we've forced folks to rely on emoji-jammed console output to debug\n  errors. While emojis are fun, this is often not the most pleasant experience. Now\n  we'll generate a `wasm-pack.log` file if `wasm-pack` errors on you, and you can\n  customize the log verbosity using the (previously unimplemented) verbosity flag.\n\n[pull/134]: https://github.com/ashleygwilliams/wasm-pack/pull/134\n\n- **`--target` flag - [djfarly], [pull/132]**\n\n  `wasm-bindgen-cli` is able to generate a JS module wrapper for generated wasm files\n  for both ES6 modules and CommonJS. Up until now, we only used wasm-bindgen's default\n  behavior, ES6 modules. You can now pass a `--target` flag with either `nodejs` or\n  `browser` to generate the type of module you want to use. Defaults to `browser` if not\n  passed.\n\n[djfarly]: https://github.com/djfarly\n[pull/132]: https://github.com/ashleygwilliams/wasm-pack/pull/132\n\n- **human readable panics - [yoshuawuyts], [pull/118]**\n\n  Panics aren't always the most friendly situation ever. While we never want to panic on ya,\n  if we do- we'll do it in a way that's a little more readable now.\n\n[pull/118]: https://github.com/ashleygwilliams/wasm-pack/pull/118\n\n- **typescript support by default - [kwonoj], [pull/109]**\n\n  `wasm-bindgen` now generates typescript type files by default. To suppress generating\n  the type file you can pass the `--no-typescript` flag. The type file is useful for more\n  than just typescript folks- many IDEs use it for completion!\n\n[kwonoj]: https://github.com/kwonoj\n[pull/109]: https://github.com/ashleygwilliams/wasm-pack/pull/109\n\n- **wrap `npm login` command - [djfarly], [pull/100]**\n\n  In order to publish a package to npm, you need to be logged in. You can now use\n  `wasm-pack login` to login to the npm (or any other) registry.\n\n[pull/100]: https://github.com/ashleygwilliams/wasm-pack/pull/100\n\n- **exit early on failure - [mgattozzi], [pull/90]**\n\n  Until now, `wasm-pack` would continue to run tasks, even if a task failed. Now- if something\n  fails, we'll exit so you don't have to wait to fix the error.\n\n[pull/90]: https://github.com/ashleygwilliams/wasm-pack/pull/90\n\n### 🤕 Fixes\n\n- **force install wasm-bindgen - [ashleygwilliams], [pull/133]**\n\n  Using an out of date version of `wasm-bindgen` can run you into a bunch of trouble. This\n  very small change should fix the large number of bug reports we received from users using\n  an out of date `wasm-bindgen-cli` by force installing `wasm-bindgen-cli` to ensure the user\n  always has the latest version. We don't expect this to be a forever solution (it's a bit\n  slow!) but it should help those who are getting started have a less rough time.\n\n[pull/133]: https://github.com/ashleygwilliams/wasm-pack/pull/133\n\n- **fix CI release builds - [ashleygwilliams], [pull/135]**\n\n  This was not working! But now it is! You can always use `cargo install` to install\n  wasm-pack, but now you can find pre-built Linux and Mac binaries in the [Releases]\n  tab of our GitHub repo.\n\n[Releases]: https://github.com/ashleygwilliams/wasm-pack/releases\n[pull/135]: https://github.com/ashleygwilliams/wasm-pack/pull/135\n\n### 🛠️ Maintenance\n\n- **remove `quicli` dependency - [mgattozzi], [pull/131]**\n\n  While `quicli` is a great way to get started writing a CLI app in Rust- it's not meant for\n  large, mature applications. Now that `wasm-pack` is bigger and has many active users, we've\n  removed this dependency to unblock further development on the tool.\n\n[pull/131]: https://github.com/ashleygwilliams/wasm-pack/pull/131\n\n- **update rustfmt CI test - [djfarly], [pull/128]**\n\n  Since 0.2.0 how one should call `rustfmt` changed! We've kept it up to date so we can continue\n  to maintain conventional style in the codebase.\n\n[pull/128]: https://github.com/ashleygwilliams/wasm-pack/pull/128\n\n- **custom module for errors - [mgattozzi], [pull/120]**\n\n  Thanks to the `failure` crate, we've been playing fast and loose with errors for a bit. We're\n  finally getting serious about error handling - by organizing all of our specific errors in a\n  specific module. This will make it easier to communicate these errors out and handle new error\n  cases from future features.\n\n[pull/120]: https://github.com/ashleygwilliams/wasm-pack/pull/120\n\n### 📖 Documentation\n\nSpecial thanks to [data-pup] who continues to be our documentation champion! In case you missed it,\ncheck out the guides in the [docs directory!](docs)!\n\n## 🌌 0.2.0\n\nThis release focuses on filling out all commands and improving stderr/out\nhandling for improved user experience!\n\n### ✨ Features\n\n- **`pack` and `publish` - [jamiebuilds], [pull/67]**\n  You can now run `wasm-pack pack` to generate a tarball of your generated package,\n  as well as run `wasm-pack publish` to publish your package to the npm registry.\n  Both commands require that you have npm installed, and the `publish` command requires\n  that you be logged in to the npm client. We're working on wrapping the `npm login`\n  command so that you can also login directly from `wasm-pack`, see [pull/100] for more\n  details.\n\n[jamiebuilds]: https://github.com/jamiebuilds\n[pull/67]: https://github.com/ashleygwilliams/wasm-pack/pull/67\n[pull/100]: https://github.com/ashleygwilliams/wasm-pack/pull/100\n\n- **`package.json` is pretty printed now - [yoshuawuyts], [pull/70]**\n\n  Previously, `package.json` was not very human readable. Now it is pretty printed!\n\n- **`collaborators` - [yoshuawuyts], [pull/70]**\n\n  `wasm-pack` now will fill out the `collaborators` field in your `package.json` for\n  you based on your `Cargo.toml` `authors` data. For more discussion on how we decided\n  on this v.s. other types of `author` fields in `package.json`, see [issues/2].\n\n[yoshuawuyts]: https://github.com/yoshuawuyts\n[pull/70]: https://github.com/ashleygwilliams/wasm-pack/pull/70\n[issues/2]: https://github.com/ashleygwilliams/wasm-pack/issues/2\n\n- **Release binaries built with CI - [ashleygwilliams], [pull/103]**\n\n[ashleygwilliams]: https://github.com/ashleygwilliams\n[pull/103]: https://github.com/ashleygwilliams/wasm-pack/pull/103\n\n### 🤕 Fixes\n\n- **Optional `package.json` fields warn instead of failing - [mgattozzi], [pull/65]**\n\n[pull/65]: https://github.com/ashleygwilliams/wasm-pack/pull/65\n\n- **Program doesn't swallow stout and sterr - [mgattozzi], [pull/90]**\n\n[mgattozzi]: https://github.com/mgattozzi\n[pull/90]: https://github.com/ashleygwilliams/wasm-pack/pull/90\n\n### 🛠️ Maintenance and 📖 Documentation\n\nThanks so much to [mgattozzi], [data-pup], [sendilkumarn], [Andy-Bell],\n[steveklabnik], [jasondavies], and [edsrzf] for all the awesome refactoring,\ndocumentation, typo-fixing, and testing work. We appreciate it so much!\n\n[data-pup]: https://github.com/data-pup\n[sendilkumarn]: https://github.com/sendilkumarn\n[Andy-Bell]: https://github.com/Andy-Bell\n[steveklabnik]: https://github.com/steveklabnik\n[jasondavies]: https://github.com/jasondavies\n[edsrzf]: https://github.com/edsrzf\n\n## 💥 0.1.0\n\n- First release!\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# The Rust Code of Conduct\n\nA version of this document [can be found online](https://www.rust-lang.org/conduct.html).\n\n## Conduct\n\n**Contact**: [rust-mods@rust-lang.org](mailto:rust-mods@rust-lang.org)\n\n* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.\n* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.\n* Please be kind and courteous. There's no need to be mean or rude.\n* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.\n* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.\n* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term \"harassment\" as including the definition in the <a href=\"http://citizencodeofconduct.org/\">Citizen Code of Conduct</a>; if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.\n* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Rust moderation team][mod_team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.\n* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.\n\n## Moderation\n\n\nThese are the policies for upholding our community's standards of conduct. If you feel that a thread needs moderation, please contact the [Rust moderation team][mod_team].\n\n1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)\n2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.\n3. Moderators will first respond to such remarks with a warning.\n4. If the warning is unheeded, the user will be \"kicked,\" i.e., kicked out of the communication channel to cool off.\n5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.\n6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.\n7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed.\n8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others.\n\nIn the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely.\n\nAnd if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.\n\nThe enforcement policies listed above apply to all official Rust venues; including official IRC channels (#rust, #rust-internals, #rust-tools, #rust-libs, #rustc, #rust-beginners, #rust-docs, #rust-community, #rust-lang, and #cargo); GitHub repositories under rust-lang, rust-lang-nursery, and rust-lang-deprecated; and all forums under rust-lang.org (users.rust-lang.org, internals.rust-lang.org). For other projects adopting the Rust Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion.\n\n*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*\n\n[mod_team]: https://www.rust-lang.org/team.html#Moderation-team\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\n## Filing an Issue\n\nIf you are trying to use `wasm-pack` and run into an issue- please file an\nissue! We'd love to get you up and running, even if the issue you have might\nnot be directly related to the code in `wasm-pack`. This tool seeks to make\nit easy for developers to get going, so there's a good chance we can do\nsomething to alleviate the issue by making `wasm-pack` better documented or\nmore robust to different developer environments.\n\nWhen filing an issue, do your best to be as specific as possible. Include\nthe version of rust you are using (`rustc --version`) and your operating\nsystem and version. The faster was can reproduce your issue, the faster we\ncan fix it for you!\n\n## Submitting a PR\n\nIf you are considering filing a pull request, make sure that there's an issue\nfiled for the work you'd like to do. There might be some discussion required!\nFiling an issue first will help ensure that the work you put into your pull\nrequest will get merged :)\n\nBefore you submit your pull request, check that you have completed all of the\nsteps mentioned in the pull request template. Link the issue that your pull\nrequest is responding to, and format your code using [rustfmt][rustfmt].\n\n### Configuring rustfmt\n\nBefore submitting code in a PR, make sure that you have formatted the codebase\nusing [rustfmt][rustfmt]. `rustfmt` is a tool for formatting Rust code, which\nhelps keep style consistent across the project. If you have not used `rustfmt`\nbefore, it is not too difficult.\n\nIf you have not already configured `rustfmt` for the\nnightly toolchain, it can be done using the following steps:\n\n**1. Use Nightly Toolchain**\n\nUse the `rustup override` command to make sure that you are using the nightly\ntoolchain. Run this command in the `wasm-pack` directory you cloned.\n\n```sh\nrustup override set nightly\n```\n\n**2. Add the rustfmt component**\n\nInstall the most recent version of `rustfmt` using this command:\n\n```sh\nrustup component add rustfmt-preview --toolchain nightly\n```\n\n**3. Running rustfmt**\n\nTo run `rustfmt`, use this command:\n\n```sh\ncargo +nightly fmt\n```\n\n[rustfmt]: https://github.com/rust-lang-nursery/rustfmt\n\n### IDE Configuration files\nMachine specific configuration files may be generaged by your IDE while working on the project. Please make sure to add these files to a global .gitignore so they are kept from accidentally being commited to the project and causing issues for other contributors.\n\nSome examples of these files are the `.idea` folder created by JetBrains products (WebStorm, IntelliJ, etc) as well as `.vscode` created by Visual Studio Code for workspace specific settings. \n\nFor help setting up a global .gitignore check out this [GitHub article]!\n\n[GitHub article]: https://help.github.com/articles/ignoring-files/#create-a-global-gitignore\n\n## Running tests\n\nSome of this project's tests run in the browser with webdriver. macOS users\nmay need to first run:\n\n```\nsafaridriver --enable\n```\n\n## Conduct\n\nAs mentioned in the readme file, this project is a part of the [`rust-wasm` working group],\nan official working group of the Rust project. We follow the Rust [Code of Conduct and enforcement policies].\n\n[`rust-wasm` working group]: https://github.com/rustwasm/team\n[Code of Conduct and enforcement policies]: CODE_OF_CONDUCT.md\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"wasm-pack\"\ndescription = \"📦✨ your favorite rust -> wasm workflow tool!\"\nversion = \"0.14.0\"\nauthors = [\"Ashley Williams <ashley666ashley@gmail.com>\", \"Jesper Håkansson <jesper@jesperh.se>\"]\nrepository = \"https://github.com/drager/wasm-pack.git\"\nlicense = \"MIT OR Apache-2.0\"\nedition = \"2021\"\nreadme = \"README.md\"\ncategories = [\"wasm\"]\ndocumentation = \"https://drager.github.io/wasm-pack/\"\n\n[dependencies]\nanyhow = \"1.0.100\"\nbinary-install = \"0.4.1\"\ncargo_metadata = \"0.23.1\"\nchrono = \"0.4.42\"\nconsole = \"0.16.1\"\ndialoguer = \"0.12.0\"\nenv_logger = { version = \"0.11.8\", default-features = false }\nglob = \"0.3.3\"\nhuman-panic = \"2.0.4\"\nlog = \"0.4.28\"\nparking_lot = \"0.12.5\"\nsemver = \"1.0.27\"\nserde = \"1.0.228\"\nserde_derive = \"1.0.228\"\nserde_ignored = \"0.1.14\"\nserde_json = \"1.0.145\"\nsiphasher = \"1.0.1\"\nstrsim = \"0.11.1\"\nclap = { version = \"4.2.5\", features = [\"derive\"] }\ntoml = \"0.9.8\"\nureq = { version = \"2.12.1\", features = [\"json\", \"socks-proxy\"] }\nwalkdir = \"2.5.0\"\nwhich = \"8.0.0\"\npath-clean = \"1.0.1\"\n\n[dev-dependencies]\nassert_cmd = \"2.1.1\"\nlazy_static = \"1.5.0\"\npredicates = \"3.1.3\"\nserial_test = \"3.2.0\"\ntempfile = \"3.23.0\"\n\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "                              Apache License\n                        Version 2.0, January 2004\n                     http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n   \"License\" shall mean the terms and conditions for use, reproduction,\n   and distribution as defined by Sections 1 through 9 of this document.\n\n   \"Licensor\" shall mean the copyright owner or entity authorized by\n   the copyright owner that is granting the License.\n\n   \"Legal Entity\" shall mean the union of the acting entity and all\n   other entities that control, are controlled by, or are under common\n   control with that entity. For the purposes of this definition,\n   \"control\" means (i) the power, direct or indirect, to cause the\n   direction or management of such entity, whether by contract or\n   otherwise, or (ii) ownership of fifty percent (50%) or more of the\n   outstanding shares, or (iii) beneficial ownership of such entity.\n\n   \"You\" (or \"Your\") shall mean an individual or Legal Entity\n   exercising permissions granted by this License.\n\n   \"Source\" form shall mean the preferred form for making modifications,\n   including but not limited to software source code, documentation\n   source, and configuration files.\n\n   \"Object\" form shall mean any form resulting from mechanical\n   transformation or translation of a Source form, including but\n   not limited to compiled object code, generated documentation,\n   and conversions to other media types.\n\n   \"Work\" shall mean the work of authorship, whether in Source or\n   Object form, made available under the License, as indicated by a\n   copyright notice that is included in or attached to the work\n   (an example is provided in the Appendix below).\n\n   \"Derivative Works\" shall mean any work, whether in Source or Object\n   form, that is based on (or derived from) the Work and for which the\n   editorial revisions, annotations, elaborations, or other modifications\n   represent, as a whole, an original work of authorship. For the purposes\n   of this License, Derivative Works shall not include works that remain\n   separable from, or merely link (or bind by name) to the interfaces of,\n   the Work and Derivative Works thereof.\n\n   \"Contribution\" shall mean any work of authorship, including\n   the original version of the Work and any modifications or additions\n   to that Work or Derivative Works thereof, that is intentionally\n   submitted to Licensor for inclusion in the Work by the copyright owner\n   or by an individual or Legal Entity authorized to submit on behalf of\n   the copyright owner. For the purposes of this definition, \"submitted\"\n   means any form of electronic, verbal, or written communication sent\n   to the Licensor or its representatives, including but not limited to\n   communication on electronic mailing lists, source code control systems,\n   and issue tracking systems that are managed by, or on behalf of, the\n   Licensor for the purpose of discussing and improving the Work, but\n   excluding communication that is conspicuously marked or otherwise\n   designated in writing by the copyright owner as \"Not a Contribution.\"\n\n   \"Contributor\" shall mean Licensor and any individual or Legal Entity\n   on behalf of whom a Contribution has been received by Licensor and\n   subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   copyright license to reproduce, prepare Derivative Works of,\n   publicly display, publicly perform, sublicense, and distribute the\n   Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   (except as stated in this section) patent license to make, have made,\n   use, offer to sell, sell, import, and otherwise transfer the Work,\n   where such license applies only to those patent claims licensable\n   by such Contributor that are necessarily infringed by their\n   Contribution(s) alone or by combination of their Contribution(s)\n   with the Work to which such Contribution(s) was submitted. If You\n   institute patent litigation against any entity (including a\n   cross-claim or counterclaim in a lawsuit) alleging that the Work\n   or a Contribution incorporated within the Work constitutes direct\n   or contributory patent infringement, then any patent licenses\n   granted to You under this License for that Work shall terminate\n   as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n   Work or Derivative Works thereof in any medium, with or without\n   modifications, and in Source or Object form, provided that You\n   meet the following conditions:\n\n   (a) You must give any other recipients of the Work or\n       Derivative Works a copy of this License; and\n\n   (b) You must cause any modified files to carry prominent notices\n       stating that You changed the files; and\n\n   (c) You must retain, in the Source form of any Derivative Works\n       that You distribute, all copyright, patent, trademark, and\n       attribution notices from the Source form of the Work,\n       excluding those notices that do not pertain to any part of\n       the Derivative Works; and\n\n   (d) If the Work includes a \"NOTICE\" text file as part of its\n       distribution, then any Derivative Works that You distribute must\n       include a readable copy of the attribution notices contained\n       within such NOTICE file, excluding those notices that do not\n       pertain to any part of the Derivative Works, in at least one\n       of the following places: within a NOTICE text file distributed\n       as part of the Derivative Works; within the Source form or\n       documentation, if provided along with the Derivative Works; or,\n       within a display generated by the Derivative Works, if and\n       wherever such third-party notices normally appear. The contents\n       of the NOTICE file are for informational purposes only and\n       do not modify the License. You may add Your own attribution\n       notices within Derivative Works that You distribute, alongside\n       or as an addendum to the NOTICE text from the Work, provided\n       that such additional attribution notices cannot be construed\n       as modifying the License.\n\n   You may add Your own copyright statement to Your modifications and\n   may provide additional or different license terms and conditions\n   for use, reproduction, or distribution of Your modifications, or\n   for any such Derivative Works as a whole, provided Your use,\n   reproduction, and distribution of the Work otherwise complies with\n   the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n   any Contribution intentionally submitted for inclusion in the Work\n   by You to the Licensor shall be under the terms and conditions of\n   this License, without any additional terms or conditions.\n   Notwithstanding the above, nothing herein shall supersede or modify\n   the terms of any separate license agreement you may have executed\n   with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n   names, trademarks, service marks, or product names of the Licensor,\n   except as required for reasonable and customary use in describing the\n   origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n   agreed to in writing, Licensor provides the Work (and each\n   Contributor provides its Contributions) on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n   implied, including, without limitation, any warranties or conditions\n   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n   PARTICULAR PURPOSE. You are solely responsible for determining the\n   appropriateness of using or redistributing the Work and assume any\n   risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n   whether in tort (including negligence), contract, or otherwise,\n   unless required by applicable law (such as deliberate and grossly\n   negligent acts) or agreed to in writing, shall any Contributor be\n   liable to You for damages, including any direct, indirect, special,\n   incidental, or consequential damages of any character arising as a\n   result of this License or out of the use or inability to use the\n   Work (including but not limited to damages for loss of goodwill,\n   work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses), even if such Contributor\n   has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n   the Work or Derivative Works thereof, You may choose to offer,\n   and charge a fee for, acceptance of support, warranty, indemnity,\n   or other liability obligations and/or rights consistent with this\n   License. However, in accepting such obligations, You may act only\n   on Your own behalf and on Your sole responsibility, not on behalf\n   of any other Contributor, and only if You agree to indemnify,\n   defend, and hold each Contributor harmless for any liability\n   incurred by, or claims asserted against, such Contributor by reason\n   of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n   To apply the Apache License to your work, attach the following\n   boilerplate notice, with the fields enclosed by brackets \"[]\"\n   replaced with your own identifying information. (Don't include\n   the brackets!)  The text should be enclosed in the appropriate\n   comment syntax for the file format. We also recommend that a\n   file or class name and description of purpose be included on the\n   same \"printed page\" as the copyright notice for easier\n   identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "Copyright (c) 2018 Ashley Williams\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n\n  <h1>📦✨ wasm-pack</h1>\n\n  <p>\n    <strong>Your favorite Rust → Wasm workflow tool!</strong>\n  </p>\n\n  <p>\n    <a href=\"https://github.com/drager/wasm-pack/actions/workflows/test.yml\"><img alt=\"Build Status\" src=\"https://github.com/drager/wasm-pack/actions/workflows/test.yml/badge.svg?branch=master\"/></a>\n    <a href=\"https://crates.io/crates/wasm-pack\"><img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/wasm-pack\"/></a>\n  </p>\n\n  <h3>\n    <a href=\"https://drager.github.io/wasm-pack/book\">Docs</a>\n    <span> | </span>\n    <a href=\"https://github.com/drager/wasm-pack/blob/master/CONTRIBUTING.md\">Contributing</a>\n    <span> | </span>\n    <a href=\"https://discordapp.com/channels/442252698964721669/443151097398296587\">Chat</a>\n  </h3>\n\n\n</div>\n\n## About\n\nThis tool seeks to be a one-stop shop for building and working with rust-\ngenerated WebAssembly that you would like to interop with JavaScript, in the\nbrowser or with Node.js. `wasm-pack` helps you build rust-generated\nWebAssembly packages that you could publish to the npm registry, or otherwise use\nalongside any javascript packages in workflows that you already use, such as [webpack].\n\n[webpack]: https://webpack.js.org/\n\n![demo](demo.gif)\n\n## 🔮 Prerequisites\n\nThis project requires Rust 1.30.0 or later.\n\n- [Development Environment](https://drager.github.io/wasm-pack/book/prerequisites/index.html)\n- [Installation](https://drager.github.io/wasm-pack/installer)\n\n## ⚡ Quickstart Guide\n\nVisit the [quickstart guide] in our documentation.\n\n[quickstart guide]: https://drager.github.io/wasm-pack/book/quickstart.html\n\n## 🎙️ Commands\n\n- [`new`](https://drager.github.io/wasm-pack/book/commands/new.html): Generate a new RustWasm project using a template\n- [`build`](https://drager.github.io/wasm-pack/book/commands/build.html): Generate an npm wasm pkg from a rustwasm crate\n- [`test`](https://drager.github.io/wasm-pack/book/commands/test.html): Run browser tests\n- [`pack` and `publish`](https://drager.github.io/wasm-pack/book/commands/pack-and-publish.html): Create a tarball of your rustwasm pkg and/or publish to a registry\n\n## 📝 Logging\n\n`wasm-pack` uses [`env_logger`] to produce logs when `wasm-pack` runs.\n\nTo configure your log level, use the `RUST_LOG` environment variable. For example:\n\n```\nRUST_LOG=info wasm-pack build\n```\n\n[`env_logger`]: https://crates.io/crates/env_logger\n\n## 👯 Contributing\n\nRead our [guide] on getting up and running for developing `wasm-pack`, and\ncheck out our [contribution policy].\n\n[guide]: https://drager.github.io/wasm-pack/book/contributing.html\n[contribution policy]: CONTRIBUTING.md\n\n## 🤹‍♀️ Governance\n\nThis project was started by [ashleygwilliams] and is maintained by [drager].\n\n[ashleygwilliams]: https://github.com/ashleygwilliams\n[drager]: https://github.com/drager\n"
  },
  {
    "path": "RELEASE_CHECKLIST.md",
    "content": "# Release Checklist\n\nThis is a list of the things that need to happen during a release.\n\n1. Open the associated milestone. All issues and PRs should be closed. If\n  they are not you should reassign all open issues and PRs to future\n  milestones.\n1. Go through the commit history since last release. Ensure that all PRs\n  that have landed are marked with the milestone. You can use this to \n  show all the PRs that are merged on or after YYY-MM-DD: \n  `https://github.com/issues?utf8=%E2%9C%93&q=repo%3Arustwasm%2Fwasm-pack+merged%3A%3E%3DYYYY-MM-DD`\n1. Go through the closed PRs in the milestone. Each should have a changelog\n  label indicating if the change is docs, fix, feature, or maintenance. If\n  there is a missing label, please add one.\n1. Choose an emoji for the release. Try to make it some sort of transition\n  from the previous releases emoji (point releases can be a little weirder).\n1. Create a new branch \"#.#.#\" where \"#.#.#\" is the release's version.\n1. Add this release to the `CHANGELOG.md`. Use the structure of previous \n  entries.\n1. Update `DEFAULT_CHROMEDRIVER_VERSION` in `chromedriver.rs`. \n  Version is the response of `https://chromedriver.storage.googleapis.com/LATEST_RELEASE`.\n1. Update `DEFAULT_GECKODRIVER_VERSION` in `geckodriver.rs`.\n  Version is the name of the latest tag - `https://github.com/mozilla/geckodriver/releases/latest`.\n1. Update the version in `Cargo.toml`.\n1. Update the version number and date in `docs/index.html`.\n1. Run `cargo update`.\n1. Run `cargo test`.\n1. Run `cargo build`.\n1. Copy `README.md` to `npm/README.md`\n1. Bump the version number in `npm/package.json`\n1. `cd npm && npm install`\n1. Push up a commit with the `Cargo.toml`, `Cargo.lock`, `docs/index.html`,\n  and `CHANGELOG.md` changes. The commit message can just be \"#.#.#\".\n1. Request review from `@ashleygwilliams` and `@drager`.\n1. `git commit --amend` all changes into the single commit.\n1. Once ready to merge, tag the commit with the tag `v#.#.#`.\n1. Wait for the CI to go green.\n1. The CI will build the release binaries. Take the `CHANGELOG.md` release\n  entry and cut and paste it into the release body.\n1. Be sure to add any missing link definitions to the release.\n1. Hit the big green Merge button.\n1. `git checkout master` and `git pull --rebase origin master`\n1. Run `cargo test`.\n1. `cargo publish`\n1. `cd npm && npm publish`\n1. Tweet.\n"
  },
  {
    "path": "clippy.toml",
    "content": "too-many-arguments-threshold = 8"
  },
  {
    "path": "docs/_installer/build-installer.rs",
    "content": "use std::fs;\n\nfn main() {\n    fs::create_dir_all(\"docs/installer\").unwrap();\n    fs::copy(\n        \"docs/_installer/wasm-pack.js\",\n        \"docs/installer/wasm-pack.js\",\n    ).unwrap();\n    let index = fs::read_to_string(\"docs/_installer/index.html\").unwrap();\n    fs::write(\n        \"docs/installer/index.html\",\n        fixup(&index),\n    ).unwrap();\n\n    let init = fs::read_to_string(\"docs/_installer/init.sh\").unwrap();\n    fs::write(\n        \"docs/installer/init.sh\",\n        fixup(&init),\n    ).unwrap();\n}\n\nfn fixup(input: &str) -> String {\n    let manifest = fs::read_to_string(\"Cargo.toml\").unwrap();\n    let version = manifest.lines()\n        .find(|line| line.starts_with(\"version =\"))\n        .unwrap();\n    let version = &version[version.find('\"').unwrap() + 1..version.rfind('\"').unwrap()];\n\n    input.replace(\"$VERSION\", &format!(\"v{}\", version))\n}\n"
  },
  {
    "path": "docs/_installer/index.html",
    "content": "<!DOCTYPE html>\n<head>\n  <meta charset=\"utf-8\" />\n  <title>wasm-pack</title>\n  <link\n    href=\"https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css\"\n    rel=\"stylesheet\"\n  />\n  <link rel=\"stylesheet\" href=\"../public/custom.css\" />\n  <style>\n    .winlink {\n      display: block;\n    }\n  </style>\n  <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"../apple-touch-icon.png\" />\n  <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"../favicon-32x32.png\" />\n  <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"../favicon-16x16.png\" />\n  <link rel=\"manifest\" href=\"../site.webmanifest\" />\n  <link rel=\"mask-icon\" href=\"../safari-pinned-tab.svg\" color=\"#5bbad5\" />\n  <meta name=\"msapplication-TileColor\" content=\"#00aba9\" />\n  <meta name=\"theme-color\" content=\"#ffffff\" />\n</head>\n<body>\n  <nav class=\"navbar\">\n    <div class=\"container\">\n      <ul class=\"navbar-list\">\n        <li class=\"navbar-logo\">\n          <a href=\"/wasm-pack\">\n            <img src=\"../public/img/rustwasm.png\" />\n          </a>\n        </li>\n        <li class=\"navbar-item\">\n          <a href=\"https://github.com/drager/wasm-pack/issues/new/choose\"\n            >File an Issue</a\n          >\n        </li>\n        <li class=\"navbar-item\">\n          <a href=\"/wasm-pack/book\">Documentation</a>\n        </li>\n        <li class=\"navbar-item\">\n          <a href=\"/wasm-pack/installer\">Install</a>\n        </li>\n      </ul>\n    </div>\n  </nav>\n  <section id=\"installer\">\n    <img src=\"../public/img/wasm-ferris.png\" />\n    <h1>Install <code>wasm-pack</code></h1>\n    <div class=\"container\">\n      <div id=\"platform-instructions-unix\" style=\"display: none\">\n        <p>\n          You appear to be running a *nix system (Unix, Linux, MacOS). Install\n          by running:\n        </p>\n        <pre class=\"primary\">\ncurl https://drager.github.io/wasm-pack/installer/init.sh -sSf | sh</pre\n        >\n        <p>\n          If you're not on *nix, or you don't like installing from <b>curl</b>,\n          follow the alternate instructions below.\n        </p>\n      </div>\n\n      <div id=\"platform-instructions-win64\" style=\"display: none\">\n        <p>\n          You appear to be running Windows 64-bit. Download and run\n          <a\n            class=\"winlink\"\n            href=\"https://github.com/drager/wasm-pack/releases/download/$VERSION/wasm-pack-init.exe\"\n            >wasm-pack-init.exe</a\n          >\n          then follow the onscreen instructions.\n        </p>\n        <hr />\n        <p>\n          If you're a Windows Subsystem for Linux user, run the following in\n          your terminal, then follow the onscreen instructions to install\n          wasm-pack.\n        </p>\n        <pre class=\"primary\">\ncurl https://drager.github.io/wasm-pack/installer/init.sh -sSf | sh</pre\n        >\n        <p>\n          If you're not on Windows 64-bit, follow the alternate instructions\n          below.\n        </p>\n      </div>\n\n      <div id=\"platform-instructions-unknown\" style=\"display: none\">\n        <p>I don't recognize your platform.</p>\n        <p>\n          We would appreciate it if you\n          <a href=\"https://github.com/drager/wasm-pack/issues/new\"\n            >reported an issue</a\n          >, along with the following values:\n        </p>\n        <div>\n          <div>navigator.platform:</div>\n          <div id=\"nav-plat\"></div>\n          <div>navigator.appVersion:</div>\n          <div id=\"nav-app\"></div>\n        </div>\n      </div>\n\n      <hr />\n\n      <div id=\"generic-instructions\">\n        <p>To install from source on any platform:</p>\n        <p><code>cargo install wasm-pack</code></p>\n        <p>\n          On supported platforms, you can also use <b>npm</b> or <b>yarn</b> to\n          download a precompiled binary:\n        </p>\n        <p>\n          <code>npm install -g wasm-pack</code> or\n          <code>yarn global add wasm-pack</code>\n        </p>\n      </div>\n    </div>\n  </section>\n  <script type=\"text/javascript\" src=\"wasm-pack.js\"></script>\n</body>\n"
  },
  {
    "path": "docs/_installer/init.sh",
    "content": "#!/bin/bash\n# Copyright 2016 The Rust Project Developers. See the COPYRIGHT\n# file at the top-level directory of this distribution and at\n# http://rust-lang.org/COPYRIGHT.\n#\n# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n# option. This file may not be copied, modified, or distributed\n# except according to those terms.\n\n# This is just a little script that can be downloaded from the internet to\n# install wasm-pack. It just does platform detection, downloads the installer\n# and runs it.\n\nset -u\n\n# Parse VERSION from environment or --version argument, default to \"latest\"\nif [ -z \"${VERSION:-}\" ]; then\n    VERSION=\"\"\n    ORIG_ARGS=(\"$@\")\n    \n    while [ $# -gt 0 ]; do\n        case $1 in\n            --version)\n                VERSION=\"$2\"\n                shift 2\n                ;;\n            *)\n                shift\n                ;;\n        esac\n    done\n    \n    set -- \"${ORIG_ARGS[@]}\"\n    \n    if [ -z \"$VERSION\" ]; then\n        VERSION=\"latest\"\n    fi\nfi\n\n# Resolve \"latest\" to actual version number\nif [ \"$VERSION\" = \"latest\" ]; then\n    VERSION=$(curl -s https://api.github.com/repos/drager/wasm-pack/releases/latest | grep '\"tag_name\"' | sed -E 's/.*\"v?([^\"]+)\".*/\\1/')\n    if [ -z \"$VERSION\" ]; then\n        err \"failed to fetch latest version from GitHub API\"\n    fi\nfi\n\n# Normalize version format for download URL\ncase \"$VERSION\" in\n    v*) ;;\n    *) VERSION=\"v$VERSION\" ;;\nesac\n\nUPDATE_ROOT=\"https://github.com/drager/wasm-pack/releases/download/$VERSION\"\n\nmain() {\n    downloader --check\n    need_cmd uname\n    need_cmd mktemp\n    need_cmd chmod\n    need_cmd mkdir\n    need_cmd rm\n    need_cmd rmdir\n    need_cmd tar\n    need_cmd which\n    need_cmd dirname\n\n    get_architecture || return 1\n    local _arch=\"$RETVAL\"\n    assert_nz \"$_arch\" \"arch\"\n\n    local _ext=\"\"\n    case \"$_arch\" in\n        *windows*)\n            _ext=\".exe\"\n            ;;\n    esac\n\n    which rustup > /dev/null 2>&1\n    need_ok \"failed to find Rust installation, is rustup installed?\"\n    local _rustup=$(which rustup)\n    local _tardir=\"wasm-pack-$VERSION-${_arch}\"\n    local _url=\"$UPDATE_ROOT/${_tardir}.tar.gz\"\n    local _dir=\"$(mktemp -d 2>/dev/null || ensure mktemp -d -t wasm-pack)\"\n    local _file=\"$_dir/input.tar.gz\"\n    local _wasmpack=\"$_dir/wasm-pack$_ext\"\n    local _wasmpackinit=\"$_dir/wasm-pack-init$_ext\"\n\n    printf '%s\\n' 'info: downloading wasm-pack' 1>&2\n\n    ensure mkdir -p \"$_dir\"\n    downloader \"$_url\" \"$_file\"\n    if [ $? != 0 ]; then\n      say \"failed to download $_url\"\n      say \"this may be a standard network error, but it may also indicate\"\n      say \"that wasm-pack's release process is not working. When in doubt\"\n      say \"please feel free to open an issue!\"\n      exit 1\n    fi\n    ensure tar xf \"$_file\" --strip-components 1 -C \"$_dir\"\n    mv \"$_wasmpack\" \"$_wasmpackinit\"\n\n    # The installer may want to ask for confirmation on stdin for various\n    # operations. We were piped through `sh` though so we probably don't have\n    # access to a tty naturally. If it looks like we're attached to a terminal\n    # (`-t 1`) then pass the tty down to the installer explicitly.\n    if [ -t 1 ]; then\n      \"$_wasmpackinit\" \"$@\" < /dev/tty\n    else\n      \"$_wasmpackinit\" \"$@\"\n    fi\n\n    local _retval=$?\n\n    ignore rm -rf \"$_dir\"\n\n    return \"$_retval\"\n}\n\nget_architecture() {\n    local _ostype=\"$(uname -s)\"\n    local _cputype=\"$(uname -m)\"\n\n    # This is when installing inside docker, or can be useful to side-step\n    # the script's built-in platform detection heuristic (if it drifts again in the future)\n    set +u\n    if [ -n \"$TARGETOS\" ]; then\n        _ostype=\"$TARGETOS\" # probably always linux\n    fi\n\n    if [ -n \"$TARGETARCH\" ]; then\n        _cputype=\"$TARGETARCH\"\n    fi\n    set -u\n\n\n    if [ \"$_ostype\" = Darwin ] && [ \"$_cputype\" = i386 ]; then\n        # Darwin `uname -s` lies\n        if sysctl hw.optional.x86_64 | grep -q ': 1'; then\n            local _cputype=x86_64\n        fi\n    fi\n\n    case \"$_ostype\" in\n        Linux | linux)\n            local _ostype=unknown-linux-musl\n            ;;\n\n        Darwin)\n            local _ostype=apple-darwin\n            ;;\n\n        MINGW* | MSYS* | CYGWIN*)\n            local _ostype=pc-windows-msvc\n            ;;\n\n        *)\n            err \"no precompiled binaries available for OS: $_ostype\"\n            ;;\n    esac\n\n    case \"$_cputype\" in\n        x86_64 | x86-64 | x64 | amd64)\n            local _cputype=x86_64\n            ;;\n        arm64 | aarch64)\n            local _cputype=aarch64\n            ;;\n        *)\n            err \"no precompiled binaries available for CPU architecture: $_cputype\"\n\n    esac\n\n    # See https://github.com/drager/wasm-pack/pull/1088\n    if [ \"$_cputype\" = \"aarch64\" ] && [ \"$_ostype\" = \"apple-darwin\" ]; then\n        _cputype=\"x86_64\"\n    fi\n\n    local _arch=\"$_cputype-$_ostype\"\n\n    RETVAL=\"$_arch\"\n}\n\nsay() {\n    echo \"wasm-pack-init: $1\"\n}\n\nerr() {\n    say \"$1\" >&2\n    exit 1\n}\n\nneed_cmd() {\n    if ! check_cmd \"$1\"\n    then err \"need '$1' (command not found)\"\n    fi\n}\n\ncheck_cmd() {\n    command -v \"$1\" > /dev/null 2>&1\n    return $?\n}\n\nneed_ok() {\n    if [ $? != 0 ]; then err \"$1\"; fi\n}\n\nassert_nz() {\n    if [ -z \"$1\" ]; then err \"assert_nz $2\"; fi\n}\n\n# Run a command that should never fail. If the command fails execution\n# will immediately terminate with an error showing the failing\n# command.\nensure() {\n    \"$@\"\n    need_ok \"command failed: $*\"\n}\n\n# This is just for indicating that commands' results are being\n# intentionally ignored. Usually, because it's being executed\n# as part of error handling.\nignore() {\n    \"$@\"\n}\n\n# This wraps curl or wget. Try curl first, if not installed,\n# use wget instead.\ndownloader() {\n    if check_cmd curl\n    then _dld=curl\n    elif check_cmd wget\n    then _dld=wget\n    else _dld='curl or wget' # to be used in error message of need_cmd\n    fi\n\n    if [ \"$1\" = --check ]\n    then need_cmd \"$_dld\"\n    elif [ \"$_dld\" = curl ]\n    then curl -sSfL \"$1\" -o \"$2\"\n    elif [ \"$_dld\" = wget ]\n    then wget \"$1\" -O \"$2\"\n    else err \"Unknown downloader\"   # should not reach here\n    fi\n}\n\nmain \"$@\" || exit 1\n"
  },
  {
    "path": "docs/_installer/wasm-pack.js",
    "content": "var platforms = [\"unknown\", \"win64\", \"unix\"];\nvar platform_override = null;\n\nfunction detect_platform() {\n    \"use strict\";\n\n    if (platform_override !== null) {\n        return platforms[platform_override];\n    }\n\n    var os = \"unknown\";\n\n    if (navigator.platform == \"Linux x86_64\") {os = \"unix\";}\n    if (navigator.platform == \"Linux i686\") {os = \"unix\";}\n    if (navigator.platform == \"Linux i686 on x86_64\") {os = \"unix\";}\n    if (navigator.platform == \"Linux aarch64\") {os = \"unix\";}\n    if (navigator.platform == \"Linux armv6l\") {os = \"unix\";}\n    if (navigator.platform == \"Linux armv7l\") {os = \"unix\";}\n    if (navigator.platform == \"Linux armv8l\") {os = \"unix\";}\n    if (navigator.platform == \"Linux ppc64\") {os = \"unix\";}\n    if (navigator.platform == \"Linux mips\") {os = \"unix\";}\n    if (navigator.platform == \"Linux mips64\") {os = \"unix\";}\n    if (navigator.platform == \"Mac\") {os = \"unix\";}\n    // if (navigator.platform == \"Win32\") {os = \"win32\";}\n    if (navigator.platform == \"Win64\" ||\n        navigator.userAgent.indexOf(\"WOW64\") != -1 ||\n        navigator.userAgent.indexOf(\"Win64\") != -1) { os = \"win64\"; }\n    if (navigator.platform == \"FreeBSD x86_64\") {os = \"unix\";}\n    if (navigator.platform == \"FreeBSD amd64\") {os = \"unix\";}\n    if (navigator.platform == \"NetBSD x86_64\") {os = \"unix\";}\n    if (navigator.platform == \"NetBSD amd64\") {os = \"unix\";}\n\n    // I wish I knew by now, but I don't. Try harder.\n    if (os == \"unknown\") {\n        // if (navigator.appVersion.indexOf(\"Win\")!=-1) {os = \"win32\";}\n        if (navigator.appVersion.indexOf(\"Mac\")!=-1) {os = \"unix\";}\n        // rust-www/#692 - FreeBSD epiphany!\n        if (navigator.appVersion.indexOf(\"FreeBSD\")!=-1) {os = \"unix\";}\n    }\n\n    // Firefox Quantum likes to hide platform and appVersion but oscpu works\n    if (navigator.oscpu) {\n        // if (navigator.oscpu.indexOf(\"Win32\")!=-1) {os = \"win32\";}\n        if (navigator.oscpu.indexOf(\"Win64\")!=-1) {os = \"win64\";}\n        if (navigator.oscpu.indexOf(\"Mac\")!=-1) {os = \"unix\";}\n        if (navigator.oscpu.indexOf(\"Linux\")!=-1) {os = \"unix\";}\n        if (navigator.oscpu.indexOf(\"FreeBSD\")!=-1) {os = \"unix\";}\n        if (navigator.oscpu.indexOf(\"NetBSD\")!=-1) {os = \"unix\";}\n    }\n\n    return os;\n}\n\nfunction adjust_for_platform() {\n    \"use strict\";\n\n    var platform = detect_platform();\n\n    platforms.forEach(function (platform_elem) {\n        var platform_div = document.getElementById(\"platform-instructions-\" + platform_elem);\n        platform_div.style.display = \"none\";\n        if (platform === platform_elem) {\n            platform_div.style.display = \"block\";\n        }\n    });\n}\n\nfunction fill_in_bug_report_values() {\n    var nav_plat = document.getElementById(\"nav-plat\");\n    var nav_app = document.getElementById(\"nav-app\");\n    nav_plat.textContent = navigator.platform;\n    nav_app.textContent = navigator.appVersion;\n}\n\n(function () {\n    adjust_for_platform();\n    fill_in_bug_report_values();\n}());\n"
  },
  {
    "path": "docs/_theme/header.hbs",
    "content": "<style>\n  header.warning {\n    background-color: rgb(242, 222, 222);\n    border-bottom-color: rgb(238, 211, 215);\n    border-bottom-left-radius: 4px;\n    border-bottom-right-radius: 4px;\n    border-bottom-style: solid;\n    border-bottom-width: 0.666667px;\n    border-image-outset: 0 0 0 0;\n    border-image-repeat: stretch stretch;\n    border-image-slice: 100% 100% 100% 100%;\n    border-image-source: none;\n    border-image-width: 1 1 1 1;\n    border-left-color: rgb(238, 211, 215);\n    border-left-style: solid;\n    border-left-width: 0.666667px;\n    border-right-color: rgb(238, 211, 215);\n    border-right-style: solid;\n    border-right-width: 0.666667px;\n    border-top-color: rgb(238, 211, 215);\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    border-top-style: solid;\n    border-top-width: 0.666667px;\n    color: rgb(185, 74, 72);\n    margin-bottom: 0px;\n    margin-left: 0px;\n    margin-right: 0px;\n    margin-top: 30px;\n    padding-bottom: 8px;\n    padding-left: 14px;\n    padding-right: 35px;\n    padding-top: 8px;\n    text-align: center;\n  }\n</style>\n<header class='warning'>\n  <p>\n    This is the <strong>unpublished</strong> documentation of\n    <code>wasm-pack</code>, the published documentation is available\n    <a href=\"https://drager.github.io/wasm-pack/\">\n      on the main Rust and WebAssembly documentation site\n    </a>. Features documented here may not be available in released versions of\n    <code>wasm-pack</code>.\n  </p>\n</header>\n"
  },
  {
    "path": "docs/book.toml",
    "content": "[book]\nauthors = [\"Ashley Williams\"]\nsrc = \"src\"\ntitle = \"Hello wasm-pack!\"\n"
  },
  {
    "path": "docs/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <square150x150logo src=\"/mstile-150x150.png\"/>\n            <TileColor>#00aba9</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<head>\n  <meta charset=\"utf-8\">\n  <title>wasm-pack</title>\n  <link href=\"https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css\" rel=\"stylesheet\">\n  <link rel=\"stylesheet\" href=\"./public/custom.css\" />\n  <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"./apple-touch-icon.png\">\n  <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"./favicon-32x32.png\">\n  <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"./favicon-16x16.png\">\n  <link rel=\"manifest\" href=\"./site.webmanifest\">\n  <link rel=\"mask-icon\" href=\"./safari-pinned-tab.svg\" color=\"#5bbad5\">\n  <meta name=\"msapplication-TileColor\" content=\"#00aba9\">\n  <meta name=\"theme-color\" content=\"#ffffff\">\n</head>\n<body>\n  <nav class=\"navbar\">\n    <div class=\"container\">\n      <ul class=\"navbar-list\">\n        <li class=\"navbar-logo\">\n          <a href=\"/wasm-pack\">\n            <img src=\"./public/img/rustwasm.png\">\n          </a>\n        </a>\n        <li class=\"navbar-item\">\n          <a href=\"https://github.com/drager/wasm-pack/issues/new/choose\">File an Issue</a>\n        </li>\n        <li class=\"navbar-item\">\n          <a href=\"/wasm-pack/book\">Documentation</a>\n        </li>\n        <li class=\"navbar-item\">\n           <a href=\"/wasm-pack/installer\">Install</a>\n        </li>\n      </ul>\n    </div>\n  </nav>\n  <header>\n    <div class=\"container\">\n      <div class=\"row\">\n        <div class=\"seven columns\" id=\"logo\">\n          <img src=\"./public/img/wasm-ferris.png\"alt=\"wasm ferris logo\" />\n          <h1><code>wasm-pack</code></h1>\n          <h2>📦✨ your favorite rust -> wasm workflow tool!</h2>\n        </div>\n        <div class=\"five columns\" id=\"installer\">\n          <a class=\"button button-primary\" href=\"/wasm-pack/installer\">✨ Install wasm-pack 0.14.0 ✨</a>\n          <p>20 Jan 2026 |\n            <a href=\"https://github.com/drager/wasm-pack/releases/tag/v0.14.0\">\n              Release Notes\n            </a>\n          </p>\n        </div>\n      </div>\n    </header>\n  </div>\n</div>\n<script type=\"text/javascript\" src=\"installer/wasm-pack.js\"></script>\n</body>\n"
  },
  {
    "path": "docs/public/custom.css",
    "content": "@import url('https://fonts.googleapis.com/css?family=Raleway');\n\n.navbar {\n  display: block;\n  width: 100%;\n  height: 6.5rem;\n  background: #fff;\n  z-index: 99;\n  border-bottom: 1px solid #eee;\n}\n\n.navbar-list {\n  list-style: none;\n  margin-bottom: 0;\n}\n\n.navbar-item {\n  position: relative;\n  float: right;\n  margin-bottom: 0;\n}\n\n.navbar-logo {\n  position: relative;\n  float: left;\n  margin-bottom: 0;\n  bottom: -5px;\n}\n\n.navbar-logo a img {\n  width: 50px;\n}\n\n.navbar-item a {\n  text-transform: uppercase;\n  font-size: 11px;\n  font-weight: 600;\n  letter-spacing: .2rem;\n  margin-right: 35px;\n  text-decoration: none;\n  line-height: 6.5rem;\n  color: #222;\n}\n\n#logo, #installer {\n  text-align: center;\n}\n\n#logo {\n  padding: 50px;\n}\n\n#logo img {\n  width: 80%;\n}\n\n#logo h1, h2 {\n  text-align: center;\n}\n\n#logo h2 {\n  font-size: 1.8rem;\n  letter-spacing: 0.01rem;\n  color: #222;\n}\n\n#installer a.button {\n  width: 100%;\n  height: 20%;\n  font-size: 1.8rem;\n  padding: 1.8rem;\n  margin: 10rem 0 1.8rem 0;\n  background-color: #6556EC;\n  border-color: #6556EC;\n}\n\n#installer img {\n  padding: 50px;\n  width: 20%;\n}\n\npre.primary {\n  margin: 0 auto 2.5rem auto;\n  width: fit-content;\n\n  padding: 20px;\n  font-size: 2rem;\n  background-color: #000;\n  color: #fff;\n}\n\na {\n  color: #6556EC;\n}\n"
  },
  {
    "path": "docs/site.webmanifest",
    "content": "{\n    \"name\": \"wasm-pack \",\n    \"short_name\": \"wasm-pack \",\n    \"icons\": [\n        {\n            \"src\": \"/android-chrome-192x192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/android-chrome-384x384.png\",\n            \"sizes\": \"384x384\",\n            \"type\": \"image/png\"\n        }\n    ],\n    \"theme_color\": \"#ffffff\",\n    \"background_color\": \"#ffffff\",\n    \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "docs/src/SUMMARY.md",
    "content": "# Summary\n\n- [Introduction](./introduction.md)\n- [Quickstart](./quickstart.md)\n- [Prerequisites](./prerequisites/index.md)\n  - [npm (optional)](./prerequisites/npm.md)\n  - [considerations](./prerequisites/considerations.md)\n  - [Non-`rustup` setups](./prerequisites/non-rustup-setups.md)\n- [Commands](./commands/index.md)\n  - [`new`](./commands/new.md)\n  - [`build`](./commands/build.md)\n  - [`test`](./commands/test.md)\n  - [`pack` and `publish`](./commands/pack-and-publish.md)\n  - [`init` (DEPRECATED)](./commands/init.md)\n- [Tutorials](./tutorials/index.md)\n  - [Hybrid applications with Webpack](./tutorials/hybrid-applications-with-webpack/index.md)\n    - [Getting started](./tutorials/hybrid-applications-with-webpack/getting-started.md)\n    - [Using your library](./tutorials/hybrid-applications-with-webpack/using-your-library.md)\n  - [npm browser packages](./tutorials/npm-browser-packages/index.md)\n    - [Getting started](./tutorials/npm-browser-packages/getting-started.md)\n      - [Manual Setup](./tutorials/npm-browser-packages/getting-started/manual-setup.md)\n    - [Template deep dive](./tutorials/npm-browser-packages/template-deep-dive/index.md)\n      - [`Cargo.toml`](./tutorials/npm-browser-packages/template-deep-dive/cargo-toml.md)\n      - [`src/lib.rs`](./tutorials/npm-browser-packages/template-deep-dive/src-lib-rs.md)\n      - [`src/utils.rs`](./tutorials/npm-browser-packages/template-deep-dive/src-utils-rs.md)\n      - [`wee_alloc`](./tutorials/npm-browser-packages/template-deep-dive/wee_alloc.md)\n      - [`tests/web.rs`](./tutorials/npm-browser-packages/template-deep-dive/tests-web-rs.md)\n    - [Building your project](./tutorials/npm-browser-packages/building-your-project.md)\n    - [Testing your project](./tutorials/npm-browser-packages/testing-your-project.md)\n    - [Packaging and publishing](./tutorials/npm-browser-packages/packaging-and-publishing.md)\n    - [Using your library](./tutorials/npm-browser-packages/using-your-library.md)\n- [`Cargo.toml` Configuration](./cargo-toml-configuration.md)\n- [Contributing](./contributing.md)\n"
  },
  {
    "path": "docs/src/cargo-toml-configuration.md",
    "content": "# `Cargo.toml` Configuration\n\n`wasm-pack` can be configured via the `package.metadata.wasm-pack` key in\n`Cargo.toml`. Every option has a default, and is not required.\n\nThere are three profiles: `dev`, `profiling`, and `release`. These correspond to\nthe `--dev`, `--profiling`, and `--release` flags passed to `wasm-pack build`.\n\nThe available configuration options and their default values are shown below:\n\n```toml\n[package.metadata.wasm-pack.profile.dev]\n# Should `wasm-opt` be used to further optimize the wasm binary generated after\n# the Rust compiler has finished? Using `wasm-opt` can often further decrease\n# binary size or do clever tricks that haven't made their way into LLVM yet.\n#\n# Configuration is set to `false` by default for the dev profile, but it can\n# be set to an array of strings which are explicit arguments to pass to\n# `wasm-opt`. For example `['-Os']` would optimize for size while `['-O4']`\n# would execute very expensive optimizations passes\n#\n# In most cases, the `-O[X]` flag is enough. However, if you require extreme\n# optimizations, see the full list of `wasm-opt` optimization flags\n# https://github.com/WebAssembly/binaryen/blob/version_117/test/lit/help/wasm-opt.test\nwasm-opt = ['-O']\n\n[package.metadata.wasm-pack.profile.dev.wasm-bindgen]\n# Should we enable wasm-bindgen's debug assertions in its generated JS glue?\ndebug-js-glue = true\n# Should wasm-bindgen demangle the symbols in the \"name\" custom section?\ndemangle-name-section = true\n# Should we emit the DWARF debug info custom sections?\ndwarf-debug-info = false\n# Should we omit the default import path?\nomit-default-module-path = false\n# Controls whether wasm-bindgen will split linked modules out into their own files. Enabling this is recommended, because it allows lazy-loading the linked modules and setting a stricter Content Security Policy. Only available in wasm-bindgen 0.2.95 and later.\nsplit-linked-modules = false\n\n[package.metadata.wasm-pack.profile.profiling]\nwasm-opt = ['-O']\n\n[package.metadata.wasm-pack.profile.profiling.wasm-bindgen]\ndebug-js-glue = false\ndemangle-name-section = true\ndwarf-debug-info = false\nomit-default-module-path = false\n\n# `wasm-opt` is on by default in for the release profile, but it can be\n# disabled by setting it to `false`\n[package.metadata.wasm-pack.profile.release]\nwasm-opt = false\n\n[package.metadata.wasm-pack.profile.release.wasm-bindgen]\ndebug-js-glue = false\ndemangle-name-section = true\ndwarf-debug-info = false\nomit-default-module-path = false\n```\n"
  },
  {
    "path": "docs/src/commands/build.md",
    "content": "# wasm-pack build\n\nThe `wasm-pack build` command creates the files necessary for JavaScript\ninteroperability and for publishing a package to npm. This involves compiling\nyour code to wasm and generating a pkg folder. This pkg folder will contain the\nwasm binary, a JS wrapper file, your `README`, and a `package.json` file.\n\nThe `pkg` directory is automatically `.gitignore`d by default, since it contains\nbuild artifacts which are not intended to be checked into version\ncontrol.<sup>[0](#footnote-0)</sup>\n\n## Path\n\nThe `wasm-pack build` command can be given an optional path argument, e.g.:\n\n```\nwasm-pack build examples/js-hello-world\n```\n\nThis path should point to a directory that contains a `Cargo.toml` file. If no\npath is given, the `build` command will run in the current directory.\n\n## Output Directory\n\nBy default, `wasm-pack` will generate a directory for its build output called `pkg`.\nIf you'd like to customize this you can use the `--out-dir` flag.\n\n```\nwasm-pack build --out-dir out\n```\n\nThe above command will put your build artifacts in a directory called `out`, instead\nof the default `pkg`.\n\n## Generated file names\n\nFlag `--out-name` sets the prefix for output file names. If not provided, package name is used instead.\n\nUsage examples, assuming our crate is named `dom`:\n\n```\nwasm-pack build\n# will produce files\n# dom.d.ts  dom.js  dom_bg.d.ts  dom_bg.wasm  package.json  README.md\n\nwasm-pack build --out-name index\n# will produce files\n# index.d.ts  index.js  index_bg.d.ts  index_bg.wasm  package.json  README.md\n```\n\n\n## Profile\n\nThe `build` command accepts an optional profile argument: one of `--dev`,\n`--profiling`, or `--release`. If none is supplied, then `--release` is used.\n\nThis controls whether debug assertions are enabled, debug info is generated, and\nwhich (if any) optimizations are enabled.\n\n| Profile       | Debug Assertions | Debug Info | Optimizations | Notes                                 |\n|---------------|------------------|------------|---------------|---------------------------------------|\n| `--dev`       | Yes              | Yes        | No            | Useful for development and debugging. |\n| `--profiling` | No               | Yes        | Yes           | Useful when profiling and investigating performance issues. |\n| `--release`   | No               | No         | Yes           | Useful for shipping to production.    |\n\nThe `--dev` profile will build the output package using cargo's [default\nnon-release profile][cargo-profile-sections-documentation]. Building this way is\nfaster but applies few optimizations to the output, and enables debug assertions\nand other runtime correctness checks. The `--profiling` and `--release` profiles\nuse cargo's release profile, but the former enables debug info as well, which\nhelps when investigating performance issues in a profiler.\n\nThe exact meaning of the profile flags may evolve as the platform matures.\n\n[cargo-profile-sections-documentation]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections\n\n## Target\n\nThe `build` command accepts a `--target` argument. This will customize the JS\nthat is emitted and how the WebAssembly files are instantiated and loaded. For\nmore documentation on the various strategies here, see the [documentation on\nusing the compiled output][deploy].\n\n```\nwasm-pack build --target nodejs\n```\n\n| Option    | Usage | Description                                                                                                     |\n|-----------|------------|-----------------------------------------------------------------------------------------------------|\n| *not specified* or `bundler` | [Bundler][bundlers] | Outputs JS that is suitable for interoperation with a Bundler like Webpack. You'll `import` the JS and the `module` key is specified in `package.json`. `sideEffects: false` is by default. |\n| `nodejs`  | [Node.js][deploy-nodejs] | Outputs JS that uses CommonJS modules, for use with a `require` statement. `main` key in `package.json`. |\n| `web` | [Native in browser][deploy-web] | Outputs JS that can be natively imported as an ES module in a browser, but the WebAssembly must be manually instantiated and loaded. |\n| `no-modules` | [Native in browser][deploy-web] | Same as `web`, except the JS is included on a page and modifies global state, and doesn't support as many `wasm-bindgen` features as `web` |\n| `deno` | [Deno][deploy-deno] | Outputs JS that can be natively imported as an ES module in deno. |\n\n[deploy]: https://wasm-bindgen.github.io/wasm-bindgen/reference/deployment.html\n[bundlers]: https://wasm-bindgen.github.io/wasm-bindgen/reference/deployment.html#bundlers\n[deploy-nodejs]: https://wasm-bindgen.github.io/wasm-bindgen/reference/deployment.html#nodejs\n[deploy-web]: https://wasm-bindgen.github.io/wasm-bindgen/reference/deployment.html#without-a-bundler\n[deploy-deno]: https://wasm-bindgen.github.io/wasm-bindgen/reference/deployment.html#deno\n\n## Scope\n\nThe `build` command also accepts an optional `--scope` argument. This will scope\nyour package name, which is useful if your package name might conflict with\nsomething in the public registry. For example:\n\n```\nwasm-pack build examples/js-hello-world --scope test\n```\n\nThis command would create a `package.json` file for a package called\n`@test/js-hello-world`. For more information about scoping, you can refer to\nthe npm documentation [here][npm-scope-documentation].\n\n[npm-scope-documentation]: https://docs.npmjs.com/misc/scope\n\n## Mode\n\nThe `build` command accepts an optional `--mode` argument.\n```\nwasm-pack build examples/js-hello-world --mode no-install\n```\n\n| Option        | Description                                                                              |\n|---------------|------------------------------------------------------------------------------------------|\n| `no-install`  | `wasm-pack build` implicitly and create wasm binding without installing `wasm-bindgen`.  |\n| `normal`      | do all the stuffs of `no-install` with installed `wasm-bindgen`.                         |\n\n## Extra options\n\nThe `build` command can pass extra options straight to `cargo build` even if\nthey are not supported in wasm-pack. To use them simply add the extra arguments\nat the very end of your command, just as you would for `cargo build`. For\nexample, to build the previous example using cargo's offline feature:\n\n```\nwasm-pack build examples/js-hello-world --mode no-install -- --offline\n```\n\n<hr style=\"font-size: 1.5em; margin-top: 2.5em\"/>\n\n<sup id=\"footnote-0\">0</sup> If you need to include additional assets in the pkg\ndirectory and your NPM package, we intend to have a solution for your use case\nsoon. [↩](#wasm-pack-build)\n"
  },
  {
    "path": "docs/src/commands/index.md",
    "content": "# Commands\n\n`wasm-pack` has several commands to help you during the process of building\na Rust-generated WebAssembly project.\n\n- `new`: This command generates a new project for you using a template. [Learn more][new]\n- `build`: This command builds a `pkg` directory for you with compiled wasm and generated JS. [Learn more][build]\n- `pack` and `publish`: These commands will create a tarball, and optionally publish it to a registry, such as npm. [Learn more][pack-pub]\n\n### Deprecated Commands\n\n- `init`: This command has been deprecated in favor of `build`.\n\n[new]: ./new.html\n[build]: ./build.html\n[pack-pub]: ./pack-and-publish.html\n\n### Log levels\n\nBy default `wasm-pack` displays a lot of useful information.\n\nYou can cause it to display even *more* information by using `--verbose`, or you can silence *all* stdout by using `--quiet`.\n\nYou can also use `--log-level` to have fine-grained control over wasm-pack's log output:\n\n* `--log-level info` is the default, it causes all messages to be logged.\n* `--log-level warn` causes warnings and errors to be displayed, but not info.\n* `--log-level error` causes only errors to be displayed.\n\nThese flags are global flags, so they can be used with every command, and they must come *before* the command:\n\n```sh\nwasm-pack --log-level error build\nwasm-pack --quiet build\nwasm-pack --verbose build\n```\n"
  },
  {
    "path": "docs/src/commands/init.md",
    "content": "# wasm-pack init (DEPRECATED)\n\nThis command has been deprecated in favor of `build`, which does the same thing, but is\na much more representative name for the command. [Read the docs for `build`.][build]\n\n[build]: ./build.html\n"
  },
  {
    "path": "docs/src/commands/new.md",
    "content": "# wasm-pack new\n\nThe `wasm-pack new` command creates a new RustWasm project for you,\nusing [`cargo-generate`] under the hood.\n\nIt takes 3 parameters, name, template, and mode:\n\n```\nwasm-pack new <name> --template <template> --mode <normal|noinstall|force>\n```\n\nThe default template is [`drager/wasm-pack-template`](https://github.com/drager/wasm-pack-template).\n\n## Name\n\nThe `wasm-pack new` command must be given a name argument, e.g.:\n\n```\nwasm-pack new myproject\n```\n\n## Template\n\nThe `wasm-pack new` command can be given an optional template argument, e.g.:\n\n```\nwasm-pack new myproject --template https://github.com/drager/wasm-pack-template\n```\n\nThe template can be an address to a git repo that contains a [`cargo-generate`]\ntemplate.\n\n[`cargo-generate`]: https://github.com/ashleygwilliams/cargo-generate\n\n## Mode\n\nThe `wasm-pack new` command can be given an optional mode argument, e.g.:\n\n```\nwasm-pack new myproject --mode noinstall\n```\n\nThe mode passed can be either \"normal\", \"noinstall\", or \"force\". \"normal\" is passed by\ndefault.\n\n`noinstall` means that wasm-pack should not attempt to install any underlying tools.\nIf a necessary tool cannot be found, the command will error.\n\n`force` means that wasm-pack should not check the local Rust version. If a local Rust\nis an unacceptable Rust version, the command will error.\n"
  },
  {
    "path": "docs/src/commands/pack-and-publish.md",
    "content": "# pack and publish\n\nThe `publish` and `pack` commands interact with the pkg directory that's\ncreated when you run `wasm-pack build`. The `pack` command creates a tarball\nfrom the pkg directory and the `publish` command creates a tarball from the\npkg directory **and** publishes it to the NPM registry.\n\nUnderneath, these commands use `npm pack` and `npm publish`. You can read\nmore about these in the NPM documentation:\n\n- [`npm pack`](https://docs.npmjs.com/cli/pack)\n- [`npm publish`](https://docs.npmjs.com/cli/publish)\n\nBoth these commands take the path to the pkg directory as the first argument.\nYou can either set the argument directly to the pkg directory or to the parent\nof the pkg directory:\n\n```\n$ wasm-pack pack myproject/pkg\n| 🎒  packed up your package!\n$ wasm-pack pack myproject\n| 🎒  packed up your package!\n```\n\nIf you try to call `pack` or `publish` on another directory, you get an error:\n\n```\n$ wasm-pack pack myproject/src/\nUnable to find the pkg directory at path 'myproject/src/', or in a child directory of 'myproject/src/'\n```\n\nIf you don't set a path, they use the current directory as the path.\n\n## Publishing tagged releases\n\nYou can also publish tagged releases with the optional `--tag` argument, e.g.\n\n```\nwasm-pack publish --tag next\n```\n\nBy default, the `latest` tag is used to identify the current version of a package,\nand npm install \\<pkg\\> (without any @\\<version\\> or @\\<tag\\> specifier) installs the latest tag.\n\nYou can read more about [distribution tags](https://docs.npmjs.com/cli/dist-tag) on NPM.\n"
  },
  {
    "path": "docs/src/commands/test.md",
    "content": "# wasm-pack test\n\nThe `wasm-pack test` command wraps the [wasm-bindgen-test-runner](https://wasm-bindgen.github.io/wasm-bindgen/wasm-bindgen-test)\nCLI allowing you to run wasm tests in different browsers without needing to install the different\nwebdrivers yourself.\n\n```\nwasm-pack test --help\n```\n\n## Path\n\nThe `wasm-pack test` command can be given an optional path argument.\n\nThis path should point to a directory that contains a `Cargo.toml` file. If no\npath is given, the `test` command will run in the current directory.\n\n```\n# Run tests for the current directory's crate\nwasm-pack test\n\n# Run tests for a specified crate\nwasm-pack test crates/crate-in-my-workspace\n```\n\n## Profile\n\nThe `test` command accepts an optional profile argument: `--release`.\n\nIf none is supplied, then a debug test build will be used.\n\n## Test environment\n\nChoose where to run your tests by passing in any combination of testing environment flags.\n\n`--headless` is useful for running browser tests in a headless browser as part of a CI process.\n\n```\nwasm-pack test --node --firefox --chrome --safari --headless\n```\n\n## Extra options\n\nThe `test` command can pass extra options straight to `cargo test` even if they are not\nsupported in wasm-pack.\n\nTo use them simply add the extra arguments at the very end of your command, just\nas you would for `cargo test`.\n\n`cargo test -h` for a list of all options that you can pass through.\n\n## Running only some tests\n\nWhen debugging a specific issue, you may find yourself wanting to run a subset of tests, instead of your entire suite of tests.\n\nHere are a few examples of how to run a subset of your tests:\n\n```\n# Example directory structure\n$ tree crates/foo\n├── Cargo.toml\n├── README.md\n├── src\n│   ├── diff\n│   │   ├── diff_test_case.rs\n│   │   └── mod.rs\n│   ├── lib.rs\n└── tests\n    ├── diff_patch.rs\n    └── node.rs\n```\n\n```\n# Run all tests in tests/diff_patch.rs in Firefox\nwasm-pack test crates/foo --firefox --headless --test diff_patch\n\n# Run all tests in tests/diff_patch.rs that contain the word \"replace\"\nwasm-pack test crates/foo --firefox --headless --test diff_patch replace\n\n# Run all tests inside of a `tests` module inside of src/lib/diff.rs\nwasm-pack test crates/foo --firefox --headless --lib diff::tests\n\n# Same as the above, but only if they contain the word replace\nwasm-pack test crates/foo --firefox --headless --lib diff::tests::replace\n```\n\nNote that you can also filter tests by location in which they're supposed to\nrun. For example:\n\n```\n# Run all tests which are intended to execute in Node.js\nwasm-pack test --node\n\n# Run all tests which are intended to be executed in a browser\nwasm-pack test --firefox --headless\n```\n"
  },
  {
    "path": "docs/src/contributing.md",
    "content": "# Contributing\n\n## Prerequisites\n\nThe technical prerequisites for contributing to this project are the same as for\nusing it. You can find them documented [here][1].\n\nYou'll also want to check out the contributing [guidelines].\n\n[1]: ./prerequisites/index.html\n[guidelines]: https://github.com/drager/wasm-pack/blob/master/CONTRIBUTING.md\n\n## 🏃‍♀️ Up and Running\n\n1. fork and clone the `drager/wasm-pack` repository\n2. install [node/npm]\n3. `cd wasm-pack`\n4. `cargo run`. To test command line arguments you can run `cargo run -- <args>`.\n\n## Documentation\n\nDocumentation lives in the `/docs` directory. Each command has its own page.\nAdditionally there are extra pages explaining the prerequisites, setup, and how to\ncontribute (which you are reading now!).\n\n## Tests\n\nTests live in the `/tests` directory. To run the tests you can run:\n\n```\ncargo test\n```\n\nYou can also manually test the CLI tool by running:\n\n```\ncargo run -- <args>\n```\n\n...for example:\n\n```\ncargo run -- init /tests/fixtures/js-hello-world --scope=ag_dubs\n```\n"
  },
  {
    "path": "docs/src/introduction.md",
    "content": "![wasm ferris](https://drager.github.io/wasm-pack/public/img/wasm-ferris.png)\n\n<h1 style=\"text-align: center;\">Welcome to the <code>wasm-pack</code> docs!</h1>\n\nThis tool seeks to be a one-stop shop for building and working with rust-\ngenerated WebAssembly that you would like to interop with JavaScript, in the\nbrowser or with Node.js. `wasm-pack` helps you build rust-generated\nWebAssembly packages that you could publish to the npm registry, or otherwise use\nalongside any javascript packages in workflows that you already use, such as [webpack].\n\n[webpack]: https://webpack.js.org/\n\n\n![demo](https://github.com/drager/wasm-pack/raw/master/demo.gif)\n"
  },
  {
    "path": "docs/src/prerequisites/considerations.md",
    "content": "# nodejs\n\nCurrently, `wasm-pack` generated npm modules require us to you have [fetch] polyfill in your node project.\n\nIf there is a module from `wasm-pack build --target nodejs` you may encounter some errors regarding global `Headers`, `Request`, `Response` and `fetch` Web APIs.\n\n## Common errors:\n\n```js\nReqwestError(reqwest::Error { kind: Builder, source: \"JsValue(ReferenceError: Headers is not defined\nReqwestError(reqwest::Error { kind: Builder, source: \"JsValue(ReferenceError: Request is not defined\n\n    var ret = getObject(arg0) instanceof Response;\nReferenceError: Response is not defined\n```\n\n## Workaround\nImport or declare fetch and objects: Headers, Request, Response\n\n```ts\n// CommonJS\nconst fetch = require('node-fetch');\n\n// ES Module\nimport fetch from 'node-fetch';\n\n// @ts-ignore\nglobal.fetch = fetch;\n// @ts-ignore\nglobal.Headers = fetch.Headers;\n// @ts-ignore\nglobal.Request = fetch.Request;\n// @ts-ignore\nglobal.Response = fetch.Response;\n```\n\n[fetch]: https://github.com/node-fetch/node-fetch\n\n"
  },
  {
    "path": "docs/src/prerequisites/index.md",
    "content": "# Prerequisites\n\nFirst you'll want to [install the `wasm-pack` CLI][wasm-pack], and `wasm-pack\n-V` should print the version that you just installed.\n\n[wasm-pack]: https://drager.github.io/wasm-pack/installer/\n\nNext, since `wasm-pack` is a build tool, you'll want to make sure you have\n[Rust][rust] installed. Make sure `rustc -V` prints out at least 1.30.0.\n\n[rust]: https://www.rust-lang.org/tools/install\n\nFinally, if you're using `wasm-pack` to publish to NPM, you'll want\nto [install and configure `npm`][npm]. In the future, we intend to rewrite the\nnpm registry client bits so that the need for a Node runtime is eliminated. If\nyou're excited about that work- you should reach out to the maintainers and get\ninvolved!\n\n[npm]: ./npm.html\n\nUsing a non-rustup setup? Learn how to configure it for wasm-pack [here](./non-rustup-setups.html).\n"
  },
  {
    "path": "docs/src/prerequisites/non-rustup-setups.md",
    "content": "# Non-Rustup setups\n`wasm-pack` compiles your code using the `wasm32-unknown-unknown` target. `wasm-pack` will automatically add this target for Rustup setups if you don't already have it installed by doing `rustup target add wasm32-unknown-unknown`. However, if you're not using Rustup, then we won't be able to do this automatically, and you'll have to do this yourself.\n\n## Manually add wasm32-unknown-unknown\n*Disclaimer: This is not guaranteed to work for every setup. These instructions below are specific for setups that match the exact rustc release, which means that the downloaded wasm32 target can be incompatible.*\n\nTo manually add the `wasm32-unknown-unknown` target you will need to download it from the rust-lang website and put the contents in the correct folder.\n\nAll the targets for all the different `rustc` versions are not presented in a human way on a website (yet) for you to just select the one you want and download it, one reason for this is that Rustup handles all of this for you and the packaging of targets was mainly built for tools. However, the following steps will walk through how to do this.\n\nFirst, check what version of `rustc` you're using by running `rustc --version`. This should display something like: `rustc 1.33.0 (2aa4c46cf 2019-02-28)`. Then you need to download the correct wasm32 target for your rustc version. The rustc version is part of the url, which means for `rustc 1.33.0` the url will look like this: `https://static.rust-lang.org/dist/rust-std-1.33.0-wasm32-unknown-unknown.tar.gz`.\n\nHere's some examples of urls for different rustc versions:\n * Nightly https://static.rust-lang.org/dist/rust-std-nightly-wasm32-unknown-unknown.tar.gz\n * Specific date nightly (2019-03-10) https://static.rust-lang.org/dist/2019-03-10/rust-std-nightly-wasm32-unknown-unknown.tar.gz\n * Beta https://static.rust-lang.org/dist/rust-std-beta-wasm32-unknown-unknown.tar.gz\n\nYou should be able to download this either by doing `wget https://static.rust-lang.org/dist/rust-std-1.33.0-wasm32-unknown-unknown.tar.gz` or by just visiting the url in a web browser.\n\nAfter you have downloaded this tarball at a location of your choice, you should unpack it. This should result in a folder named `rust-std-1.33.0-wasm32-unknown-unknown` that contains some folders and files, but the interesting one is a folder called `rust-std-wasm32-unknown-unknown` which contains a `lib` and that should contain a `rustlib` folder and in that, a folder called `wasm32-unknown-unknown`. This is the folder we want to move.\n\nHere's how the structure should look like for rustc 1.33.0:\n```\nrust-std-1.33.0-wasm32-unknown-unknown\n├── components\n├── install.sh\n├── rust-installer-version\n└── rust-std-wasm32-unknown-unknown\n    ├── lib\n    │   └── rustlib\n    │       └── wasm32-unknown-unknown\n```\n\nTo know where we should move this `wasm32-unknown-unknown` folder we need to run `rustc --print sysroot` which should print a path that looks something like this (this will vary on different operating systems): `/home/user/rust/rust-1.33.0-2019-02-28-2aa4c46cf`. That folder should contain a `lib` folder that contains a `rustlib` folder. We should move the `wasm32-unknown-unknown` to this folder.\n\nOn unix-like operating systems we can do that with the following command:\n`mv rust-std-1.33.0-wasm32-unknown-unknown/rust-std-wasm32-unknown-unknown/lib/rustlib/wasm32-unknown-unknown /home/user/rust/rust-1.33.0-2019-02-28-2aa4c46cf/lib/rustlib/` and that should be it!\n"
  },
  {
    "path": "docs/src/prerequisites/npm.md",
    "content": "# npm\n\nCurrently, `wasm-pack` requires that you have npm installed to pack and publish your\npackage. Longterm, this will be replaced by a Rust only version.\n\nIf you would rather use another package manager that interfaces with the npm registry\nyou may, however, the `pack`, `publish`, and `login` commands wrap the npm CLI interface\nand as a result require that npm be installed.\n\nYou can install [npm] by following [these instructions][npm-install-info].\n\n[npm]: https://www.npmjs.com\n\n### npm Account\n\nPart of the `wasm-pack` workflow is to publish your package to the npm Registry.\n\nRegardless of which package manager CLI tool you prefer, if you wish to publish\nyour package to the npm registry you'll need an npm account.\n\nYou can find information about signing up for npm [here][npm-signup-info].\n\n[`npm link`]: https://docs.npmjs.com/cli/link\n[npm-install-info]: https://docs.npmjs.com/downloading-and-installing-node-js-and-npm\n[npm-signup-info]: https://www.npmjs.com/signup\n"
  },
  {
    "path": "docs/src/quickstart.md",
    "content": "# Quickstart\n\n1. Install `rust` using [`rustup`].\n1. [Install this tool.]\n1. Run `wasm-pack new hello-wasm`.\n1. `cd hello-wasm`\n1. Run `wasm-pack build --target web`.\n1. This tool generates files in a `pkg` dir\n1. Import it: `import init, { greet } from \"./pkg/hello_wasm.js\"`, initialize it: `await init()`, and then use it: `greet()`\n1. To publish to npm, run `wasm-pack publish`. You may need to login to the\n   registry you want to publish to. You can login using `wasm-pack login`.\n\n[`rustup`]: https://rustup.rs/\n[Install this tool.]: https://drager.github.io/wasm-pack/installer/\n"
  },
  {
    "path": "docs/src/tutorials/hybrid-applications-with-webpack/getting-started.md",
    "content": "# Getting Started\n\nYou can create a new Rust-WebAssembly webpack project by using the [rustwasm webpack-template].\n\nRun:\n\n```\nnpm init rust-webpack my-app\n```\n\nThe last argument will be your project name. After you run the command, you will have a\ndirectory with a new project, ready to go. We'll talk about what's been included in this\ntemplate further in this guide.\n\n[rustwasm webpack-template]: https://github.com/drager/rust-webpack-template\n"
  },
  {
    "path": "docs/src/tutorials/hybrid-applications-with-webpack/index.md",
    "content": "# Hybrid Applications with Webpack\n\nThe goal of this tutorial is to introduce you to the [`rust-webpack-template`]\nand the `wasm-pack` workflow by building the example app in the template.\n\nThis tutorial is aimed at folks who are both beginners to WebAssembly and Rust- you don't need\nmuch Rust knowledge to complete this tutorial.\n\nBe sure to have read and followed the [Prerequisites](../../prerequisites/index.html).\n\n[Rust]: https://www.rust-lang.org\n[Node.js]: https://nodejs.org\n[npm]: https://npmjs.com\n[`rust-webpack-template`]: https://github.com/drager/rust-webpack-template\n"
  },
  {
    "path": "docs/src/tutorials/hybrid-applications-with-webpack/using-your-library.md",
    "content": "# Run The Code\n\nThe Rust Webpack template is designed for creating monorepo-style Web applications with\nRust-generated WebAssembly and Webpack without publishing your wasm to NPM.\nThis portion of the tutorial will explain how to build a [Webpack] JavaScript project\nthat will run your WebAssembly code in the browser.\n\n[Webpack]: https://webpack.js.org/\n\n## Scaffold a JavaScript Project\n\nTo generate a new Rust Webpack project, we've used the [`rust-webpack`] npm template.\n\n[`rust-webpack`]: https://github.com/drager/rust-webpack-template\n\n```\nnpm init rust-webpack your-package-name\n```\n\nA new project folder will be created with the name you supply.\n\nIf we look in the project, we'll see the following:\n\n- `.gitignore`: ignores `node_modules`\n- `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you\n- `README.md`: the file you are reading now!\n- `index.html`: a bare bones html document that includes the webpack bundle\n- `js/index.js`: example JS file with a comment showing how to import and use a wasm pkg\n- `package.json` and `package-lock.json`:\n  - pulls in devDependencies for using webpack:\n      - [`webpack`](https://www.npmjs.com/package/webpack)\n      - [`webpack-cli`](https://www.npmjs.com/package/webpack-cli)\n      - [`webpack-dev-server`](https://www.npmjs.com/package/webpack-dev-server)\n  - defines a `start` script to run `webpack-dev-server`\n- `webpack.config.js`: configuration file for bundling your JS with webpack\n- `crate/src/lib.rs`: your Rust crate code!\n\n## Your Rust Crate\n\nThe scaffolded project includes an example Rust WebAssembly webpack crate.\n\nInside the `crate/src/lib.rs` file we see a `run` function that's callable from our JS file:\n```rust\n// Called by our JS entry point to run the example.\n#[wasm_bindgen]\npub fn run() -> Result<(), JsValue> {\n    set_panic_hook();\n\n    // ...\n    let p: web_sys::Node = document.create_element(\"p\")?.into();\n    p.set_text_content(Some(\"Hello from Rust, WebAssembly, and Webpack!\"));\n    // ...\n\n    Ok(())\n}\n```\n\nNow, open up the `js/index.js` file. We see our Rust-generated wasm `run` function being\ncalled inside our JS file.\n\n```js\nimport(\"../crate/pkg\").then(module => {\n  module.run();\n});\n```\n\n## Run The Project\n\nTo generate our Rust-compiled to wasm code, in the root directory we run:\n```bash\nnpm run build\n```\nThis will create our bundled JavaScript module in a new directory `dist`.\n\nWe should be ready to run our project now!\nIn the root directory, we'll run:\n\n```bash\nnpm start\n```\n\nThen in a web browser navigate to `http://localhost:8080` and you should be greeted\nwith text in the body of the page that says \"Hello from Rust, WebAssembly, and Webpack!\"\n\nIf you did congrats! You've successfully used the rust-webpack template!\n"
  },
  {
    "path": "docs/src/tutorials/index.md",
    "content": "# Tutorials\n\nWe have two tutorials that help you get started with `wasm-pack`:\n\n- If you want to create and publish a package: [npm browser packages]\n- If you'd like to develop a Wasm library alongside a JavaScript application using Webpack: [Hybrid applications with Webpack]\n\n[npm browser packages]: npm-browser-packages/index.html\n[Hybrid applications with Webpack]: hybrid-applications-with-webpack/index.html\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/building-your-project.md",
    "content": "# Building your project\n\nWe've written our code so now we need to build it.\n\nWe are writing a crate that should be used in the browser, so we run this in\nour terminal:\n\n```bash\n$ wasm-pack build\n```\n\nIf you were writing a package that should be used in Node.js (with CommonJS\nmodules, e.g. `require`), you would run this in your terminal:\n\n```bash\n$ wasm-pack build --target nodejs\n```\n\nThis command when run does a few things:\n\n1. It'll compile your code to wasm if you haven't already\n2. It'll generate a `pkg` folder with the wasm file, a JS wrapper file around\n   the wasm, your README, and a `package.json` file.\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/getting-started/manual-setup.md",
    "content": "# Manual Setup\n\n⚠️ This is not the recommended way to start a `wasm-pack` project! If you ended up\nhere by mistake, go check out our [recommended project start][template].\n\n[template]: ../getting-started.html\n\n### Step 1: Create a New Rust Library Project\n\nYou can create a new Rust project named `my-lib` using this command.\n\n```\ncargo new --lib my-lib\n```\n\nThe `--lib` flag specifies that the project is a library, which is important\nbecause we will be calling this code from JavaScript.\n\n### Step 2: Edit your `Cargo.toml` File\n\n#### Add the `wasm-bindgen` dependency\n\nYou will need to add `wasm-bindgen` to your `Cargo.toml` in the dependencies\nsection. `wasm-bindgen` is a tool that facilitates interoperability between\nwasm modules and JavaScript.\n\n⚠️ If you are coming from JavaScript, you might note that when we add the dependency\nthere is no `^` or `~` symbol- it looks like we're locking to the `0.2` version.\nHowever, that's not the case! In Rust, the `^` is implied.\n\n#### Add `crate-type`\n\nNext, add a `[lib]` section, with a new field named `crate-type` set to\n`\"cdylib\"`. This specifies that the library is a C compatible dynamic library,\nwhich helps `cargo` pass the correct flags to the Rust compiler when targeting\n`wasm32`.\n\nAfter making these changes, your `Cargo.toml` file should look something like\nthis:\n\n```toml\n[package]\nname = \"hello-wasm\"\nversion = \"0.1.0\"\nauthors = [\"Ashley Williams <ashley666ashley@gmail.com>\"]\ndescription = \"babby's first wasm package\"\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/ashleygwilliams/hello-wasm\"\n\n[lib]\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nwasm-bindgen=\"0.2\"\n```\n\n### Step 3: Write some Rust!\n\nNow that your crate is correctly configured in your `Cargo.toml` file, the only step\nleft to setup your project is to have some Rust code in your `src/lib.rs` file.\n\n#### Browser Example\n\nThe template we have gives you a quick \"Hello, World\" project to use for compiling into\na WebAssembly library that you can use in the browser:\n\n```rust\nextern crate wasm_bindgen;\n\nuse wasm_bindgen::prelude::*;\n\n#[wasm_bindgen]\nextern {\n    fn alert(s: &str);\n}\n\n#[wasm_bindgen]\npub fn greet() {\n    alert(\"Hello, World!\");\n}\n```\n\nAnd that's it! We'll talk about what this code does in the [template deep dive], which you are all\nsetup for now. Happy `wasm-pack`ing!\n\n[template deep dive]: ../template-deep-dive/index.html\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/getting-started.md",
    "content": "# Getting Started\n\nYou can create a new Rust-WebAssembly project by using the [rustwasm wasm-pack-template].\n\nTo so do, you'll need the `cargo-generate` tool. To install `cargo-generate`:\n\n```\ncargo install cargo-generate\n```\n\nThen run:\n\n```\ncargo generate --git https://github.com/drager/wasm-pack-template\n```\n\nYou will be prompted to give your project a name. Once you do, you will have a directory\nwith a new project, ready to go. We'll talk about what's been included in this template\nfurther in this guide.\n\n[rustwasm wasm-pack-template]: https://github.com/drager/wasm-pack-template\n\n## Manual Setup\n\n⚠️ If you'd rather not use a template, or are having trouble with the template, you can\ndo a manual setup by following [these instructions].\n\n[these instructions]: ./getting-started/manual-setup.html\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/index.md",
    "content": "# npm Browser Package Tutorial\n\nThe goal of this tutorial is to introduce you to the `wasm-pack` workflow by building a small npm\npackage designed to be used in a browser application.\n\nThis tutorial is aimed at folks who are both beginners to WebAssembly and Rust- you don't need\nmuch Rust knowledge to complete this tutorial.\n\nBe sure to have done the following before starting:\n\n1. [Install `wasm-pack`](https://drager.github.io/wasm-pack/installer/)\n1. Read and install the [Prerequisites](../../prerequisites/index.html).\n\n⚠️ We strongly recommend that you install [Node.js] using a version manager. You can learn more [here](https://npmjs.com/get-npm).\n\n[Rust]: https://www.rust-lang.org\n[Node.js]: https://nodejs.org\n[npm]: https://npmjs.com\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/packaging-and-publishing.md",
    "content": "# Package Code for npm\n\nWe've made our code so now we need to package it all up. In your project directory run the following\ncommand:\n\n```bash\n$ wasm-pack build --scope MYSCOPE\n```\n\nwhere `MYSCOPE` is your npm username. Normally you could just type `wasm-pack build` but since\nother people are doing this tutorial as well we don't want conflicts with the `wasm-add` package\nname! This command when run does a few things:\n\n1. It'll compile your code to wasm if you haven't already\n2. It'll generate a pkg folder with the wasm file, a JS wrapper file around the wasm, your README,\n   and a `package.json` file.\n\nThis is everything you need to upload your code to npm! Let's do just that!\n\nFirst off you'll need to login to npm with the account you made earlier if you didn't already have\none:\n\n```bash\n$ wasm-pack login\n```\n\nNext you'll need to go into the `pkg` directory and actually upload the package:\n\n```bash\n$ cd pkg\n$ npm publish --access=public\n```\n\nNow normally if things are not scoped you can just do `npm publish` but if you give it a scope\nyou'll need to tell npm that this is actually public so it can publish it. We need to do that here\nsince we gave our packages a scope to avoid conflicting with each other! Next up is actually running\nthe code and verifying we got it from npm and how we can use that code.\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/template-deep-dive/building-your-project.md",
    "content": "# Building your project\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/template-deep-dive/cargo-toml.md",
    "content": "# Cargo.toml\n\n`Cargo.toml` is the manifest file for Rust's package manager, [`cargo`]. This file contains\nmetadata such as name, version, and dependencies for packages, which are call \"crates\" in Rust.\n\n[`cargo`]: https://doc.rust-lang.org/cargo/\n\nThere's a bunch of metadata that the template gives us, but there are three key parts to discuss:\n\n1. [`crate-type`](#a1-crate-type)\n2. [`wasm-bindgen` dependency](#a2-wasm-bindgen-dependency)\n3. [`[features]` and `wee_alloc`, `console_error_panic_hook` dependencies](#a3-features-and-wee_alloc-console_error_panic_hook-dependencies)\n\n<hr/>\n\n## 1. `crate-type`\n\n```toml\n[lib]\ncrate-type = [\"cdylib\", \"rlib\"]\n```\n\nA Rust-`wasm` crate is a bit different from a normal crate, and as a result, we need to note\nthis in our `Cargo.toml`.\n\nThis `[lib]` annotation is typically not needed in Cargo projects, and if you're\nfamiliar with other Rust crates you'll remember that the most common crate types\nare `rlib` (the default) or `bin` for binaries (which don't need a `crate-type`\nannotation).\n\nHere though `crate-type = [\"cdylib\"]` typically signifies that you'd like the\ncompiler to create a dynamic system library, but for WebAssembly target it\nsimply means \"create a `*.wasm` file without a `start` function\". On other\nplatforms this output type will create `*.so` file on Linux, `*.dylib` on\nmacOS, and `*.dll` Windows.\n\nWe also specify `crate-type = [\"rlib\"]` to ensure that our library can be unit\ntested with `wasm-pack test` (which we'll see later). Without this we wouldn't\nbe able to test our library because the `cdylib` crate type is incompatible with\n`wasm-pack`'s style of unit tests.\n\nYou can read more about linking and crate types, [here](https://doc.rust-lang.org/reference/linkage.html).\n\n## 2. `wasm-bindgen` dependency\n\n[`wasm-bindgen`] is our most important dependency. This package allows us to use the\n`#[wasm-bindgen]` attribute to tag code that represents the interface we want between\nour JavaScript and Rust-generated `wasm`. We can import JS and export Rust by using this\nattribute.\n\n[`wasm-bindgen`]: https://rustwasm.github.io/docs/wasm-bindgen/\n\n```toml\nwasm-bindgen = \"0.2\"\n```\n\nWe'll see more about how to use this library when we discuss what has been generated in `lib.rs`.\n\n⚠️ If you are coming from JavaScript, you might note that when we add the dependency\nthere is no `^` or `~` symbol- it looks like we're locking to the `0.2` version.\nHowever, that's not the case! In Rust, the `^` is implied. You can read more about this in the\n[cargo documentation on specifying dependencies].\n\n[cargo documentation on specifying dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html\n\n## 3. `[features]` and [`wee_alloc`], [`console_error_panic_hook`] dependencies\n\n[`wee_alloc`]: https://crates.io/crates/wee_alloc\n[`console_error_panic_hook`]: https://crates.io/crates/console_error_panic_hook\n\nAs part of our effort to design a template that helps people discover useful crates\nfor their particular use case, this template includes two dependencies that can be\nvery useful for folks developing Rust-`wasm` crates:[ `console_error_panic_hook`] and\n[`wee_alloc`].\n\nBecause these dependencies are useful primarily in a specific portion of the Rust-`wasm`\ncrate development workflow, we've also set up a bit of glue code that allows us to include\nthem both as dependencies, but also allows them to be optionally included.\n\n```toml\n[features]\ndefault = [\"console_error_panic_hook\"]\n\n[dependencies]\nwasm-bindgen = \"0.2\"\n\n# The `console_error_panic_hook` crate provides better debugging of panics by\n# logging them with `console.error`. This is great for development, but requires\n# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for\n# code size when deploying.\nconsole_error_panic_hook = { version = \"0.1.1\", optional = true }\n\n# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size\n# compared to the default allocator's ~10K. It is slower than the default\n# allocator, however.\n#\n# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.\nwee_alloc = { version = \"0.4.2\", optional = true }\n```\n\nIn our code, we'll mark certain parts of code as running only if certain `[features]`\nare enabled, specifically, `console_error_panic_hook` and `wee_alloc`. By default,\nonly `console_error_panic_hook` is enabled. To disable or enable either feature, by\ndefault, we can edit the `default` vector under `[features]`.\n\nTo learn more about these features, we discuss them in-depth in the [`src/lib.rs`] and\n[`src/utils.rs`] sections.\n\n[`src/lib.rs`]: src-lib-rs.html\n[`src/utils.rs`]: src-utils-rs.html\n\nBriefly, they include:\n\n+ **console_error_panic_hook** for logging panic messages to the developer console.\n+ **wee_alloc**, an allocator optimized for small code size.\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/template-deep-dive/index.md",
    "content": "# Template Deep Dive\n\n⚠️ This section is a deep dive into the contents of the files of a \"Hello, World\" project,\nspecifically written for people who are not that familiar with Rust. If you'd rather just\ncheckout the workflow, feel free to skip this section!\n\n⚠️ If you haven't used a template to set up your project, the contents of your files\nmay look slightly different than what is described here.\n\n### What the Template Gave Us\n\nLet's start by taking a look at what the template generated for us.\n\n- [`Cargo.toml` - the Cargo manifest](./cargo-toml.html)\n- [`src/lib.rs` - main library module](./src-lib-rs.html)\n- [`src/utils.rs` - a utility module](./src-utils-rs.html)\n- [`wee_alloc` - a tiny memory allocator](./wee_alloc.html)\n- [`tests/web.rs` - running headless browser tests](./tests-web-rs.html)\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/template-deep-dive/src-lib-rs.md",
    "content": "# src/lib.rs\n\n`lib.rs` is the template's main source file. The name `lib.rs` commonly implies that this Rust project will be compiled as a library.\n\nIt contains three key parts:\n\n1. [`#[wasm_bindgen] functions`](#a1-wasm_bindgen-functions)\n2. [Crate imports](#a2-crate-imports)\n3. [`wee_alloc` optional dependecy](#a3-wee_alloc-optional-dependecy)\n\t- [What is `wee_alloc`?](#what-is-wee_alloc)\n\n---\n\nWe'll start with the most important part of `lib.rs` -- the two `#[wasm_bindgen]` functions (which you can find at the bottom of the file). In many cases, this is the only part of `lib.rs` you will need to modify.\n\n## 1. Using `wasm_bindgen`\n\nTo expose functionality from the `wasm-bindgen` crate more conveniently we can use the `use` keyword.\n`use` allows us to conveniently refer to parts of a crate or module. You can learn more about how Rust\nlets you write modular code in [this chapter of the book](https://doc.rust-lang.org/book/ch07-02-modules-and-use-to-control-scope-and-privacy.html).\n\n```rust\nuse wasm_bindgen::prelude::*;\n```\n\nMany crates contain a prelude, a list of things that are convenient to import\nall at once. This allows common features of the module to be conveniently\naccessed without a lengthy prefix. For example, in this file we can use\n`#[wasm_bindgen]` only because it is brought into scope by the prelude.\n\nThe asterisk at the end of this `use` indicates that everything inside the module `wasm_bindgen::prelude` (i.e. the module `prelude` inside the crate `wasm_bindgen`) can be referred to without prefixing it with `wasm_bindgen::prelude`.\n\nFor example, `#[wasm_bindgen]` could also be written as `#[wasm_bindgen::prelude::wasm_bindgen]`, although this is not recommended.\n\n## 1. `#[wasm_bindgen]` functions\n\nThe `#[wasm_bindgen]` attribute indicates that the function below it will be accessible both in JavaScript and Rust.\n\n```rust\n#[wasm_bindgen]\nextern {\n    fn alert(s: &str);\n}\n```\n\nThe `extern` block imports the external JavaScript function `alert` into Rust. This declaration is required to call `alert` from Rust. By declaring it in this way, `wasm-bindgen` will create JavaScript stubs for `alert` which allow us to pass strings back and forth between Rust and JavaScript.\n\nWe can see that the `alert` function requires a single parameter `s` of type `&str`, a string. In Rust, any string literal such as `\"Hello, test-wasm!\"` is of type `&str`. So, `alert` could be called by writing `alert(\"Hello, test-wasm!\");`.\n\nWe knew to declare `alert` in this way because it is how we would call `alert` in JavaScript -- by passing it a string argument.\n\n```rust\n#[wasm_bindgen]\npub fn greet() {\n    alert(\"Hello, test-wasm!\");\n}\n```\n\nIf we were to write the `greet` function without the `#[wasm_bindgen]` attribute, then `greet` would not be easily accessible within JavaScript. Furthermore, we wouldn't be able to natively convert certain types such as `&str` between JavaScript and Rust. So, both the `#[wasm_bindgen]` attribute and the prior import of `alert` allow `greet` to be called from JavaScript.\n\nThis is all you need to know to interface with JavaScript, at least to start! You can learn a bunch more by reading the\n[`wasm-bindgen` documentation]!\n\n[`wasm-bindgen` documentation]: https://rustwasm.github.io/docs/wasm-bindgen/\n\nIf you are curious about the rest, read on.\n\n## 2. Crate Organization\n\n```rust\nmod utils;\n```\nThis statement declares a new module named `utils` that is defined by the contents of `utils.rs`. Equivalently, we could place the contents of `utils.rs` inside the `utils` declaration, replacing the line with:\n\n```rust\nmod utils {\n    // contents of utils.rs\n}\n```\n\nEither way, the contents of `utils.rs` define a single public function `set_panic_hook`. Because we are placing it inside the `utils` module, we will be able to call the function directly by writing `utils::set_panic_hook()`. We will discuss how and why to use this function in `src/utils.rs`.\n\n\n```rust\n    // When the `wee_alloc` feature is enabled, use `wee_alloc` as the global\n    // allocator.\n    if #[cfg(feature = \"wee_alloc\")] {\n        #[global_allocator]\tstatic ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;\n```\n\nAt compile time this will test if the `wee_alloc` feature is enabled for this\ncompilation. If it's enabled we'll configure a global allocator (according to\n[`wee_alloc`'s docs][wee-alloc-docs]), otherwise it'll compile to nothing.\n\n[wee-alloc-docs]: https://docs.rs/wee_alloc/0.4.3/wee_alloc/\n\nAs we saw earlier, the `default` vector in `[features]` only contains `\"console_error_panic_hook\"` and not `\"wee_alloc\"`. So, in this case, this \nblock will be replaced by no code at all, and hence the default memory allocator will be used instead of `wee_alloc`.\n\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/template-deep-dive/src-utils-rs.md",
    "content": "# src/utils.rs\n\nThe purpose of `utils.rs` is to define the `utils` module, which contains a single function `set_panic_hook`. This function becomes part of the `utils` module in `lib.rs`, as described in the preceding section.\n\nIf the `console_error_panic_hook` feature is not enabled, then `set_panic_hook` is defined to be an inlined empty function. So, there is no run-time performance or code-size penalty incurred by its use.\n\nWe will discuss:\n1. [Defining `set_panic_hook`](#1-defining-set_panic_hook)\n2. [What is `console_error_panic_hook`?](#2-what-is-console_error_panic_hook)\n\n\n---\n\n## 1. Defining `set_panic_hook`\n\n```rust\npub fn set_panic_hook() {\n    // When the `console_error_panic_hook` feature is enabled, we can call the\n    // `set_panic_hook` function at least once during initialization, and then\n    // we will get better error messages if our code ever panics.\n    //\n    // For more details see\n    // https://github.com/rustwasm/console_error_panic_hook#readme\n    #[cfg(feature = \"console_error_panic_hook\")]\n    console_error_panic_hook::set_once();\n}\n```\n\nHere, we define a function that's preceded by a `cfg` attribute. This attribue,\n`#[cfg(feature = \"console_error_panic_hook\")]`, tells Rust to check if the \n`console_error_panic_hook` feature is set at compile time. If it is, it will call\nthis function. If it isn't- it won't! \n\n## 2. What is `console_error_panic_hook`?\n\nThe [crate `console_error_panic_hook`][ceph] allows debugging Rust panic\nmessages in a web browser, making it much easier to debug WebAssembly code.\n\nLet's compare what happens when Rust code panics before and after enabling the\nfeature:\n\n**Before:** `\"RuntimeError: Unreachable executed\"`\n\n**After:** `\"panicked at 'index out of bounds: the len is 3 but the index is 4', libcore/slice/mod.rs:2046:10\"`\n\nTo do this, a [panic hook] is configured that logs panics to the\ndeveloper console via the JavaScript `console.error` function.\n\nNote though that `console_error_panic_hook` is not entirely automatic, so you'll\nneed to make sure that `utils::set_panic_hook()` is called before any of our\ncode runs (and it's safe to run `set_panic_hook` many times).\n\nFor more details, see the [`console_error_panic_hook`\nrepository](https://github.com/rustwasm/console_error_panic_hook).\n\n[ceph]: https://crates.io/crates/console_error_panic_hook\n[panic hook]: https://doc.rust-lang.org/std/panic/fn.set_hook.html\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/template-deep-dive/tests-web-rs.md",
    "content": "# tests/web.rs\n\n`web.rs` is an integration test [defined with Cargo][cargo-tests] that is\nintended to be run in a headless web browser via the `wasm-pack test` command.\n\n[cargo-tests]: https://doc.rust-lang.org/cargo/guide/tests.html\n\nIt contains three key parts:\n\n1. [`#[wasm_bindgen_test] functions`](#a1-wasm_bindgen_test-functions)\n2. [Crate Configuration](#a2-crate-configuration)\n3. [`#![cfg]` directives](#a3-cfg-directives)\n\n---\n\n## 1. `#[wasm_bindgen_test]` functions\n\nThe `#[wasm_bindgen_test]` is like the [normal Rust `#[test]`\nattribute][rust-test], except it defines a test accessible to WebAssembly and\nheadless web browser testing.\n\n> **Note**: Eventually `#[test]` will work with WebAssembly as well! Currently\n> though [custom test frameworks][ctf] are not stable.\n\n[rust-test]: https://doc.rust-lang.org/book/ch11-01-writing-tests.html\n[ctf]: https://github.com/rust-lang/rust/issues/50297\n\n```rust\n#[wasm_bindgen_test]\nfn pass() {\n    assert_eq!(1 + 1, 2);\n}\n```\n\nHere the `pass` function is a unit test which asserts that arithmetic works in\nWebAssembly like we'd expect everywhere else. If the test panics (such as the\n`assert_eq!` being false) then the test will fail, otherwise the test will\nsucceed.\n\nThe [reference documentation for `#[wasm_bindgen_test]`][wbg-test] should have\nmore information about defining these tests.\n\n[wbg-test]: https://rustwasm.github.io/docs/wasm-bindgen/wasm-bindgen-test/index.html\n\n## 2. Crate Configuration\n\nOther than the test in this module, we'll also see:\n\n```rust\nuse wasm_bindgen_test::*;\n\nwasm_bindgen_test_configure!(run_in_browser);\n```\n\nLike we saw earlier in `src/lib.rs` the `*` import pulls in everything from\n`wasm_bindgen_test`, notably the `wasm_bindgen_test_configure` macro and the\n`wasm_bindgen_test` attribute.\n\nThe `wasm_bindgen_test_configure` macro (denoted by ending in `!`) is used to\nindicate that the test is intended to execute in a web browser as opposed to\nNode.js, which is the default.\n\n## 3. `#![cfg]` directives\n\nThe last part we'll notice about this crate is this statement at the top:\n\n```rust\n#![cfg(target_arch = \"wasm32\")]\n```\n\nThis statement means that the test is only intended for the `wasm32`\narchitecture, or the `wasm32-unknown-unknown` target. This enables `cargo test`\nto work in your project if the library is also being developed for other\nplatforms by ensuring that these tests only execute in a web browser.\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/template-deep-dive/wee_alloc.md",
    "content": "# wee_alloc\n\n1. [What is `wee_alloc`?](#what-is-wee_alloc)\n2. [Enabling `wee_alloc`](#enabling-wee_alloc)\n\n## What is `wee_alloc`?\n\nWebAssembly code is frequently transmitted over the wire to users, so compiled\ncode size is often important to ensure an application loads quickly and is\nresponsive.\n\n> `wee_alloc` is a tiny allocator designed for WebAssembly that has a (pre-compression) code-size footprint of only a single kilobyte.\n\n[An analysis](http://fitzgeraldnick.com/2018/02/09/wee-alloc.html) suggests that over half of the bare minimum WebAssembly memory footprint is required by Rust's default memory allocator. Yet, WebAssembly code often does not require a sophisticated allocator, since it often just requests a couple of large initial allocations.\n\n`wee_alloc` trades off size for speed. It has a tiny code-size\nfootprint, but it is not competitive in terms of performance with the\ndefault global allocator, for example.\n\nFor even more details, see the [`wee_alloc`\nrepository](https://github.com/rustwasm/wee_alloc), or\n[general documentation](https://rustwasm.github.io/docs/book/reference/code-size.html) about\nshrinking code size of WebAssembly binaries.\n\n## Enabling `wee_alloc`\n\nIn `lib.rs`, we have the configuration for `wee_alloc` inside a `cfg_if!` macro:\n\n```rust\ncfg_if! {\n    if #[cfg(feature = \"wee_alloc\")] {\n        #[global_allocator]\n        static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;\n    }\n}\n```\n\nThis code block is intended to initialize `wee_alloc` as the global memory\nallocator, but only if the `wee_alloc` feature is enabled at compile time. The\nfeature can be enabled by passing extra options while building:\n\n```\n$ wasm-pack build --features wee_alloc\n```\n\nor alternatively you could turn it on by default in `Cargo.toml`:\n\n```toml\n[features]\ndefault = [\"console_error_panic_hook\", \"wee_alloc\"]\n```\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/testing-your-project.md",
    "content": "# Testing your project\n\nNow after writing and building code, let's actually execute it! You can execute\ntests with:\n\n```bash\n$ wasm-pack test --firefox\n[INFO]: Checking for the Wasm target...\n    Finished dev [unoptimized + debuginfo] target(s) in 0.02s\n     Running target/wasm32-unknown-unknown/debug/deps/web-9e7d380f8600b08e.wasm\nInteractive browsers tests are now available at http://127.0.0.1:8000\n\nNote that interactive mode is enabled because `NO_HEADLESS`\nis specified in the environment of this process. Once you're\ndone with testing you'll need to kill this server with\nCtrl-C.\n```\n\nThe console won't finish just yet, but as indicated you can visit\nhttp://127.0.0.1:8000 in your web browser to see the test output:\n\n```\nrunning 1 test\n\ntest web::pass ... ok\n\ntest result: ok. 1 passed; 0 failed; 0 ignored\n```\n\nand we've now executed our first tests in a web browser!\n\nIf you'd like to execute tests in a headless web browser (you don't need to\nmanually visit a page) you can do:\n\n```bash\n$ wasm-pack test --headless --firefox\n```\n\nand similarly if you're developing a project for Node.js you can also execute\n`wasm-pack test --nodejs` to run tests in Node.\n\nBe sure to see the [testing reference documentation][testing-reference] for\nother supported features as well!\n\n[testing-reference]: https://rustwasm.github.io/docs/wasm-bindgen/wasm-bindgen-test/index.html\n"
  },
  {
    "path": "docs/src/tutorials/npm-browser-packages/using-your-library.md",
    "content": "# Run The Code From npm\n\nThis portion of the tutorial will help you create a [Webpack] JavaScript project that will\nrun your WebAssembly code in the browser.\n\n[Webpack]: https://webpack.js.org/\n\n## Scaffold a JavaScript Project\n\nTo scaffold a project that we can use our new package in, we'll use an npm template called\n[`create-wasm-app`]. To use this run this command in a directory *different* than your Rust\nproject:\n\n[`create-wasm-app`]: https://github.com/rustwasm/create-wasm-app\n\n```\nnpm init wasm-app my-new-wasm-app\n```\n\nInstead of `my-new-wasm-app` you can choose a different project name.\nThe tool will create a directory with that name.\n\nIf we look in that directory, we'll see the following:\n\n- `.gitignore`: ignores `node_modules`\n- `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you\n- `README.md`: the file you are reading now!\n- `index.html`: a bare bones html document that includes the webpack bundle\n- `index.js`: example js file with a comment showing how to import and use a wasm pkg\n- `package.json` and `package-lock.json`: \n  - pulls in devDependencies for using webpack:\n      - [`webpack`](https://www.npmjs.com/package/webpack)\n      - [`webpack-cli`](https://www.npmjs.com/package/webpack-cli)\n      - [`webpack-dev-server`](https://www.npmjs.com/package/webpack-dev-server)\n  - defines a `start` script to run `webpack-dev-server`\n- `webpack.config.js`: configuration file for bundling your js with webpack\n\n## Add Your npm Package\n\nThe scaffolded project includes an example WebAssembly package, `hello-wasm-pack`, in your\n`package.json`. Go into the `package.json` file, add your package, and remove the \n`hello-wasm-pack` dependency from the `\"dependencies\"` section.\n\nNow, open up the `index.js` file. Replace the `hello-wasm-pack` in the first line with the\nname of your package:\n\n```js\nimport * as wasm from \"<your package name>\";\n\nwasm.greet();\n```\n\n## Run The Project\n\nBefore we run our project, we need to make sure we install our dependencies:\n\n```bash\nnpm install\n```\n\nWe should be ready to run our project now! To run our project we'll run:\n\n```bash\nnpm start\n```\n\nThen in a web browser navigate to `http://localhost:8080` and you should be greeted with an\nalert box that says \"Hello World!\".\n\nIf you did congrats you've successfully uploaded your first bit of wasm code to npm and used it\nproperly!\n"
  },
  {
    "path": "docs/src/tutorials/standalone-wasm-binaries/index.md",
    "content": "# Standalone WASM Binaries\n"
  },
  {
    "path": "npm/.gitignore",
    "content": "node_modules"
  },
  {
    "path": "npm/README.md",
    "content": "<div align=\"center\">\n\n  <h1>📦✨ wasm-pack</h1>\n\n  <p>\n    <strong>Your favorite Rust → Wasm workflow tool!</strong>\n  </p>\n\n  <p>\n    <a href=\"https://github.com/drager/wasm-pack/actions/workflows/test.yml\"><img alt=\"Build Status\" src=\"https://github.com/drager/wasm-pack/actions/workflows/test.yml/badge.svg?branch=master\"/></a>\n    <a href=\"https://crates.io/crates/wasm-pack\"><img alt=\"crates.io\" src=\"https://img.shields.io/crates/v/wasm-pack\"/></a>\n  </p>\n\n  <h3>\n    <a href=\"https://drager.github.io/wasm-pack/book\">Docs</a>\n    <span> | </span>\n    <a href=\"https://github.com/drager/wasm-pack/blob/master/CONTRIBUTING.md\">Contributing</a>\n    <span> | </span>\n    <a href=\"https://discordapp.com/channels/442252698964721669/443151097398296587\">Chat</a>\n  </h3>\n\n\n</div>\n\n## About\n\nThis tool seeks to be a one-stop shop for building and working with rust-\ngenerated WebAssembly that you would like to interop with JavaScript, in the\nbrowser or with Node.js. `wasm-pack` helps you build rust-generated\nWebAssembly packages that you could publish to the npm registry, or otherwise use\nalongside any javascript packages in workflows that you already use, such as [webpack].\n\n[webpack]: https://webpack.js.org/\n\n![demo](demo.gif)\n\n## 🔮 Prerequisites\n\nThis project requires Rust 1.30.0 or later.\n\n- [Development Environment](https://drager.github.io/wasm-pack/book/prerequisites/index.html)\n- [Installation](https://drager.github.io/wasm-pack/installer)\n\n## ⚡ Quickstart Guide\n\nVisit the [quickstart guide] in our documentation.\n\n[quickstart guide]: https://drager.github.io/wasm-pack/book/quickstart.html\n\n## 🎙️ Commands\n\n- [`new`](https://drager.github.io/wasm-pack/book/commands/new.html): Generate a new RustWasm project using a template\n- [`build`](https://drager.github.io/wasm-pack/book/commands/build.html): Generate an npm wasm pkg from a rustwasm crate\n- [`test`](https://drager.github.io/wasm-pack/book/commands/test.html): Run browser tests\n- [`pack` and `publish`](https://drager.github.io/wasm-pack/book/commands/pack-and-publish.html): Create a tarball of your rustwasm pkg and/or publish to a registry\n\n## 📝 Logging\n\n`wasm-pack` uses [`env_logger`] to produce logs when `wasm-pack` runs.\n\nTo configure your log level, use the `RUST_LOG` environment variable. For example:\n\n```\nRUST_LOG=info wasm-pack build\n```\n\n[`env_logger`]: https://crates.io/crates/env_logger\n\n## 👯 Contributing\n\nRead our [guide] on getting up and running for developing `wasm-pack`, and\ncheck out our [contribution policy].\n\n[guide]: https://drager.github.io/wasm-pack/book/contributing.html\n[contribution policy]: CONTRIBUTING.md\n\n## 🤹‍♀️ Governance\n\nThis project was started by [ashleygwilliams] and is maintained by [drager].\n\n[ashleygwilliams]: https://github.com/ashleygwilliams\n[drager]: https://github.com/drager\n"
  },
  {
    "path": "npm/binary.js",
    "content": "const { Binary } = require(\"binary-install\");\nconst { join } = require(\"path\");\nconst os = require(\"os\");\n\nconst windows = \"x86_64-pc-windows-msvc\";\n\nconst getPlatform = () => {\n  const type = os.type();\n  const arch = os.arch();\n\n  // https://github.com/nodejs/node/blob/c3664227a83cf009e9a2e1ddeadbd09c14ae466f/deps/uv/src/win/util.c#L1566-L1573\n  if ((type === \"Windows_NT\" || type.startsWith(\"MINGW32_NT-\")) && arch === \"x64\") {\n    return windows;\n  }\n  if (type === \"Linux\" && arch === \"x64\") {\n    return \"x86_64-unknown-linux-musl\";\n  }\n  if (type === \"Linux\" && arch === \"arm64\") {\n    return \"aarch64-unknown-linux-musl\";\n  }\n  if (type === \"Darwin\" && arch === \"x64\") {\n    return \"x86_64-apple-darwin\";\n  }\n  if (type === \"Darwin\" && arch === \"arm64\") {\n    return \"aarch64-apple-darwin\";\n  }\n\n  throw new Error(`Unsupported platform: ${type} ${arch}`);\n};\n\nconst getBinary = () => {\n  const platform = getPlatform();\n  const version = require(\"./package.json\").version;\n  const author = \"drager\";\n  const name = \"wasm-pack\";\n  const url = `https://github.com/${author}/${name}/releases/download/v${version}/${name}-v${version}-${platform}.tar.gz`;\n  return new Binary(platform === windows ? \"wasm-pack.exe\" : \"wasm-pack\", url, {\n    installDirectory: join(__dirname, \"binary\"),\n  });\n};\n\nconst install = () => {\n  const binary = getBinary();\n  binary.install();\n};\n\nconst run = () => {\n  const binary = getBinary();\n  binary.run();\n};\n\nmodule.exports = {\n  install,\n  run,\n};\n"
  },
  {
    "path": "npm/install.js",
    "content": "#!/usr/bin/env node\n\nconst { install } = require(\"./binary\");\ninstall();\n"
  },
  {
    "path": "npm/package.json",
    "content": "{\n  \"name\": \"wasm-pack\",\n  \"version\": \"0.14.0\",\n  \"description\": \"📦✨ your favorite rust -> wasm workflow tool!\",\n  \"main\": \"binary.js\",\n  \"scripts\": {\n    \"postinstall\": \"node ./install.js\"\n  },\n  \"bin\": {\n    \"wasm-pack\": \"./run.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/drager/wasm-pack.git\"\n  },\n  \"keywords\": [\n    \"wasm\",\n    \"rust-wasm\",\n    \"registry\",\n    \"cli\",\n    \"rust\",\n    \"npm\",\n    \"package\"\n  ],\n  \"author\": \"Jesper Håkansson <jesper@jesperh.se>\",\n  \"license\": \"MIT OR Apache-2.0\",\n  \"bugs\": {\n    \"url\": \"https://github.com/drager/wasm-pack/issues\"\n  },\n  \"homepage\": \"https://github.com/drager/wasm-pack#readme\",\n  \"dependencies\": {\n    \"binary-install\": \"^1.1.2\"\n  },\n  \"resolutions\": {\n    \"tar\": \"^7.5.3\",\n    \"axios\": \"^0.30.0\"\n  }\n}\n"
  },
  {
    "path": "npm/run.js",
    "content": "#!/usr/bin/env node\n\nconst { run } = require(\"./binary\");\nrun();\n"
  },
  {
    "path": "src/bindgen.rs",
    "content": "//! Functionality related to running `wasm-bindgen`.\n\nuse crate::child;\nuse crate::command::build::{BuildProfile, Target};\nuse crate::install::{self, Tool};\nuse crate::manifest::CrateData;\nuse anyhow::{bail, Context, Result};\nuse semver;\nuse std::path::Path;\nuse std::process::Command;\n\n/// Run the `wasm-bindgen` CLI to generate bindings for the current crate's\n/// `.wasm`.\npub fn wasm_bindgen_build(\n    wasm_path: &str,\n    data: &CrateData,\n    install_status: &install::Status,\n    out_dir: &Path,\n    out_name: &Option<String>,\n    disable_dts: bool,\n    weak_refs: bool,\n    reference_types: bool,\n    target: Target,\n    profile: BuildProfile,\n) -> Result<()> {\n    let out_dir = out_dir.to_str().unwrap();\n\n    let dts_arg = if disable_dts {\n        \"--no-typescript\"\n    } else {\n        \"--typescript\"\n    };\n    let bindgen_path = install::get_tool_path(install_status, Tool::WasmBindgen)?\n        .binary(&Tool::WasmBindgen.to_string())?;\n\n    let mut cmd = Command::new(&bindgen_path);\n    cmd.arg(&wasm_path)\n        .arg(\"--out-dir\")\n        .arg(out_dir)\n        .arg(dts_arg);\n\n    if weak_refs {\n        cmd.arg(\"--weak-refs\");\n    }\n\n    if reference_types {\n        cmd.arg(\"--reference-types\");\n    }\n\n    let target_arg = build_target_arg(target, &bindgen_path)?;\n    if supports_dash_dash_target(&bindgen_path)? {\n        cmd.arg(\"--target\").arg(target_arg);\n    } else {\n        cmd.arg(target_arg);\n    }\n\n    if let Some(value) = out_name {\n        cmd.arg(\"--out-name\").arg(value);\n    }\n\n    let profile = data.configured_profile(profile);\n    if profile.wasm_bindgen_debug_js_glue() {\n        cmd.arg(\"--debug\");\n    }\n    if !profile.wasm_bindgen_demangle_name_section() {\n        cmd.arg(\"--no-demangle\");\n    }\n    if profile.wasm_bindgen_dwarf_debug_info() {\n        cmd.arg(\"--keep-debug\");\n    }\n    if profile.wasm_bindgen_omit_default_module_path() {\n        cmd.arg(\"--omit-default-module-path\");\n    }\n    if profile.wasm_bindgen_split_linked_modules() {\n        cmd.arg(\"--split-linked-modules\");\n    }\n\n    child::run(cmd, \"wasm-bindgen\").context(\"Running the wasm-bindgen CLI\")?;\n    Ok(())\n}\n\n/// Check if the `wasm-bindgen` dependency is locally satisfied for the web target\nfn supports_web_target(cli_path: &Path) -> Result<bool> {\n    let cli_version = semver::Version::parse(&install::get_cli_version(\n        &install::Tool::WasmBindgen,\n        cli_path,\n    )?)?;\n    let expected_version = semver::Version::parse(\"0.2.39\")?;\n    Ok(cli_version >= expected_version)\n}\n\n/// Check if the `wasm-bindgen` dependency is locally satisfied for the --target flag\nfn supports_dash_dash_target(cli_path: &Path) -> Result<bool> {\n    let cli_version = semver::Version::parse(&install::get_cli_version(\n        &install::Tool::WasmBindgen,\n        cli_path,\n    )?)?;\n    let expected_version = semver::Version::parse(\"0.2.40\")?;\n    Ok(cli_version >= expected_version)\n}\n\nfn build_target_arg(target: Target, cli_path: &Path) -> Result<String> {\n    if !supports_dash_dash_target(cli_path)? {\n        Ok(build_target_arg_legacy(target, cli_path)?)\n    } else {\n        Ok(target.to_string())\n    }\n}\n\nfn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String> {\n    log::info!(\"Your version of wasm-bindgen is out of date. You should consider updating your Cargo.toml to a version >= 0.2.40.\");\n    let target_arg = match target {\n        Target::Nodejs => \"--nodejs\",\n        Target::NoModules => \"--no-modules\",\n        Target::Web => {\n            if supports_web_target(cli_path)? {\n                \"--web\"\n            } else {\n                bail!(\"Your current version of wasm-bindgen does not support the 'web' target. Please update your project to wasm-bindgen version >= 0.2.39.\")\n            }\n        }\n        Target::Bundler => \"--browser\",\n        Target::Deno => \"--deno\",\n    };\n    Ok(target_arg.to_string())\n}\n"
  },
  {
    "path": "src/build/mod.rs",
    "content": "//! Building a Rust crate into a `.wasm` binary.\n\nuse crate::child;\nuse crate::command::build::BuildProfile;\nuse crate::emoji;\nuse crate::manifest::Crate;\nuse crate::PBAR;\nuse anyhow::{anyhow, bail, Context, Result};\nuse cargo_metadata::Message;\nuse std::io::BufReader;\nuse std::path::Path;\nuse std::process::{Command, Stdio};\nuse std::str;\n\npub mod wasm_target;\n\n/// Used when comparing the currently installed\n/// wasm-pack version with the latest on crates.io.\npub struct WasmPackVersion {\n    /// The currently installed wasm-pack version.\n    pub local: String,\n    /// The latest version of wasm-pack that's released at\n    /// crates.io.\n    pub latest: String,\n}\n\n/// Ensure that `rustc` is present and that it is >= 1.30.0\npub fn check_rustc_version() -> Result<String> {\n    let local_minor_version = rustc_minor_version();\n    match local_minor_version {\n        Some(mv) => {\n            if mv < 30 {\n                bail!(\n                    \"Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.\",\n                    mv.to_string()\n                )\n            } else {\n                Ok(mv.to_string())\n            }\n        }\n        None => bail!(\"We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher.\"),\n    }\n}\n\n// from https://github.com/alexcrichton/proc-macro2/blob/79e40a113b51836f33214c6d00228934b41bd4ad/build.rs#L44-L61\nfn rustc_minor_version() -> Option<u32> {\n    macro_rules! otry {\n        ($e:expr) => {\n            match $e {\n                Some(e) => e,\n                None => return None,\n            }\n        };\n    }\n    let output = otry!(Command::new(\"rustc\").arg(\"--version\").output().ok());\n    let version = otry!(str::from_utf8(&output.stdout).ok());\n    let mut pieces = version.split('.');\n    if pieces.next() != Some(\"rustc 1\") {\n        return None;\n    }\n    otry!(pieces.next()).parse().ok()\n}\n\n/// Checks and returns local and latest versions of wasm-pack\npub fn check_wasm_pack_versions() -> Result<WasmPackVersion> {\n    match wasm_pack_local_version() {\n        Some(local) => Ok(WasmPackVersion {local, latest: Crate::return_wasm_pack_latest_version()?.unwrap_or_else(|| \"\".to_string())}),\n        None => bail!(\"We can't figure out what your wasm-pack version is, make sure the installation path is correct.\")\n    }\n}\n\nfn wasm_pack_local_version() -> Option<String> {\n    let output = env!(\"CARGO_PKG_VERSION\");\n    Some(output.to_string())\n}\n\n/// Run `cargo build` for Wasm with config derived from the given `BuildProfile`.\npub fn cargo_build_wasm(\n    path: &Path,\n    profile: BuildProfile,\n    extra_options: &[String],\n) -> Result<String> {\n    let msg = format!(\"{}Compiling to Wasm...\", emoji::CYCLONE);\n    PBAR.info(&msg);\n\n    let mut cmd = Command::new(\"cargo\");\n    cmd.current_dir(path).arg(\"build\").arg(\"--lib\");\n\n    if PBAR.quiet() {\n        cmd.arg(\"--quiet\");\n    }\n\n    match profile {\n        BuildProfile::Profiling => {\n            // Once there are DWARF debug info consumers, force enable debug\n            // info, because builds that use the release cargo profile disables\n            // debug info.\n            //\n            // cmd.env(\"RUSTFLAGS\", \"-g\");\n            cmd.arg(\"--release\");\n        }\n        BuildProfile::Release => {\n            cmd.arg(\"--release\");\n        }\n        BuildProfile::Dev => {\n            // Plain cargo builds use the dev cargo profile, which includes\n            // debug info by default.\n        }\n        BuildProfile::Custom(arg) => {\n            cmd.arg(\"--profile\").arg(arg);\n        }\n    }\n\n    // If user has specified a custom --target in Cargo options, we shouldn't override it.\n    // Otherwise, default to wasm32-unknown-unknown.\n    cmd.env(\"CARGO_BUILD_TARGET\", \"wasm32-unknown-unknown\");\n\n    // The `cargo` command is executed inside the directory at `path`, so relative paths set via extra options won't work.\n    // To remedy the situation, all detected paths are converted to absolute paths.\n    let mut handle_path = false;\n    let extra_options_with_absolute_paths = extra_options\n        .iter()\n        .map(|option| -> Result<String> {\n            let value = if handle_path && Path::new(option).is_relative() {\n                std::env::current_dir()?\n                    .join(option)\n                    .to_str()\n                    .ok_or_else(|| anyhow!(\"path contains non-UTF-8 characters\"))?\n                    .to_string()\n            } else {\n                option.to_string()\n            };\n            handle_path = matches!(&**option, \"--target-dir\" | \"--out-dir\" | \"--manifest-path\");\n            Ok(value)\n        })\n        .collect::<Result<Vec<_>>>()?;\n    cmd.args(extra_options_with_absolute_paths);\n\n    cmd.arg(\"--message-format=json\");\n\n    let mut cargo_process = cmd.stdout(Stdio::piped()).spawn()?;\n\n    let final_artifact =\n        Message::parse_stream(BufReader::new(cargo_process.stdout.as_mut().unwrap()))\n            .filter_map(|msg| {\n                match msg {\n                    Ok(Message::CompilerArtifact(artifact)) => return Some(artifact),\n                    Ok(Message::CompilerMessage(msg)) => eprintln!(\"{msg}\"),\n                    Ok(Message::TextLine(text)) => eprintln!(\"{text}\"),\n                    Err(err) => log::error!(\"Couldn't parse cargo message: {err}\"),\n                    _ => {} // ignore messages irrelevant to the user\n                }\n                None\n            })\n            .last();\n\n    if !cargo_process\n        .wait()\n        .context(\"Failed to wait for cargo build process\")?\n        .success()\n    {\n        bail!(\"`cargo build` failed, see the output above for details\");\n    }\n\n    let wasm_files: Vec<_> = final_artifact\n        .context(\"Expected at least one compiler artifact in the output of `cargo build`\")?\n        .filenames\n        .into_iter()\n        .filter(|path| path.extension() == Some(\"wasm\"))\n        .collect();\n\n    match <[_; 1]>::try_from(wasm_files) {\n        Ok([filename]) => Ok(filename.into_string()),\n        Err(filenames) => {\n            bail!(\n                \"Expected exactly one .wasm file in the compiler artifact, but found {filenames:?}\"\n            )\n        }\n    }\n}\n\n/// Runs `cargo build --tests` targeting `wasm32-unknown-unknown`.\n///\n/// This generates the `Cargo.lock` file that we use in order to know which version of\n/// wasm-bindgen-cli to use when running tests.\n///\n/// Note that the command to build tests and the command to run tests must use the same parameters, i.e. features to be\n/// disabled / enabled must be consistent for both `cargo build` and `cargo test`.\n///\n/// # Parameters\n///\n/// * `path`: Path to the crate directory to build tests.\n/// * `debug`: Whether to build tests in `debug` mode.\n/// * `extra_options`: Additional parameters to pass to `cargo` when building tests.\npub fn cargo_build_wasm_tests(path: &Path, debug: bool, extra_options: &[String]) -> Result<()> {\n    let mut cmd = Command::new(\"cargo\");\n\n    cmd.current_dir(path).arg(\"build\").arg(\"--tests\");\n\n    if PBAR.quiet() {\n        cmd.arg(\"--quiet\");\n    }\n\n    if !debug {\n        cmd.arg(\"--release\");\n    }\n\n    cmd.env(\"CARGO_BUILD_TARGET\", \"wasm32-unknown-unknown\");\n\n    cmd.args(extra_options);\n\n    child::run(cmd, \"cargo build\").context(\"Compilation of your program failed\")?;\n    Ok(())\n}\n"
  },
  {
    "path": "src/build/wasm_target.rs",
    "content": "//! Checking for the wasm32 target\n\nuse crate::child;\nuse crate::emoji;\nuse crate::PBAR;\nuse anyhow::{anyhow, bail, Context, Result};\nuse log::error;\nuse log::info;\nuse std::fmt;\nuse std::path::PathBuf;\nuse std::process::Command;\n\nstruct Wasm32Check<'target> {\n    target: &'target str,\n    rustc_path: PathBuf,\n    sysroot: PathBuf,\n    found: bool,\n    is_rustup: bool,\n}\n\nimpl fmt::Display for Wasm32Check<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        if !self.found {\n            let rustup_string = if self.is_rustup {\n                \"It looks like Rustup is being used.\".to_owned()\n            } else {\n                format!(\"It looks like Rustup is not being used. For non-Rustup setups, the {} target needs to be installed manually. See https://drager.github.io/wasm-pack/book/prerequisites/non-rustup-setups.html on how to do this.\", self.target)\n            };\n\n            writeln!(\n                f,\n                \"{} target not found in sysroot: {:?}\",\n                self.target, self.sysroot\n            )\n            .and_then(|_| {\n                writeln!(\n                    f,\n                    \"\\nUsed rustc from the following path: {:?}\",\n                    self.rustc_path\n                )\n            })\n            .and_then(|_| writeln!(f, \"{}\", rustup_string))\n        } else {\n            write!(\n                f,\n                \"sysroot: {:?}, rustc path: {:?}, was found: {}, isRustup: {}\",\n                self.sysroot, self.rustc_path, self.found, self.is_rustup\n            )\n        }\n    }\n}\n\n/// Ensure that `rustup` has the requested target installed for\n/// current toolchain\npub fn check_for_wasm_target(target: &str) -> Result<()> {\n    let msg = format!(\"{}Checking for the Wasm target...\", emoji::TARGET);\n    PBAR.info(&msg);\n\n    // Check if wasm32 target is present, otherwise bail.\n    match check_target(target) {\n        Ok(ref wasm32_check) if wasm32_check.found => Ok(()),\n        Ok(wasm32_check) => bail!(\"{}\", wasm32_check),\n        Err(err) => Err(err),\n    }\n}\n\n/// Get rustc's sysroot as a PathBuf\nfn get_rustc_sysroot() -> Result<PathBuf> {\n    let command = Command::new(\"rustc\")\n        .args(&[\"--print\", \"sysroot\"])\n        .output()?;\n\n    if command.status.success() {\n        Ok(String::from_utf8(command.stdout)?.trim().into())\n    } else {\n        Err(anyhow!(\n            \"Getting rustc's sysroot wasn't successful. Got {}\",\n            command.status\n        ))\n    }\n}\n\n/// Get target libdir\nfn get_rustc_target_libdir(target: &str) -> Result<PathBuf> {\n    let command = Command::new(\"rustc\")\n        .args(&[\"--target\", target, \"--print\", \"target-libdir\"])\n        .output()?;\n\n    if command.status.success() {\n        Ok(String::from_utf8(command.stdout)?.trim().into())\n    } else {\n        Err(anyhow!(\n            \"Getting rustc's {target} target wasn't successful. Got {}\",\n            command.status\n        ))\n    }\n}\n\nfn does_target_libdir_exist(target: &str) -> bool {\n    let result = get_rustc_target_libdir(target);\n\n    match result {\n        Ok(target_libdir_path) => {\n            if target_libdir_path.exists() {\n                info!(\"Found {target} in {:?}\", target_libdir_path);\n                true\n            } else {\n                info!(\"Failed to find {target} in {:?}\", target_libdir_path);\n                false\n            }\n        }\n        Err(_) => {\n            error!(\"Some error in getting the target libdir!\");\n            false\n        }\n    }\n}\n\nfn check_target(target: &'_ str) -> Result<Wasm32Check<'_>> {\n    let sysroot = get_rustc_sysroot()?;\n    let rustc_path = which::which(\"rustc\")?;\n\n    if does_target_libdir_exist(target) {\n        Ok(Wasm32Check {\n            target,\n            rustc_path,\n            sysroot,\n            found: true,\n            is_rustup: false,\n        })\n    // If it doesn't exist, then we need to check if we're using rustup.\n    } else {\n        // If sysroot contains \"rustup\", then we can assume we're using rustup\n        // and use rustup to add the requested target.\n        if sysroot.to_string_lossy().contains(\"rustup\") {\n            rustup_add_wasm_target(target).map(|()| Wasm32Check {\n                target,\n                rustc_path,\n                sysroot,\n                found: true,\n                is_rustup: true,\n            })\n        } else {\n            Ok(Wasm32Check {\n                target,\n                rustc_path,\n                sysroot,\n                found: false,\n                is_rustup: false,\n            })\n        }\n    }\n}\n\n/// Add target using `rustup`.\nfn rustup_add_wasm_target(target: &str) -> Result<()> {\n    let mut cmd = Command::new(\"rustup\");\n    cmd.arg(\"target\").arg(\"add\").arg(target);\n    child::run(cmd, \"rustup\").with_context(|| format!(\"Adding the {target} target with rustup\"))?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/cache.rs",
    "content": "//! Getting and configuring wasm-pack's binary cache.\n\nuse anyhow::Result;\nuse binary_install::Cache;\nuse std::env;\nuse std::path::Path;\n\n/// Get wasm-pack's binary cache.\npub fn get_wasm_pack_cache() -> Result<Cache> {\n    if let Ok(path) = env::var(\"WASM_PACK_CACHE\") {\n        Ok(Cache::at(Path::new(&path)))\n    } else {\n        Cache::new(\"wasm-pack\")\n    }\n}\n"
  },
  {
    "path": "src/child.rs",
    "content": "//! Utilities for managing child processes.\n//!\n//! This module helps us ensure that all child processes that we spawn get\n//! properly logged and their output is logged as well.\n\nuse anyhow::{bail, Result};\nuse log::info;\nuse std::process::{Command, Stdio};\n\n/// Return a new Command object\npub fn new_command(program: &str) -> Command {\n    // On Windows, initializes launching <program> as `cmd /c <program>`.\n    // Initializing only with `Command::new(\"npm\")` will launch\n    //   `npm` with quotes, `\"npm\"`, causing a run-time error on Windows.\n    // See rustc: #42436, #42791, #44542\n\n    if cfg!(windows) {\n        let mut cmd = Command::new(\"cmd\");\n        cmd.arg(\"/c\").arg(program);\n        cmd\n    } else {\n        Command::new(program)\n    }\n}\n\n/// Run the given command and return on success.\npub fn run(mut command: Command, command_name: &str) -> Result<()> {\n    info!(\"Running {:?}\", command);\n\n    let status = command.status()?;\n\n    if status.success() {\n        Ok(())\n    } else {\n        bail!(\n            \"failed to execute `{}`: exited with {}\\n  full command: {:?}\",\n            command_name,\n            status,\n            command,\n        )\n    }\n}\n\n/// Run the given command and return its stdout.\npub fn run_capture_stdout(\n    mut command: Command,\n    command_name: impl std::fmt::Display,\n) -> Result<String> {\n    info!(\"Running {:?}\", command);\n\n    let output = command\n        .stderr(Stdio::inherit())\n        .stdin(Stdio::inherit())\n        .output()?;\n\n    if output.status.success() {\n        Ok(String::from_utf8_lossy(&output.stdout).into_owned())\n    } else {\n        bail!(\n            \"failed to execute `{}`: exited with {}\\n  full command: {:?}\",\n            command_name,\n            output.status,\n            command,\n        )\n    }\n}\n"
  },
  {
    "path": "src/command/build.rs",
    "content": "//! Implementation of the `wasm-pack build` command.\n\nuse crate::bindgen;\nuse crate::build;\nuse crate::cache;\nuse crate::command::utils::{create_pkg_dir, get_crate_path};\nuse crate::emoji;\nuse crate::install::{self, InstallMode, Tool};\nuse crate::license;\nuse crate::lockfile::Lockfile;\nuse crate::manifest;\nuse crate::readme;\nuse crate::wasm_opt;\nuse crate::PBAR;\nuse anyhow::{anyhow, bail, Error, Result};\nuse binary_install::Cache;\nuse clap::Args;\nuse log::info;\nuse path_clean::PathClean;\nuse std::fmt;\nuse std::path::PathBuf;\nuse std::str::FromStr;\nuse std::time::Instant;\n\n/// Everything required to configure and run the `wasm-pack build` command.\n#[allow(missing_docs)]\npub struct Build {\n    pub crate_path: PathBuf,\n    pub crate_data: manifest::CrateData,\n    pub scope: Option<String>,\n    pub disable_dts: bool,\n    pub weak_refs: bool,\n    pub reference_types: bool,\n    pub target: Target,\n    pub no_pack: bool,\n    pub no_opt: bool,\n    pub profile: BuildProfile,\n    pub mode: InstallMode,\n    pub out_dir: PathBuf,\n    pub out_name: Option<String>,\n    pub bindgen: Option<install::Status>,\n    pub cache: Cache,\n    pub extra_options: Vec<String>,\n    target_triple: String,\n    wasm_path: Option<String>,\n}\n\n/// What sort of output we're going to be generating and flags we're invoking\n/// `wasm-bindgen` with.\n#[derive(Clone, Copy, Debug)]\npub enum Target {\n    /// Default output mode or `--target bundler`, indicates output will be\n    /// used with a bundle in a later step.\n    Bundler,\n    /// Correspond to `--target web` where the output is natively usable as an\n    /// ES module in a browser and the wasm is manually instantiated.\n    Web,\n    /// Correspond to `--target nodejs` where the output is natively usable as\n    /// a Node.js module loaded with `require`.\n    Nodejs,\n    /// Correspond to `--target no-modules` where the output is natively usable\n    /// in a browser but pollutes the global namespace and must be manually\n    /// instantiated.\n    NoModules,\n    /// Correspond to `--target deno` where the output is natively usable as\n    /// a Deno module loaded with `import`.\n    Deno,\n}\n\nimpl Default for Target {\n    fn default() -> Target {\n        Target::Bundler\n    }\n}\n\nimpl fmt::Display for Target {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let s = match self {\n            Target::Bundler => \"bundler\",\n            Target::Web => \"web\",\n            Target::Nodejs => \"nodejs\",\n            Target::NoModules => \"no-modules\",\n            Target::Deno => \"deno\",\n        };\n        write!(f, \"{}\", s)\n    }\n}\n\nimpl FromStr for Target {\n    type Err = Error;\n    fn from_str(s: &str) -> Result<Self> {\n        match s {\n            \"bundler\" | \"browser\" => Ok(Target::Bundler),\n            \"web\" => Ok(Target::Web),\n            \"nodejs\" => Ok(Target::Nodejs),\n            \"no-modules\" => Ok(Target::NoModules),\n            \"deno\" => Ok(Target::Deno),\n            _ => bail!(\"Unknown target: {}\", s),\n        }\n    }\n}\n\n/// The build profile controls whether optimizations, debug info, and assertions\n/// are enabled or disabled.\n#[derive(Clone, Debug)]\npub enum BuildProfile {\n    /// Enable assertions and debug info. Disable optimizations.\n    Dev,\n    /// Enable optimizations. Disable assertions and debug info.\n    Release,\n    /// Enable optimizations and debug info. Disable assertions.\n    Profiling,\n    /// User-defined profile with --profile flag\n    Custom(String),\n}\n\n/// Everything required to configure and run the `wasm-pack build` command.\n#[derive(Debug, Args)]\n#[command(allow_hyphen_values = true, trailing_var_arg = true)]\npub struct BuildOptions {\n    /// The path to the Rust crate. If not set, searches up the path from the current directory.\n    #[clap()]\n    pub path: Option<PathBuf>,\n\n    /// The npm scope to use in package.json, if any.\n    #[clap(long = \"scope\", short = 's')]\n    pub scope: Option<String>,\n\n    #[clap(long = \"mode\", short = 'm', default_value = \"normal\")]\n    /// Sets steps to be run. [possible values: no-install, normal, force]\n    pub mode: InstallMode,\n\n    #[clap(long = \"no-typescript\")]\n    /// By default a *.d.ts file is generated for the generated JS file, but\n    /// this flag will disable generating this TypeScript file.\n    pub disable_dts: bool,\n\n    #[clap(long = \"weak-refs\")]\n    /// Enable usage of the JS weak references proposal.\n    pub weak_refs: bool,\n\n    #[clap(long = \"reference-types\")]\n    /// Enable usage of WebAssembly reference types.\n    pub reference_types: bool,\n\n    #[clap(long = \"target\", short = 't', default_value = \"bundler\")]\n    /// Sets the target environment. [possible values: bundler, nodejs, web, no-modules, deno]\n    pub target: Target,\n\n    #[clap(long = \"debug\")]\n    /// Deprecated. Renamed to `--dev`.\n    pub debug: bool,\n\n    #[clap(long = \"dev\")]\n    /// Create a development build. Enable debug info, and disable\n    /// optimizations.\n    pub dev: bool,\n\n    #[clap(long = \"release\")]\n    /// Create a release build. Enable optimizations and disable debug info.\n    pub release: bool,\n\n    #[clap(long = \"profiling\")]\n    /// Create a profiling build. Enable optimizations and debug info.\n    pub profiling: bool,\n\n    #[clap(long = \"profile\")]\n    /// User-defined profile with --profile flag\n    pub profile: Option<String>,\n\n    #[clap(long = \"out-dir\", short = 'd', default_value = \"pkg\")]\n    /// Sets the output directory with a relative path.\n    pub out_dir: String,\n\n    #[clap(long = \"out-name\")]\n    /// Sets the output file names. Defaults to package name.\n    pub out_name: Option<String>,\n\n    #[clap(long = \"no-pack\", alias = \"no-package\")]\n    /// Option to not generate a package.json\n    pub no_pack: bool,\n\n    #[clap(long = \"no-opt\", alias = \"no-optimization\")]\n    /// Option to skip optimization with wasm-opt\n    pub no_opt: bool,\n\n    /// List of extra options to pass to `cargo build`\n    pub extra_options: Vec<String>,\n}\n\nimpl Default for BuildOptions {\n    fn default() -> Self {\n        Self {\n            path: None,\n            scope: None,\n            mode: InstallMode::default(),\n            disable_dts: false,\n            weak_refs: false,\n            reference_types: false,\n            target: Target::default(),\n            debug: false,\n            dev: false,\n            no_pack: false,\n            no_opt: false,\n            release: false,\n            profiling: false,\n            profile: None,\n            out_dir: String::new(),\n            out_name: None,\n            extra_options: Vec::new(),\n        }\n    }\n}\n\ntype BuildStep = fn(&mut Build) -> Result<()>;\n\nimpl Build {\n    /// Construct a build command from the given options.\n    pub fn try_from_opts(mut build_opts: BuildOptions) -> Result<Self> {\n        if let Some(path) = &build_opts.path {\n            if path.to_string_lossy().starts_with(\"--\") {\n                let path = build_opts.path.take().unwrap();\n                build_opts\n                    .extra_options\n                    .insert(0, path.to_string_lossy().into_owned());\n            }\n        }\n        let crate_path = get_crate_path(build_opts.path)?;\n        let crate_data = manifest::CrateData::new(&crate_path, build_opts.out_name.clone())?;\n        let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir)).clean();\n\n        let dev = build_opts.dev || build_opts.debug;\n        let profile = match (\n            dev,\n            build_opts.release,\n            build_opts.profiling,\n            build_opts.profile,\n        ) {\n            (false, false, false, None) | (false, true, false, None) => BuildProfile::Release,\n            (true, false, false, None) => BuildProfile::Dev,\n            (false, false, true, None) => BuildProfile::Profiling,\n            (false, false, false, Some(profile)) => BuildProfile::Custom(profile),\n            // Unfortunately, `clap` doesn't expose clap's `conflicts_with`\n            // functionality yet, so we have to implement it ourselves.\n            _ => bail!(\"Can only supply one of the --dev, --release, --profiling, or --profile 'name' flags\"),\n        };\n\n        let extra_options = build_opts.extra_options;\n\n        let target_triple = {\n            let mut extra_options_iter = extra_options.iter();\n            if extra_options_iter\n                .by_ref()\n                .any(|option| option == \"--target\")\n            {\n                extra_options_iter.next().map(|s| s.as_str())\n            } else {\n                None\n            }\n            .unwrap_or(\"wasm32-unknown-unknown\")\n        };\n\n        Ok(Build {\n            crate_path,\n            crate_data,\n            scope: build_opts.scope,\n            disable_dts: build_opts.disable_dts,\n            weak_refs: build_opts.weak_refs,\n            reference_types: build_opts.reference_types,\n            target: build_opts.target,\n            no_pack: build_opts.no_pack,\n            no_opt: build_opts.no_opt,\n            profile,\n            mode: build_opts.mode,\n            out_dir,\n            out_name: build_opts.out_name,\n            bindgen: None,\n            cache: cache::get_wasm_pack_cache()?,\n            target_triple: target_triple.to_owned(),\n            extra_options,\n            wasm_path: None,\n        })\n    }\n\n    /// Configures the global binary cache used for this build\n    pub fn set_cache(&mut self, cache: Cache) {\n        self.cache = cache;\n    }\n\n    /// Execute this `Build` command.\n    pub fn run(&mut self) -> Result<()> {\n        let process_steps = Build::get_process_steps(self.mode, self.no_pack, self.no_opt);\n\n        let started = Instant::now();\n\n        for (_, process_step) in process_steps {\n            process_step(self)?;\n        }\n\n        let duration = crate::command::utils::elapsed(started.elapsed());\n        info!(\"Done in {}.\", &duration);\n        info!(\n            \"Your wasm pkg is ready to publish at {}.\",\n            self.out_dir.display()\n        );\n\n        PBAR.info(&format!(\"{} Done in {}\", emoji::SPARKLE, &duration));\n\n        PBAR.info(&format!(\n            \"{} Your wasm pkg is ready to publish at {}.\",\n            emoji::PACKAGE,\n            self.out_dir.display()\n        ));\n        Ok(())\n    }\n\n    fn get_process_steps(\n        mode: InstallMode,\n        no_pack: bool,\n        no_opt: bool,\n    ) -> Vec<(&'static str, BuildStep)> {\n        macro_rules! steps {\n            ($($name:ident),+) => {\n                {\n                let mut steps: Vec<(&'static str, BuildStep)> = Vec::new();\n                    $(steps.push((stringify!($name), Build::$name));)*\n                        steps\n                    }\n                };\n            ($($name:ident,)*) => (steps![$($name),*])\n        }\n        let mut steps = Vec::new();\n        match &mode {\n            InstallMode::Force => {}\n            _ => {\n                steps.extend(steps![\n                    step_check_rustc_version,\n                    step_check_crate_config,\n                    step_check_for_wasm_target,\n                ]);\n            }\n        }\n\n        steps.extend(steps![\n            step_build_wasm,\n            step_create_dir,\n            step_install_wasm_bindgen,\n            step_run_wasm_bindgen,\n        ]);\n\n        if !no_opt {\n            steps.extend(steps![step_run_wasm_opt]);\n        }\n\n        if !no_pack {\n            steps.extend(steps![\n                step_create_json,\n                step_copy_readme,\n                step_copy_license,\n            ]);\n        }\n\n        steps\n    }\n\n    fn step_check_rustc_version(&mut self) -> Result<()> {\n        info!(\"Checking rustc version...\");\n        let version = build::check_rustc_version()?;\n        let msg = format!(\"rustc version is {}.\", version);\n        info!(\"{}\", &msg);\n        Ok(())\n    }\n\n    fn step_check_crate_config(&mut self) -> Result<()> {\n        info!(\"Checking crate configuration...\");\n        self.crate_data.check_crate_config()?;\n        info!(\"Crate is correctly configured.\");\n        Ok(())\n    }\n\n    fn step_check_for_wasm_target(&mut self) -> Result<()> {\n        info!(\"Checking for wasm-target...\");\n        build::wasm_target::check_for_wasm_target(&self.target_triple)?;\n        info!(\"Checking for wasm-target was successful.\");\n        Ok(())\n    }\n\n    fn step_build_wasm(&mut self) -> Result<()> {\n        info!(\"Building wasm...\");\n        let wasm_path =\n            build::cargo_build_wasm(&self.crate_path, self.profile.clone(), &self.extra_options)?;\n        info!(\"wasm built at {wasm_path:#?}.\");\n        self.wasm_path = Some(wasm_path);\n        Ok(())\n    }\n\n    fn step_create_dir(&mut self) -> Result<()> {\n        info!(\"Creating a pkg directory...\");\n        create_pkg_dir(&self.out_dir)?;\n        info!(\"Created a pkg directory at {:#?}.\", &self.crate_path);\n        Ok(())\n    }\n\n    fn step_create_json(&mut self) -> Result<()> {\n        self.crate_data.write_package_json(\n            &self.out_dir,\n            &self.scope,\n            self.disable_dts,\n            self.target,\n        )?;\n        info!(\n            \"Wrote a package.json at {:#?}.\",\n            &self.out_dir.join(\"package.json\")\n        );\n        Ok(())\n    }\n\n    fn step_copy_readme(&mut self) -> Result<()> {\n        info!(\"Copying readme from crate...\");\n        readme::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;\n        info!(\"Copied readme from crate to {:#?}.\", &self.out_dir);\n        Ok(())\n    }\n\n    fn step_copy_license(&mut self) -> Result<()> {\n        info!(\"Copying license from crate...\");\n        license::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;\n        info!(\"Copied license from crate to {:#?}.\", &self.out_dir);\n        Ok(())\n    }\n\n    fn step_install_wasm_bindgen(&mut self) -> Result<()> {\n        info!(\"Identifying wasm-bindgen dependency...\");\n        let lockfile = Lockfile::new(&self.crate_data)?;\n        let bindgen_version = lockfile.require_wasm_bindgen()?;\n        info!(\"Installing wasm-bindgen-cli...\");\n        let bindgen = install::download_prebuilt_or_cargo_install(\n            Tool::WasmBindgen,\n            &self.cache,\n            bindgen_version,\n            self.mode.install_permitted(),\n        )?;\n        self.bindgen = Some(bindgen);\n        info!(\"Installing wasm-bindgen-cli was successful.\");\n        Ok(())\n    }\n\n    fn step_run_wasm_bindgen(&mut self) -> Result<()> {\n        info!(\"Building the wasm bindings...\");\n        bindgen::wasm_bindgen_build(\n            self.wasm_path.as_ref().unwrap(),\n            &self.crate_data,\n            self.bindgen.as_ref().unwrap(),\n            &self.out_dir,\n            &self.out_name,\n            self.disable_dts,\n            self.weak_refs,\n            self.reference_types,\n            self.target,\n            self.profile.clone(),\n        )?;\n        info!(\"wasm bindings were built at {:#?}.\", &self.out_dir);\n        Ok(())\n    }\n\n    fn step_run_wasm_opt(&mut self) -> Result<()> {\n        let mut args = match self\n            .crate_data\n            .configured_profile(self.profile.clone())\n            .wasm_opt_args()\n        {\n            Some(args) => args,\n            None => return Ok(()),\n        };\n        if self.reference_types {\n            args.push(\"--enable-reference-types\".into());\n        }\n        info!(\"executing wasm-opt with {:?}\", args);\n        wasm_opt::run(\n            &self.cache,\n            &self.out_dir,\n            &args,\n            self.mode.install_permitted(),\n        ).map_err(|e| {\n            anyhow!(\n                \"{}\\nTo disable `wasm-opt`, add `wasm-opt = false` to your package metadata in your `Cargo.toml`.\", e\n            )\n        })\n    }\n}\n"
  },
  {
    "path": "src/command/generate.rs",
    "content": "use crate::cache;\nuse crate::generate;\nuse crate::install::{self, Tool};\nuse crate::PBAR;\nuse anyhow::Result;\nuse log::info;\n\n/// Executes the 'cargo-generate' command in the current directory\n/// which generates a new rustwasm project from a template.\npub fn generate(template: String, name: String, install_permitted: bool) -> Result<()> {\n    info!(\"Generating a new rustwasm project...\");\n    let download = install::download_prebuilt_or_cargo_install(\n        Tool::CargoGenerate,\n        &cache::get_wasm_pack_cache()?,\n        \"latest\",\n        install_permitted,\n    )?;\n    generate::generate(&template, &name, &download)?;\n\n    let msg = format!(\"🐑 Generated new project at /{}\", name);\n    PBAR.info(&msg);\n    Ok(())\n}\n"
  },
  {
    "path": "src/command/login.rs",
    "content": "use crate::npm;\nuse crate::PBAR;\nuse anyhow::Result;\nuse log::info;\n\npub fn login(\n    registry: Option<String>,\n    scope: &Option<String>,\n    auth_type: &Option<String>,\n) -> Result<()> {\n    let registry = registry.unwrap_or_else(|| npm::DEFAULT_NPM_REGISTRY.to_string());\n\n    info!(\"Logging in to npm...\");\n    info!(\n        \"Scope: {:?} Registry: {}, Auth Type: {:?}.\",\n        &scope, &registry, &auth_type\n    );\n    info!(\"npm info located in the npm debug log\");\n    npm::npm_login(&registry, &scope, &auth_type)?;\n    info!(\"Logged you in!\");\n\n    PBAR.info(&\"👋  logged you in!\".to_string());\n    Ok(())\n}\n"
  },
  {
    "path": "src/command/mod.rs",
    "content": "//! CLI command structures, parsing, and execution.\n#![allow(clippy::redundant_closure)]\n\npub mod build;\nmod generate;\nmod login;\nmod pack;\n/// Data structures and functions for publishing a package.\npub mod publish;\npub mod test;\npub mod utils;\n\nuse self::build::{Build, BuildOptions};\nuse self::generate::generate;\nuse self::login::login;\nuse self::pack::pack;\nuse self::publish::{access::Access, publish};\nuse self::test::{Test, TestOptions};\nuse crate::install::InstallMode;\nuse anyhow::Result;\nuse clap::Subcommand;\nuse log::info;\nuse std::path::PathBuf;\n/// The various kinds of commands that `wasm-pack` can execute.\n#[derive(Debug, Subcommand)]\npub enum Command {\n    /// 🏗️  build your npm package!\n    #[clap(name = \"build\", alias = \"init\")]\n    Build(BuildOptions),\n\n    #[clap(name = \"pack\")]\n    /// 🍱  create a tar of your npm package but don't publish!\n    Pack {\n        #[clap(long = \"pkg-dir\", short = 'd', default_value = \"pkg\")]\n        /// The name of the output directory where the npm package is stored\n        pkg_directory: PathBuf,\n\n        /// The path to the Rust crate. If not set, searches up the path from the current directory.\n        #[clap()]\n        path: Option<PathBuf>,\n    },\n\n    #[clap(name = \"new\")]\n    /// 🐑 create a new project with a template\n    Generate {\n        /// The name of the project\n        name: String,\n        /// The URL to the template\n        #[clap(\n            long = \"template\",\n            default_value = \"https://github.com/drager/wasm-pack-template\"\n        )]\n        template: String,\n        #[clap(long = \"mode\", short = 'm', default_value = \"normal\")]\n        /// Should we install or check the presence of binary tools. [possible values: no-install, normal, force]\n        mode: InstallMode,\n    },\n\n    #[clap(name = \"publish\")]\n    /// 🎆  pack up your npm package and publish!\n    Publish {\n        #[clap(long = \"target\", short = 't', default_value = \"bundler\")]\n        /// Sets the target environment. [possible values: bundler, nodejs, web, no-modules]\n        target: String,\n\n        /// The access level for the package to be published\n        #[clap(long = \"access\", short = 'a')]\n        access: Option<Access>,\n\n        /// The distribution tag being used for publishing.\n        /// See https://docs.npmjs.com/cli/dist-tag\n        #[clap(long = \"tag\")]\n        tag: Option<String>,\n\n        #[clap(long = \"pkg-dir\", short = 'd', default_value = \"pkg\")]\n        /// The name of the output directory where the npm package is stored\n        pkg_directory: PathBuf,\n\n        /// The path to the Rust crate. If not set, searches up the path from the current directory.\n        #[clap()]\n        path: Option<PathBuf>,\n    },\n\n    #[clap(name = \"login\", alias = \"adduser\", alias = \"add-user\")]\n    /// 👤  Add an npm registry user account! (aliases: adduser, add-user)\n    Login {\n        #[clap(long = \"registry\", short = 'r')]\n        /// Default: 'https://registry.npmjs.org/'.\n        /// The base URL of the npm package registry. If scope is also\n        /// specified, this registry will only be used for packages with that\n        /// scope. scope defaults to the scope of the project directory you're\n        /// currently in, if any.\n        registry: Option<String>,\n\n        #[clap(long = \"scope\", short = 's')]\n        /// Default: none.\n        /// If specified, the user and login credentials given will be\n        /// associated with the specified scope.\n        scope: Option<String>,\n\n        #[clap(long = \"auth-type\", short = 't')]\n        /// Default: 'legacy'.\n        /// Type: 'legacy', 'sso', 'saml', 'oauth'.\n        /// What authentication strategy to use with adduser/login. Some npm\n        /// registries (for example, npmE) might support alternative auth\n        /// strategies besides classic username/password entry in legacy npm.\n        auth_type: Option<String>,\n    },\n\n    #[clap(name = \"test\")]\n    /// 👩‍🔬  test your wasm!\n    Test(TestOptions),\n}\n\n/// Run a command with the given logger!\npub fn run_wasm_pack(command: Command) -> Result<()> {\n    // Run the correct command based off input and store the result of it so that we can clear\n    // the progress bar then return it\n    match command {\n        Command::Build(build_opts) => {\n            info!(\"Running build command...\");\n            Build::try_from_opts(build_opts).and_then(|mut b| b.run())\n        }\n        Command::Pack {\n            path,\n            pkg_directory,\n        } => {\n            info!(\"Running pack command...\");\n            info!(\"Path: {:?}\", &path);\n            pack(path, pkg_directory)\n        }\n        Command::Generate {\n            template,\n            name,\n            mode,\n        } => {\n            info!(\"Running generate command...\");\n            info!(\"Template: {:?}\", &template);\n            info!(\"Name: {:?}\", &name);\n            generate(template, name, mode.install_permitted())\n        }\n        Command::Publish {\n            target,\n            path,\n            access,\n            tag,\n            pkg_directory,\n        } => {\n            info!(\"Running publish command...\");\n            info!(\"Path: {:?}\", &path);\n            publish(&target, path, access, tag, pkg_directory)\n        }\n        Command::Login {\n            registry,\n            scope,\n            auth_type,\n        } => {\n            info!(\"Running login command...\");\n            info!(\n                \"Registry: {:?}, Scope: {:?}, Auth Type: {:?}\",\n                &registry, &scope, &auth_type\n            );\n            login(registry, &scope, &auth_type)\n        }\n        Command::Test(test_opts) => {\n            info!(\"Running test command...\");\n            Test::try_from_opts(test_opts).and_then(|t| t.run())\n        }\n    }\n}\n"
  },
  {
    "path": "src/command/pack.rs",
    "content": "use crate::command::utils::{find_pkg_directory, get_crate_path};\nuse crate::npm;\nuse crate::PBAR;\nuse anyhow::{anyhow, Result};\nuse log::info;\nuse std::path::PathBuf;\n\n/// Executes the 'npm pack' command on the 'pkg' directory\n/// which creates a tarball that can be published to the NPM registry\npub fn pack(path: Option<PathBuf>, pkg_directory: PathBuf) -> Result<()> {\n    let crate_path = get_crate_path(path)?;\n\n    info!(\"Packing up the npm package...\");\n    let pkg_directory = find_pkg_directory(&crate_path, &pkg_directory).ok_or_else(|| {\n        anyhow!(\n            \"Unable to find the pkg directory at path {:#?}, or in a child directory of {:#?}\",\n            &crate_path,\n            &crate_path\n        )\n    })?;\n    npm::npm_pack(&pkg_directory.to_string_lossy())?;\n    info!(\n        \"Your package is located at {:#?}\",\n        crate_path.join(pkg_directory)\n    );\n\n    PBAR.info(\"🎒  packed up your package!\");\n    Ok(())\n}\n"
  },
  {
    "path": "src/command/publish/access.rs",
    "content": "use anyhow::{bail, Error, Result};\nuse std::fmt;\nuse std::str::FromStr;\n\n/// Represents access level for the to-be publish package. Passed to `wasm-pack publish` as a flag, e.g. `--access=public`.\n#[derive(Clone, Debug)]\npub enum Access {\n    /// Access is granted to all. All unscoped packages *must* be public.\n    Public,\n    /// Access is restricted, granted via npm permissions. Must be a scoped package.\n    Restricted,\n}\n\nimpl FromStr for Access {\n    type Err = Error;\n\n    fn from_str(s: &str) -> Result<Self> {\n        match s {\n      \"public\" => Ok(Access::Public),\n      \"restricted\" => Ok(Access::Restricted),\n      \"private\" => Ok(Access::Restricted),\n      _ => bail!(\"{} is not a supported access level. See https://docs.npmjs.com/cli/access for more information on npm package access levels.\", s),\n    }\n    }\n}\n\nimpl fmt::Display for Access {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let printable = match *self {\n            Access::Public => \"--access=public\",\n            Access::Restricted => \"--access=restricted\",\n        };\n        write!(f, \"{}\", printable)\n    }\n}\n"
  },
  {
    "path": "src/command/publish/mod.rs",
    "content": "/// Data structure to represent published package access level.\npub mod access;\n\nuse self::access::Access;\nuse crate::command::build::{Build, BuildOptions, Target};\nuse crate::command::utils::{find_pkg_directory, get_crate_path};\nuse crate::npm;\nuse crate::PBAR;\nuse anyhow::{anyhow, bail, Result};\nuse dialoguer::{Confirm, Input, Select};\nuse log::info;\nuse std::path::PathBuf;\nuse std::str::FromStr;\n\n/// Creates a tarball from a 'pkg' directory\n/// and publishes it to the NPM registry\npub fn publish(\n    _target: &str,\n    path: Option<PathBuf>,\n    access: Option<Access>,\n    tag: Option<String>,\n    pkg_directory: PathBuf,\n) -> Result<()> {\n    let crate_path = get_crate_path(path)?;\n\n    info!(\"Publishing the npm package...\");\n    info!(\"npm info located in the npm debug log\");\n\n    let pkg_directory = match find_pkg_directory(&crate_path, &pkg_directory) {\n        Some(path) => Ok(path),\n        None => {\n            // while `wasm-pack publish`, if the pkg directory cannot be found,\n            // then try to `wasm-pack build`\n            if Confirm::new()\n                .with_prompt(\"Your package hasn't been built, build it?\")\n                .interact()?\n            {\n                let out_dir = Input::new()\n                    .with_prompt(\"out_dir[default: pkg]\")\n                    .default(\".\".to_string())\n                    .show_default(false)\n                    .interact()?;\n                let out_dir = format!(\"{}/pkg\", out_dir);\n                let target = Select::new()\n                    .with_prompt(\"target[default: bundler]\")\n                    .items(&[\"bundler\", \"nodejs\", \"web\", \"no-modules\"])\n                    .default(0)\n                    .interact()?\n                    .to_string();\n                let target = Target::from_str(&target)?;\n                let build_opts = BuildOptions {\n                    path: Some(crate_path.clone()),\n                    target,\n                    out_dir: out_dir.clone(),\n                    ..Default::default()\n                };\n                Build::try_from_opts(build_opts)\n                    .and_then(|mut build| build.run())\n                    .map(|()| crate_path.join(out_dir))\n                    .map_err(|_| {\n                        anyhow!(\n                            \"Unable to find the pkg directory at path '{:#?}',\\\n                             or in a child directory of '{:#?}'\",\n                            &crate_path,\n                            &crate_path\n                        )\n                    })\n            } else {\n                bail!(\n                    \"Unable to find the pkg directory at path '{:#?}',\\\n                     or in a child directory of '{:#?}'\",\n                    &crate_path,\n                    &crate_path\n                )\n            }\n        }\n    }?;\n    npm::npm_publish(&pkg_directory.to_string_lossy(), access, tag)?;\n    info!(\"Published your package!\");\n\n    PBAR.info(\"💥  published your package!\");\n    Ok(())\n}\n"
  },
  {
    "path": "src/command/test.rs",
    "content": "//! Implementation of the `wasm-pack test` command.\n\nuse crate::build;\nuse crate::cache;\nuse crate::command::utils::get_crate_path;\nuse crate::install::{self, InstallMode, Tool};\nuse crate::lockfile::Lockfile;\nuse crate::manifest;\nuse crate::test::{self, webdriver};\nuse anyhow::{bail, Result};\nuse binary_install::Cache;\nuse clap::Args;\nuse console::style;\nuse log::info;\nuse std::path::PathBuf;\nuse std::str::FromStr;\nuse std::time::Instant;\n\n#[derive(Debug, Default, Args)]\n#[command(allow_hyphen_values = true, trailing_var_arg = true)]\n/// Everything required to configure the `wasm-pack test` command.\npub struct TestOptions {\n    #[clap(long = \"node\")]\n    /// Run the tests in Node.js.\n    pub node: bool,\n\n    #[clap(long = \"firefox\")]\n    /// Run the tests in Firefox. This machine must have a Firefox installation.\n    /// If the `geckodriver` WebDriver client is not on the `$PATH`, and not\n    /// specified with `--geckodriver`, then `wasm-pack` will download a local\n    /// copy.\n    pub firefox: bool,\n\n    #[clap(long = \"geckodriver\")]\n    /// The path to the `geckodriver` WebDriver client for testing in\n    /// Firefox. Implies `--firefox`.\n    pub geckodriver: Option<PathBuf>,\n\n    #[clap(long = \"chrome\")]\n    /// Run the tests in Chrome. This machine must have a Chrome installation.\n    /// If the `chromedriver` WebDriver client is not on the `$PATH`, and not\n    /// specified with `--chromedriver`, then `wasm-pack` will download a local\n    /// copy.\n    pub chrome: bool,\n\n    #[clap(long = \"chromedriver\")]\n    /// The path to the `chromedriver` WebDriver client for testing in\n    /// Chrome. Implies `--chrome`.\n    pub chromedriver: Option<PathBuf>,\n\n    #[clap(long = \"safari\")]\n    /// Run the tests in Safari. This machine must have a Safari installation,\n    /// and the `safaridriver` WebDriver client must either be on the `$PATH` or\n    /// specified explicitly with the `--safaridriver` flag. `wasm-pack` cannot\n    /// download the `safaridriver` WebDriver client for you.\n    pub safari: bool,\n\n    #[clap(long = \"safaridriver\")]\n    /// The path to the `safaridriver` WebDriver client for testing in\n    /// Safari. Implies `--safari`.\n    pub safaridriver: Option<PathBuf>,\n\n    #[clap(long = \"headless\")]\n    /// When running browser tests, run the browser in headless mode without any\n    /// UI or windows.\n    pub headless: bool,\n\n    #[clap(long = \"mode\", short = 'm', default_value = \"normal\")]\n    /// Sets steps to be run. [possible values: no-install, normal]\n    pub mode: InstallMode,\n\n    #[clap(long = \"release\", short = 'r')]\n    /// Build with the release profile.\n    pub release: bool,\n\n    /// Path to the Rust crate, and extra options to pass to `cargo test`.\n    ///\n    /// If the path is not provided, this command searches up the path from the current directory.\n    ///\n    /// This is a workaround to allow wasm pack to provide the same command line interface as `cargo`.\n    /// See <https://github.com/drager/wasm-pack/pull/851> for more information.\n    pub path_and_extra_options: Vec<String>,\n}\n\n/// A configured `wasm-pack test` command.\npub struct Test {\n    crate_path: PathBuf,\n    crate_data: manifest::CrateData,\n    cache: Cache,\n    node: bool,\n    mode: InstallMode,\n    firefox: bool,\n    geckodriver: Option<PathBuf>,\n    chrome: bool,\n    chromedriver: Option<PathBuf>,\n    safari: bool,\n    safaridriver: Option<PathBuf>,\n    headless: bool,\n    release: bool,\n    test_runner_path: Option<PathBuf>,\n    extra_options: Vec<String>,\n}\n\ntype TestStep = fn(&mut Test) -> Result<()>;\n\nimpl Test {\n    /// Construct a test command from the given options.\n    pub fn try_from_opts(test_opts: TestOptions) -> Result<Self> {\n        let TestOptions {\n            node,\n            mode,\n            headless,\n            release,\n            chrome,\n            chromedriver,\n            firefox,\n            geckodriver,\n            safari,\n            safaridriver,\n            mut path_and_extra_options,\n        } = test_opts;\n\n        let first_arg_is_path = path_and_extra_options\n            .get(0)\n            .map(|first_arg| !first_arg.starts_with(\"-\"))\n            .unwrap_or(false);\n\n        let (path, extra_options) = if first_arg_is_path {\n            let path = PathBuf::from_str(&path_and_extra_options.remove(0))?;\n            let extra_options = path_and_extra_options;\n\n            (Some(path), extra_options)\n        } else {\n            (None, path_and_extra_options)\n        };\n\n        let crate_path = get_crate_path(path)?;\n        let crate_data = manifest::CrateData::new(&crate_path, None)?;\n        let any_browser = chrome || firefox || safari;\n\n        if !node && !any_browser {\n            bail!(\"Must specify at least one of `--node`, `--chrome`, `--firefox`, or `--safari`\")\n        }\n\n        if headless && !any_browser {\n            bail!(\n                \"The `--headless` flag only applies to browser tests. Node does not provide a UI, \\\n                 so it doesn't make sense to talk about a headless version of Node tests.\"\n            )\n        }\n\n        Ok(Test {\n            cache: cache::get_wasm_pack_cache()?,\n            crate_path,\n            crate_data,\n            node,\n            mode,\n            chrome,\n            chromedriver,\n            firefox,\n            geckodriver,\n            safari,\n            safaridriver,\n            headless,\n            release,\n            test_runner_path: None,\n            extra_options,\n        })\n    }\n\n    /// Configures the cache that this test command uses\n    pub fn set_cache(&mut self, cache: Cache) {\n        self.cache = cache;\n    }\n\n    /// Execute this test command.\n    pub fn run(mut self) -> Result<()> {\n        let process_steps = self.get_process_steps();\n\n        let started = Instant::now();\n        for (_, process_step) in process_steps {\n            process_step(&mut self)?;\n        }\n        let duration = crate::command::utils::elapsed(started.elapsed());\n        info!(\"Done in {}.\", &duration);\n\n        Ok(())\n    }\n\n    fn get_process_steps(&self) -> Vec<(&'static str, TestStep)> {\n        macro_rules! steps {\n            ($($name:ident $(if $e:expr)* ),+) => {\n                {\n                    let mut steps: Vec<(&'static str, TestStep)> = Vec::new();\n                    $(\n                        $(if $e)* {\n                            steps.push((stringify!($name), Test::$name));\n                        }\n                    )*\n                    steps\n                }\n            };\n            ($($name:ident $(if $e:expr)* ,)*) => (steps![$($name $(if $e)* ),*])\n        }\n        match self.mode {\n            InstallMode::Normal => steps![\n                step_check_rustc_version,\n                step_check_for_wasm_target,\n                step_build_tests,\n                step_install_wasm_bindgen,\n                step_test_node if self.node,\n                step_get_chromedriver if self.chrome && self.chromedriver.is_none(),\n                step_test_chrome if self.chrome,\n                step_get_geckodriver if self.firefox && self.geckodriver.is_none(),\n                step_test_firefox if self.firefox,\n                step_get_safaridriver if self.safari && self.safaridriver.is_none(),\n                step_test_safari if self.safari,\n            ],\n            InstallMode::Force => steps![\n                step_check_for_wasm_target,\n                step_build_tests,\n                step_install_wasm_bindgen,\n                step_test_node if self.node,\n                step_get_chromedriver if self.chrome && self.chromedriver.is_none(),\n                step_test_chrome if self.chrome,\n                step_get_geckodriver if self.firefox && self.geckodriver.is_none(),\n                step_test_firefox if self.firefox,\n                step_get_safaridriver if self.safari && self.safaridriver.is_none(),\n                step_test_safari if self.safari,\n            ],\n            InstallMode::Noinstall => steps![\n                step_build_tests,\n                step_install_wasm_bindgen,\n                step_test_node if self.node,\n                step_get_chromedriver if self.chrome && self.chromedriver.is_none(),\n                step_test_chrome if self.chrome,\n                step_get_geckodriver if self.firefox && self.geckodriver.is_none(),\n                step_test_firefox if self.firefox,\n                step_get_safaridriver if self.safari && self.safaridriver.is_none(),\n                step_test_safari if self.safari,\n            ],\n        }\n    }\n\n    fn step_check_rustc_version(&mut self) -> Result<()> {\n        info!(\"Checking rustc version...\");\n        let _ = build::check_rustc_version()?;\n        info!(\"Rustc version is correct.\");\n        Ok(())\n    }\n\n    fn step_check_for_wasm_target(&mut self) -> Result<()> {\n        info!(\"Adding wasm-target...\");\n        build::wasm_target::check_for_wasm_target(\"wasm32-unknown-unknown\")?;\n        info!(\"Adding wasm-target was successful.\");\n        Ok(())\n    }\n\n    fn step_build_tests(&mut self) -> Result<()> {\n        info!(\"Compiling tests to wasm...\");\n\n        // If the user has run `wasm-pack test -- --features \"f1\" -- test_name`, then we want to only pass through\n        // `--features \"f1\"` to `cargo build`\n        let extra_options =\n            if let Some(index) = self.extra_options.iter().position(|arg| arg == \"--\") {\n                &self.extra_options[..index]\n            } else {\n                &self.extra_options\n            };\n        build::cargo_build_wasm_tests(&self.crate_path, !self.release, extra_options)?;\n\n        info!(\"Finished compiling tests to wasm.\");\n        Ok(())\n    }\n\n    fn step_install_wasm_bindgen(&mut self) -> Result<()> {\n        info!(\"Identifying wasm-bindgen dependency...\");\n        let lockfile = Lockfile::new(&self.crate_data)?;\n        let bindgen_version = lockfile.require_wasm_bindgen()?;\n\n        // Unlike `wasm-bindgen` and `wasm-bindgen-cli`, `wasm-bindgen-test`\n        // will work with any semver compatible `wasm-bindgen-cli`, so just make\n        // sure that it is depended upon, so we can run tests on\n        // `wasm32-unkown-unknown`. Don't enforce that it is the same version as\n        // `wasm-bindgen`.\n        if lockfile.wasm_bindgen_test_version().is_none() {\n            bail!(\n                \"Ensure that you have \\\"{}\\\" as a dependency in your Cargo.toml file:\\n\\\n                 [dev-dependencies]\\n\\\n                 wasm-bindgen-test = \\\"0.2\\\"\",\n                style(\"wasm-bindgen-test\").bold().dim(),\n            )\n        }\n\n        let status = install::download_prebuilt_or_cargo_install(\n            Tool::WasmBindgen,\n            &self.cache,\n            &bindgen_version,\n            self.mode.install_permitted(),\n        )?;\n\n        self.test_runner_path = match status {\n            install::Status::Found(dl) => Some(dl.binary(\"wasm-bindgen-test-runner\")?),\n            _ => bail!(\"Could not find 'wasm-bindgen-test-runner'.\"),\n        };\n\n        info!(\"Getting wasm-bindgen-cli was successful.\");\n        Ok(())\n    }\n\n    fn step_test_node(&mut self) -> Result<()> {\n        assert!(self.node);\n        info!(\"Running tests in node...\");\n        test::cargo_test_wasm(\n            &self.crate_path,\n            self.release,\n            vec![\n                (\n                    \"CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER\",\n                    &**self.test_runner_path.as_ref().unwrap(),\n                ),\n                (\"WASM_BINDGEN_TEST_ONLY_NODE\", \"1\".as_ref()),\n            ],\n            &self.extra_options,\n        )?;\n        info!(\"Finished running tests in node.\");\n        Ok(())\n    }\n\n    fn step_get_chromedriver(&mut self) -> Result<()> {\n        assert!(self.chrome && self.chromedriver.is_none());\n\n        self.chromedriver = Some(webdriver::get_or_install_chromedriver(\n            &self.cache,\n            self.mode,\n        )?);\n        Ok(())\n    }\n\n    fn step_test_chrome(&mut self) -> Result<()> {\n        let chromedriver = self.chromedriver.as_ref().unwrap().display().to_string();\n        let chromedriver = chromedriver.as_str();\n        info!(\n            \"Running tests in Chrome with chromedriver at {}\",\n            chromedriver\n        );\n\n        let mut envs = self.webdriver_env();\n        envs.push((\"CHROMEDRIVER\", chromedriver));\n\n        test::cargo_test_wasm(&self.crate_path, self.release, envs, &self.extra_options)?;\n        Ok(())\n    }\n\n    fn step_get_geckodriver(&mut self) -> Result<()> {\n        assert!(self.firefox && self.geckodriver.is_none());\n\n        self.geckodriver = Some(webdriver::get_or_install_geckodriver(\n            &self.cache,\n            self.mode,\n        )?);\n        Ok(())\n    }\n\n    fn step_test_firefox(&mut self) -> Result<()> {\n        let geckodriver = self.geckodriver.as_ref().unwrap().display().to_string();\n        let geckodriver = geckodriver.as_str();\n        info!(\n            \"Running tests in Firefox with geckodriver at {}\",\n            geckodriver\n        );\n\n        let mut envs = self.webdriver_env();\n        envs.push((\"GECKODRIVER\", geckodriver));\n\n        test::cargo_test_wasm(&self.crate_path, self.release, envs, &self.extra_options)?;\n        Ok(())\n    }\n\n    fn step_get_safaridriver(&mut self) -> Result<()> {\n        assert!(self.safari && self.safaridriver.is_none());\n\n        self.safaridriver = Some(webdriver::get_safaridriver()?);\n        Ok(())\n    }\n\n    fn step_test_safari(&mut self) -> Result<()> {\n        let safaridriver = self.safaridriver.as_ref().unwrap().display().to_string();\n        let safaridriver = safaridriver.as_str();\n        info!(\n            \"Running tests in Safari with safaridriver at {}\",\n            safaridriver\n        );\n\n        let mut envs = self.webdriver_env();\n        envs.push((\"SAFARIDRIVER\", safaridriver));\n\n        test::cargo_test_wasm(&self.crate_path, self.release, envs, &self.extra_options)?;\n        Ok(())\n    }\n\n    fn webdriver_env(&self) -> Vec<(&'static str, &str)> {\n        let test_runner = self.test_runner_path.as_ref().unwrap().to_str().unwrap();\n        info!(\"Using wasm-bindgen test runner at {}\", test_runner);\n        let mut envs = vec![\n            (\"CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER\", test_runner),\n            (\"WASM_BINDGEN_TEST_ONLY_WEB\", \"1\"),\n        ];\n        if !self.headless {\n            envs.push((\"NO_HEADLESS\", \"1\"));\n        }\n        envs\n    }\n}\n"
  },
  {
    "path": "src/command/utils.rs",
    "content": "//! Utility functions for commands.\n#![allow(clippy::redundant_closure)]\n\nuse anyhow::Result;\nuse std::fs;\nuse std::path::{Path, PathBuf};\nuse std::time::Duration;\nuse walkdir::WalkDir;\n\n/// If an explicit path is given, then use it, otherwise assume the current\n/// directory is the crate path.\npub fn get_crate_path(path: Option<PathBuf>) -> Result<PathBuf> {\n    match path {\n        Some(p) => Ok(p),\n        None => find_manifest_from_cwd(),\n    }\n}\n\n/// Search up the path for the manifest file from the current working directory\n/// If we don't find the manifest file then return back the current working directory\n/// to provide the appropriate error\nfn find_manifest_from_cwd() -> Result<PathBuf> {\n    let mut parent_path = std::env::current_dir()?;\n    let mut manifest_path = parent_path.join(\"Cargo.toml\");\n    loop {\n        if !manifest_path.is_file() {\n            if parent_path.pop() {\n                manifest_path = parent_path.join(\"Cargo.toml\");\n            } else {\n                return Ok(PathBuf::from(\".\"));\n            }\n        } else {\n            return Ok(parent_path);\n        }\n    }\n}\n\n/// Construct our `pkg` directory in the crate.\npub fn create_pkg_dir(out_dir: &Path) -> Result<()> {\n    let _ = fs::remove_file(out_dir.join(\"package.json\")); // Clean up package.json from previous runs\n    fs::create_dir_all(&out_dir)?;\n    fs::write(out_dir.join(\".gitignore\"), \"*\")?;\n    Ok(())\n}\n\n/// Locates the pkg directory from a specific path\n/// Returns None if unable to find the 'pkg' directory\npub fn find_pkg_directory(path: &Path, pkg_directory: &Path) -> Option<PathBuf> {\n    if is_pkg_directory(path, pkg_directory) {\n        return Some(path.to_owned());\n    }\n\n    WalkDir::new(path)\n        .into_iter()\n        .filter_map(|x| x.ok().map(|e| e.into_path()))\n        .find(|x| is_pkg_directory(&x, pkg_directory))\n}\n\nfn is_pkg_directory(path: &Path, pkg_directory: &Path) -> bool {\n    path.exists() && path.is_dir() && path.ends_with(pkg_directory)\n}\n\n/// Render a `Duration` to a form suitable for display on a console\npub fn elapsed(duration: Duration) -> String {\n    let secs = duration.as_secs();\n\n    if secs >= 60 {\n        format!(\"{}m {:02}s\", secs / 60, secs % 60)\n    } else {\n        format!(\"{}.{:02}s\", secs, duration.subsec_nanos() / 10_000_000)\n    }\n}\n"
  },
  {
    "path": "src/emoji.rs",
    "content": "//! Emoji constants used by `wasm-pack`.\n//!\n//! For the woefully unfamiliar:\n//!\n//! > Emoji are ideograms and smileys used in electronic messages and web\n//! > pages. Emoji exist in various genres, including facial expressions, common\n//! > objects, places and types of weather, and animals. They are much like\n//! > emoticons, but emoji are actual pictures instead of typographics.\n//!\n//! -- https://en.wikipedia.org/wiki/Emoji\n\n#![allow(missing_docs)]\n\nuse console::Emoji;\n\npub static TARGET: Emoji = Emoji(\"🎯  \", \"\");\npub static CYCLONE: Emoji = Emoji(\"🌀  \", \"\");\npub static FOLDER: Emoji = Emoji(\"📂  \", \"\");\npub static MEMO: Emoji = Emoji(\"📝  \", \"\");\npub static DOWN_ARROW: Emoji = Emoji(\"⬇️  \", \"\");\npub static RUNNER: Emoji = Emoji(\"🏃‍♀️  \", \"\");\npub static SPARKLE: Emoji = Emoji(\"✨  \", \":-)\");\npub static PACKAGE: Emoji = Emoji(\"📦  \", \":-)\");\npub static WARN: Emoji = Emoji(\"⚠️  \", \":-)\");\npub static DANCERS: Emoji = Emoji(\"👯  \", \"\");\npub static ERROR: Emoji = Emoji(\"⛔  \", \"\");\npub static INFO: Emoji = Emoji(\"ℹ️  \", \"\");\npub static WRENCH: Emoji = Emoji(\"🔧  \", \"\");\npub static CRAB: Emoji = Emoji(\"🦀  \", \"\");\npub static SHEEP: Emoji = Emoji(\"🐑 \", \"\");\n"
  },
  {
    "path": "src/generate.rs",
    "content": "//! Functionality related to running `cargo-generate`.\n\nuse crate::child;\nuse crate::emoji;\nuse crate::install::{self, Tool};\nuse anyhow::{Context, Result};\nuse std::process::Command;\n\n/// Run `cargo generate` in the current directory to create a new\n/// project from a template\npub fn generate(template: &str, name: &str, install_status: &install::Status) -> Result<()> {\n    let bin_path = install::get_tool_path(install_status, Tool::CargoGenerate)?\n        .binary(&Tool::CargoGenerate.to_string())?;\n    let mut cmd = Command::new(&bin_path);\n    cmd.arg(\"generate\");\n    cmd.arg(\"--git\").arg(&template);\n    cmd.arg(\"--name\").arg(&name);\n\n    println!(\n        \"{} Generating a new rustwasm project with name '{}'...\",\n        emoji::SHEEP,\n        name\n    );\n    child::run(cmd, \"cargo-generate\").context(\"Running cargo-generate\")?;\n    Ok(())\n}\n"
  },
  {
    "path": "src/install/arch.rs",
    "content": "use anyhow::{bail, Result};\nuse std::fmt;\n\nuse crate::target;\n\n/// An enum representing supported architectures\n#[derive(Clone, PartialEq, Eq)]\npub enum Arch {\n    /// x86 64-bit\n    X86_64,\n    /// x86 32-bit\n    X86,\n    /// ARM 64-bit\n    AArch64,\n}\n\nimpl Arch {\n    /// Gets the current architecture\n    pub fn get() -> Result<Self> {\n        if target::x86_64 {\n            Ok(Arch::X86_64)\n        } else if target::x86 {\n            Ok(Arch::X86)\n        } else if target::aarch64 {\n            Ok(Arch::AArch64)\n        } else {\n            bail!(\"Unrecognized target!\")\n        }\n    }\n}\n\nimpl fmt::Display for Arch {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let s = match self {\n            Arch::X86_64 => \"x86-64\",\n            Arch::X86 => \"x86\",\n            Arch::AArch64 => \"aarch64\",\n        };\n        write!(f, \"{}\", s)\n    }\n}\n"
  },
  {
    "path": "src/install/krate.rs",
    "content": "use crate::install::Tool;\nuse anyhow::Result;\nuse serde::Deserialize;\nconst VERSION: Option<&str> = option_env!(\"CARGO_PKG_VERSION\");\n\n#[derive(Debug, Deserialize)]\npub struct Krate {\n    pub max_version: String,\n}\n\n#[derive(Debug, Deserialize)]\npub struct KrateResponse {\n    #[serde(rename = \"crate\")]\n    pub krate: Krate,\n}\n\nimpl Krate {\n    pub fn new(name: &Tool) -> Result<Krate> {\n        let krate_address = format!(\"https://crates.io/api/v1/crates/{}\", name);\n        let res = ureq::builder()\n            .try_proxy_from_env(true)\n            .build()\n            .get(&krate_address)\n            .set(\n                \"user-agent\",\n                &format!(\"wasm-pack/{}\", VERSION.unwrap_or(\"unknown\")),\n            )\n            .call()?;\n\n        let kr: KrateResponse = res.into_json()?;\n        Ok(kr.krate)\n    }\n}\n"
  },
  {
    "path": "src/install/mod.rs",
    "content": "//! Functionality related to installing prebuilt binaries and/or running cargo install.\n\nuse self::krate::Krate;\nuse crate::child;\nuse crate::emoji;\nuse crate::install;\nuse crate::PBAR;\nuse anyhow::{anyhow, bail, Context, Result};\nuse binary_install::{Cache, Download};\nuse log::debug;\nuse log::{info, warn};\nuse std::env;\nuse std::fs;\nuse std::path::Path;\nuse std::process::Command;\nuse which::which;\n\nmod arch;\nmod krate;\nmod mode;\nmod os;\nmod tool;\npub use self::arch::Arch;\npub use self::mode::InstallMode;\npub use self::os::Os;\npub use self::tool::Tool;\n\n/// Possible outcomes of attempting to find/install a tool\npub enum Status {\n    /// Couldn't install tool because downloads are forbidden by user\n    CannotInstall,\n    /// The current platform doesn't support precompiled binaries for this tool\n    PlatformNotSupported,\n    /// We found the tool at the specified path\n    Found(Download),\n}\n\n/// Handles possible installs status and returns the download or a error message\npub fn get_tool_path(status: &Status, tool: Tool) -> Result<&Download> {\n    match status {\n        Status::Found(download) => Ok(download),\n        Status::CannotInstall => bail!(\"Not able to find or install a local {}.\", tool),\n        install::Status::PlatformNotSupported => {\n            bail!(\"{} does not currently support your platform.\", tool)\n        }\n    }\n}\n\n/// Install a cargo CLI tool\n///\n/// Prefers an existing local install, if any exists. Then checks if there is a\n/// global install on `$PATH` that fits the bill. Then attempts to download a\n/// tarball from the GitHub releases page, if this target has prebuilt\n/// binaries. Finally, falls back to `cargo install`.\npub fn download_prebuilt_or_cargo_install(\n    tool: Tool,\n    cache: &Cache,\n    version: &str,\n    install_permitted: bool,\n) -> Result<Status> {\n    // If the tool is installed globally and it has the right version, use\n    // that. Assume that other tools are installed next to it.\n    //\n    // This situation can arise if the tool is already installed via\n    // `cargo install`, for example.\n    if let Ok(path) = which(tool.to_string()) {\n        debug!(\"found global {} binary at: {}\", tool, path.display());\n        if check_version(&tool, &path, version)? {\n            let download = Download::at(path.parent().unwrap());\n            return Ok(Status::Found(download));\n        }\n    }\n\n    let msg = format!(\"{}Installing {}...\", emoji::DOWN_ARROW, tool);\n    PBAR.info(&msg);\n\n    let dl = download_prebuilt(&tool, cache, version, install_permitted);\n    match dl {\n        Ok(dl) => return Ok(dl),\n        Err(e) => {\n            warn!(\n                \"could not download pre-built `{}`: {}. Falling back to `cargo install`.\",\n                tool, e\n            );\n        }\n    }\n\n    cargo_install(tool, cache, version, install_permitted)\n}\n\n/// Check if the tool dependency is locally satisfied.\npub fn check_version(tool: &Tool, path: &Path, expected_version: &str) -> Result<bool> {\n    let expected_version = if expected_version == \"latest\" {\n        let krate = Krate::new(tool)?;\n        krate.max_version\n    } else {\n        expected_version.to_string()\n    };\n\n    let v = get_cli_version(tool, path)?;\n    info!(\n        \"Checking installed `{}` version == expected version: {} == {}\",\n        tool, v, &expected_version\n    );\n    Ok(v == expected_version)\n}\n\n/// Fetches the version of a CLI tool\npub fn get_cli_version(tool: &Tool, path: &Path) -> Result<String> {\n    let mut cmd = Command::new(path);\n    cmd.arg(\"--version\");\n    let stdout = child::run_capture_stdout(cmd, tool)?;\n    let version = stdout.trim().split_whitespace().nth(1);\n    match version {\n        Some(v) => Ok(v.to_string()),\n        None => bail!(\"Something went wrong! We couldn't determine your version of the wasm-bindgen CLI. We were supposed to set that up for you, so it's likely not your fault! You should file an issue: https://github.com/drager/wasm-pack/issues/new?template=bug_report.md.\")\n    }\n}\n\n/// Downloads a precompiled copy of the tool, if available.\npub fn download_prebuilt(\n    tool: &Tool,\n    cache: &Cache,\n    version: &str,\n    install_permitted: bool,\n) -> Result<Status> {\n    let url = match prebuilt_url(tool, version) {\n        Ok(url) => url,\n        Err(e) => bail!(\n            \"no prebuilt {} binaries are available for this platform: {}\",\n            tool,\n            e,\n        ),\n    };\n    match tool {\n        Tool::WasmBindgen => {\n            let binaries = &[\"wasm-bindgen\", \"wasm-bindgen-test-runner\"];\n            match cache.download(install_permitted, \"wasm-bindgen\", binaries, &url)? {\n                Some(download) => Ok(Status::Found(download)),\n                None => bail!(\"wasm-bindgen v{} is not installed!\", version),\n            }\n        }\n        Tool::CargoGenerate => {\n            let binaries = &[\"cargo-generate\"];\n            match cache.download(install_permitted, \"cargo-generate\", binaries, &url)? {\n                Some(download) => Ok(Status::Found(download)),\n                None => bail!(\"cargo-generate v{} is not installed!\", version),\n            }\n        }\n        Tool::WasmOpt => {\n            let binaries: &[&str] = match Os::get()? {\n                Os::MacOS => &[\"bin/wasm-opt\", \"lib/libbinaryen.dylib\"],\n                Os::Linux => &[\"bin/wasm-opt\"],\n                Os::Windows => &[\"bin/wasm-opt.exe\"],\n            };\n            match cache.download(install_permitted, \"wasm-opt\", binaries, &url)? {\n                Some(download) => Ok(Status::Found(download)),\n                // TODO(ag_dubs): why is this different? i forget...\n                None => Ok(Status::CannotInstall),\n            }\n        }\n    }\n}\n\n/// Returns the URL of a precompiled version of wasm-bindgen, if we have one\n/// available for our host platform.\nfn prebuilt_url(tool: &Tool, version: &str) -> Result<String> {\n    let os = Os::get()?;\n    let arch = Arch::get()?;\n    prebuilt_url_for(tool, version, &arch, &os)\n}\n\n/// Get the download URL for some tool at some version, architecture and operating system\npub fn prebuilt_url_for(tool: &Tool, version: &str, arch: &Arch, os: &Os) -> Result<String> {\n    let target = match (os, arch, tool) {\n        (Os::Linux, Arch::AArch64, Tool::WasmOpt) => \"aarch64-linux\",\n        (Os::Linux, Arch::AArch64, _) => \"aarch64-unknown-linux-gnu\",\n        (Os::Linux, Arch::X86_64, Tool::WasmOpt) => \"x86_64-linux\",\n        (Os::Linux, Arch::X86_64, Tool::CargoGenerate) => \"x86_64-unknown-linux-gnu\",\n        (Os::Linux, Arch::X86_64, _) => \"x86_64-unknown-linux-musl\",\n        (Os::MacOS, Arch::X86_64, Tool::WasmOpt) => \"x86_64-macos\",\n        (Os::MacOS, Arch::X86_64, _) => \"x86_64-apple-darwin\",\n        (Os::MacOS, Arch::AArch64, Tool::CargoGenerate) => \"aarch64-apple-darwin\",\n        (Os::MacOS, Arch::AArch64, Tool::WasmOpt) => \"arm64-macos\",\n        (Os::Windows, Arch::X86_64, Tool::WasmOpt) => \"x86_64-windows\",\n        (Os::Windows, Arch::X86_64, _) => \"x86_64-pc-windows-msvc\",\n        _ => bail!(\"Unrecognized target!\"),\n    };\n    match tool {\n        Tool::WasmBindgen => {\n            Ok(format!(\n                \"https://github.com/wasm-bindgen/wasm-bindgen/releases/download/{0}/wasm-bindgen-{0}-{1}.tar.gz\",\n                version,\n                target\n            ))\n        },\n        Tool::CargoGenerate => {\n            Ok(format!(\n                \"https://github.com/cargo-generate/cargo-generate/releases/download/v{0}/cargo-generate-v{0}-{1}.tar.gz\",\n                \"0.23.7\",\n                target\n            ))\n        },\n        Tool::WasmOpt => {\n            Ok(format!(\n        \"https://github.com/WebAssembly/binaryen/releases/download/{vers}/binaryen-{vers}-{target}.tar.gz\",\n        vers = \"version_117\", // Make sure to update the version in docs/src/cargo-toml-configuration.md as well\n        target = target,\n            ))\n        }\n    }\n}\n\n/// Use `cargo install` to install the tool locally into the given\n/// crate.\npub fn cargo_install(\n    tool: Tool,\n    cache: &Cache,\n    version: &str,\n    install_permitted: bool,\n) -> Result<Status> {\n    debug!(\n        \"Attempting to use a `cargo install`ed version of `{}={}`\",\n        tool, version,\n    );\n\n    let dirname = format!(\"{}-cargo-install-{}\", tool, version);\n    let destination = cache.join(dirname.as_ref());\n    if destination.exists() {\n        debug!(\n            \"`cargo install`ed `{}={}` already exists at {}\",\n            tool,\n            version,\n            destination.display()\n        );\n        let download = Download::at(&destination);\n        return Ok(Status::Found(download));\n    }\n\n    if !install_permitted {\n        return Ok(Status::CannotInstall);\n    }\n\n    // Run `cargo install` to a temporary location to handle ctrl-c gracefully\n    // and ensure we don't accidentally use stale files in the future\n    let tmp = cache.join(format!(\".{}\", dirname).as_ref());\n    drop(fs::remove_dir_all(&tmp));\n    debug!(\"cargo installing {} to tempdir: {}\", tool, tmp.display(),);\n\n    let context = format!(\"failed to create temp dir for `cargo install {}`\", tool);\n    fs::create_dir_all(&tmp).context(context)?;\n\n    let crate_name = match tool {\n        Tool::WasmBindgen => \"wasm-bindgen-cli\".to_string(),\n        _ => tool.to_string(),\n    };\n    let mut cmd = Command::new(\"cargo\");\n\n    cmd.arg(\"install\")\n        .arg(\"--force\")\n        .arg(crate_name)\n        .arg(\"--root\")\n        .arg(&tmp);\n\n    if version != \"latest\" {\n        cmd.arg(\"--version\").arg(version);\n    }\n\n    let context = format!(\"Installing {} with cargo\", tool);\n    child::run(cmd, \"cargo install\").context(context)?;\n\n    // `cargo install` will put the installed binaries in `$root/bin/*`, but we\n    // just want them in `$root/*` directly (which matches how the tarballs are\n    // laid out, and where the rest of our code expects them to be). So we do a\n    // little renaming here.\n    let binaries: Result<Vec<&str>> = match tool {\n        Tool::WasmBindgen => Ok(vec![\"wasm-bindgen\", \"wasm-bindgen-test-runner\"]),\n        Tool::CargoGenerate => Ok(vec![\"cargo-generate\"]),\n        Tool::WasmOpt => bail!(\"Cannot install wasm-opt with cargo.\"),\n    };\n\n    for b in binaries?.iter().cloned() {\n        let from = tmp\n            .join(\"bin\")\n            .join(b)\n            .with_extension(env::consts::EXE_EXTENSION);\n        let to = tmp.join(from.file_name().unwrap());\n        fs::rename(&from, &to).with_context(|| {\n            anyhow!(\n                \"failed to move {} to {} for `cargo install`ed `{}`\",\n                from.display(),\n                to.display(),\n                b\n            )\n        })?;\n    }\n\n    // Finally, move the `tmp` directory into our binary cache.\n    fs::rename(&tmp, &destination)?;\n\n    let download = Download::at(&destination);\n    Ok(Status::Found(download))\n}\n"
  },
  {
    "path": "src/install/mode.rs",
    "content": "use anyhow::{bail, Error, Result};\nuse std::str::FromStr;\n\n/// The `InstallMode` determines which mode of initialization we are running, and\n/// what install steps we perform.\n#[derive(Clone, Copy, Debug)]\npub enum InstallMode {\n    /// Perform all the install steps.\n    Normal,\n    /// Don't install tools like `wasm-bindgen`, just use the global\n    /// environment's existing versions to do builds.\n    Noinstall,\n    /// Skip the rustc version check\n    Force,\n}\n\nimpl Default for InstallMode {\n    fn default() -> InstallMode {\n        InstallMode::Normal\n    }\n}\n\nimpl FromStr for InstallMode {\n    type Err = Error;\n    fn from_str(s: &str) -> Result<Self> {\n        match s {\n            \"no-install\" => Ok(InstallMode::Noinstall),\n            \"normal\" => Ok(InstallMode::Normal),\n            \"force\" => Ok(InstallMode::Force),\n            _ => bail!(\"Unknown build mode: {}\", s),\n        }\n    }\n}\n\nimpl InstallMode {\n    /// Determines if installation is permitted during a function call based on --mode flag\n    pub fn install_permitted(self) -> bool {\n        match self {\n            InstallMode::Normal => true,\n            InstallMode::Force => true,\n            InstallMode::Noinstall => false,\n        }\n    }\n}\n"
  },
  {
    "path": "src/install/os.rs",
    "content": "use anyhow::{bail, Result};\nuse std::fmt;\n\nuse crate::target;\n\n/// An enum representing supported operating systems\n#[derive(Clone, PartialEq, Eq)]\npub enum Os {\n    /// Linux operating system\n    Linux,\n    /// Macos operating system\n    MacOS,\n    /// Windows operating system\n    Windows,\n}\n\nimpl Os {\n    /// Get the current operating system\n    pub fn get() -> Result<Self> {\n        if target::LINUX {\n            Ok(Os::Linux)\n        } else if target::MACOS {\n            Ok(Os::MacOS)\n        } else if target::WINDOWS {\n            Ok(Os::Windows)\n        } else {\n            bail!(\"Unrecognized target!\")\n        }\n    }\n}\n\nimpl fmt::Display for Os {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let s = match self {\n            Os::Linux => \"linux\",\n            Os::MacOS => \"macOS\",\n            Os::Windows => \"windows\",\n        };\n        write!(f, \"{}\", s)\n    }\n}\n"
  },
  {
    "path": "src/install/tool.rs",
    "content": "use std::fmt;\n\n/// Represents the set of CLI tools wasm-pack uses\npub enum Tool {\n    /// cargo-generate CLI tool\n    CargoGenerate,\n    /// wasm-bindgen CLI tools\n    WasmBindgen,\n    /// wasm-opt CLI tool\n    WasmOpt,\n}\n\nimpl fmt::Display for Tool {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        let s = match self {\n            Tool::CargoGenerate => \"cargo-generate\",\n            Tool::WasmBindgen => \"wasm-bindgen\",\n            Tool::WasmOpt => \"wasm-opt\",\n        };\n        write!(f, \"{}\", s)\n    }\n}\n"
  },
  {
    "path": "src/installer.rs",
    "content": "//! Self-installation of `wasm-pack`\n//!\n//! This module contains one public function which will self-install the\n//! currently running executable as `wasm-pack`. Our goal is to install this in\n//! a place that's already in `PATH`, ideally in an idiomatic location. To that\n//! end we place `wasm-pack` next to the `rustup` executable in `PATH`.\n//!\n//! This installer is run directly (probably by clicking on it) on Windows,\n//! meaning it will pop up a console (as we're a console app). Output goes to\n//! the console and users interact with it through the console. On Unix this is\n//! intended to be run from a shell script (docs/installer/init.sh) which is\n//! downloaded via curl/sh, and then the shell script downloads this executable\n//! and runs it.\n//!\n//! This may get more complicated over time (self updates anyone?) but for now\n//! it's pretty simple! We're largely just moving over our currently running\n//! executable to a different path.\n\nuse std::env;\nuse std::fs;\nuse std::io;\nuse std::io::IsTerminal;\nuse std::path::Path;\nuse std::process;\n\nuse anyhow::{anyhow, bail, Context, Result};\nuse which;\n\npub fn install() -> ! {\n    if let Err(e) = do_install() {\n        eprintln!(\"{}\", e);\n        for cause in e.chain() {\n            eprintln!(\"Caused by: {}\", cause);\n        }\n    }\n\n    // On Windows we likely popped up a console for the installation. If we were\n    // to exit here immediately then the user wouldn't see any error that\n    // happened above or any successful message. Let's wait for them to say\n    // they've read everything and then continue.\n    if cfg!(windows) {\n        println!(\"Press enter to close this window...\");\n        let mut line = String::new();\n        drop(io::stdin().read_line(&mut line));\n    }\n\n    process::exit(0);\n}\n\nfn do_install() -> Result<()> {\n    // Find `rustup.exe` in PATH, we'll be using its installation directory as\n    // our installation directory.\n    let rustup = match which::which(\"rustup\") {\n        Ok(path) => path,\n        Err(_) => {\n            bail!(\n                \"failed to find an installation of `rustup` in `PATH`, \\\n                 is rustup already installed?\"\n            );\n        }\n    };\n    let installation_dir = match rustup.parent() {\n        Some(parent) => parent,\n        None => bail!(\"can't install when `rustup` is at the root of the filesystem\"),\n    };\n    let destination = installation_dir\n        .join(\"wasm-pack\")\n        .with_extension(env::consts::EXE_EXTENSION);\n\n    if destination.exists() {\n        confirm_can_overwrite(&destination)?;\n    }\n\n    // Our relatively simple install step!\n    let me = env::current_exe()?;\n    fs::copy(&me, &destination)\n        .with_context(|| anyhow!(\"failed to copy executable to `{}`\", destination.display()))?;\n    println!(\n        \"info: successfully installed wasm-pack to `{}`\",\n        destination.display()\n    );\n\n    // ... and that's it!\n\n    Ok(())\n}\n\nfn confirm_can_overwrite(dst: &Path) -> Result<()> {\n    // If the `-f` argument was passed, we can always overwrite everything.\n    if env::args().any(|arg| arg == \"-f\") {\n        return Ok(());\n    }\n\n    let stdin = io::stdin();\n\n    // If we're not attached to a TTY then we can't get user input, so there's\n    // nothing to do except inform the user about the `-f` flag.\n    if !stdin.is_terminal() {\n        bail!(\n            \"existing wasm-pack installation found at `{}`, pass `-f` to \\\n             force installation over this file, otherwise aborting \\\n             installation now\",\n            dst.display()\n        );\n    }\n\n    // It looks like we're at an interactive prompt, so ask the user if they'd\n    // like to overwrite the previous installation.\n    eprintln!(\n        \"info: existing wasm-pack installation found at `{}`\",\n        dst.display()\n    );\n    eprint!(\"info: would you like to overwrite this file? [y/N]: \");\n    let mut line = String::new();\n    stdin.read_line(&mut line).context(\"failed to read stdin\")?;\n\n    if line.starts_with('y') || line.starts_with('Y') {\n        return Ok(());\n    }\n\n    bail!(\"aborting installation\");\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "//! Your favorite rust -> wasm workflow tool!\n\n#![deny(missing_docs)]\n\nextern crate anyhow;\nextern crate cargo_metadata;\nextern crate console;\nextern crate glob;\nextern crate parking_lot;\nextern crate semver;\nextern crate serde;\nextern crate strsim;\nextern crate which;\n#[macro_use]\nextern crate serde_derive;\nextern crate binary_install;\nextern crate chrono;\nextern crate dialoguer;\nextern crate log;\nextern crate serde_ignored;\nextern crate serde_json;\nextern crate toml;\nextern crate walkdir;\n\npub mod bindgen;\npub mod build;\npub mod cache;\npub mod child;\npub mod command;\npub mod emoji;\npub mod generate;\npub mod install;\npub mod license;\npub mod lockfile;\npub mod manifest;\npub mod npm;\npub mod progressbar;\npub mod readme;\npub mod stamps;\npub mod target;\npub mod test;\npub mod wasm_opt;\n\nuse crate::progressbar::{LogLevel, ProgressOutput};\nuse clap::builder::ArgAction;\nuse clap::Parser;\n\n/// The global progress bar and user-facing message output.\npub static PBAR: ProgressOutput = ProgressOutput::new();\n\n/// 📦 ✨  pack and publish your wasm!\n#[derive(Debug, Parser)]\n#[command(version)]\npub struct Cli {\n    /// The subcommand to run.\n    #[clap(subcommand)] // Note that we mark a field as a subcommand\n    pub cmd: command::Command,\n\n    /// Log verbosity is based off the number of v used\n    #[clap(long = \"verbose\", short = 'v', action = ArgAction::Count)]\n    pub verbosity: u8,\n\n    #[clap(long = \"quiet\", short = 'q')]\n    /// No output printed to stdout\n    pub quiet: bool,\n\n    #[clap(long = \"log-level\", default_value = \"info\")]\n    /// The maximum level of messages that should be logged by wasm-pack. [possible values: info, warn, error]\n    pub log_level: LogLevel,\n}\n"
  },
  {
    "path": "src/license.rs",
    "content": "//! Copy `LICENSE` file(s) for the packaged wasm.\n\nuse anyhow::{anyhow, Result};\nuse std::fs;\nuse std::path::Path;\n\nuse crate::manifest::CrateData;\nuse crate::PBAR;\nuse glob::glob;\n\nfn glob_license_files(path: &Path) -> Result<Vec<String>> {\n    let mut license_files: Vec<String> = Vec::new();\n    let path_string = match path.join(\"LICENSE*\").to_str() {\n        Some(path_string) => path_string.to_owned(),\n        None => {\n            return Err(anyhow!(\"Could not convert joined license path to String\"));\n        }\n    };\n\n    for entry in glob(&path_string)? {\n        match entry {\n            Ok(globed_path) => {\n                let file_name = match globed_path.file_name() {\n                    Some(file_name) => file_name,\n                    None => return Err(anyhow!(\"Could not get file name from path\")),\n                };\n                let file_name_string = match file_name.to_str() {\n                    Some(file_name_string) => file_name_string.to_owned(),\n                    None => return Err(anyhow!(\"Could not convert filename to String\")),\n                };\n                license_files.push(file_name_string);\n            }\n            Err(e) => println!(\"{:?}\", e),\n        }\n    }\n    Ok(license_files)\n}\n\n/// Copy the crate's license into the `pkg` directory.\npub fn copy_from_crate(crate_data: &CrateData, path: &Path, out_dir: &Path) -> Result<()> {\n    assert!(\n        fs::metadata(path).ok().map_or(false, |m| m.is_dir()),\n        \"crate directory should exist\"\n    );\n\n    assert!(\n        fs::metadata(&out_dir).ok().map_or(false, |m| m.is_dir()),\n        \"crate's pkg directory should exist\"\n    );\n\n    match (crate_data.crate_license(), crate_data.crate_license_file()) {\n        (Some(_), _) => {\n            let license_files = glob_license_files(path);\n\n            match license_files {\n                Ok(files) => {\n                    if files.is_empty() {\n                        PBAR.info(\"License key is set in Cargo.toml but no LICENSE file(s) were found; Please add the LICENSE file(s) to your project directory\");\n                        return Ok(());\n                    }\n                    for license_file in files {\n                        let crate_license_path = path.join(&license_file);\n                        let new_license_path = out_dir.join(&license_file);\n                        if fs::copy(&crate_license_path, &new_license_path).is_err() {\n                            PBAR.info(\"origin crate has no LICENSE\");\n                        }\n                    }\n                }\n                Err(_) => PBAR.info(\"origin crate has no LICENSE\"),\n            }\n        }\n        (None, Some(license_file)) => {\n            let crate_license_path = path.join(&license_file);\n            let new_license_path = out_dir.join(&license_file);\n            if fs::copy(&crate_license_path, &new_license_path).is_err() {\n                PBAR.info(\"origin crate has no LICENSE\");\n            }\n        }\n        (None, None) => {}\n    };\n\n    Ok(())\n}\n"
  },
  {
    "path": "src/lockfile.rs",
    "content": "//! Reading Cargo.lock lock file.\n\n#![allow(clippy::new_ret_no_self)]\n\nuse std::fs;\nuse std::path::PathBuf;\n\nuse crate::manifest::CrateData;\nuse anyhow::{anyhow, bail, Context, Result};\nuse console::style;\nuse toml;\n\n/// This struct represents the contents of `Cargo.lock`.\n#[derive(Clone, Debug, Deserialize)]\npub struct Lockfile {\n    package: Vec<Package>,\n}\n\n/// This struct represents a single package entry in `Cargo.lock`\n#[derive(Clone, Debug, Deserialize)]\nstruct Package {\n    name: String,\n    version: String,\n}\n\nimpl Lockfile {\n    /// Read the `Cargo.lock` file for the crate at the given path.\n    pub fn new(crate_data: &CrateData) -> Result<Lockfile> {\n        let lock_path = get_lockfile_path(crate_data)?;\n        let lockfile = fs::read_to_string(&lock_path)\n            .with_context(|| anyhow!(\"failed to read: {}\", lock_path.display()))?;\n        let lockfile = toml::from_str(&lockfile)\n            .with_context(|| anyhow!(\"failed to parse: {}\", lock_path.display()))?;\n        Ok(lockfile)\n    }\n\n    /// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.\n    pub fn wasm_bindgen_version(&self) -> Option<&str> {\n        self.get_package_version(\"wasm-bindgen\")\n    }\n\n    /// Like `wasm_bindgen_version`, except it returns an error instead of\n    /// `None`.\n    pub fn require_wasm_bindgen(&self) -> Result<&str> {\n        self.wasm_bindgen_version().ok_or_else(|| {\n            anyhow!(\n                \"Ensure that you have \\\"{}\\\" as a dependency in your Cargo.toml file:\\n\\\n                 [dependencies]\\n\\\n                 wasm-bindgen = \\\"0.2\\\"\",\n                style(\"wasm-bindgen\").bold().dim(),\n            )\n        })\n    }\n\n    /// Get the version of `wasm-bindgen` dependency used in the `Cargo.lock`.\n    pub fn wasm_bindgen_test_version(&self) -> Option<&str> {\n        self.get_package_version(\"wasm-bindgen-test\")\n    }\n\n    fn get_package_version(&self, package: &str) -> Option<&str> {\n        self.package\n            .iter()\n            .find(|p| p.name == package)\n            .map(|p| &p.version[..])\n    }\n}\n\n/// Given the path to the crate that we are building, return a `PathBuf`\n/// containing the location of the lock file, by finding the workspace root.\nfn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf> {\n    // Check that a lock file can be found in the directory. Return an error\n    // if it cannot, otherwise return the path buffer.\n    let lockfile_path = crate_data.workspace_root().join(\"Cargo.lock\");\n    if !lockfile_path.is_file() {\n        bail!(\"Could not find lockfile at {:?}\", lockfile_path)\n    } else {\n        Ok(lockfile_path)\n    }\n}\n"
  },
  {
    "path": "src/main.rs",
    "content": "#![allow(clippy::redundant_closure, clippy::redundant_pattern_matching)]\n\nextern crate anyhow;\nextern crate clap;\nextern crate env_logger;\nextern crate human_panic;\nextern crate log;\nextern crate wasm_pack;\nextern crate which;\n\nuse anyhow::Result;\nuse clap::Parser;\nuse std::env;\nuse std::panic;\nuse std::sync::mpsc;\nuse std::thread;\nuse wasm_pack::{\n    build::{self, WasmPackVersion},\n    command::run_wasm_pack,\n    Cli, PBAR,\n};\n\nmod installer;\n\nfn background_check_for_updates() -> mpsc::Receiver<Result<WasmPackVersion>> {\n    let (sender, receiver) = mpsc::channel();\n\n    let _detached_thread = thread::spawn(move || {\n        let wasm_pack_version = build::check_wasm_pack_versions();\n\n        if let Ok(wasm_pack_version) = wasm_pack_version {\n            if !wasm_pack_version.local.is_empty()\n                && !wasm_pack_version.latest.is_empty()\n                && wasm_pack_version.local != wasm_pack_version.latest\n            {\n                let _ = sender.send(Ok(wasm_pack_version));\n            }\n        } else {\n            let _ = sender.send(wasm_pack_version);\n        }\n    });\n\n    receiver\n}\n\nfn main() {\n    env_logger::init();\n\n    setup_panic_hooks();\n\n    if let Err(e) = run() {\n        eprintln!(\"Error: {}\", e);\n        for cause in e.chain() {\n            eprintln!(\"Caused by: {}\", cause);\n        }\n        ::std::process::exit(1);\n    }\n}\n\nfn run() -> Result<()> {\n    let wasm_pack_version = background_check_for_updates();\n\n    // Deprecate `init`\n    if let Some(\"init\") = env::args().nth(1).as_ref().map(|arg| arg.as_str()) {\n        println!(\"wasm-pack init is deprecated, consider using wasm-pack build\");\n    }\n\n    if let Ok(me) = env::current_exe() {\n        // If we're actually running as the installer then execute our\n        // self-installation, otherwise just continue as usual.\n        if me\n            .file_stem()\n            .and_then(|s| s.to_str())\n            .expect(\"executable should have a filename\")\n            .starts_with(\"wasm-pack-init\")\n        {\n            installer::install();\n        }\n    }\n\n    let args = Cli::parse();\n\n    PBAR.set_log_level(args.log_level);\n\n    if args.quiet {\n        PBAR.set_quiet(true);\n    }\n\n    run_wasm_pack(args.cmd)?;\n\n    if let Ok(wasm_pack_version) = wasm_pack_version.try_recv() {\n        match wasm_pack_version {\n            Ok(wasm_pack_version) =>\n                PBAR.warn(&format!(\"There's a newer version of wasm-pack available, the new version is: {}, you are using: {}. \\\n                To update, navigate to: https://drager.github.io/wasm-pack/installer/\", wasm_pack_version.latest, wasm_pack_version.local)),\n            Err(err) => PBAR.warn(&format!(\"{}\", err))\n        }\n    }\n\n    Ok(())\n}\n\nfn setup_panic_hooks() {\n    let meta = human_panic::Metadata::new(env!(\"CARGO_PKG_NAME\"), env!(\"CARGO_PKG_VERSION\"))\n        .authors(env!(\"CARGO_PKG_AUTHORS\").replace(\":\", \", \"))\n        .homepage(env!(\"CARGO_PKG_HOMEPAGE\"));\n\n    let default_hook = panic::take_hook();\n\n    if let Err(_) = env::var(\"RUST_BACKTRACE\") {\n        panic::set_hook(Box::new(move |info| {\n            // First call the default hook that prints to standard error.\n            default_hook(info);\n\n            // Then call human_panic.\n            let file_path = human_panic::handle_dump(&meta, info);\n            human_panic::print_msg(file_path, &meta)\n                .expect(\"human-panic: printing error message to console failed\");\n        }));\n    }\n}\n"
  },
  {
    "path": "src/manifest/mod.rs",
    "content": "//! Reading and writing Cargo.toml and package.json manifests.\n\n#![allow(\n    clippy::new_ret_no_self,\n    clippy::needless_pass_by_value,\n    clippy::redundant_closure\n)]\n\nuse anyhow::{anyhow, bail, Context, Result};\nmod npm;\n\nuse std::path::Path;\nuse std::{collections::HashMap, fs};\n\nuse self::npm::{\n    repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage,\n};\nuse crate::command::build::{BuildProfile, Target};\nuse crate::PBAR;\nuse cargo_metadata::{CrateType, Metadata, TargetKind};\nuse chrono::offset;\nuse chrono::DateTime;\nuse serde::{self, Deserialize};\nuse serde_json;\nuse std::collections::BTreeSet;\nuse std::env;\nuse std::io::Write;\nuse strsim::levenshtein;\nuse toml;\n\nconst WASM_PACK_METADATA_KEY: &str = \"package.metadata.wasm-pack\";\nconst WASM_PACK_VERSION: Option<&'static str> = option_env!(\"CARGO_PKG_VERSION\");\nconst WASM_PACK_REPO_URL: &str = \"https://github.com/drager/wasm-pack\";\n\n/// Store for metadata learned about a crate\npub struct CrateData {\n    data: Metadata,\n    current_idx: usize,\n    manifest: CargoManifest,\n    out_name: Option<String>,\n}\n\n#[doc(hidden)]\n#[derive(Deserialize)]\npub struct CargoManifest {\n    package: CargoPackage,\n}\n\n#[derive(Deserialize)]\nstruct CargoPackage {\n    name: String,\n\n    #[serde(default)]\n    metadata: CargoMetadata,\n}\n\n#[derive(Default, Deserialize)]\nstruct CargoMetadata {\n    #[serde(default, rename = \"wasm-pack\")]\n    wasm_pack: CargoWasmPack,\n}\n\n#[derive(Default, Deserialize)]\nstruct CargoWasmPack {\n    #[serde(default)]\n    profile: CargoWasmPackProfiles,\n}\n\n#[derive(Deserialize)]\nstruct CargoWasmPackProfiles {\n    #[serde(\n        default = \"CargoWasmPackProfile::default_dev\",\n        deserialize_with = \"CargoWasmPackProfile::deserialize_dev\"\n    )]\n    dev: CargoWasmPackProfile,\n\n    #[serde(\n        default = \"CargoWasmPackProfile::default_release\",\n        deserialize_with = \"CargoWasmPackProfile::deserialize_release\"\n    )]\n    release: CargoWasmPackProfile,\n\n    #[serde(\n        default = \"CargoWasmPackProfile::default_profiling\",\n        deserialize_with = \"CargoWasmPackProfile::deserialize_profiling\"\n    )]\n    profiling: CargoWasmPackProfile,\n\n    #[serde(\n        default = \"CargoWasmPackProfile::default_custom\",\n        deserialize_with = \"CargoWasmPackProfile::deserialize_custom\"\n    )]\n    custom: CargoWasmPackProfile,\n}\n\nimpl Default for CargoWasmPackProfiles {\n    fn default() -> CargoWasmPackProfiles {\n        CargoWasmPackProfiles {\n            dev: CargoWasmPackProfile::default_dev(),\n            release: CargoWasmPackProfile::default_release(),\n            profiling: CargoWasmPackProfile::default_profiling(),\n            custom: CargoWasmPackProfile::default_custom(),\n        }\n    }\n}\n\n/// This is where configuration goes for wasm-bindgen, wasm-opt, wasm-snip, or\n/// anything else that wasm-pack runs.\n#[derive(Default, Deserialize)]\npub struct CargoWasmPackProfile {\n    #[serde(default, rename = \"wasm-bindgen\")]\n    wasm_bindgen: CargoWasmPackProfileWasmBindgen,\n    #[serde(default, rename = \"wasm-opt\")]\n    wasm_opt: Option<CargoWasmPackProfileWasmOpt>,\n}\n\n#[derive(Default, Deserialize)]\nstruct CargoWasmPackProfileWasmBindgen {\n    #[serde(default, rename = \"debug-js-glue\")]\n    debug_js_glue: Option<bool>,\n\n    #[serde(default, rename = \"demangle-name-section\")]\n    demangle_name_section: Option<bool>,\n\n    #[serde(default, rename = \"dwarf-debug-info\")]\n    dwarf_debug_info: Option<bool>,\n\n    #[serde(default, rename = \"omit-default-module-path\")]\n    omit_default_module_path: Option<bool>,\n\n    #[serde(default, rename = \"split-linked-modules\")]\n    split_linked_modules: Option<bool>,\n}\n\n/// Struct for storing information received from crates.io\n#[derive(Deserialize, Debug)]\npub struct Crate {\n    #[serde(rename = \"crate\")]\n    crt: CrateInformation,\n}\n\n#[derive(Deserialize, Debug)]\nstruct CrateInformation {\n    max_version: String,\n}\n\nimpl Crate {\n    /// Returns latest wasm-pack version\n    pub fn return_wasm_pack_latest_version() -> Result<Option<String>> {\n        let current_time = chrono::offset::Local::now();\n        let old_metadata_file = Self::return_wasm_pack_file();\n\n        match old_metadata_file {\n            Some(ref file_contents) => {\n                let last_updated = Self::return_stamp_file_value(&file_contents, \"created\")\n                    .and_then(|t| DateTime::parse_from_str(t.as_str(), \"%+\").ok());\n\n                last_updated\n                    .map(|last_updated| {\n                        if current_time.signed_duration_since(last_updated).num_hours() > 24 {\n                            Self::return_api_call_result(current_time).map(Some)\n                        } else {\n                            Ok(Self::return_stamp_file_value(&file_contents, \"version\"))\n                        }\n                    })\n                    .unwrap_or_else(|| Ok(None))\n            }\n            None => Self::return_api_call_result(current_time).map(Some),\n        }\n    }\n\n    fn return_api_call_result(current_time: DateTime<offset::Local>) -> Result<String> {\n        let version = Self::return_latest_wasm_pack_version();\n\n        // We always override the stamp file with the current time because we don't\n        // want to hit the API all the time if it fails. It should follow the same\n        // \"policy\" as the success. This means that the 24 hours rate limiting\n        // will be active regardless if the check succeeded or failed.\n        match version {\n            Ok(ref version) => Self::override_stamp_file(current_time, Some(&version)).ok(),\n            Err(_) => Self::override_stamp_file(current_time, None).ok(),\n        };\n\n        version\n    }\n\n    fn override_stamp_file(\n        current_time: DateTime<offset::Local>,\n        version: Option<&str>,\n    ) -> Result<()> {\n        let path = env::current_exe()?;\n\n        let mut file = fs::OpenOptions::new()\n            .read(true)\n            .write(true)\n            .append(true)\n            .create(true)\n            .open(path.with_extension(\"stamp\"))?;\n\n        file.set_len(0)?;\n\n        write!(file, \"created {:?}\", current_time)?;\n\n        if let Some(version) = version {\n            write!(file, \"\\nversion {}\", version)?;\n        }\n\n        Ok(())\n    }\n\n    /// Return stamp file where metadata is stored.\n    fn return_wasm_pack_file() -> Option<String> {\n        if let Ok(path) = env::current_exe() {\n            if let Ok(file) = fs::read_to_string(path.with_extension(\"stamp\")) {\n                return Some(file);\n            }\n        }\n        None\n    }\n\n    /// Returns wasm-pack latest version (if it's received) by executing check_wasm_pack_latest_version function.\n    fn return_latest_wasm_pack_version() -> Result<String> {\n        Self::check_wasm_pack_latest_version().map(|crt| crt.crt.max_version)\n    }\n\n    /// Read the stamp file and return value assigned to a certain key.\n    fn return_stamp_file_value(file: &str, word: &str) -> Option<String> {\n        let created = file\n            .lines()\n            .find(|line| line.starts_with(word))\n            .and_then(|l| l.split_whitespace().nth(1));\n\n        created.map(|s| s.to_string())\n    }\n\n    /// Call to the crates.io api and return the latest version of `wasm-pack`\n    fn check_wasm_pack_latest_version() -> Result<Crate> {\n        let url = \"https://crates.io/api/v1/crates/wasm-pack\";\n        let agent = ureq::builder()\n            .try_proxy_from_env(true)\n            .user_agent(&format!(\n                \"wasm-pack/{} ({})\",\n                WASM_PACK_VERSION.unwrap_or_else(|| \"unknown\"),\n                WASM_PACK_REPO_URL\n            ))\n            .build();\n        let resp = agent\n            .get(url)\n            .call()\n            .context(\"failed to get wasm-pack version\")?;\n\n        let status_code = resp.status();\n\n        if 200 <= status_code && status_code < 300 {\n            let json = resp.into_json()?;\n\n            Ok(json)\n        } else {\n            bail!(\n                \"Received a bad HTTP status code ({}) when checking for newer wasm-pack version at: {}\",\n                status_code,\n                url\n            )\n        }\n    }\n}\n\n#[derive(Clone, Deserialize)]\n#[serde(untagged)]\nenum CargoWasmPackProfileWasmOpt {\n    Enabled(bool),\n    ExplicitArgs(Vec<String>),\n}\n\nimpl Default for CargoWasmPackProfileWasmOpt {\n    fn default() -> Self {\n        CargoWasmPackProfileWasmOpt::Enabled(false)\n    }\n}\n\nimpl CargoWasmPackProfile {\n    fn default_dev() -> Self {\n        CargoWasmPackProfile {\n            wasm_bindgen: CargoWasmPackProfileWasmBindgen {\n                debug_js_glue: Some(true),\n                demangle_name_section: Some(true),\n                dwarf_debug_info: Some(false),\n                omit_default_module_path: Some(false),\n                split_linked_modules: Some(false),\n            },\n            wasm_opt: None,\n        }\n    }\n\n    fn default_release() -> Self {\n        CargoWasmPackProfile {\n            wasm_bindgen: CargoWasmPackProfileWasmBindgen {\n                debug_js_glue: Some(false),\n                demangle_name_section: Some(true),\n                dwarf_debug_info: Some(false),\n                omit_default_module_path: Some(false),\n                split_linked_modules: Some(false),\n            },\n            wasm_opt: Some(CargoWasmPackProfileWasmOpt::Enabled(true)),\n        }\n    }\n\n    fn default_profiling() -> Self {\n        CargoWasmPackProfile {\n            wasm_bindgen: CargoWasmPackProfileWasmBindgen {\n                debug_js_glue: Some(false),\n                demangle_name_section: Some(true),\n                dwarf_debug_info: Some(false),\n                omit_default_module_path: Some(false),\n                split_linked_modules: Some(false),\n            },\n            wasm_opt: Some(CargoWasmPackProfileWasmOpt::Enabled(true)),\n        }\n    }\n\n    fn default_custom() -> Self {\n        CargoWasmPackProfile {\n            wasm_bindgen: CargoWasmPackProfileWasmBindgen {\n                debug_js_glue: Some(false),\n                demangle_name_section: Some(true),\n                dwarf_debug_info: Some(false),\n                omit_default_module_path: Some(false),\n                split_linked_modules: Some(false),\n            },\n            wasm_opt: Some(CargoWasmPackProfileWasmOpt::Enabled(true)),\n        }\n    }\n\n    fn deserialize_dev<'de, D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let mut profile = <Option<Self>>::deserialize(deserializer)?.unwrap_or_default();\n        profile.update_with_defaults(&Self::default_dev());\n        Ok(profile)\n    }\n\n    fn deserialize_release<'de, D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let mut profile = <Option<Self>>::deserialize(deserializer)?.unwrap_or_default();\n        profile.update_with_defaults(&Self::default_release());\n        Ok(profile)\n    }\n\n    fn deserialize_profiling<'de, D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let mut profile = <Option<Self>>::deserialize(deserializer)?.unwrap_or_default();\n        profile.update_with_defaults(&Self::default_profiling());\n        Ok(profile)\n    }\n\n    fn deserialize_custom<'de, D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let mut profile = <Option<Self>>::deserialize(deserializer)?.unwrap_or_default();\n        profile.update_with_defaults(&Self::default_custom());\n        Ok(profile)\n    }\n\n    fn update_with_defaults(&mut self, defaults: &Self) {\n        macro_rules! d {\n            ( $( $path:ident ).* ) => {\n                self. $( $path ).* .get_or_insert(defaults. $( $path ).* .unwrap());\n            }\n        }\n        d!(wasm_bindgen.debug_js_glue);\n        d!(wasm_bindgen.demangle_name_section);\n        d!(wasm_bindgen.dwarf_debug_info);\n        d!(wasm_bindgen.omit_default_module_path);\n        d!(wasm_bindgen.split_linked_modules);\n\n        if self.wasm_opt.is_none() {\n            self.wasm_opt = defaults.wasm_opt.clone();\n        }\n    }\n\n    /// Get this profile's configured `[wasm-bindgen.debug-js-glue]` value.\n    pub fn wasm_bindgen_debug_js_glue(&self) -> bool {\n        self.wasm_bindgen.debug_js_glue.unwrap()\n    }\n\n    /// Get this profile's configured `[wasm-bindgen.demangle-name-section]` value.\n    pub fn wasm_bindgen_demangle_name_section(&self) -> bool {\n        self.wasm_bindgen.demangle_name_section.unwrap()\n    }\n\n    /// Get this profile's configured `[wasm-bindgen.dwarf-debug-info]` value.\n    pub fn wasm_bindgen_dwarf_debug_info(&self) -> bool {\n        self.wasm_bindgen.dwarf_debug_info.unwrap()\n    }\n\n    /// Get this profile's configured `[wasm-bindgen.omit-default-module-path]` value.\n    pub fn wasm_bindgen_omit_default_module_path(&self) -> bool {\n        self.wasm_bindgen.omit_default_module_path.unwrap()\n    }\n\n    /// Get this profile's configured `[wasm-bindgen.split-linked-modules]` value.\n    pub fn wasm_bindgen_split_linked_modules(&self) -> bool {\n        self.wasm_bindgen.split_linked_modules.unwrap()\n    }\n\n    /// Get this profile's configured arguments for `wasm-opt`, if enabled.\n    pub fn wasm_opt_args(&self) -> Option<Vec<String>> {\n        match self.wasm_opt.as_ref()? {\n            CargoWasmPackProfileWasmOpt::Enabled(false) => None,\n            CargoWasmPackProfileWasmOpt::Enabled(true) => Some(vec![\"-O\".to_string()]),\n            CargoWasmPackProfileWasmOpt::ExplicitArgs(s) => Some(s.clone()),\n        }\n    }\n}\n\nstruct NpmData {\n    name: String,\n    files: Vec<String>,\n    dts_file: Option<String>,\n    main: String,\n    homepage: Option<String>, // https://docs.npmjs.com/files/package.json#homepage,\n    keywords: Option<Vec<String>>, // https://docs.npmjs.com/files/package.json#keywords\n}\n\n#[doc(hidden)]\npub struct ManifestAndUnusedKeys {\n    pub manifest: CargoManifest,\n    pub unused_keys: BTreeSet<String>,\n}\n\nimpl CrateData {\n    /// Reads all metadata for the crate whose manifest is inside the directory\n    /// specified by `path`.\n    pub fn new(crate_path: &Path, out_name: Option<String>) -> Result<CrateData> {\n        let manifest_path = crate_path.join(\"Cargo.toml\");\n        if !manifest_path.is_file() {\n            bail!(\n                \"crate directory is missing a `Cargo.toml` file; is `{}` the \\\n                 wrong directory?\",\n                crate_path.display()\n            )\n        }\n\n        let data = cargo_metadata::MetadataCommand::new()\n            .manifest_path(&manifest_path)\n            .exec()?;\n\n        let manifest_and_keys = CrateData::parse_crate_data(&manifest_path)?;\n        CrateData::warn_for_unused_keys(&manifest_and_keys);\n\n        let manifest = manifest_and_keys.manifest;\n        let current_idx = data\n            .packages\n            .iter()\n            .position(|pkg| {\n                pkg.name == manifest.package.name\n                    && CrateData::is_same_path(pkg.manifest_path.as_std_path(), &manifest_path)\n            })\n            .ok_or_else(|| anyhow!(\"failed to find package in metadata\"))?;\n\n        Ok(CrateData {\n            data,\n            manifest,\n            current_idx,\n            out_name,\n        })\n    }\n\n    fn is_same_path(path1: &Path, path2: &Path) -> bool {\n        if let Ok(path1) = fs::canonicalize(&path1) {\n            if let Ok(path2) = fs::canonicalize(&path2) {\n                return path1 == path2;\n            }\n        }\n        path1 == path2\n    }\n\n    /// Read the `manifest_path` file and deserializes it using the toml Deserializer.\n    /// Returns a Result containing `ManifestAndUnusedKeys` which contains `CargoManifest`\n    /// and a `BTreeSet<String>` containing the unused keys from the parsed file.\n    ///\n    /// # Errors\n    /// Will return Err if the file (manifest_path) couldn't be read or\n    /// if deserialize to `CargoManifest` fails.\n    pub fn parse_crate_data(manifest_path: &Path) -> Result<ManifestAndUnusedKeys> {\n        let manifest = fs::read_to_string(&manifest_path)\n            .with_context(|| anyhow!(\"failed to read: {}\", manifest_path.display()))?;\n        let manifest = toml::Deserializer::parse(&manifest).with_context(|| {\n            anyhow!(\n                \"failed to create TOML deserializer for: {}\",\n                manifest_path.display()\n            )\n        })?;\n\n        let mut unused_keys = BTreeSet::new();\n        let levenshtein_threshold = 1;\n\n        let manifest: CargoManifest = serde_ignored::deserialize(manifest, |path| {\n            let path_string = path.to_string();\n\n            if path_string.starts_with(\"package.metadata\")\n                && (path_string.contains(\"wasm-pack\")\n                    || levenshtein(WASM_PACK_METADATA_KEY, &path_string) <= levenshtein_threshold)\n            {\n                unused_keys.insert(path_string);\n            }\n        })\n        .with_context(|| anyhow!(\"failed to parse manifest: {}\", manifest_path.display()))?;\n\n        Ok(ManifestAndUnusedKeys {\n            manifest,\n            unused_keys,\n        })\n    }\n\n    /// Iterating through all the passed `unused_keys` and output\n    /// a warning for each unknown key.\n    pub fn warn_for_unused_keys(manifest_and_keys: &ManifestAndUnusedKeys) {\n        manifest_and_keys.unused_keys.iter().for_each(|path| {\n            PBAR.warn(&format!(\n                \"\\\"{}\\\" is an unknown key and will be ignored. Please check your Cargo.toml.\",\n                path\n            ));\n        });\n    }\n\n    /// Get the configured profile.\n    pub fn configured_profile(&self, profile: BuildProfile) -> &CargoWasmPackProfile {\n        match profile {\n            BuildProfile::Dev => &self.manifest.package.metadata.wasm_pack.profile.dev,\n            BuildProfile::Profiling => &self.manifest.package.metadata.wasm_pack.profile.profiling,\n            BuildProfile::Release => &self.manifest.package.metadata.wasm_pack.profile.release,\n            BuildProfile::Custom(_) => &self.manifest.package.metadata.wasm_pack.profile.custom,\n        }\n    }\n\n    /// Check that the crate the given path is properly configured.\n    pub fn check_crate_config(&self) -> Result<()> {\n        self.check_crate_type()?;\n        Ok(())\n    }\n\n    fn check_crate_type(&self) -> Result<()> {\n        let pkg = &self.data.packages[self.current_idx];\n        let any_cdylib = pkg\n            .targets\n            .iter()\n            .filter(|target| target.kind.iter().any(|k| k == &TargetKind::CDyLib))\n            .any(|target| target.crate_types.iter().any(|s| s == &CrateType::CDyLib));\n        if any_cdylib {\n            return Ok(());\n        }\n        bail!(\n            \"crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your \\\n             Cargo.toml file:\\n\\n\\\n             [lib]\\n\\\n             crate-type = [\\\"cdylib\\\", \\\"rlib\\\"]\"\n        )\n    }\n\n    fn pkg(&self) -> &cargo_metadata::Package {\n        &self.data.packages[self.current_idx]\n    }\n\n    /// Get the crate name for the crate at the given path.\n    pub fn crate_name(&self) -> String {\n        let pkg = self.pkg();\n        match pkg\n            .targets\n            .iter()\n            .find(|t| t.kind.iter().any(|k| k == &TargetKind::CDyLib))\n        {\n            Some(lib) => lib.name.replace(\"-\", \"_\"),\n            None => pkg.name.replace(\"-\", \"_\"),\n        }\n    }\n\n    /// Get the prefix for output file names\n    pub fn name_prefix(&self) -> String {\n        match &self.out_name {\n            Some(value) => value.clone(),\n            None => self.crate_name(),\n        }\n    }\n\n    /// Gets the optional path to the readme, or None if disabled.\n    pub fn crate_readme(&self) -> Option<String> {\n        self.pkg()\n            .readme\n            .clone()\n            .map(|readme_file| readme_file.into_string())\n    }\n\n    /// Get the license for the crate at the given path.\n    pub fn crate_license(&self) -> &Option<String> {\n        &self.pkg().license\n    }\n\n    /// Get the license file path for the crate at the given path.\n    pub fn crate_license_file(&self) -> Option<String> {\n        self.pkg()\n            .license_file\n            .clone()\n            .map(|license_file| license_file.into_string())\n    }\n\n    /// Returns the path to this project's target directory where artifacts are\n    /// located after a cargo build.\n    pub fn target_directory(&self) -> &Path {\n        Path::new(&self.data.target_directory)\n    }\n\n    /// Returns the path to this project's root cargo workspace directory\n    pub fn workspace_root(&self) -> &Path {\n        Path::new(&self.data.workspace_root)\n    }\n\n    /// Generate a package.json file inside in `./pkg`.\n    pub fn write_package_json(\n        &self,\n        out_dir: &Path,\n        scope: &Option<String>,\n        disable_dts: bool,\n        target: Target,\n    ) -> Result<()> {\n        let pkg_file_path = out_dir.join(\"package.json\");\n        // Check if a `package.json` was already generated by wasm-bindgen, if so\n        // we merge the NPM dependencies already specified in it.\n        let existing_deps = if pkg_file_path.exists() {\n            // It's just a map of dependency names to versions\n            Some(serde_json::from_str::<HashMap<String, String>>(\n                &fs::read_to_string(&pkg_file_path)?,\n            )?)\n        } else {\n            None\n        };\n        let npm_data = match target {\n            Target::Nodejs => self.to_commonjs(scope, disable_dts, existing_deps, out_dir),\n            Target::NoModules => self.to_nomodules(scope, disable_dts, existing_deps, out_dir),\n            Target::Bundler => self.to_esmodules(scope, disable_dts, existing_deps, out_dir),\n            Target::Web => self.to_web(scope, disable_dts, existing_deps, out_dir),\n            // Deno does not need package.json\n            Target::Deno => return Ok(()),\n        };\n\n        let npm_json = serde_json::to_string_pretty(&npm_data)?;\n\n        fs::write(&pkg_file_path, npm_json)\n            .with_context(|| anyhow!(\"failed to write: {}\", pkg_file_path.display()))?;\n        Ok(())\n    }\n\n    fn npm_data(\n        &self,\n        scope: &Option<String>,\n        add_js_bg_to_package_json: bool,\n        disable_dts: bool,\n        out_dir: &Path,\n    ) -> NpmData {\n        let name_prefix = self.name_prefix();\n        let wasm_file = format!(\"{}_bg.wasm\", name_prefix);\n        let js_file = format!(\"{}.js\", name_prefix);\n        let mut files = vec![wasm_file];\n\n        files.push(js_file.clone());\n        if add_js_bg_to_package_json {\n            let js_bg_file = format!(\"{}_bg.js\", name_prefix);\n            files.push(js_bg_file);\n        }\n\n        let pkg = &self.data.packages[self.current_idx];\n        let npm_name = match scope {\n            Some(s) => format!(\"@{}/{}\", s, pkg.name),\n            None => pkg.name.to_string(),\n        };\n\n        let dts_file = if !disable_dts {\n            let file = format!(\"{}.d.ts\", name_prefix);\n            files.push(file.to_string());\n            Some(file)\n        } else {\n            None\n        };\n\n        let keywords = if pkg.keywords.len() > 0 {\n            Some(pkg.keywords.clone())\n        } else {\n            None\n        };\n\n        if let Ok(entries) = fs::read_dir(out_dir) {\n            let file_names = entries\n                .filter_map(|e| e.ok())\n                .filter(|e| e.metadata().map(|m| m.is_file()).unwrap_or(false))\n                .filter_map(|e| e.file_name().into_string().ok())\n                .filter(|f| f.starts_with(\"LICENSE\"))\n                .filter(|f| f != \"LICENSE\");\n            for file_name in file_names {\n                files.push(file_name);\n            }\n        }\n\n        NpmData {\n            name: npm_name,\n            dts_file,\n            files,\n            main: js_file,\n            homepage: self.pkg().homepage.clone(),\n            keywords,\n        }\n    }\n\n    fn license(&self) -> Option<String> {\n        self.crate_license().clone().or_else(|| {\n            self.crate_license_file().clone().map(|file| {\n                // When license is written in file: https://docs.npmjs.com/files/package.json#license\n                format!(\"SEE LICENSE IN {}\", file)\n            })\n        })\n    }\n\n    fn to_commonjs(\n        &self,\n        scope: &Option<String>,\n        disable_dts: bool,\n        dependencies: Option<HashMap<String, String>>,\n        out_dir: &Path,\n    ) -> NpmPackage {\n        let data = self.npm_data(scope, false, disable_dts, out_dir);\n        let pkg = &self.data.packages[self.current_idx];\n\n        self.check_optional_fields();\n\n        NpmPackage::CommonJSPackage(CommonJSPackage {\n            name: data.name,\n            collaborators: pkg.authors.clone(),\n            description: self.pkg().description.clone(),\n            version: pkg.version.to_string(),\n            license: self.license(),\n            repository: self.pkg().repository.clone().map(|repo_url| Repository {\n                ty: \"git\".to_string(),\n                url: repo_url,\n            }),\n            files: data.files,\n            main: data.main,\n            homepage: data.homepage,\n            types: data.dts_file,\n            keywords: data.keywords,\n            dependencies,\n        })\n    }\n\n    fn to_esmodules(\n        &self,\n        scope: &Option<String>,\n        disable_dts: bool,\n        dependencies: Option<HashMap<String, String>>,\n        out_dir: &Path,\n    ) -> NpmPackage {\n        let data = self.npm_data(scope, true, disable_dts, out_dir);\n        let pkg = &self.data.packages[self.current_idx];\n\n        self.check_optional_fields();\n\n        NpmPackage::ESModulesPackage(ESModulesPackage {\n            name: data.name,\n            ty: \"module\".into(),\n            collaborators: pkg.authors.clone(),\n            description: self.pkg().description.clone(),\n            version: pkg.version.to_string(),\n            license: self.license(),\n            repository: self.pkg().repository.clone().map(|repo_url| Repository {\n                ty: \"git\".to_string(),\n                url: repo_url,\n            }),\n            files: data.files,\n            main: data.main.clone(),\n            homepage: data.homepage,\n            types: data.dts_file,\n            side_effects: vec![format!(\"./{}\", data.main), \"./snippets/*\".to_owned()],\n            keywords: data.keywords,\n            dependencies,\n        })\n    }\n\n    fn to_web(\n        &self,\n        scope: &Option<String>,\n        disable_dts: bool,\n        dependencies: Option<HashMap<String, String>>,\n        out_dir: &Path,\n    ) -> NpmPackage {\n        let data = self.npm_data(scope, false, disable_dts, out_dir);\n        let pkg = &self.data.packages[self.current_idx];\n\n        self.check_optional_fields();\n\n        NpmPackage::ESModulesPackage(ESModulesPackage {\n            name: data.name,\n            ty: \"module\".into(),\n            collaborators: pkg.authors.clone(),\n            description: self.pkg().description.clone(),\n            version: pkg.version.to_string(),\n            license: self.license(),\n            repository: self.pkg().repository.clone().map(|repo_url| Repository {\n                ty: \"git\".to_string(),\n                url: repo_url,\n            }),\n            files: data.files,\n            main: data.main,\n            homepage: data.homepage,\n            types: data.dts_file,\n            side_effects: vec![\"./snippets/*\".to_owned()],\n            keywords: data.keywords,\n            dependencies,\n        })\n    }\n\n    fn to_nomodules(\n        &self,\n        scope: &Option<String>,\n        disable_dts: bool,\n        dependencies: Option<HashMap<String, String>>,\n        out_dir: &Path,\n    ) -> NpmPackage {\n        let data = self.npm_data(scope, false, disable_dts, out_dir);\n        let pkg = &self.data.packages[self.current_idx];\n\n        self.check_optional_fields();\n\n        NpmPackage::NoModulesPackage(NoModulesPackage {\n            name: data.name,\n            collaborators: pkg.authors.clone(),\n            description: self.pkg().description.clone(),\n            version: pkg.version.to_string(),\n            license: self.license(),\n            repository: self.pkg().repository.clone().map(|repo_url| Repository {\n                ty: \"git\".to_string(),\n                url: repo_url,\n            }),\n            files: data.files,\n            browser: data.main,\n            homepage: data.homepage,\n            types: data.dts_file,\n            keywords: data.keywords,\n            dependencies,\n        })\n    }\n\n    fn check_optional_fields(&self) {\n        let mut messages = vec![];\n        if self.pkg().description.is_none() {\n            messages.push(\"description\");\n        }\n        if self.pkg().repository.is_none() {\n            messages.push(\"repository\");\n        }\n        if self.pkg().license.is_none() && self.pkg().license_file.is_none() {\n            messages.push(\"license\");\n        }\n\n        match messages.len() {\n            1 => PBAR.info(&format!(\"Optional field missing from Cargo.toml: '{}'. This is not necessary, but recommended\", messages[0])),\n            2 => PBAR.info(&format!(\"Optional fields missing from Cargo.toml: '{}', '{}'. These are not necessary, but recommended\", messages[0], messages[1])),\n            3 => PBAR.info(&format!(\"Optional fields missing from Cargo.toml: '{}', '{}', and '{}'. These are not necessary, but recommended\", messages[0], messages[1], messages[2])),\n            _ => ()\n        };\n    }\n}\n"
  },
  {
    "path": "src/manifest/npm/commonjs.rs",
    "content": "use std::collections::HashMap;\n\nuse crate::manifest::npm::repository::Repository;\n\n#[derive(Serialize)]\npub struct CommonJSPackage {\n    pub name: String,\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub collaborators: Vec<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub description: Option<String>,\n    pub version: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub license: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub repository: Option<Repository>,\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub files: Vec<String>,\n    pub main: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub homepage: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub types: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub keywords: Option<Vec<String>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dependencies: Option<HashMap<String, String>>,\n}\n"
  },
  {
    "path": "src/manifest/npm/esmodules.rs",
    "content": "use std::collections::HashMap;\n\nuse crate::manifest::npm::repository::Repository;\n\n#[derive(Serialize)]\npub struct ESModulesPackage {\n    pub name: String,\n    #[serde(rename = \"type\")]\n    pub ty: String,\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub collaborators: Vec<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub description: Option<String>,\n    pub version: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub license: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub repository: Option<Repository>,\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub files: Vec<String>,\n    pub main: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub homepage: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub types: Option<String>,\n    #[serde(rename = \"sideEffects\")]\n    pub side_effects: Vec<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub keywords: Option<Vec<String>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dependencies: Option<HashMap<String, String>>,\n}\n"
  },
  {
    "path": "src/manifest/npm/mod.rs",
    "content": "mod commonjs;\nmod esmodules;\nmod nomodules;\npub mod repository;\n\npub use self::commonjs::CommonJSPackage;\npub use self::esmodules::ESModulesPackage;\npub use self::nomodules::NoModulesPackage;\n\n#[derive(Serialize)]\n#[serde(untagged)]\npub enum NpmPackage {\n    CommonJSPackage(CommonJSPackage),\n    ESModulesPackage(ESModulesPackage),\n    NoModulesPackage(NoModulesPackage),\n}\n"
  },
  {
    "path": "src/manifest/npm/nomodules.rs",
    "content": "use std::collections::HashMap;\n\nuse crate::manifest::npm::repository::Repository;\n\n#[derive(Serialize)]\npub struct NoModulesPackage {\n    pub name: String,\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub collaborators: Vec<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub description: Option<String>,\n    pub version: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub license: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub repository: Option<Repository>,\n    #[serde(skip_serializing_if = \"Vec::is_empty\")]\n    pub files: Vec<String>,\n    pub browser: String,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub homepage: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub types: Option<String>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub keywords: Option<Vec<String>>,\n    #[serde(skip_serializing_if = \"Option::is_none\")]\n    pub dependencies: Option<HashMap<String, String>>,\n}\n"
  },
  {
    "path": "src/manifest/npm/repository.rs",
    "content": "#[derive(Serialize)]\npub struct Repository {\n    #[serde(rename = \"type\")]\n    pub ty: String,\n    pub url: String,\n}\n"
  },
  {
    "path": "src/npm.rs",
    "content": "//! Functionality related to publishing to npm.\n\nuse crate::child;\nuse crate::command::publish::access::Access;\nuse anyhow::{bail, Context, Result};\nuse log::info;\n\n/// The default npm registry used when we aren't working with a custom registry.\npub const DEFAULT_NPM_REGISTRY: &str = \"https://registry.npmjs.org/\";\n\n/// Run the `npm pack` command.\npub fn npm_pack(path: &str) -> Result<()> {\n    let mut cmd = child::new_command(\"npm\");\n    cmd.current_dir(path).arg(\"pack\");\n    child::run(cmd, \"npm pack\").context(\"Packaging up your code failed\")?;\n    Ok(())\n}\n\n/// Run the `npm publish` command.\npub fn npm_publish(path: &str, access: Option<Access>, tag: Option<String>) -> Result<()> {\n    let mut cmd = child::new_command(\"npm\");\n    match access {\n        Some(a) => cmd.current_dir(path).arg(\"publish\").arg(&a.to_string()),\n        None => cmd.current_dir(path).arg(\"publish\"),\n    };\n    if let Some(tag) = tag {\n        cmd.arg(\"--tag\").arg(tag);\n    };\n\n    child::run(cmd, \"npm publish\").context(\"Publishing to npm failed\")?;\n    Ok(())\n}\n\n/// Run the `npm login` command.\npub fn npm_login(registry: &str, scope: &Option<String>, auth_type: &Option<String>) -> Result<()> {\n    let mut args = vec![\"login\".to_string(), format!(\"--registry={}\", registry)];\n\n    if let Some(scope) = scope {\n        args.push(format!(\"--scope={}\", scope));\n    }\n\n    if let Some(auth_type) = auth_type {\n        args.push(format!(\"--auth_type={}\", auth_type));\n    }\n\n    // Interactively ask user for npm login info.\n    //  (child::run does not support interactive input)\n    let mut cmd = child::new_command(\"npm\");\n    cmd.args(args);\n\n    info!(\"Running {:?}\", cmd);\n    if cmd.status()?.success() {\n        Ok(())\n    } else {\n        bail!(\"Login to registry {} failed\", registry)\n    }\n}\n"
  },
  {
    "path": "src/progressbar.rs",
    "content": "//! Fancy progress bar functionality.\n\nuse crate::emoji;\nuse anyhow::{bail, Error, Result};\nuse console::style;\nuse std::sync::atomic::{AtomicBool, AtomicU8, Ordering};\n\n#[repr(u8)]\n#[derive(Debug, Clone, Copy)]\n/// The maximum log level for wasm-pack\n// The ordering is important: the least verbose must be at\n// the top and the most verbose at the bottom\npub enum LogLevel {\n    /// Logs only error\n    Error,\n    /// Logs only warn and error\n    Warn,\n    /// Logs everything\n    Info,\n}\n\nimpl std::str::FromStr for LogLevel {\n    type Err = Error;\n    fn from_str(s: &str) -> Result<Self> {\n        match s {\n            \"error\" => Ok(LogLevel::Error),\n            \"warn\" => Ok(LogLevel::Warn),\n            \"info\" => Ok(LogLevel::Info),\n            _ => bail!(\"Unknown log-level: {}\", s),\n        }\n    }\n}\n\n/// Synchronized progress bar and status message printing.\npub struct ProgressOutput {\n    quiet: AtomicBool,\n    log_level: AtomicU8,\n}\n\nimpl ProgressOutput {\n    /// Returns a new ProgressOutput\n    pub const fn new() -> Self {\n        Self {\n            quiet: AtomicBool::new(false),\n            log_level: AtomicU8::new(LogLevel::Info as u8),\n        }\n    }\n\n    /// Print the given message.\n    fn message(&self, message: &str) {\n        eprintln!(\"{}\", message);\n    }\n\n    /// Returns whether it should silence stdout or not\n    pub fn quiet(&self) -> bool {\n        self.quiet.load(Ordering::SeqCst)\n    }\n\n    /// Causes it to silence stdout\n    pub fn set_quiet(&self, quiet: bool) {\n        self.quiet.store(quiet, Ordering::SeqCst);\n    }\n\n    /// Returns whether the specified log level is enabled or not\n    pub fn is_log_enabled(&self, level: LogLevel) -> bool {\n        (level as u8) <= self.log_level.load(Ordering::SeqCst)\n    }\n\n    /// Sets the log level for wasm-pack\n    pub fn set_log_level(&self, log_level: LogLevel) {\n        self.log_level.store(log_level as u8, Ordering::SeqCst);\n    }\n\n    /// Add an informational message.\n    pub fn info(&self, message: &str) {\n        if !self.quiet() && self.is_log_enabled(LogLevel::Info) {\n            let info = format!(\"{}: {}\", style(\"[INFO]\").bold().dim(), message,);\n            self.message(&info);\n        }\n    }\n\n    /// Add a warning message.\n    pub fn warn(&self, message: &str) {\n        if !self.quiet() && self.is_log_enabled(LogLevel::Warn) {\n            let warn = format!(\n                \"{}: {} {}\",\n                style(\"[WARN]\").bold().dim(),\n                emoji::WARN,\n                message\n            );\n            self.message(&warn);\n        }\n    }\n\n    /// Add an error message.\n    pub fn error(&self, message: &str) {\n        if self.is_log_enabled(LogLevel::Error) {\n            let err = format!(\n                \"{}: {} {}\",\n                style(\"[ERR]\").bold().dim(),\n                emoji::ERROR,\n                message\n            );\n            self.message(&err);\n        }\n    }\n}\n\nimpl Default for ProgressOutput {\n    fn default() -> Self {\n        ProgressOutput::new()\n    }\n}\n"
  },
  {
    "path": "src/readme.rs",
    "content": "//! Generating `README` files for the packaged wasm.\n\nuse anyhow::{Context, Result};\nuse std::fs;\nuse std::path::Path;\n\nuse crate::manifest::CrateData;\nuse crate::PBAR;\n\n/// Copy the crate's README into the `pkg` directory.\npub fn copy_from_crate(crate_data: &CrateData, path: &Path, out_dir: &Path) -> Result<()> {\n    assert!(\n        fs::metadata(path).ok().map_or(false, |m| m.is_dir()),\n        \"crate directory should exist\"\n    );\n    assert!(\n        fs::metadata(&out_dir).ok().map_or(false, |m| m.is_dir()),\n        \"crate's pkg directory should exist\"\n    );\n\n    let crate_readme_path = match crate_data.crate_readme() {\n        None => return Ok(()),\n        Some(readme_path) => path.join(readme_path),\n    };\n\n    let new_readme_path = out_dir.join(\"README.md\");\n    if crate_readme_path.exists() {\n        fs::copy(&crate_readme_path, &new_readme_path).context(\"failed to copy README\")?;\n    } else {\n        PBAR.warn(\"origin crate has no README\");\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "src/stamps.rs",
    "content": "//! Key-value store in `*.stamps` file.\n\nuse anyhow::{anyhow, Context, Result};\nuse std::{env, fs, path::PathBuf};\n\n/// Get a value corresponding to the key from the JSON value.\n///\n/// You should use return value of function `read_stamps_file_to_json()` as `json` argument.\npub fn get_stamp_value(key: impl AsRef<str>, json: &serde_json::Value) -> Result<String> {\n    json.get(key.as_ref())\n        .and_then(|value| value.as_str().map(ToOwned::to_owned))\n        .ok_or_else(|| anyhow!(\"cannot get stamp value for key '{}'\", key.as_ref()))\n}\n\n/// Save the key-value pair to the store.\npub fn save_stamp_value(key: impl Into<String>, value: impl AsRef<str>) -> Result<()> {\n    let mut json = read_stamps_file_to_json().unwrap_or_else(|_| serde_json::Map::new().into());\n\n    {\n        let stamps = json\n            .as_object_mut()\n            .ok_or_else(|| anyhow!(\"stamps file doesn't contain JSON object\"))?;\n        stamps.insert(key.into(), value.as_ref().into());\n    }\n\n    write_to_stamps_file(json)\n}\n\n/// Get the path of the `*.stamps` file that is used as the store.\npub fn get_stamps_file_path() -> Result<PathBuf> {\n    let path = env::current_exe()\n        .map(|path| path.with_extension(\"stamps\"))\n        .context(\"cannot get stamps file path\")?;\n    Ok(path)\n}\n\n/// Read `*.stamps` file and convert its content to the JSON value.\npub fn read_stamps_file_to_json() -> Result<serde_json::Value> {\n    let stamps_file_path = get_stamps_file_path()?;\n    let stamps_file_content =\n        fs::read_to_string(stamps_file_path).context(\"cannot find or read stamps file\")?;\n    let json: serde_json::Value = serde_json::from_str(&stamps_file_content)\n        .context(\"stamps file doesn't contain valid JSON\")?;\n    Ok(json)\n}\n\nfn write_to_stamps_file(json: serde_json::Value) -> Result<()> {\n    let stamps_file_path = get_stamps_file_path()?;\n    let pretty_json = serde_json::to_string_pretty(&json).context(\"JSON serialization failed\")?;\n    fs::write(stamps_file_path, pretty_json).context(\"cannot write to stamps file\")?;\n    Ok(())\n}\n"
  },
  {
    "path": "src/target.rs",
    "content": "//! Information about the target wasm-pack is currently being compiled for.\n//!\n//! That is, whether we are building wasm-pack for windows vs linux, and x86 vs\n//! x86-64, etc.\n\n#![allow(missing_docs)]\n\npub const LINUX: bool = cfg!(target_os = \"linux\");\npub const MACOS: bool = cfg!(target_os = \"macos\");\npub const WINDOWS: bool = cfg!(target_os = \"windows\");\n\n#[allow(non_upper_case_globals)]\npub const x86_64: bool = cfg!(target_arch = \"x86_64\");\n#[allow(non_upper_case_globals)]\npub const x86: bool = cfg!(target_arch = \"x86\");\n#[allow(non_upper_case_globals)]\npub const aarch64: bool = cfg!(target_arch = \"aarch64\");\n"
  },
  {
    "path": "src/test/mod.rs",
    "content": "//! Testing a Rust crate compiled to wasm.\n\npub mod webdriver;\n\nuse crate::child;\nuse crate::PBAR;\nuse anyhow::{Context, Result};\nuse std::ffi::OsStr;\nuse std::path::Path;\nuse std::process::Command;\n\n/// Run `cargo test` with the `nightly` toolchain and targeting\n/// `wasm32-unknown-unknown`.\npub fn cargo_test_wasm<I, K, V>(\n    path: &Path,\n    release: bool,\n    envs: I,\n    extra_options: &[String],\n) -> Result<()>\nwhere\n    I: IntoIterator<Item = (K, V)>,\n    K: AsRef<OsStr>,\n    V: AsRef<OsStr>,\n{\n    let mut cmd = Command::new(\"cargo\");\n\n    cmd.envs(envs);\n    cmd.current_dir(path).arg(\"test\");\n\n    if PBAR.quiet() {\n        cmd.arg(\"--quiet\");\n    }\n\n    if release {\n        cmd.arg(\"--release\");\n    }\n\n    cmd.arg(\"--target\").arg(\"wasm32-unknown-unknown\");\n\n    cmd.args(extra_options);\n\n    child::run(cmd, \"cargo test\").context(\"Running Wasm tests with wasm-bindgen-test failed\")?;\n\n    // NB: `child::run` took care of ensuring that test output gets printed.\n    Ok(())\n}\n"
  },
  {
    "path": "src/test/webdriver/chromedriver.rs",
    "content": "use super::get_and_notify;\nuse crate::install::InstallMode;\nuse crate::stamps;\nuse crate::target;\nuse anyhow::{bail, Context, Result};\nuse binary_install::Cache;\nuse chrono::DateTime;\nuse std::collections::HashMap;\nuse std::path::PathBuf;\n\n// Keep it up to date with each `wasm-pack` release.\n// https://chromedriver.storage.googleapis.com/LATEST_RELEASE\nconst DEFAULT_CHROMEDRIVER_VERSION: &str = \"143.0.7499.192\";\n\nconst CHROMEDRIVER_LAST_UPDATED_STAMP: &str = \"chromedriver_last_updated\";\nconst CHROMEDRIVER_VERSION_STAMP: &str = \"chromedriver_version\";\n\n/// Get the path to an existing `chromedriver`, or install it if no existing\n/// binary is found or if there is a new binary version.\npub fn get_or_install_chromedriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {\n    if let Ok(path) = which::which(\"chromedriver\") {\n        return Ok(path);\n    }\n    install_chromedriver(cache, mode.install_permitted())\n}\n\n/// Download and install a pre-built `chromedriver` binary.\npub fn install_chromedriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {\n    let target = if target::LINUX && target::x86_64 {\n        \"linux64\"\n    } else if target::MACOS && target::x86_64 {\n        \"mac-x64\"\n    } else if target::MACOS && target::aarch64 {\n        \"mac-arm64\"\n    } else if target::WINDOWS {\n        \"win32\"\n    } else {\n        bail!(\"chromedriver binaries are unavailable for this target\")\n    };\n\n    let url = get_chromedriver_url(target);\n\n    match get_and_notify(cache, installation_allowed, \"chromedriver\", &url)? {\n        Some(path) => Ok(path),\n        None => bail!(\n            \"No cached `chromedriver` binary found, and could not find a global \\\n             `chromedriver` on the `$PATH`. Not installing `chromedriver` because of noinstall \\\n             mode.\"\n        ),\n    }\n}\n\n/// Get `chromedriver` download URL.\n///\n/// _Algorithm_:\n/// 1. Try to open `*.stamps` file and deserialize its content to JSON object.\n/// 2. Try to compare current time with the saved one.\n/// 3. If the saved time is older than 1 day or something failed\n///    => fetch a new version and save version & time.\n/// 4. If everything failed, use the default version.\n/// 5. Return URL.\n///\n/// _Notes:_\n///\n/// It returns the latest one without checking the installed `Chrome` version\n/// because it's not easy to find out `Chrome` version on `Windows` -\n/// https://bugs.chromium.org/p/chromium/issues/detail?id=158372\n///\n/// The official algorithm for `chromedriver` version selection:\n/// https://chromedriver.chromium.org/downloads/version-selection\nfn get_chromedriver_url(target: &str) -> String {\n    let fetch_and_save_version =\n        || fetch_chromedriver_version().and_then(save_chromedriver_version);\n\n    let chromedriver_version = match stamps::read_stamps_file_to_json() {\n        Ok(json) => {\n            if should_load_chromedriver_version_from_stamp(&json) {\n                stamps::get_stamp_value(CHROMEDRIVER_VERSION_STAMP, &json)\n            } else {\n                fetch_and_save_version()\n            }\n        }\n        Err(_) => fetch_and_save_version(),\n    }\n    .unwrap_or_else(|error| {\n        log::warn!(\n            \"Cannot load or fetch chromedriver's latest version data, \\\n             the default version {} will be used. Error: {}\",\n            DEFAULT_CHROMEDRIVER_VERSION,\n            error\n        );\n        DEFAULT_CHROMEDRIVER_VERSION.to_owned()\n    });\n    assemble_chromedriver_url(&chromedriver_version, target)\n}\n\n// ------ `get_chromedriver_url` helpers ------\n\nfn save_chromedriver_version(version: String) -> Result<String> {\n    stamps::save_stamp_value(CHROMEDRIVER_VERSION_STAMP, &version)?;\n\n    let current_time = chrono::offset::Local::now().to_rfc3339();\n    stamps::save_stamp_value(CHROMEDRIVER_LAST_UPDATED_STAMP, current_time)?;\n\n    Ok(version)\n}\n\nfn should_load_chromedriver_version_from_stamp(json: &serde_json::Value) -> bool {\n    let last_updated = stamps::get_stamp_value(CHROMEDRIVER_LAST_UPDATED_STAMP, json)\n        .ok()\n        .and_then(|last_updated| DateTime::parse_from_rfc3339(&last_updated).ok());\n\n    match last_updated {\n        None => false,\n        Some(last_updated) => {\n            let current_time = chrono::offset::Local::now();\n            current_time.signed_duration_since(last_updated).num_hours() < 24\n        }\n    }\n}\n\n/// Channel information from the chromedriver version endpoint.\n#[derive(Deserialize)]\nstruct ChannelInfo {\n    version: String,\n}\n\n/// The response from the chromedriver version endpoint.\n#[derive(Deserialize)]\nstruct GoodLatestVersions {\n    channels: HashMap<String, ChannelInfo>,\n}\n\n/// Retrieve the latest version of chromedriver from the json endpoints.\n/// See: <https://github.com/GoogleChromeLabs/chrome-for-testing#json-api-endpoints>\nfn fetch_chromedriver_version() -> Result<String> {\n    let info: GoodLatestVersions = ureq::builder()\n        .try_proxy_from_env(true)\n        .build()\n        .get(\"https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json\")\n        .call()\n        .context(\"fetching of chromedriver's LATEST_RELEASE failed\")?\n        .into_json()\n        .context(\"converting chromedriver version response to GoodLatestVersions failed\")?;\n\n    let version = info\n        .channels\n        .get(\"Stable\")\n        .ok_or_else(|| anyhow::anyhow!(\"no Stable channel found in chromedriver version response\"))?\n        .version\n        .clone();\n\n    println!(\"chromedriver version: {}\", version);\n\n    Ok(version)\n}\n\nfn assemble_chromedriver_url(chromedriver_version: &str, target: &str) -> String {\n    format!(\n        \"https://storage.googleapis.com/chrome-for-testing-public/{version}/{target}/chromedriver-{target}.zip\",\n        version = chromedriver_version,\n        target = target,\n    )\n}\n"
  },
  {
    "path": "src/test/webdriver/geckodriver.rs",
    "content": "use super::get_and_notify;\nuse crate::install::InstallMode;\nuse crate::stamps;\nuse crate::target;\nuse anyhow::{anyhow, bail, Context, Result};\nuse binary_install::Cache;\nuse chrono::DateTime;\nuse std::path::PathBuf;\n\n// Keep it up to date with each `wasm-pack` release.\n// https://github.com/mozilla/geckodriver/releases/latest\nconst DEFAULT_GECKODRIVER_VERSION: &str = \"v0.36.0\";\nconst DEFAULT_WINDOWS_GECKODRIVER_VERSION: &str = \"v0.24.0\";\n\nconst GECKODRIVER_LAST_UPDATED_STAMP: &str = \"geckodriver_last_updated\";\nconst GECKODRIVER_VERSION_STAMP: &str = \"geckodriver_version\";\n\n/// Get the path to an existing `geckodriver`, or install it if no existing\n/// binary is found or if there is a new binary version.\npub fn get_or_install_geckodriver(cache: &Cache, mode: InstallMode) -> Result<PathBuf> {\n    // geckodriver Windows binaries >v0.24.0 have an additional\n    // runtime dependency that we cannot be sure is present on the\n    // user's machine\n    //\n    // https://github.com/mozilla/geckodriver/issues/1617\n    //\n    // until this is resolved, always install v0.24.0 on windows\n    if !target::WINDOWS {\n        if let Ok(path) = which::which(\"geckodriver\") {\n            log::info!(\"[geckodriver] Found geckodriver at {:?}\", path);\n            return Ok(path);\n        }\n    }\n    install_geckodriver(cache, mode.install_permitted())\n}\n\n/// Download and install a pre-built `geckodriver` binary.\npub fn install_geckodriver(cache: &Cache, installation_allowed: bool) -> Result<PathBuf> {\n    let (target, ext) = if target::LINUX && target::x86 {\n        (\"linux32\", \"tar.gz\")\n    } else if target::LINUX && target::x86_64 {\n        (\"linux64\", \"tar.gz\")\n    } else if target::LINUX && target::aarch64 {\n        (\"linux-aarch64\", \"tar.gz\")\n    } else if target::MACOS {\n        (\"macos\", \"tar.gz\")\n    } else if target::WINDOWS && target::x86 {\n        (\"win32\", \"zip\")\n    } else if target::WINDOWS && target::x86_64 {\n        (\"win64\", \"zip\")\n    } else {\n        bail!(\"geckodriver binaries are unavailable for this target\")\n    };\n\n    let url = get_geckodriver_url(target, ext);\n\n    match get_and_notify(cache, installation_allowed, \"geckodriver\", &url)? {\n        Some(path) => Ok(path),\n        None => bail!(\n            \"No cached `geckodriver` binary found, and could not find a global `geckodriver` \\\n             on the `$PATH`. Not installing `geckodriver` because of noinstall mode.\"\n        ),\n    }\n}\n\n/// Get `geckodriver` download URL.\n///\n/// _Algorithm_:\n/// 1. Try to open `*.stamps` file and deserialize its content to JSON object.\n/// 2. Try to compare current time with the saved one.\n/// 3. If the saved time is older than 1 day or something failed\n///    => fetch a new version and save version & time.\n/// 4. If everything failed, use the default version.\n/// 5. Return URL.\n///\n/// _Notes:_\n///\n/// It returns the latest one without checking the installed `Firefox` version\n/// - it should be relatively safe because each `geckodriver` supports many `Firefox` versions:\n/// https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html#supported-platforms\nfn get_geckodriver_url(target: &str, ext: &str) -> String {\n    let fetch_and_save_version =\n        || fetch_latest_geckodriver_tag_json().and_then(save_geckodriver_version);\n\n    let geckodriver_version = if target::WINDOWS {\n        log::info!(\n            \"[geckodriver] Windows detected, holding geckodriver version to {}\",\n            DEFAULT_WINDOWS_GECKODRIVER_VERSION\n        );\n        DEFAULT_WINDOWS_GECKODRIVER_VERSION.to_owned()\n    } else {\n        log::info!(\"[geckodriver] Looking up latest version of geckodriver...\");\n        match stamps::read_stamps_file_to_json() {\n            Ok(json) => {\n                if should_load_geckodriver_version_from_stamp(&json) {\n                    stamps::get_stamp_value(GECKODRIVER_VERSION_STAMP, &json)\n                } else {\n                    fetch_and_save_version()\n                }\n            }\n            Err(_) => fetch_and_save_version(),\n        }\n        .unwrap_or_else(|error| {\n            log::warn!(\n                \"[geckodriver] Cannot load or fetch geckodriver's latest version data, \\\n                 the default version {} will be used. Error: {}\",\n                DEFAULT_GECKODRIVER_VERSION,\n                error\n            );\n            DEFAULT_GECKODRIVER_VERSION.to_owned()\n        })\n    };\n    let url = assemble_geckodriver_url(&geckodriver_version, target, ext);\n    log::info!(\"[geckodriver] Fetching geckodriver at {}\", url);\n    url\n}\n\n// ------ `get_geckodriver_url` helpers  ------\n\nfn save_geckodriver_version(version: String) -> Result<String> {\n    stamps::save_stamp_value(GECKODRIVER_VERSION_STAMP, &version)?;\n\n    let current_time = chrono::offset::Local::now().to_rfc3339();\n    stamps::save_stamp_value(GECKODRIVER_LAST_UPDATED_STAMP, current_time)?;\n\n    Ok(version)\n}\n\nfn should_load_geckodriver_version_from_stamp(json: &serde_json::Value) -> bool {\n    let last_updated = stamps::get_stamp_value(GECKODRIVER_LAST_UPDATED_STAMP, json)\n        .ok()\n        .and_then(|last_updated| DateTime::parse_from_rfc3339(&last_updated).ok());\n\n    match last_updated {\n        None => false,\n        Some(last_updated) => {\n            let current_time = chrono::offset::Local::now();\n            current_time.signed_duration_since(last_updated).num_hours() < 24\n        }\n    }\n}\n\nfn fetch_latest_geckodriver_tag_json() -> Result<String> {\n    let content: serde_json::Value = ureq::builder()\n        .try_proxy_from_env(true)\n        .build()\n        .get(\"https://github.com/mozilla/geckodriver/releases/latest\")\n        .set(\"Accept\", \"application/json\")\n        .call()\n        .context(\"fetching of geckodriver's latest release data failed\")?\n        .into_json()?;\n\n    get_version_from_json(content)\n}\n\n/// JSON example: `{\"id\":15227534,\"tag_name\":\"v0.24.0\",\"update_url\":\"/mozzila...`\nfn get_version_from_json(json: serde_json::Value) -> Result<String> {\n    json.get(\"tag_name\")\n        .and_then(|tag_name| tag_name.as_str().map(ToOwned::to_owned))\n        .ok_or_else(|| anyhow!(\"cannot get `tag_name` from geckodriver's latest release data\"))\n}\n\nfn assemble_geckodriver_url(tag: &str, target: &str, ext: &str) -> String {\n    format!(\n        \"https://github.com/mozilla/geckodriver/releases/download/{tag}/geckodriver-{tag}-{target}.{ext}\",\n        tag=tag,\n        target=target,\n        ext=ext,\n    )\n}\n"
  },
  {
    "path": "src/test/webdriver/safaridriver.rs",
    "content": "use anyhow::{bail, Result};\nuse std::path::PathBuf;\n\n/// Get the path to an existing `safaridriver`.\n///\n/// We can't install `safaridriver` if an existing one is not found because\n/// Apple does not provide pre-built binaries. However, `safaridriver` *should*\n/// be present by default.\npub fn get_safaridriver() -> Result<PathBuf> {\n    match which::which(\"safaridriver\") {\n        Ok(p) => Ok(p),\n        Err(_) => bail!(\"could not find `safaridriver` on the `$PATH`\"),\n    }\n}\n"
  },
  {
    "path": "src/test/webdriver.rs",
    "content": "//! Getting WebDriver client binaries.\n\nmod chromedriver;\nmod geckodriver;\nmod safaridriver;\n\nuse crate::PBAR;\nuse anyhow::Result;\nuse binary_install::Cache;\nuse std::path::PathBuf;\n\npub use self::{\n    chromedriver::{get_or_install_chromedriver, install_chromedriver},\n    geckodriver::{get_or_install_geckodriver, install_geckodriver},\n    safaridriver::get_safaridriver,\n};\n\n// ------ driver helpers  ------\n\nfn get_and_notify(\n    cache: &Cache,\n    installation_allowed: bool,\n    name: &str,\n    url: &str,\n) -> Result<Option<PathBuf>> {\n    if let Some(dl) = cache.download(false, name, &[name], url)? {\n        return Ok(Some(dl.binary(name)?));\n    }\n    if installation_allowed {\n        PBAR.info(&format!(\"Getting {}...\", name));\n    }\n    match cache.download(installation_allowed, name, &[name], url)? {\n        Some(dl) => Ok(Some(dl.binary(name)?)),\n        None => Ok(None),\n    }\n}\n"
  },
  {
    "path": "src/wasm_opt.rs",
    "content": "//! Support for downloading and executing `wasm-opt`\n\nuse crate::child;\nuse crate::install;\nuse crate::PBAR;\nuse anyhow::Result;\nuse binary_install::Cache;\nuse std::path::Path;\nuse std::path::PathBuf;\nuse std::process::Command;\n\n/// Execute `wasm-opt` over wasm binaries found in `out_dir`, downloading if\n/// necessary into `cache`. Passes `args` to each invocation of `wasm-opt`.\npub fn run(cache: &Cache, out_dir: &Path, args: &[String], install_permitted: bool) -> Result<()> {\n    let wasm_opt_path = match find_wasm_opt(cache, install_permitted)? {\n        Some(path) => path,\n        // `find_wasm_opt` will have already logged a message about this, so we don't need to here.\n        None => return Ok(()),\n    };\n\n    PBAR.info(\"Optimizing wasm binaries with `wasm-opt`...\");\n\n    for file in out_dir.read_dir()? {\n        let file = file?;\n        let path = file.path();\n        if path.extension().and_then(|s| s.to_str()) != Some(\"wasm\") {\n            continue;\n        }\n\n        let tmp = path.with_extension(\"wasm-opt.wasm\");\n        let mut cmd = Command::new(&wasm_opt_path);\n        cmd.arg(&path).arg(\"-o\").arg(&tmp).args(args);\n        child::run(cmd, \"wasm-opt\")?;\n        std::fs::rename(&tmp, &path)?;\n    }\n\n    Ok(())\n}\n\n/// Attempts to find `wasm-opt` in `PATH` locally, or failing that downloads a\n/// precompiled binary.\n///\n/// Returns `Some` if a binary was found or it was successfully downloaded.\n/// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't\n/// have precompiled binaries. Returns an error if we failed to download the\n/// binary.\npub fn find_wasm_opt(cache: &Cache, install_permitted: bool) -> Result<Option<PathBuf>> {\n    // First attempt to look up in PATH. If found assume it works.\n    if let Ok(path) = which::which(\"wasm-opt\") {\n        PBAR.info(&format!(\"found wasm-opt at {:?}\", path));\n        return Ok(Some(path));\n    }\n\n    match install::download_prebuilt(&install::Tool::WasmOpt, cache, \"latest\", install_permitted)? {\n        install::Status::Found(download) => Ok(Some(download.binary(\"bin/wasm-opt\")?)),\n        install::Status::CannotInstall => {\n            PBAR.info(\"Skipping wasm-opt as no downloading was requested\");\n            Ok(None)\n        }\n        install::Status::PlatformNotSupported => {\n            PBAR.info(\"Skipping wasm-opt because it is not supported on this platform\");\n            Ok(None)\n        }\n    }\n}\n"
  },
  {
    "path": "tests/all/build.rs",
    "content": "use crate::utils;\nuse assert_cmd::prelude::*;\nuse std::fs;\nuse std::path::Path;\n\n#[test]\nfn build_in_non_crate_directory_doesnt_panic() {\n    let fixture = utils::fixture::not_a_crate();\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\".\")\n        .assert()\n        .failure()\n        .stderr(predicates::str::contains(\"missing a `Cargo.toml`\"));\n}\n\n#[test]\nfn it_should_build_js_hello_world_example() {\n    let fixture = utils::fixture::js_hello_world();\n    fixture.wasm_pack().arg(\"build\").assert().success();\n}\n\n#[test]\nfn it_should_not_make_a_pkg_json_if_passed_no_pack() {\n    let fixture = utils::fixture::js_hello_world();\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--no-pack\")\n        .assert()\n        .success();\n\n    let pkg_path = fixture.path.join(\"pkg\");\n    assert_eq!(pkg_path.join(\"package.json\").exists(), false);\n    assert_eq!(pkg_path.join(\"README.md\").exists(), false);\n    assert_eq!(pkg_path.join(\"licence\").exists(), false);\n}\n\n#[test]\nfn it_should_build_js_hello_world_example_with_custom_target_dir() {\n    let fixture = utils::fixture::js_hello_world();\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--target-dir\")\n        .arg(\"target2\")\n        .arg(\"--all-features\")\n        .arg(\"--offline\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn it_should_build_crates_in_a_workspace() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [workspace]\n                members = [\"blah\"]\n            \"#,\n        )\n        .file(\n            Path::new(\"blah\").join(\"Cargo.toml\"),\n            r#\"\n                [package]\n                authors = [\"The wasm-pack developers\"]\n                description = \"so awesome rust+wasm package\"\n                license = \"WTFPL\"\n                name = \"blah\"\n                repository = \"https://github.com/drager/wasm-pack.git\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n            \"#,\n        )\n        .file(\n            Path::new(\"blah\").join(\"src\").join(\"lib.rs\"),\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub fn hello() -> u32 { 42 }\n            \"#,\n        )\n        .install_local_wasm_bindgen();\n    fixture\n        .wasm_pack()\n        .current_dir(&fixture.path.join(\"blah\"))\n        .arg(\"build\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn renamed_crate_name_works() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                name = \"foo\"\n                version = \"0.1.0\"\n                authors = []\n\n                [lib]\n                crate-type = [\"cdylib\"]\n                name = 'bar'\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n            \"#,\n        )\n        .file(\n            \"src/lib.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub fn one() -> u32 { 1 }\n            \"#,\n        )\n        .install_local_wasm_bindgen();\n    fixture.wasm_pack().arg(\"build\").assert().success();\n}\n\n#[test]\nfn dash_dash_web_target_has_error_on_old_bindgen() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                name = \"foo\"\n                version = \"0.1.0\"\n                authors = []\n\n                [lib]\n                crate-type = [\"cdylib\"]\n                name = 'bar'\n\n                [dependencies]\n                wasm-bindgen = \"=0.2.37\"\n            \"#,\n        )\n        .file(\n            \"src/lib.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub fn one() -> u32 { 1 }\n            \"#,\n        )\n        .install_local_wasm_bindgen();\n    let cmd = fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--target\")\n        .arg(\"web\")\n        .assert()\n        .failure();\n    let output = String::from_utf8(cmd.get_output().stderr.clone()).unwrap();\n\n    assert!(\n        output.contains(\"Please update your project to wasm-bindgen version >= 0.2.39\")\n            || output.contains(\"older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust\"),\n        \"Output did not contain 'Please update your project to wasm-bindgen version >= 0.2.39' or 'older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust', output was {}\",\n        output\n    );\n}\n\n#[test]\nfn it_should_build_nested_project_with_transitive_dependencies() {\n    let fixture = utils::fixture::transitive_dependencies();\n    fixture.install_local_wasm_bindgen();\n    fixture\n        .wasm_pack()\n        .current_dir(fixture.path.join(\"main\"))\n        .arg(\"build\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn build_different_profiles() {\n    let fixture = utils::fixture::js_hello_world();\n    fixture.install_local_wasm_bindgen();\n\n    for profile in [\"--dev\", \"--debug\", \"--profiling\", \"--release\"]\n        .iter()\n        .cloned()\n    {\n        fixture\n            .wasm_pack()\n            .arg(\"build\")\n            .arg(profile)\n            .assert()\n            .success();\n    }\n}\n\n#[test]\nfn build_custom_profile() {\n    let profile_name = \"my-custom-profile\";\n    let fixture = utils::fixture::js_hello_world_with_custom_profile(profile_name);\n    fixture.install_local_wasm_bindgen();\n\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--profile\")\n        .arg(profile_name)\n        .assert()\n        .success();\n}\n\n#[test]\nfn build_with_and_without_wasm_bindgen_debug() {\n    for debug in [true, false].iter().cloned() {\n        let fixture = utils::fixture::Fixture::new();\n        fixture\n            .readme()\n            .file(\n                \"Cargo.toml\",\n                format!(\n                    r#\"\n                    [package]\n                    authors = [\"The wasm-pack developers\"]\n                    description = \"so awesome rust+wasm package\"\n                    license = \"WTFPL\"\n                    name = \"whatever\"\n                    repository = \"https://github.com/drager/wasm-pack.git\"\n                    version = \"0.1.0\"\n\n                    [lib]\n                    crate-type = [\"cdylib\"]\n\n                    [dependencies]\n                    wasm-bindgen = \"0.2\"\n\n                    [package.metadata.wasm-pack.profile.dev.wasm-bindgen]\n                    debug-js-glue = {}\n                    \"#,\n                    debug\n                ),\n            )\n            .file(\n                \"src/lib.rs\",\n                r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub struct MyThing {}\n\n                #[wasm_bindgen]\n                impl MyThing {\n                    #[wasm_bindgen(constructor)]\n                    pub fn new() -> MyThing {\n                        MyThing {}\n                    }\n                }\n\n                #[wasm_bindgen]\n                pub fn take(foo: MyThing) {\n                    drop(foo);\n                }\n                \"#,\n            )\n            .install_local_wasm_bindgen();\n\n        fixture\n            .wasm_pack()\n            .arg(\"build\")\n            .arg(\"--dev\")\n            .assert()\n            .success();\n\n        let contents = fs::read_to_string(fixture.path.join(\"pkg/whatever_bg.js\")).unwrap();\n        let contains_move_assertions =\n            contents.contains(\"throw new Error('Attempt to use a moved value')\");\n        assert_eq!(\n            contains_move_assertions, debug,\n            \"Should contain moved value assertions iff debug assertions are enabled. \\\n             Contains move assertions? {}. \\\n             Is a debug JS glue build? {}.\",\n            contains_move_assertions, debug,\n        );\n    }\n}\n\n#[test]\nfn build_with_arbitrary_cargo_options() {\n    let fixture = utils::fixture::js_hello_world();\n    fixture.install_local_wasm_bindgen();\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--no-default-features\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn build_no_install() {\n    let fixture = utils::fixture::js_hello_world();\n    fixture.install_local_wasm_bindgen();\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--mode\")\n        .arg(\"no-install\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn build_force() {\n    let fixture = utils::fixture::js_hello_world();\n    fixture.install_local_wasm_bindgen();\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--mode\")\n        .arg(\"force\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn build_from_new() {\n    let fixture = utils::fixture::not_a_crate();\n    let name = \"generated-project\";\n    fixture.wasm_pack().arg(\"new\").arg(name).assert().success();\n    let project_location = fixture.path.join(&name);\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(&project_location)\n        .assert()\n        .success();\n}\n\n#[test]\nfn build_crates_with_same_names() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"somename1/Cargo.toml\",\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"somename\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"0.2\"\n            somenameother = { path = \"../somename2\", package = \"somename\" }\n            \"#,\n        )\n        .file(\n            \"somename1/src/lib.rs\",\n            r#\"\n            extern crate wasm_bindgen;\n            use wasm_bindgen::prelude::*;\n            #[wasm_bindgen]\n            pub fn method() -> i32 {\n                somenameother::method()\n            }\n            \"#,\n        )\n        .file(\n            \"somename2/Cargo.toml\",\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"somename\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.1\"\n\n            [lib]\n            crate-type = [\"rlib\"]\n            \"#,\n        )\n        .file(\n            \"somename2/src/lib.rs\",\n            r#\"\n            pub fn method() -> i32 {\n                0\n            }\n            \"#,\n        );\n    fixture.install_local_wasm_bindgen();\n    fixture\n        .wasm_pack()\n        .current_dir(fixture.path.join(\"somename1\"))\n        .arg(\"build\")\n        .assert()\n        .success();\n}\n"
  },
  {
    "path": "tests/all/download.rs",
    "content": "use wasm_pack::install::{self, Arch, Os, Tool};\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(windows, target_arch = \"x86_64\"),\n))]\nfn can_download_prebuilt_wasm_bindgen() {\n    let dir = tempfile::TempDir::new().unwrap();\n    let cache = binary_install::Cache::at(dir.path());\n    if let install::Status::Found(dl) =\n        install::download_prebuilt(&Tool::WasmBindgen, &cache, \"0.2.100\", true).unwrap()\n    {\n        assert!(dl.binary(\"wasm-bindgen\").unwrap().is_file());\n        assert!(dl.binary(\"wasm-bindgen-test-runner\").unwrap().is_file())\n    } else {\n        assert!(false, \"Download failed\")\n    }\n}\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(windows, target_arch = \"x86_64\"),\n))]\nfn downloading_prebuilt_wasm_bindgen_handles_http_errors() {\n    let dir = tempfile::TempDir::new().unwrap();\n    let bad_version = \"0.2.95-some-trailing-version-stuff-that-does-not-exist\";\n    let cache = binary_install::Cache::at(dir.path());\n    let result = install::download_prebuilt(&Tool::WasmBindgen, &cache, bad_version, true);\n    assert!(result.is_err());\n    let error = result.err().unwrap();\n\n    assert!(error.chain().any(|e| e.to_string().contains(\"404\")));\n    assert!(error.chain().any(|e| e.to_string().contains(bad_version)));\n}\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(windows, target_arch = \"x86_64\"),\n))]\nfn can_download_prebuilt_cargo_generate() {\n    let dir = tempfile::TempDir::new().unwrap();\n    let cache = binary_install::Cache::at(dir.path());\n    if let install::Status::Found(dl) =\n        install::download_prebuilt(&Tool::CargoGenerate, &cache, \"latest\", true).unwrap()\n    {\n        assert!(dl.binary(\"cargo-generate\").unwrap().is_file());\n    } else {\n        assert!(false, \"Download Failed\");\n    }\n}\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"aarch64\"),\n    all(windows, target_arch = \"x86_64\"),\n))]\nfn can_download_prebuilt_wasm_opt() {\n    let dir = tempfile::TempDir::new().unwrap();\n    let cache = binary_install::Cache::at(dir.path());\n    if let install::Status::Found(dl) =\n        install::download_prebuilt(&Tool::WasmOpt, &cache, \"latest\", true).unwrap()\n    {\n        assert!(dl.binary(\"bin/wasm-opt\").unwrap().is_file());\n    } else {\n        assert!(false, \"Download Failed\");\n    }\n}\n\n#[test]\nfn all_latest_tool_download_urls_valid() {\n    let mut errors = Vec::new();\n\n    for tool in [Tool::CargoGenerate, Tool::WasmBindgen, Tool::WasmOpt] {\n        for arch in [Arch::X86_64, Arch::X86, Arch::AArch64] {\n            for os in [Os::Linux, Os::MacOS, Os::Windows] {\n                // For all valid tool, arch & os combinations,\n                // error out when any of them is a 404 or similar\n                if let Ok(url) = install::prebuilt_url_for(&tool, \"0.2.92\", &arch, &os) {\n                    // Use HTTP HEAD instead of GET to avoid fetching lots of stuff\n                    let res = ureq::head(&url).call().unwrap();\n                    let status = res.status();\n                    if 500 > status && status >= 400 {\n                        errors.push(format!(\n                            \"Can't download URL {} for {} on {}: {}\",\n                            url,\n                            arch,\n                            os,\n                            res.status()\n                        ));\n                    }\n                }\n            }\n        }\n    }\n    if !errors.is_empty() {\n        panic!(\n            \"Some URLs for prebuild tools were unavailable:\\n{}\",\n            errors.join(\"\\n\")\n        );\n    }\n}\n"
  },
  {
    "path": "tests/all/generate.rs",
    "content": "use crate::utils;\nuse assert_cmd::prelude::*;\n\n#[test]\nfn new_with_no_name_errors() {\n    let fixture = utils::fixture::not_a_crate();\n    fixture.install_local_cargo_generate();\n    fixture.wasm_pack().arg(\"new\").assert().failure();\n}\n\n#[test]\nfn new_with_name_succeeds() {\n    let fixture = utils::fixture::not_a_crate();\n    fixture.install_local_cargo_generate();\n    fixture\n        .wasm_pack()\n        .arg(\"new\")\n        .arg(\"hello\")\n        .assert()\n        .success();\n}\n"
  },
  {
    "path": "tests/all/license.rs",
    "content": "extern crate anyhow;\nextern crate wasm_pack;\n\nuse std::fs;\n\nuse crate::utils::{self, fixture};\nuse wasm_pack::license;\nuse wasm_pack::manifest::CrateData;\n\n#[test]\nfn it_copies_a_license_default_path() {\n    let fixture = fixture::single_license();\n    let out_dir = fixture.path.join(\"pkg\");\n    fs::create_dir(&out_dir).expect(\"should create pkg directory OK\");\n    let crate_data = CrateData::new(&fixture.path, None);\n\n    assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok());\n\n    let crate_license_path = fixture.path.join(\"LICENSE\");\n    let pkg_license_path = out_dir.join(\"LICENSE\");\n    println!(\n        \"wasm-pack: should have copied LICENSE from '{}' to '{}'\",\n        crate_license_path.display(),\n        pkg_license_path.display()\n    );\n    assert!(fs::metadata(&crate_license_path).is_ok());\n\n    assert!(fs::metadata(&pkg_license_path).is_ok());\n\n    let crate_license = utils::file::read_file(&crate_license_path).unwrap();\n    let pkg_license = utils::file::read_file(&pkg_license_path).unwrap();\n    assert_eq!(crate_license, pkg_license);\n}\n\n#[test]\nfn it_copies_a_license_provided_path() {\n    let fixture = fixture::single_license();\n    let out_dir = fixture.path.join(\"pkg\");\n    fs::create_dir(&out_dir).expect(\"should create pkg directory OK\");\n    let crate_data = CrateData::new(&fixture.path, None);\n\n    assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok());\n    let crate_license_path = fixture.path.join(\"LICENSE\");\n    let pkg_license_path = out_dir.join(\"LICENSE\");\n    println!(\n        \"wasm-pack: should have copied LICENSE from '{}' to '{}'\",\n        crate_license_path.display(),\n        pkg_license_path.display()\n    );\n    assert!(fs::metadata(&crate_license_path).is_ok());\n    assert!(fs::metadata(&pkg_license_path).is_ok());\n\n    let crate_license = utils::file::read_file(&crate_license_path).unwrap();\n    let pkg_license = utils::file::read_file(&pkg_license_path).unwrap();\n    assert_eq!(crate_license, pkg_license);\n}\n\n#[test]\nfn it_copies_all_licenses_default_path() {\n    let fixture = fixture::dual_license();\n    let out_dir = fixture.path.join(\"pkg\");\n    fs::create_dir(&out_dir).expect(\"should create pkg directory OK\");\n    let crate_data = CrateData::new(&fixture.path, None);\n\n    assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok());\n\n    let crate_license_path = fixture.path.join(\"LICENSE-WTFPL\");\n    let pkg_license_path = out_dir.join(\"LICENSE-WTFPL\");\n\n    let crate_license_path_2 = fixture.path.join(\"LICENSE-MIT\");\n    let pkg_license_path_2 = out_dir.join(\"LICENSE-MIT\");\n\n    println!(\n        \"wasm-pack: should have copied LICENSE from '{}' to '{}'\",\n        crate_license_path.display(),\n        pkg_license_path.display()\n    );\n    assert!(fs::metadata(&crate_license_path).is_ok());\n    assert!(fs::metadata(&pkg_license_path).is_ok());\n\n    assert!(fs::metadata(&crate_license_path_2).is_ok());\n    assert!(fs::metadata(&pkg_license_path_2).is_ok());\n\n    let crate_license = utils::file::read_file(&crate_license_path).unwrap();\n    let pkg_license = utils::file::read_file(&pkg_license_path).unwrap();\n    assert_eq!(crate_license, pkg_license);\n\n    let crate_license_2 = utils::file::read_file(&crate_license_path_2).unwrap();\n    let pkg_license_2 = utils::file::read_file(&pkg_license_path_2).unwrap();\n    assert_eq!(crate_license_2, pkg_license_2);\n}\n\n#[test]\nfn it_copies_all_licenses_provided_path() {\n    let fixture = fixture::dual_license();\n    let out_dir = fixture.path.join(\"pkg\");\n    fs::create_dir(&out_dir).expect(\"should create pkg directory OK\");\n    let crate_data = CrateData::new(&fixture.path, None);\n\n    assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok());\n\n    let crate_license_path = fixture.path.join(\"LICENSE-WTFPL\");\n    let pkg_license_path = out_dir.join(\"LICENSE-WTFPL\");\n\n    let crate_license_path_2 = fixture.path.join(\"LICENSE-MIT\");\n    let pkg_license_path_2 = out_dir.join(\"LICENSE-MIT\");\n\n    println!(\n        \"wasm-pack: should have copied LICENSE from '{}' to '{}'\",\n        crate_license_path.display(),\n        pkg_license_path.display()\n    );\n    assert!(fs::metadata(&crate_license_path).is_ok());\n    assert!(fs::metadata(&pkg_license_path).is_ok());\n\n    assert!(fs::metadata(&crate_license_path_2).is_ok());\n    assert!(fs::metadata(&pkg_license_path_2).is_ok());\n\n    let crate_license = utils::file::read_file(&crate_license_path).unwrap();\n    let pkg_license = utils::file::read_file(&pkg_license_path).unwrap();\n    assert_eq!(crate_license, pkg_license);\n\n    let crate_license_2 = utils::file::read_file(&crate_license_path_2).unwrap();\n    let pkg_license_2 = utils::file::read_file(&pkg_license_path_2).unwrap();\n    assert_eq!(crate_license_2, pkg_license_2);\n}\n\n#[test]\nfn it_copies_a_non_standard_license_provided_path() {\n    let license_file = \"NON-STANDARD-LICENSE\";\n    let fixture = fixture::non_standard_license(license_file);\n    let out_dir = fixture.path.join(\"pkg\");\n    fs::create_dir(&out_dir).expect(\"should create pkg directory OK\");\n    let crate_data = CrateData::new(&fixture.path, None);\n\n    assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok());\n\n    let crate_license_path = fixture.path.join(license_file);\n    let pkg_license_path = out_dir.join(license_file);\n    println!(\n        \"wasm-pack: should have copied LICENSE from '{}' to '{}'\",\n        crate_license_path.display(),\n        pkg_license_path.display()\n    );\n    assert!(fs::metadata(&crate_license_path).is_ok());\n\n    assert!(fs::metadata(&pkg_license_path).is_ok());\n\n    let crate_license = utils::file::read_file(&crate_license_path).unwrap();\n    let pkg_license = utils::file::read_file(&pkg_license_path).unwrap();\n    assert_eq!(crate_license, pkg_license);\n}\n"
  },
  {
    "path": "tests/all/lockfile.rs",
    "content": "use crate::utils::fixture;\nuse semver::{Version, VersionReq};\nuse wasm_pack::lockfile::Lockfile;\nuse wasm_pack::manifest::CrateData;\n\n#[test]\nfn it_gets_wasm_bindgen_version() {\n    let fixture = fixture::js_hello_world();\n    fixture.cargo_check();\n    let data = CrateData::new(&fixture.path, None).unwrap();\n    let lock = Lockfile::new(&data).unwrap();\n    assert_eq!(lock.wasm_bindgen_version(), Some(\"0.2.100\"),);\n}\n\n#[test]\nfn it_gets_wasm_bindgen_test_version() {\n    let fixture = fixture::wbg_test_node();\n    fixture.cargo_check();\n    let data = CrateData::new(&fixture.path, None).unwrap();\n    let lock = Lockfile::new(&data).unwrap();\n    let ver = Version::parse(lock.wasm_bindgen_test_version().unwrap()).unwrap();\n    assert!(VersionReq::parse(\"0.3\").unwrap().matches(&ver));\n}\n\n#[test]\nfn it_gets_wasm_bindgen_version_in_crate_inside_workspace() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [workspace]\n                members = [\"./blah\"]\n            \"#,\n        )\n        .file(\n            \"blah/Cargo.toml\",\n            r#\"\n                [package]\n                authors = [\"The wasm-pack developers\"]\n                description = \"so awesome rust+wasm package\"\n                license = \"WTFPL\"\n                name = \"blah\"\n                repository = \"https://github.com/drager/wasm-pack.git\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"=0.2.100\"\n            \"#,\n        )\n        .file(\n            \"blah/src/lib.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub fn hello() -> u32 { 42 }\n            \"#,\n        );\n    fixture.cargo_check();\n    let data = CrateData::new(&fixture.path.join(\"blah\"), None).unwrap();\n    let lock = Lockfile::new(&data).unwrap();\n    assert_eq!(lock.wasm_bindgen_version(), Some(\"0.2.100\"),);\n}\n\n#[test]\nfn it_gets_wasm_bindgen_version_from_dependencies() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [workspace]\n                members = [\"./parent\", \"./child\"]\n            \"#,\n        )\n        .file(\n            \"child/Cargo.toml\",\n            r#\"\n                [package]\n                authors = [\"The wasm-pack developers\"]\n                description = \"so awesome rust+wasm package\"\n                license = \"WTFPL\"\n                name = \"child\"\n                repository = \"https://github.com/drager/wasm-pack.git\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"=0.2.100\"\n            \"#,\n        )\n        .file(\n            \"child/src/lib.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub fn hello() -> u32 { 42 }\n            \"#,\n        )\n        .file(\n            \"parent/Cargo.toml\",\n            r#\"\n                [package]\n                authors = [\"The wasm-pack developers\"]\n                description = \"so awesome rust+wasm package\"\n                license = \"WTFPL\"\n                name = \"parent\"\n                repository = \"https://github.com/drager/wasm-pack.git\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n            \"#,\n        )\n        .file(\n            \"parent/src/lib.rs\",\n            r#\"\n                // Just re-export all of `child`.\n                extern crate child;\n                pub use child::*;\n            \"#,\n        );\n    fixture.cargo_check();\n    let data = CrateData::new(&fixture.path.join(\"parent\"), None).unwrap();\n    let lock = Lockfile::new(&data).unwrap();\n    assert_eq!(lock.wasm_bindgen_version(), Some(\"0.2.100\"),);\n}\n"
  },
  {
    "path": "tests/all/log_level.rs",
    "content": "use crate::utils;\nuse assert_cmd::prelude::*;\nuse predicates::boolean::PredicateBooleanExt;\nuse predicates::prelude::predicate::str::contains;\nuse predicates::reflection::PredicateReflection;\nuse predicates::Predicate;\nuse wasm_pack::emoji;\n\nfn matches_info() -> impl Predicate<str> + PredicateReflection {\n    contains(format!(\"[INFO]: {}Checking for the Wasm target...\", emoji::TARGET))\n        .and(contains(format!(\"[INFO]: {}Compiling to Wasm...\", emoji::CYCLONE)))\n        .and(contains(\"[INFO]: License key is set in Cargo.toml but no LICENSE file(s) were found; Please add the LICENSE file(s) to your project directory\"))\n        .and(contains(\"[INFO]: Optimizing wasm binaries with `wasm-opt`...\"))\n        .and(contains(format!(\"[INFO]: {} Done in \", emoji::SPARKLE)))\n        .and(contains(format!(\"[INFO]: {} Your wasm pkg is ready to publish at \", emoji::PACKAGE)))\n}\n\nfn matches_cargo() -> impl Predicate<str> + PredicateReflection {\n    contains(\"Finished release [optimized] target(s) in \").or(contains(\n        \"Finished `release` profile [optimized] target(s) in \",\n    ))\n}\n\n#[test]\nfn quiet() {\n    utils::fixture::Fixture::new()\n        .cargo_toml(\"js-hello-world\")\n        .hello_world_src_lib()\n        .wasm_pack()\n        .arg(\"--quiet\")\n        .arg(\"build\")\n        .assert()\n        .success()\n        .stdout(\"\")\n        .stderr(\"\");\n}\n\n#[test]\nfn log_level_info() {\n    utils::fixture::Fixture::new()\n        .cargo_toml(\"js-hello-world\")\n        .hello_world_src_lib()\n        .wasm_pack()\n        .arg(\"--log-level\")\n        .arg(\"info\")\n        .arg(\"build\")\n        .assert()\n        .success()\n        .stdout(\"\")\n        .stderr(matches_cargo().and(matches_info()));\n}\n\n#[test]\nfn log_level_warn() {\n    utils::fixture::Fixture::new()\n        .cargo_toml(\"js-hello-world\")\n        .hello_world_src_lib()\n        .wasm_pack()\n        .arg(\"--log-level\")\n        .arg(\"warn\")\n        .arg(\"build\")\n        .assert()\n        .success()\n        .stdout(\"\")\n        .stderr(matches_cargo().and(matches_info().not()));\n}\n\n#[test]\nfn log_level_error() {\n    utils::fixture::Fixture::new()\n        .cargo_toml(\"js-hello-world\")\n        .hello_world_src_lib()\n        .wasm_pack()\n        .arg(\"--log-level\")\n        .arg(\"error\")\n        .arg(\"build\")\n        .assert()\n        .success()\n        .stdout(\"\")\n        .stderr(matches_cargo().and(matches_info().not()));\n}\n"
  },
  {
    "path": "tests/all/main.rs",
    "content": "extern crate anyhow;\nextern crate assert_cmd;\nextern crate lazy_static;\nextern crate predicates;\n#[macro_use]\nextern crate serde_derive;\nextern crate binary_install;\nextern crate serde_json;\n#[macro_use]\nextern crate serial_test;\nextern crate clap;\nextern crate tempfile;\nextern crate wasm_pack;\n\nmod build;\nmod download;\nmod generate;\nmod license;\nmod lockfile;\nmod log_level;\nmod manifest;\nmod readme;\nmod stamps;\nmod test;\nmod utils;\nmod wasm_opt;\nmod webdriver;\n"
  },
  {
    "path": "tests/all/manifest.rs",
    "content": "use crate::utils::{self, fixture};\nuse assert_cmd::prelude::*;\nuse std::collections::{HashMap, HashSet};\nuse std::fs;\nuse std::path::PathBuf;\nuse wasm_pack::command::build::Target;\nuse wasm_pack::command::utils::get_crate_path;\nuse wasm_pack::{self, emoji, license, manifest};\n\n#[test]\nfn it_gets_the_crate_name_default_path() {\n    let path = &PathBuf::from(\".\");\n    let crate_data = manifest::CrateData::new(&path, None).unwrap();\n    let name = crate_data.crate_name();\n    assert_eq!(name, \"wasm_pack\");\n}\n\n#[test]\nfn it_gets_the_crate_name_provided_path() {\n    let fixture = fixture::js_hello_world();\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    assert_eq!(crate_data.crate_name(), \"js_hello_world\");\n}\n\n#[test]\nfn it_gets_the_default_name_prefix() {\n    let path = &PathBuf::from(\".\");\n    let crate_data = manifest::CrateData::new(&path, None).unwrap();\n    let name = crate_data.name_prefix();\n    assert_eq!(name, \"wasm_pack\");\n}\n\n#[test]\nfn it_gets_the_name_prefix_passed_from_cli() {\n    let path = &PathBuf::from(\".\");\n    let crate_data = manifest::CrateData::new(&path, Some(\"index\".to_owned())).unwrap();\n    let name = crate_data.name_prefix();\n    assert_eq!(name, \"index\");\n}\n\n#[test]\nfn it_checks_has_cdylib_default_path() {\n    let fixture = fixture::no_cdylib();\n    // Ensure that there is a `Cargo.lock`.\n    fixture.cargo_check();\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    assert!(crate_data.check_crate_config().is_err());\n}\n\n#[test]\nfn it_checks_has_cdylib_provided_path() {\n    let fixture = fixture::js_hello_world();\n    // Ensure that there is a `Cargo.lock`.\n    fixture.cargo_check();\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    crate_data.check_crate_config().unwrap();\n}\n\n#[test]\nfn it_checks_has_cdylib_wrong_crate_type() {\n    let fixture = fixture::bad_cargo_toml();\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    assert!(crate_data.check_crate_config().is_err());\n}\n\n#[test]\nfn it_recognizes_a_map_during_depcheck() {\n    let fixture = fixture::serde_feature();\n    // Ensure that there is a `Cargo.lock`.\n    fixture.cargo_check();\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    crate_data.check_crate_config().unwrap();\n}\n\n#[test]\nfn it_creates_a_package_json_default_path() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, false, Target::Bundler)\n        .is_ok());\n    let package_json_path = &fixture.path.join(\"pkg\").join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"js-hello-world\");\n    assert_eq!(pkg.ty, \"module\");\n    assert_eq!(pkg.repository.ty, \"git\");\n    assert_eq!(\n        pkg.repository.url,\n        \"https://github.com/drager/wasm-pack.git\"\n    );\n    assert_eq!(pkg.main, \"js_hello_world.js\");\n    assert_eq!(pkg.types, \"js_hello_world.d.ts\");\n    assert_eq!(\n        pkg.side_effects,\n        vec![\"./js_hello_world.js\", \"./snippets/*\"]\n    );\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> = [\n        \"js_hello_world.d.ts\",\n        \"js_hello_world_bg.js\",\n        \"js_hello_world_bg.wasm\",\n        \"js_hello_world.js\",\n    ]\n    .iter()\n    .map(|&s| String::from(s))\n    .collect();\n    assert_eq!(actual_files, expected_files);\n}\n\n#[test]\nfn it_creates_a_package_json_provided_path() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, false, Target::Bundler)\n        .is_ok());\n    let package_json_path = &fixture.path.join(\"pkg\").join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"js-hello-world\");\n    assert_eq!(pkg.ty, \"module\");\n    assert_eq!(pkg.main, \"js_hello_world.js\");\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> = [\n        \"js_hello_world.d.ts\",\n        \"js_hello_world_bg.js\",\n        \"js_hello_world_bg.wasm\",\n        \"js_hello_world.js\",\n    ]\n    .iter()\n    .map(|&s| String::from(s))\n    .collect();\n    assert_eq!(actual_files, expected_files);\n}\n\n#[test]\nfn it_creates_a_package_json_provided_path_with_scope() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &Some(\"test\".to_string()), false, Target::Bundler,)\n        .is_ok());\n    let package_json_path = &fixture.path.join(\"pkg\").join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"@test/js-hello-world\");\n    assert_eq!(pkg.ty, \"module\");\n    assert_eq!(pkg.main, \"js_hello_world.js\");\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> = [\n        \"js_hello_world.d.ts\",\n        \"js_hello_world_bg.js\",\n        \"js_hello_world_bg.wasm\",\n        \"js_hello_world.js\",\n    ]\n    .iter()\n    .map(|&s| String::from(s))\n    .collect();\n    assert_eq!(actual_files, expected_files);\n}\n\n#[test]\nfn it_creates_a_pkg_json_with_correct_files_on_node() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, false, Target::Nodejs)\n        .is_ok());\n    let package_json_path = &out_dir.join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"js-hello-world\");\n    assert_eq!(pkg.repository.ty, \"git\");\n    assert_eq!(\n        pkg.repository.url,\n        \"https://github.com/drager/wasm-pack.git\"\n    );\n    assert_eq!(pkg.main, \"js_hello_world.js\");\n    assert_eq!(pkg.types, \"js_hello_world.d.ts\");\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> = [\n        \"js_hello_world_bg.wasm\",\n        \"js_hello_world.d.ts\",\n        \"js_hello_world.js\",\n    ]\n    .iter()\n    .map(|&s| String::from(s))\n    .collect();\n    assert_eq!(actual_files, expected_files);\n}\n\n#[test]\nfn it_creates_a_pkg_json_with_correct_files_on_nomodules() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, false, Target::NoModules)\n        .is_ok());\n    let package_json_path = &out_dir.join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"js-hello-world\");\n    assert_eq!(pkg.repository.ty, \"git\");\n    assert_eq!(\n        pkg.repository.url,\n        \"https://github.com/drager/wasm-pack.git\"\n    );\n    assert_eq!(pkg.browser, \"js_hello_world.js\");\n    assert_eq!(pkg.types, \"js_hello_world.d.ts\");\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> = [\n        \"js_hello_world.d.ts\",\n        \"js_hello_world_bg.wasm\",\n        \"js_hello_world.js\",\n    ]\n    .iter()\n    .map(|&s| String::from(s))\n    .collect();\n    assert_eq!(actual_files, expected_files);\n}\n\n#[test]\nfn it_creates_a_package_json_with_correct_files_when_out_name_is_provided() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, Some(\"index\".to_owned())).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, false, Target::Bundler)\n        .is_ok());\n    let package_json_path = &fixture.path.join(\"pkg\").join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"js-hello-world\");\n    assert_eq!(pkg.ty, \"module\");\n    assert_eq!(pkg.repository.ty, \"git\");\n    assert_eq!(\n        pkg.repository.url,\n        \"https://github.com/drager/wasm-pack.git\"\n    );\n    assert_eq!(pkg.main, \"index.js\");\n    assert_eq!(pkg.types, \"index.d.ts\");\n    assert_eq!(pkg.side_effects, vec![\"./index.js\", \"./snippets/*\"]);\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> =\n        [\"index_bg.wasm\", \"index_bg.js\", \"index.d.ts\", \"index.js\"]\n            .iter()\n            .map(|&s| String::from(s))\n            .collect();\n    assert_eq!(actual_files, expected_files);\n}\n\n#[test]\nfn it_creates_a_pkg_json_in_out_dir() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"./custom/out\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, false, Target::Bundler)\n        .is_ok());\n\n    let package_json_path = &fixture.path.join(&out_dir).join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n}\n\n#[test]\nfn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, true, Target::Bundler)\n        .is_ok());\n    let package_json_path = &out_dir.join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"js-hello-world\");\n    assert_eq!(pkg.ty, \"module\");\n    assert_eq!(pkg.repository.ty, \"git\");\n    assert_eq!(\n        pkg.repository.url,\n        \"https://github.com/drager/wasm-pack.git\"\n    );\n    assert_eq!(pkg.main, \"js_hello_world.js\");\n    assert_eq!(pkg.description, \"so awesome rust+wasm package\");\n    assert_eq!(pkg.license, \"WTFPL\");\n    assert_eq!(pkg.types, \"\");\n    assert_eq!(\n        pkg.side_effects,\n        vec![\"./js_hello_world.js\", \"./snippets/*\"]\n    );\n    assert_eq!(\n        pkg.keywords, None,\n        \"keywords is not None: {:?}\",\n        pkg.keywords,\n    );\n    assert_eq!(pkg.version, \"0.1.0\");\n    assert_eq!(pkg.module, \"\");\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> = [\n        \"js_hello_world_bg.wasm\",\n        \"js_hello_world_bg.js\",\n        \"js_hello_world.js\",\n    ]\n    .iter()\n    .map(|&s| String::from(s))\n    .collect();\n    assert_eq!(actual_files, expected_files);\n}\n\n#[test]\nfn it_creates_a_package_json_with_npm_dependencies_provided_by_wasm_bindgen() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    // Write a `package.json` in the out_dir, as wasm-bindgen does:\n    utils::manifest::create_wbg_package_json(\n        &out_dir,\n        r#\"\n        { \"foo\": \"^1.2.3\" }\n    \"#,\n    )\n    .unwrap();\n    assert!(crate_data\n        .write_package_json(&out_dir, &None, true, Target::Bundler)\n        .is_ok());\n    let package_json_path = &out_dir.join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.name, \"js-hello-world\");\n    assert_eq!(pkg.repository.ty, \"git\");\n    assert_eq!(\n        pkg.repository.url,\n        \"https://github.com/drager/wasm-pack.git\"\n    );\n    assert_eq!(pkg.main, \"js_hello_world.js\");\n\n    let actual_files: HashSet<String> = pkg.files.into_iter().collect();\n    let expected_files: HashSet<String> = [\n        \"js_hello_world_bg.wasm\",\n        \"js_hello_world_bg.js\",\n        \"js_hello_world.js\",\n    ]\n    .iter()\n    .map(|&s| String::from(s))\n    .collect();\n    assert_eq!(actual_files, expected_files);\n\n    let dependencies: Option<HashMap<String, String>> = pkg.dependencies;\n    assert!(dependencies.is_some());\n    let mut expected_dependencies: HashMap<String, String> = HashMap::new();\n    expected_dependencies.insert(\"foo\".to_owned(), \"^1.2.3\".to_owned());\n\n    assert_eq!(dependencies.unwrap(), expected_dependencies);\n}\n\n#[test]\nfn it_errors_when_wasm_bindgen_is_not_declared() {\n    let fixture = fixture::bad_cargo_toml();\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    assert!(crate_data.check_crate_config().is_err());\n}\n\n#[test]\nfn it_sets_homepage_field_if_available_in_cargo_toml() {\n    // When 'homepage' is available\n    let fixture = utils::fixture::Fixture::new();\n    fixture.hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"homepage-field-test\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n            homepage = \"https://drager.github.io/wasm-pack/\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"=0.2\"\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"=0.2\"\n        \"#,\n    );\n\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    crate_data\n        .write_package_json(&out_dir, &None, true, Target::Bundler)\n        .unwrap();\n\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(\n        pkg.homepage,\n        Some(\"https://drager.github.io/wasm-pack/\".to_string()),\n    );\n\n    // When 'homepage' is unavailable\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    crate_data\n        .write_package_json(&out_dir, &None, true, Target::Bundler)\n        .unwrap();\n\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.homepage, None);\n}\n\n#[test]\nfn it_sets_keywords_field_if_available_in_cargo_toml() {\n    // When 'homepage' is available\n    let fixture = utils::fixture::Fixture::new();\n    fixture.hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"homepage-field-test\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n            keywords = [\"wasm\"]\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"=0.2\"\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"=0.2\"\n        \"#,\n    );\n\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    crate_data\n        .write_package_json(&out_dir, &None, true, Target::Bundler)\n        .unwrap();\n\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    let keywords = pkg.keywords.clone().unwrap();\n    assert!(\n        keywords.contains(&\"wasm\".to_string()),\n        \"keywords is not in files: {:?}\",\n        keywords,\n    );\n\n    // When 'keywords' is unavailable\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    crate_data\n        .write_package_json(&out_dir, &None, true, Target::Bundler)\n        .unwrap();\n\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n    assert_eq!(pkg.keywords, None);\n}\n\n#[test]\nfn it_does_not_error_when_wasm_bindgen_is_declared() {\n    let fixture = fixture::js_hello_world();\n    // Ensure that there is a `Cargo.lock`.\n    fixture.cargo_check();\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n    crate_data.check_crate_config().unwrap();\n}\n\n#[test]\nfn configure_wasm_bindgen_debug_incorrectly_is_error() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture.readme().hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"whatever\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"0.2\"\n\n            [package.metadata.wasm-pack.profile.dev.wasm-bindgen]\n            debug-js-glue = \"not a boolean\"\n            \"#,\n    );\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--dev\")\n        .assert()\n        .failure();\n}\n\n#[test]\nfn parse_crate_data_returns_unused_keys_in_cargo_toml() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"whatever\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"0.2\"\n\n            # Note: production is not valid.\n            [package.metadata.wasm-pack.profile.production.wasm-bindgen]\n            debug-js-glue = true\n            \"#,\n        )\n        .hello_world_src_lib()\n        .install_local_wasm_bindgen();\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .assert()\n        .success()\n        .stderr(predicates::str::contains(format!(\n        \"[WARN]: {} \\\"package.metadata.wasm-pack.profile.production\\\" is an unknown key and will \\\n         be ignored. Please check your Cargo.toml.\",\n        emoji::WARN\n    )));\n}\n\n#[test]\nfn it_lists_license_files_in_files_field_of_package_json() {\n    let fixture = fixture::dual_license();\n    let out_dir = fixture.path.join(\"pkg\");\n\n    let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap();\n\n    wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap();\n    license::copy_from_crate(&crate_data, &fixture.path, &out_dir).unwrap();\n    crate_data\n        .write_package_json(&out_dir, &None, false, Target::Bundler)\n        .unwrap();\n\n    let package_json_path = &fixture.path.join(\"pkg\").join(\"package.json\");\n    fs::metadata(package_json_path).unwrap();\n    let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap();\n\n    assert!(\n        pkg.files.contains(&\"LICENSE-WTFPL\".to_string()),\n        \"LICENSE-WTFPL is not in files: {:?}\",\n        pkg.files,\n    );\n\n    assert!(\n        pkg.files.contains(&\"LICENSE-MIT\".to_string()),\n        \"LICENSE-MIT is not in files: {:?}\",\n        pkg.files,\n    );\n}\n\n#[test]\nfn it_recurses_up_the_path_to_find_cargo_toml() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture.hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"recurse-for-manifest-test\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n            homepage = \"https://drager.github.io/wasm-pack/\"\n        \"#,\n    );\n    let path = get_crate_path(None).unwrap();\n    let crate_data = manifest::CrateData::new(&path, None).unwrap();\n    let name = crate_data.crate_name();\n    assert_eq!(name, \"wasm_pack\");\n}\n\n#[test]\nfn it_doesnt_recurse_up_the_path_to_find_cargo_toml_when_default() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture.hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"recurse-for-manifest-test\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n            homepage = \"https://drager.github.io/wasm-pack/\"\n        \"#,\n    );\n    let path = get_crate_path(Some(PathBuf::from(\"src\"))).unwrap();\n    let crate_data = manifest::CrateData::new(&path, None);\n    assert!(crate_data.is_err());\n}\n"
  },
  {
    "path": "tests/all/readme.rs",
    "content": "extern crate anyhow;\nextern crate wasm_pack;\n\nuse std::fs;\n\nuse crate::utils::{self, fixture};\nuse assert_cmd::prelude::*;\nuse predicates::boolean::PredicateBooleanExt;\nuse wasm_pack::manifest::CrateData;\nuse wasm_pack::readme;\n\n#[test]\nfn it_copies_a_readme_default_path() {\n    let fixture = fixture::js_hello_world();\n    let out_dir = fixture.path.join(\"pkg\");\n    fs::create_dir(&out_dir).expect(\"should create pkg directory OK\");\n    let crate_data = CrateData::new(&fixture.path, None).unwrap();\n\n    assert!(readme::copy_from_crate(&crate_data, &fixture.path, &out_dir).is_ok());\n\n    let crate_readme_path = fixture.path.join(\"README.md\");\n    let pkg_readme_path = out_dir.join(\"README.md\");\n    println!(\n        \"wasm-pack: should have copied README.md from '{}' to '{}'\",\n        crate_readme_path.display(),\n        pkg_readme_path.display()\n    );\n    assert!(fs::metadata(&crate_readme_path).is_ok());\n\n    assert!(fs::metadata(&pkg_readme_path).is_ok());\n\n    let crate_readme = utils::file::read_file(&crate_readme_path).unwrap();\n    let pkg_readme = utils::file::read_file(&pkg_readme_path).unwrap();\n    assert_eq!(crate_readme, pkg_readme);\n}\n\n#[test]\nfn it_copies_a_readme_provided_path() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .hello_world_src_lib()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"js-hello-world\"\n            readme = \"docs/README.md\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            # Note that this uses and `=` dependency because there are\n            # various tests which assert that the version of wasm\n            # bindgen downloaded is what we expect, and if `=` is\n            # removed then it will download whatever the newest version\n            # of wasm-bindgen is which may not be what's listed here.\n            wasm-bindgen = \"=0.2.100\"\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"0.3\"\n        \"#,\n        )\n        .file(\n            \"docs/README.md\",\n            r#\"\n            # Fixture!\n            > an example rust -> wasm project\n        \"#,\n        );\n\n    let crate_docs_dir = fixture.path.join(\"docs\");\n    let out_dir = fixture.path.join(\"pkg\");\n    fs::create_dir(&out_dir).expect(\"should create pkg directory OK\");\n    let crate_data = CrateData::new(&fixture.path, None).unwrap();\n\n    assert!(readme::copy_from_crate(&crate_data, &fixture.path, &out_dir).is_ok());\n    let crate_readme_path = crate_docs_dir.join(\"README.md\");\n    let pkg_readme_path = out_dir.join(\"README.md\");\n    println!(\n        \"wasm-pack: should have copied README.md from '{}' to '{}'\",\n        crate_readme_path.display(),\n        pkg_readme_path.display()\n    );\n    assert!(fs::metadata(&crate_readme_path).is_ok());\n    assert!(fs::metadata(&pkg_readme_path).is_ok());\n\n    let crate_readme = utils::file::read_file(&crate_readme_path).unwrap();\n    let pkg_readme = utils::file::read_file(&pkg_readme_path).unwrap();\n    assert_eq!(crate_readme, pkg_readme);\n}\n\n#[test]\nfn it_ignores_a_disabled_readme() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .hello_world_src_lib()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            name = \"js-hello-world\"\n            readme = false\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            # Note that this uses and `=` dependency because there are\n            # various tests which assert that the version of wasm\n            # bindgen downloaded is what we expect, and if `=` is\n            # removed then it will download whatever the newest version\n            # of wasm-bindgen is which may not be what's listed here.\n            wasm-bindgen = \"=0.2.100\"\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"0.3\"\n        \"#,\n        )\n        .license()\n        .wasm_pack()\n        .arg(\"build\")\n        .assert()\n        .success()\n        .stderr(predicates::str::contains(\"origin crate has no README\").not());\n}\n"
  },
  {
    "path": "tests/all/stamps.rs",
    "content": "use std::{fs, panic};\nuse wasm_pack::stamps;\n\nfn run_test<T>(test: T) -> ()\nwhere\n    T: FnOnce() -> () + panic::UnwindSafe,\n{\n    before();\n    let result = panic::catch_unwind(|| test());\n    after();\n    assert!(result.is_ok())\n}\n\nfn before() {\n    remove_stamps_file()\n}\n\nfn after() {\n    remove_stamps_file()\n}\n\nfn remove_stamps_file() {\n    let stamps_file_path = stamps::get_stamps_file_path().unwrap();\n    if stamps_file_path.exists() {\n        fs::remove_file(stamps_file_path).unwrap();\n    }\n}\n\n#[test]\n#[should_panic]\n#[serial]\nfn load_stamp_from_non_existent_file() {\n    run_test(|| {\n        // ACT\n        let json = stamps::read_stamps_file_to_json().unwrap();\n        stamps::get_stamp_value(\"Foo\", &json).unwrap();\n    })\n}\n\n#[test]\n#[serial]\nfn load_stamp() {\n    run_test(|| {\n        // ARRANGE\n        stamps::save_stamp_value(\"Foo\", \"Bar\").unwrap();\n\n        // ACT\n        let json = stamps::read_stamps_file_to_json().unwrap();\n        let stamp_value = stamps::get_stamp_value(\"Foo\", &json).unwrap();\n\n        // ASSERT\n        assert_eq!(stamp_value, \"Bar\");\n    })\n}\n\n#[test]\n#[serial]\nfn update_stamp() {\n    run_test(|| {\n        // ARRANGE\n        stamps::save_stamp_value(\"Foo\", \"Bar\").unwrap();\n\n        // ACT\n        stamps::save_stamp_value(\"Foo\", \"John\").unwrap();\n\n        // ASSERT\n        let json = stamps::read_stamps_file_to_json().unwrap();\n        let stamp_value = stamps::get_stamp_value(\"Foo\", &json).unwrap();\n        assert_eq!(stamp_value, \"John\");\n    })\n}\n"
  },
  {
    "path": "tests/all/test.rs",
    "content": "use crate::utils::fixture;\nuse assert_cmd::prelude::*;\nuse predicates::prelude::*;\nuse std::env;\n\n#[test]\nfn it_can_run_node_tests() {\n    let fixture = fixture::wbg_test_node();\n    fixture.install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn it_can_run_tests_with_different_wbg_test_and_wbg_versions() {\n    let fixture = fixture::wbg_test_diff_versions();\n    fixture.install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .assert()\n        .success();\n}\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"aarch64\"),\n    all(target_os = \"windows\", target_arch = \"x86\"),\n    all(target_os = \"windows\", target_arch = \"x86_64\")\n))]\nfn it_can_run_browser_tests() {\n    let fixture = fixture::wbg_test_browser();\n    fixture.install_local_wasm_bindgen();\n\n    let firefox = cfg!(any(\n        all(target_os = \"linux\", target_arch = \"x86\"),\n        all(target_os = \"linux\", target_arch = \"x86_64\"),\n        all(target_os = \"macos\", target_arch = \"x86_64\"),\n        all(target_os = \"macos\", target_arch = \"aarch64\"),\n        all(target_os = \"windows\", target_arch = \"x86\"),\n        all(target_os = \"windows\", target_arch = \"x86_64\")\n    ));\n    if firefox {\n        fixture.install_local_geckodriver();\n    }\n\n    let chrome = cfg!(any(\n        all(target_os = \"linux\", target_arch = \"x86_64\"),\n        all(target_os = \"macos\", target_arch = \"x86_64\"),\n        all(target_os = \"windows\", target_arch = \"x86\")\n    ));\n    if chrome {\n        fixture.install_local_chromedriver();\n    }\n\n    let safari = cfg!(target_os = \"macos\");\n\n    if !firefox && !chrome && !safari {\n        return;\n    }\n\n    let mut cmd = fixture.wasm_pack();\n    cmd.arg(\"test\").arg(\"--headless\");\n\n    if firefox {\n        cmd.arg(\"--firefox\");\n    }\n    if chrome {\n        cmd.arg(\"--chrome\");\n    }\n    if safari {\n        cmd.arg(\"--safari\");\n    }\n\n    let _lock = fixture.lock();\n    cmd.assert().success();\n}\n\n#[test]\nfn it_can_run_failing_tests() {\n    let fixture = fixture::wbg_test_fail();\n    fixture.install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .assert()\n        .failure()\n        .stderr(predicates::str::contains(\n            \"Running Wasm tests with wasm-bindgen-test failed\",\n        ));\n}\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86\"),\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"aarch64\"),\n    all(target_os = \"windows\", target_arch = \"x86\"),\n    all(target_os = \"windows\", target_arch = \"x86_64\")\n))]\nfn it_can_find_a_webdriver_on_path() {\n    let fixture = fixture::wbg_test_browser();\n    let local_geckodriver = fixture.install_local_geckodriver();\n    let local_wasm_bindgen = fixture.install_local_wasm_bindgen();\n\n    let mut paths: Vec<_> = env::split_paths(&env::var(\"PATH\").unwrap()).collect();\n    paths.insert(0, local_geckodriver.parent().unwrap().to_path_buf());\n    paths.insert(0, local_wasm_bindgen.parent().unwrap().to_path_buf());\n    let path = env::join_paths(paths).unwrap();\n\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .env(\"PATH\", &path)\n        .arg(\"test\")\n        .arg(\"--firefox\")\n        .arg(\"--headless\")\n        .arg(\"--mode\")\n        .arg(\"no-install\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn it_requires_node_or_a_browser() {\n    let fixture = fixture::wbg_test_node();\n    fixture.install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .assert()\n        .failure()\n        .stderr(predicates::str::contains(\"Must specify at least one of\"));\n}\n\n#[test]\nfn the_headless_flag_requires_a_browser() {\n    let fixture = fixture::wbg_test_node();\n    fixture.install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .arg(\"--headless\")\n        .assert()\n        .failure()\n        .stderr(predicates::str::contains(\"only applies to browser tests\"));\n}\n\n#[test]\nfn complains_about_missing_wasm_bindgen_test_dependency() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                authors = [\"The wasm-pack developers\"]\n                description = \"so awesome rust+wasm package\"\n                license = \"WTFPL\"\n                name = \"missing-wbg-test\"\n                repository = \"https://github.com/drager/wasm-pack.git\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n\n                [dev-dependencies]\n                # no wasm-bindgen-test dep here!\n            \"#,\n        )\n        .hello_world_src_lib()\n        .install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .assert()\n        .failure()\n        .stderr(predicates::str::contains(\n            \"Ensure that you have \\\"wasm-bindgen-test\\\" as a dependency in your Cargo.toml file\",\n        ))\n        .stderr(predicates::str::contains(\"[dev-dependencies]\"))\n        .stderr(predicates::str::contains(\"wasm-bindgen-test = \\\"0.2\\\"\"));\n}\n\n#[test]\nfn renamed_crate_name_works() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                name = \"foo\"\n                version = \"0.1.0\"\n                authors = []\n\n                [lib]\n                crate-type = [\"cdylib\"]\n                name = 'bar'\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n\n                [dev-dependencies]\n                wasm-bindgen-test = \"0.2\"\n            \"#,\n        )\n        .file(\n            \"src/lib.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub fn one() -> u32 { 1 }\n            \"#,\n        )\n        .install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn cdylib_not_required() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                name = \"foo\"\n                version = \"0.1.0\"\n                authors = []\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n\n                [dev-dependencies]\n                wasm-bindgen-test = \"0.2\"\n            \"#,\n        )\n        .file(\n            \"src/lib.rs\",\n            r#\"\n                pub fn foo() -> u32 { 1 }\n            \"#,\n        )\n        .file(\n            \"tests/foo.rs\",\n            r#\"\n                extern crate wasm_bindgen_test;\n                use wasm_bindgen_test::*;\n\n                #[wasm_bindgen_test]\n                fn smoke() {\n                    foo::foo();\n                }\n            \"#,\n        )\n        .install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .assert()\n        .success();\n}\n\n#[test]\nfn test_output_is_printed_once_in_both_stdout_and_failures() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml(\"test-output-printed-once\")\n        .hello_world_src_lib()\n        .file(\n            \"tests/node.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                extern crate wasm_bindgen_test;\n                use wasm_bindgen::prelude::*;\n                use wasm_bindgen_test::*;\n                #[wasm_bindgen]\n                extern {\n                    #[wasm_bindgen(js_namespace = console)]\n                    fn log(s: &str);\n                }\n                #[wasm_bindgen_test]\n                fn yabba() {\n                    log(\"YABBA DABBA DOO\");\n                    assert_eq!(1, 2);\n                }\n            \"#,\n        )\n        .install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    // With newer wasm-bindgen-test, logs only appear once in the failure output\n    fixture\n        .wasm_pack()\n        .arg(\"test\")\n        .arg(\"--node\")\n        .assert()\n        .failure()\n        .stdout(predicate::function(|out: &str| {\n            out.matches(\"YABBA DABBA DOO\").count() == 1\n        }));\n}\n\n#[test]\nfn extra_options_is_passed_to_cargo_when_building_tests() {\n    let fixture = fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                name = \"foo\"\n                version = \"0.1.0\"\n                authors = []\n\n                [dev-dependencies]\n                wasm-bindgen-test = \"0.2\"\n\n                [features]\n                default = [\"native\"]\n                native = []\n            \"#,\n        )\n        .file(\n            \"src/lib.rs\",\n            r#\"\n                pub fn foo() -> u32 {\n                    #[cfg(feature = \"native\")]\n                    compile_error!(\"Test should pass through `--no-default-features` for this to pass.\");\n\n                    1\n                }\n            \"#,\n        )\n        .file(\n            \"tests/foo.rs\",\n            r#\"\n                extern crate wasm_bindgen_test;\n                use wasm_bindgen_test::*;\n\n                #[wasm_bindgen_test]\n                fn smoke() {\n                    foo::foo();\n                }\n\n                #[wasm_bindgen_test]\n                fn fire() {\n                    panic!(\"This should be filtered from test execution.\");\n                }\n            \"#,\n        )\n        .install_local_wasm_bindgen();\n    let _lock = fixture.lock();\n    fixture\n        .wasm_pack()\n        .args(&[\"test\", \"--node\", \"--no-default-features\", \"--\", \"smoke\"])\n        .assert()\n        .success();\n}\n"
  },
  {
    "path": "tests/all/utils/file.rs",
    "content": "use std::fs::File;\nuse std::io::Read;\nuse std::path::Path;\n\nuse anyhow::Result;\n\npub fn read_file(path: &Path) -> Result<String> {\n    let mut file = File::open(path)?;\n    let mut contents = String::new();\n    file.read_to_string(&mut contents)?;\n\n    Ok(contents)\n}\n"
  },
  {
    "path": "tests/all/utils/fixture.rs",
    "content": "use binary_install::Cache;\nuse lazy_static::lazy_static;\nuse std::env;\nuse std::fs;\nuse std::mem::ManuallyDrop;\nuse std::path::{Path, PathBuf};\nuse std::process::{Command, Stdio};\nuse std::sync::{MutexGuard, Once};\nuse std::thread;\nuse tempfile::TempDir;\nuse wasm_pack;\nuse wasm_pack::install::{self, Tool};\n\n/// A test fixture in a temporary directory.\npub struct Fixture {\n    // NB: we wrap the fixture's tempdir in a `ManuallyDrop` so that if a test\n    // fails, its directory isn't deleted, and we have a chance to manually\n    // inspect its state and figure out what is going on.\n    pub dir: ManuallyDrop<TempDir>,\n    pub path: PathBuf,\n}\n\nimpl Fixture {\n    /// Create a new test fixture in a temporary directory.\n    pub fn new() -> Fixture {\n        // Make sure that all fixtures end up sharing a target dir, and we don't\n        // recompile wasm-bindgen and friends many times over.\n        static SET_TARGET_DIR: Once = Once::new();\n        let target_dir = Path::new(env!(\"CARGO_MANIFEST_DIR\")).join(\"target\");\n        SET_TARGET_DIR.call_once(|| {\n            env::set_var(\"CARGO_TARGET_DIR\", &target_dir);\n        });\n\n        let root = target_dir.join(\"t\");\n        fs::create_dir_all(&root).unwrap();\n        let dir = TempDir::new_in(&root).unwrap();\n        let path = dir.path().join(\"wasm-pack\");\n        eprintln!(\"Created fixture at {}\", path.display());\n        Fixture {\n            dir: ManuallyDrop::new(dir),\n            path,\n        }\n    }\n\n    /// Create a file within this fixture.\n    ///\n    /// `path` should be a relative path to the file (relative within this\n    /// fixture's path).\n    ///\n    /// The `contents` are written to the file.\n    pub fn file<P: AsRef<Path>, C: AsRef<[u8]>>(&self, path: P, contents: C) -> &Self {\n        assert!(path.as_ref().is_relative());\n        let path = self.path.join(path);\n        if let Some(parent) = path.parent() {\n            fs::create_dir_all(parent).unwrap();\n        }\n        fs::write(path, contents).unwrap();\n        self\n    }\n\n    /// Add a generic `README.md` file to the fixture.\n    pub fn readme(&self) -> &Self {\n        self.file(\n            \"README.md\",\n            r#\"\n                # Fixture!\n                > an example rust -> wasm project\n            \"#,\n        )\n    }\n\n    /// Add `LICENSE` file to the fixture.\n    pub fn license(&self) -> &Self {\n        self.file(\n            \"LICENSE\",\n            r#\"\n                I'm a license!\n            \"#,\n        )\n    }\n\n    /// Add `WTFPL LICENSE` file to the fixture.\n    pub fn wtfpl_license(&self) -> &Self {\n        self.file(\n            \"LICENSE-WTFPL\",\n            r#\"\n                DO WHATEVER YOU WANT TO PUBLIC LICENSE\n                    Version 2, December 2004\n\n                Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>\n\n                Everyone is permitted to copy and distribute verbatim or modified\n                copies of this license document, and changing it is allowed as long\n                as the name is changed.\n\n                DO WHATEVER YOU WANT TO PUBLIC LICENSE\n                TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n                0. You just DO WHATEVER YOU WANT TO.\n            \"#,\n        )\n    }\n\n    /// Add `MIT LICENSE` file to the fixture.\n    pub fn mit_license(&self) -> &Self {\n        self.file(\n            \"LICENSE-MIT\",\n            r#\"\n                Copyright <YEAR> <COPYRIGHT HOLDER>\n\n                Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\n                The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\n                THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n            \"#,\n        )\n    }\n\n    /// Add a `Cargo.toml` with a correctly configured `wasm-bindgen`\n    /// dependency, `wasm-bindgen-test` dev-dependency, and `crate-type =\n    /// [\"cdylib\"]`.\n    ///\n    /// `name` is the crate's name.\n    pub fn cargo_toml(&self, name: &str) -> &Self {\n        self.file(\n            \"Cargo.toml\",\n            &format!(\n                r#\"\n                    [package]\n                    authors = [\"The wasm-pack developers\"]\n                    description = \"so awesome rust+wasm package\"\n                    license = \"WTFPL\"\n                    name = \"{}\"\n                    repository = \"https://github.com/drager/wasm-pack.git\"\n                    version = \"0.1.0\"\n\n                    [lib]\n                    crate-type = [\"cdylib\"]\n\n                    [dependencies]\n                    # Note that this uses and `=` dependency because there are\n                    # various tests which assert that the version of wasm\n                    # bindgen downloaded is what we expect, and if `=` is\n                    # removed then it will download whatever the newest version\n                    # of wasm-bindgen is which may not be what's listed here.\n                    wasm-bindgen = \"=0.2.100\"\n\n                    [dev-dependencies]\n                    wasm-bindgen-test = \"0.3\"\n                \"#,\n                name\n            ),\n        )\n    }\n\n    /// Add a `Cargo.toml` with a correctly configured `wasm-bindgen`\n    /// dependency, `wasm-bindgen-test` dev-dependency, and `crate-type =\n    /// [\"cdylib\"]`.\n    ///\n    /// `name` is the crate's name.\n    /// `profile` is the custom profile name.\n    pub fn cargo_toml_with_custom_profile(&self, name: &str, profile_name: &str) -> &Self {\n        self.file(\n            \"Cargo.toml\",\n            &format!(\n                r#\"\n                    [package]\n                    authors = [\"The wasm-pack developers\"]\n                    description = \"so awesome rust+wasm package\"\n                    license = \"WTFPL\"\n                    name = \"{}\"\n                    repository = \"https://github.com/drager/wasm-pack.git\"\n                    version = \"0.1.0\"\n\n                    [lib]\n                    crate-type = [\"cdylib\"]\n\n                    [dependencies]\n                    # Note that this uses and `=` dependency because there are\n                    # various tests which assert that the version of wasm\n                    # bindgen downloaded is what we expect, and if `=` is\n                    # removed then it will download whatever the newest version\n                    # of wasm-bindgen is which may not be what's listed here.\n                    wasm-bindgen = \"=0.2.100\"\n\n                    [dev-dependencies]\n                    wasm-bindgen-test = \"0.3\"\n\n                    [profile.{}]\n                    inherits = \"release\"\n                    opt-level = 'z'\n                    lto = true\n                \"#,\n                name, profile_name\n            ),\n        )\n    }\n\n    /// Add a `Cargo.toml` with a correctly configured `wasm-bindgen`\n    /// dependency, `wasm-bindgen-test` dev-dependency, and `crate-type =\n    /// [\"cdylib\"]`.\n    ///\n    /// `name` is the crate's name.\n    /// `license_file` is license file path\n    pub fn cargo_toml_with_license_file(&self, name: &str, license_file: &str) -> &Self {\n        self.file(\n            \"Cargo.toml\",\n            &format!(\n                r#\"\n                    [package]\n                    authors = [\"The wasm-pack developers\"]\n                    description = \"so awesome rust+wasm package\"\n                    name = \"{}\"\n                    license-file = \"{}\"\n                    repository = \"https://github.com/drager/wasm-pack.git\"\n                    version = \"0.1.0\"\n\n                    [lib]\n                    crate-type = [\"cdylib\"]\n\n                    [dependencies]\n                    wasm-bindgen = \"=0.2.100\"\n\n                    [dev-dependencies]\n                    wasm-bindgen-test = \"=0.2.21\"\n                \"#,\n                name, license_file\n            ),\n        )\n    }\n\n    /// Add a `src/lib.rs` file that contains a \"hello world\" program.\n    pub fn hello_world_src_lib(&self) -> &Self {\n        self.file(\n            \"src/lib.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                // Import the `window.alert` function from the Web.\n                #[wasm_bindgen]\n                extern {\n                    fn alert(s: &str);\n                }\n\n                // Export a `greet` function from Rust to JavaScript, that alerts a\n                // hello message.\n                #[wasm_bindgen]\n                pub fn greet(name: &str) {\n                    alert(&format!(\"Hello, {}!\", name));\n                }\n            \"#,\n        )\n    }\n\n    /// Install a local wasm-bindgen for this fixture.\n    ///\n    /// Takes care not to re-install for every fixture, but only the one time\n    /// for the whole test suite.\n    pub fn install_local_wasm_bindgen(&self) -> PathBuf {\n        // If wasm-bindgen is being used then it's very likely wasm-opt is going\n        // to be used as well.\n        self.install_wasm_opt();\n\n        static INSTALL_WASM_BINDGEN: Once = Once::new();\n        let cache = self.cache();\n        let version = \"0.2.100\";\n\n        let download = || {\n            if let Ok(download) =\n                install::download_prebuilt(&Tool::WasmBindgen, &cache, version, true)\n            {\n                return Ok(download);\n            }\n\n            install::cargo_install(Tool::WasmBindgen, &cache, version, true)\n        };\n\n        // Only one thread can perform the actual download, and then afterwards\n        // everything will hit the cache so we can run the same path.\n        INSTALL_WASM_BINDGEN.call_once(|| {\n            download().unwrap();\n        });\n        if let install::Status::Found(dl) = download().unwrap() {\n            dl.binary(\"wasm-bindgen\").unwrap()\n        } else {\n            panic!(\"Download failed\")\n        }\n    }\n\n    pub fn install_wasm_opt(&self) {\n        static INSTALL_WASM_OPT: Once = Once::new();\n        let cache = self.cache();\n\n        INSTALL_WASM_OPT.call_once(|| {\n            wasm_pack::wasm_opt::find_wasm_opt(&cache, true).unwrap();\n        });\n    }\n\n    /// Install a local cargo-generate for this fixture.\n    ///\n    /// Takes care not to re-install for every fixture, but only the one time\n    /// for the whole test suite.\n    pub fn install_local_cargo_generate(&self) -> PathBuf {\n        static INSTALL_CARGO_GENERATE: Once = Once::new();\n        let cache = self.cache();\n\n        let download = || {\n            if let Ok(download) =\n                install::download_prebuilt(&Tool::CargoGenerate, &cache, \"latest\", true)\n            {\n                return Ok(download);\n            }\n\n            install::cargo_install(Tool::CargoGenerate, &cache, \"latest\", true)\n        };\n\n        // Only one thread can perform the actual download, and then afterwards\n        // everything will hit the cache so we can run the same path.\n        INSTALL_CARGO_GENERATE.call_once(|| {\n            download().unwrap();\n        });\n        if let install::Status::Found(dl) = download().unwrap() {\n            dl.binary(\"cargo-generate\").unwrap()\n        } else {\n            panic!(\"Download failed\")\n        }\n    }\n\n    /// Download `geckodriver` and return its path.\n    ///\n    /// Takes care to ensure that only one `geckodriver` is downloaded for the whole\n    /// test suite.\n    pub fn install_local_geckodriver(&self) -> PathBuf {\n        static FETCH_GECKODRIVER: Once = Once::new();\n        let cache = self.cache();\n\n        // like above for synchronization\n        FETCH_GECKODRIVER.call_once(|| {\n            wasm_pack::test::webdriver::install_geckodriver(&cache, true).unwrap();\n        });\n        wasm_pack::test::webdriver::install_geckodriver(&cache, true).unwrap()\n    }\n\n    /// Download `chromedriver` and return its path.\n    ///\n    /// Takes care to ensure that only one `chromedriver` is downloaded for the whole\n    /// test suite.\n    pub fn install_local_chromedriver(&self) -> PathBuf {\n        static FETCH_CHROMEDRIVER: Once = Once::new();\n        let cache = self.cache();\n\n        // like above for synchronization\n        FETCH_CHROMEDRIVER.call_once(|| {\n            wasm_pack::test::webdriver::install_chromedriver(&cache, true).unwrap();\n        });\n        wasm_pack::test::webdriver::install_chromedriver(&cache, true).unwrap()\n    }\n\n    pub fn cache_dir(&self) -> PathBuf {\n        Path::new(env!(\"CARGO_MANIFEST_DIR\"))\n            .join(\"target\")\n            .join(\"test_cache\")\n    }\n\n    pub fn cache(&self) -> Cache {\n        let cache_dir = self.cache_dir();\n        fs::create_dir_all(&cache_dir).unwrap();\n        Cache::at(&cache_dir)\n    }\n\n    /// The `step_install_wasm_bindgen` and `step_run_wasm_bindgen` steps only\n    /// occur after the `step_build_wasm` step. In order to read the lockfile\n    /// in the test fixture's temporary directory, we should first build the\n    /// crate, targeting `wasm32-unknown-unknown`.\n    pub fn cargo_check(&self) -> &Self {\n        Command::new(\"cargo\")\n            .current_dir(&self.path)\n            .arg(\"check\")\n            .arg(\"--target\")\n            .arg(\"wasm32-unknown-unknown\")\n            .stdout(Stdio::null())\n            .stderr(Stdio::null())\n            .status()\n            .unwrap();\n        self\n    }\n\n    /// Get a `wasm-pack` command configured to run in this fixure's temp\n    /// directory and using the test cache.\n    pub fn wasm_pack(&self) -> Command {\n        use assert_cmd::cargo;\n\n        let mut cmd = Command::new(cargo::cargo_bin!(env!(\"CARGO_PKG_NAME\")));\n\n        cmd.current_dir(&self.path);\n        cmd.env(\"WASM_PACK_CACHE\", self.cache_dir());\n\n        // Some of the tests assume that Cargo's output does not contain colors.\n        cmd.env_remove(\"CARGO_TERM_COLOR\");\n\n        cmd\n    }\n\n    pub fn lock(&self) -> MutexGuard<'static, ()> {\n        use std::sync::Mutex;\n        lazy_static! {\n            static ref ONE_TEST_AT_A_TIME: Mutex<()> = Mutex::new(());\n        }\n        ONE_TEST_AT_A_TIME.lock().unwrap_or_else(|e| e.into_inner())\n    }\n}\n\nimpl Drop for Fixture {\n    fn drop(&mut self) {\n        if !thread::panicking() {\n            unsafe { ManuallyDrop::drop(&mut self.dir) }\n        }\n    }\n}\n\npub fn bad_cargo_toml() -> Fixture {\n    let fixture = Fixture::new();\n    fixture.readme().hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            name = \"bad-cargo-toml\"\n            version = \"0.1.0\"\n            authors = [\"The wasm-pack developers\"]\n\n            [lib]\n            crate-type = [\"foo\"]\n\n            [dependencies]\n            # Note: no wasm-bindgen dependency!\n        \"#,\n    );\n    fixture\n}\n\npub fn js_hello_world() -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml(\"js-hello-world\")\n        .hello_world_src_lib();\n    fixture\n}\n\npub fn js_hello_world_with_custom_profile(profile_name: &str) -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml_with_custom_profile(\"js-hello-world\", profile_name)\n        .hello_world_src_lib();\n    fixture\n}\n\npub fn no_cdylib() -> Fixture {\n    let fixture = Fixture::new();\n    fixture.readme().hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"foo\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            # [lib]\n            # crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"0.2\"\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"0.3\"\n        \"#,\n    );\n    fixture\n}\n\npub fn not_a_crate() -> Fixture {\n    let fixture = Fixture::new();\n    fixture.file(\"README.md\", \"This is not a Rust crate!\");\n    fixture\n}\n\npub fn serde_feature() -> Fixture {\n    let fixture = Fixture::new();\n    fixture.readme().hello_world_src_lib().file(\n        \"Cargo.toml\",\n        r#\"\n            [package]\n            name = \"serde-serialize\"\n            version = \"0.1.0\"\n            authors = [\"The wasm-pack developers\"]\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies.wasm-bindgen]\n            version = \"^0.2\"\n            features = [\"serde-serialize\"]\n        \"#,\n    );\n    fixture\n}\n\npub fn wbg_test_diff_versions() -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                name = \"wbg-test-diff-versions\"\n                version = \"0.1.0\"\n                authors = [\"The wasm-pack developers\"]\n\n                [lib]\n                crate-type = [\"cdylib\", \"rlib\"]\n\n                [dependencies]\n                # We depend on the latest wasm-bindgen 0.2\n                wasm-bindgen = \"0.2\"\n\n                [dev-dependencies]\n                # And we depend on wasm-bindgen-test 0.2.29. This should still\n                # work, and we should end up with the latest `wasm-bindgen` and\n                # wasm-bindgen-test at 0.2.29, and everything should still work.\n                wasm-bindgen-test = \"0.2.29\"\n            \"#,\n        )\n        .file(\n            \"src/lib.rs\",\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                #[wasm_bindgen]\n                pub fn one() -> u32 { 1 }\n            \"#,\n        )\n        .file(\n            \"tests/node.rs\",\n            r#\"\n                extern crate wbg_test_diff_versions;\n                extern crate wasm_bindgen_test;\n                use wasm_bindgen_test::*;\n\n                #[wasm_bindgen_test]\n                fn pass() {\n                    assert_eq!(wbg_test_diff_versions::one(), 1);\n                }\n            \"#,\n        );\n    fixture\n}\n\npub fn wbg_test_browser() -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml(\"wbg-test-browser\")\n        .hello_world_src_lib()\n        .file(\n            \"tests/browser.rs\",\n            r#\"\n                extern crate wasm_bindgen_test;\n                use wasm_bindgen_test::*;\n\n                wasm_bindgen_test_configure!(run_in_browser);\n\n                #[wasm_bindgen_test]\n                fn pass() {\n                    assert_eq!(1, 1);\n                }\n            \"#,\n        );\n    fixture\n}\n\npub fn wbg_test_fail() -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml(\"wbg-test-fail\")\n        .hello_world_src_lib()\n        .file(\n            \"tests/node.rs\",\n            r#\"\n                extern crate wasm_bindgen_test;\n                use wasm_bindgen_test::*;\n\n                #[wasm_bindgen_test]\n                fn pass() {\n                    assert_eq!(1, 2);\n                }\n            \"#,\n        );\n    fixture\n}\n\npub fn wbg_test_node() -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml(\"wbg-test-node\")\n        .hello_world_src_lib()\n        .file(\n            \"tests/node.rs\",\n            r#\"\n                extern crate wasm_bindgen_test;\n                use wasm_bindgen_test::*;\n\n                #[wasm_bindgen_test]\n                fn pass() {\n                    assert_eq!(1, 1);\n                }\n            \"#,\n        );\n    fixture\n}\n\npub fn transitive_dependencies() -> Fixture {\n    fn project_main_fixture(fixture: &mut Fixture) {\n        fixture.file(PathBuf::from(\"main/README\"), \"# Main Fixture\\n\");\n        fixture.file(\n            PathBuf::from(\"main/Cargo.toml\"),\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"main_project\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"0.2\"\n            project_a = { path = \"../project_a\" }\n            project_b = { path = \"../project_b\" }\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"0.3\"\n        \"#,\n        );\n        fixture.file(\n            PathBuf::from(\"main/src/lib.rs\"),\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                // Import the `window.alert` function from the Web.\n                #[wasm_bindgen]\n                extern {\n                    fn alert(s: &str);\n                }\n\n                // Export a `greet` function from Rust to JavaScript, that alerts a\n                // hello message.\n                #[wasm_bindgen]\n                pub fn greet(name: &str) {\n                    alert(&format!(\"Hello, {}!\", name));\n                }\n            \"#,\n        );\n    }\n\n    fn project_a_fixture(fixture: &mut Fixture) {\n        fixture.file(\n            PathBuf::from(\"project_a/README\"),\n            \"# Project Alpha Fixture\\n\",\n        );\n        fixture.file(\n            PathBuf::from(\"project_a/Cargo.toml\"),\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"project_a\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"0.2\"\n            project_b = { path = \"../project_b\" }\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"0.3\"\n        \"#,\n        );\n        fixture.file(\n            PathBuf::from(\"project_a/src/lib.rs\"),\n            r#\"\n                extern crate wasm_bindgen;\n                // extern crate project_b;\n                use wasm_bindgen::prelude::*;\n\n                // Import the `window.alert` function from the Web.\n                #[wasm_bindgen]\n                extern {\n                    fn alert(s: &str);\n                }\n\n                // Export a `greet` function from Rust to JavaScript, that alerts a\n                // hello message.\n                #[wasm_bindgen]\n                pub fn greet(name: &str) {\n                    alert(&format!(\"Hello, {}!\", name));\n                }\n            \"#,\n        );\n    }\n\n    fn project_b_fixture(fixture: &mut Fixture) {\n        fixture.file(\n            PathBuf::from(\"project_b/README\"),\n            \"# Project Beta Fixture\\n\",\n        );\n        fixture.file(\n            PathBuf::from(\"project_b/Cargo.toml\"),\n            r#\"\n            [package]\n            authors = [\"The wasm-pack developers\"]\n            description = \"so awesome rust+wasm package\"\n            license = \"WTFPL\"\n            name = \"project_b\"\n            repository = \"https://github.com/drager/wasm-pack.git\"\n            version = \"0.1.0\"\n\n            [lib]\n            crate-type = [\"cdylib\"]\n\n            [dependencies]\n            wasm-bindgen = \"0.2\"\n\n            [dev-dependencies]\n            wasm-bindgen-test = \"0.3\"\n        \"#,\n        );\n        fixture.file(\n            PathBuf::from(\"project_b/src/lib.rs\"),\n            r#\"\n                extern crate wasm_bindgen;\n                use wasm_bindgen::prelude::*;\n\n                // Import the `window.alert` function from the Web.\n                #[wasm_bindgen]\n                extern {\n                    fn alert(s: &str);\n                }\n\n                // Export a `greet` function from Rust to JavaScript, that alerts a\n                // hello message.\n                #[wasm_bindgen]\n                pub fn greet(name: &str) {\n                    alert(&format!(\"Hello, {}!\", name));\n                }\n            \"#,\n        );\n    }\n\n    let mut fixture = Fixture::new();\n    project_b_fixture(&mut fixture);\n    project_a_fixture(&mut fixture);\n    project_main_fixture(&mut fixture);\n    fixture\n}\n\npub fn single_license() -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml(\"single_license\")\n        .license()\n        .hello_world_src_lib();\n    fixture\n}\n\npub fn dual_license() -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml(\"dual_license\")\n        .wtfpl_license()\n        .mit_license()\n        .hello_world_src_lib();\n    fixture\n}\n\npub fn non_standard_license(license_file: &str) -> Fixture {\n    let fixture = Fixture::new();\n    fixture\n        .readme()\n        .cargo_toml_with_license_file(\"dual_license\", license_file)\n        .file(license_file, \"license file for test\")\n        .hello_world_src_lib();\n    fixture\n}\n"
  },
  {
    "path": "tests/all/utils/manifest.rs",
    "content": "use std::io::prelude::*;\nuse std::path::Path;\nuse std::{collections::HashMap, fs::File};\n\nuse anyhow::Result;\nuse serde_json;\n\n#[derive(Deserialize)]\npub struct NpmPackage {\n    pub name: String,\n    #[serde(default = \"default_none\", rename = \"type\")]\n    pub ty: String,\n    pub description: String,\n    pub version: String,\n    pub license: String,\n    pub repository: Repository,\n    pub files: Vec<String>,\n    #[serde(default = \"default_none\")]\n    pub main: String,\n    #[serde(default = \"default_none\")]\n    pub module: String,\n    #[serde(default = \"default_none\")]\n    pub browser: String,\n    #[serde(default = \"default_none\")]\n    pub types: String,\n    #[serde(default = \"Vec::new\", rename = \"sideEffects\")]\n    pub side_effects: Vec<String>,\n    pub homepage: Option<String>,\n    pub keywords: Option<Vec<String>>,\n    pub dependencies: Option<HashMap<String, String>>,\n}\n\nfn default_none() -> String {\n    \"\".to_string()\n}\n\n#[derive(Deserialize)]\npub struct Repository {\n    #[serde(rename = \"type\")]\n    pub ty: String,\n    pub url: String,\n}\n\npub fn read_package_json(path: &Path, out_dir: &Path) -> Result<NpmPackage> {\n    let manifest_path = path.join(out_dir).join(\"package.json\");\n    let mut pkg_file = File::open(manifest_path)?;\n    let mut pkg_contents = String::new();\n    pkg_file.read_to_string(&mut pkg_contents)?;\n\n    Ok(serde_json::from_str(&pkg_contents)?)\n}\n\npub fn create_wbg_package_json(out_dir: &Path, contents: &str) -> Result<()> {\n    let manifest_path = out_dir.join(\"package.json\");\n    Ok(std::fs::write(manifest_path, contents)?)\n}\n"
  },
  {
    "path": "tests/all/utils/mod.rs",
    "content": "pub mod file;\npub mod fixture;\npub mod manifest;\n"
  },
  {
    "path": "tests/all/wasm_opt.rs",
    "content": "use crate::utils;\nuse assert_cmd::prelude::*;\nuse predicates::prelude::*;\n\n#[test]\nfn off_in_dev() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture.readme().cargo_toml(\"foo\").file(\"src/lib.rs\", \"\");\n    fixture.install_local_wasm_bindgen();\n    fixture.install_wasm_opt();\n\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--dev\")\n        .assert()\n        .stderr(predicates::str::contains(\"wasm-opt\").not())\n        .success();\n}\n\n#[test]\nfn on_in_release() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture.readme().cargo_toml(\"foo\").file(\"src/lib.rs\", \"\");\n    fixture.install_local_wasm_bindgen();\n    fixture.install_wasm_opt();\n\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .assert()\n        .stderr(predicates::str::contains(\"wasm-opt\"))\n        .success();\n}\n\n#[test]\nfn disable_in_release() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                authors = []\n                description = \"\"\n                license = \"MIT\"\n                name = \"foo\"\n                repository = \"\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n\n                [package.metadata.wasm-pack.profile.release]\n                wasm-opt = false\n            \"#,\n        )\n        .file(\"src/lib.rs\", \"\");\n    fixture.install_local_wasm_bindgen();\n    fixture.install_wasm_opt();\n\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .assert()\n        .stderr(predicates::str::contains(\"wasm-opt\").not())\n        .success();\n}\n\n#[test]\nfn enable_in_dev() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                authors = []\n                description = \"\"\n                license = \"MIT\"\n                name = \"foo\"\n                repository = \"\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n\n                [package.metadata.wasm-pack.profile.dev]\n                wasm-opt = true\n            \"#,\n        )\n        .file(\"src/lib.rs\", \"\");\n    fixture.install_local_wasm_bindgen();\n    fixture.install_wasm_opt();\n\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .arg(\"--dev\")\n        .assert()\n        .stderr(predicates::str::contains(\n            \"Optimizing wasm binaries with `wasm-opt`\",\n        ))\n        .success();\n}\n\n#[test]\nfn custom_args() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                authors = []\n                description = \"\"\n                license = \"MIT\"\n                name = \"foo\"\n                repository = \"\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n\n                [package.metadata.wasm-pack.profile.release]\n                wasm-opt = ['--not-accepted-argument']\n            \"#,\n        )\n        .file(\"src/lib.rs\", \"\");\n    fixture.install_local_wasm_bindgen();\n    fixture.install_wasm_opt();\n\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .assert()\n        .stderr(predicates::str::contains(\"--not-accepted-argument\"))\n        .failure();\n}\n\n#[test]\nfn misconfigured() {\n    let fixture = utils::fixture::Fixture::new();\n    fixture\n        .readme()\n        .file(\n            \"Cargo.toml\",\n            r#\"\n                [package]\n                authors = []\n                description = \"\"\n                license = \"MIT\"\n                name = \"foo\"\n                repository = \"\"\n                version = \"0.1.0\"\n\n                [lib]\n                crate-type = [\"cdylib\"]\n\n                [dependencies]\n                wasm-bindgen = \"0.2\"\n\n                [package.metadata.wasm-pack.profile.release]\n                wasm-opt = 32\n            \"#,\n        )\n        .file(\"src/lib.rs\", \"\");\n    fixture.install_local_wasm_bindgen();\n    fixture.install_wasm_opt();\n\n    fixture\n        .wasm_pack()\n        .arg(\"build\")\n        .assert()\n        .stderr(predicates::str::contains(\"failed to parse manifest\"))\n        .failure();\n}\n"
  },
  {
    "path": "tests/all/webdriver.rs",
    "content": "use crate::utils::fixture;\nuse binary_install::Cache;\nuse wasm_pack::test::webdriver;\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(target_os = \"windows\", target_arch = \"x86\"),\n    all(target_os = \"windows\", target_arch = \"x86_64\")\n))]\nfn can_install_chromedriver() {\n    let fixture = fixture::js_hello_world();\n    let cache = Cache::at(&fixture.path);\n    assert!(webdriver::install_chromedriver(&cache, true).is_ok());\n}\n\n#[test]\n#[cfg(any(\n    all(target_os = \"linux\", target_arch = \"x86\"),\n    all(target_os = \"linux\", target_arch = \"x86_64\"),\n    all(target_os = \"linux\", target_arch = \"aarch64\"),\n    all(target_os = \"macos\", target_arch = \"x86_64\"),\n    all(target_os = \"macos\", target_arch = \"aarch64\"),\n    all(target_os = \"windows\", target_arch = \"x86\"),\n    all(target_os = \"windows\", target_arch = \"x86_64\")\n))]\nfn can_install_geckodriver() {\n    let fixture = fixture::js_hello_world();\n    let cache = Cache::at(&fixture.path);\n    assert!(webdriver::install_geckodriver(&cache, true).is_ok());\n}\n"
  }
]