diff --git a/.github/test-actions/test-artifact-version/action.yml b/.github/test-actions/test-artifact-version/action.yml new file mode 100644 index 000000000..f68483a10 --- /dev/null +++ b/.github/test-actions/test-artifact-version/action.yml @@ -0,0 +1,88 @@ +name: Test inject-branch-version and check-artifact-version + +runs: + using: composite + steps: + - uses: ./actions/detect-branch-version + id: version-detector + + - name: Inject version into Rust crate + uses: ./actions/inject-branch-version + with: + project-directory: ./tests/rust-crate + + - name: Inject version into Rust web assembly + uses: ./actions/inject-branch-version + with: + project-directory: ./tests/rust-wasm + + - name: Inject version into NodeJS package + uses: ./actions/inject-branch-version + with: + project-directory: ./tests/npm-package + + - name: Inject version into unknown project + uses: ./actions/inject-branch-version + with: + artifact-descriptor: some-descriptor.txt + project-directory: ./tests/unknown-tech + + - name: Display updated artifacts + shell: bash + run: | + echo "🦀Rust descriptor:" + less ./tests/rust-crate/Cargo.toml + + echo + + echo "🦀Rust 🌐web assembly descriptor:" + less ./tests/rust-wasm/Cargo.toml + + echo + + echo "📦NodeJS descriptor:" + less ./tests/npm-package/package.json + + echo + + echo "🎁Unknown tech descriptor:" + less ./tests/unknown-tech/some-descriptor.txt + + echo "🌳🌳🌳" + + - name: Version should appear correctly in Rust crate + uses: ./actions/check-artifact-version + with: + project-directory: ./tests/rust-crate + + - name: Version should appear correctly in Rust wasm + uses: ./actions/check-artifact-version + with: + project-directory: ./tests/rust-wasm + + - name: Version should appear correctly in npm package + uses: ./actions/check-artifact-version + with: + project-directory: ./tests/npm-package + + - name: Version should appear correctly in unknown descriptor + shell: bash + run: | + version="${{ steps.version-detector.outputs.version }}" + + if ! cat ./tests/unknown-tech/some-descriptor.txt | grep -q "v$version" + then + echo "❌Error while injecting the version into a custom descriptor!" >&2 + exit 1 + fi + + - name: Version should be injected multiple times + shell: bash + run: | + version="${{ steps.version-detector.outputs.version }}" + + if ! cat ./tests/unknown-tech/some-descriptor.txt | grep -q "'$version';" + then + echo "❌The version was not injected globally into a custom descriptor!" >&2 + exit 1 + fi diff --git a/.github/test-actions/test-check-rust-versions/action.yml b/.github/test-actions/test-check-rust-versions/action.yml new file mode 100644 index 000000000..e2b159a59 --- /dev/null +++ b/.github/test-actions/test-check-rust-versions/action.yml @@ -0,0 +1,14 @@ +name: Test check-rust-versions + +runs: + using: composite + steps: + - name: Checking Rust versions for Rust crate should work + uses: ./actions/check-rust-versions + with: + project-directory: ./tests/rust-crate + + - name: Checking Rust versions for Rust web assembly should work + uses: ./actions/check-rust-versions + with: + project-directory: ./tests/rust-wasm diff --git a/.github/test-actions/test-detect-branch-version/action.yml b/.github/test-actions/test-detect-branch-version/action.yml new file mode 100644 index 000000000..d16bb330f --- /dev/null +++ b/.github/test-actions/test-detect-branch-version/action.yml @@ -0,0 +1,69 @@ +name: Test detect-branch-version + +runs: + using: composite + steps: + - uses: ./actions/detect-branch-version + id: detector + + - name: Branch should not be empty + shell: bash + run: | + branch="${{ steps.detector.outputs.branch }}" + + echo "🔎Branch retrieved from action: '$branch'" + if [[ -z "$branch" ]] + then + echo "❌The branch should not be empty!" >&2 + exit 1 + fi + + - name: The detected branch should be the one starting the pull request for this test + shell: bash + run: | + headRef="${{ github.head_ref }}" + branch="${{ steps.detector.outputs.branch }}" + + echo "🔎Head ref in pull request: '$headRef'" + + if [[ "$branch" != "$headRef" ]] + then + echo "❌The branch ('$branch') should match the head_ref ('$headRef')!" >&2 + exit 1 + fi + + - name: Version should not be empty + shell: bash + run: | + version="${{ steps.detector.outputs.version }}" + + echo "🔎Version retrieved from action: '$version'" + if [[ -z "$version" ]] + then + echo "❌The version should not be empty!" >&2 + exit 1 + fi + + - name: Escaped version should include escaped dots + shell: bash + run: | + escapedVersion="${{ steps.detector.outputs.escaped-version }}" + + echo "🔎Escaped version retrieved from action: '$escapedVersion'" + if ! echo "$escapedVersion" | egrep -q "\\\." + then + echo "❌The escaped version should include '\.'!" >&2 + exit 1 + fi + + - name: Major component should not be empty + shell: bash + run: | + major="${{ steps.detector.outputs.major }}" + + echo "🔎Major version component: '$major'" + if [[ -z "$major" ]] + then + echo "❌The major component should not be empty!" >&2 + exit 1 + fi diff --git a/.github/test-actions/test-detect-project-tech/action.yml b/.github/test-actions/test-detect-project-tech/action.yml new file mode 100644 index 000000000..02015ce99 --- /dev/null +++ b/.github/test-actions/test-detect-project-tech/action.yml @@ -0,0 +1,120 @@ +name: Test detect-project-tech + +runs: + using: composite + steps: + - uses: ./actions/detect-project-tech + id: detect-rust-crate + with: + project-directory: ./tests/rust-crate + + - name: Tech for Rust crate should be detected + shell: bash + run: | + tech="${{ steps.detect-rust-crate.outputs.project-tech }}" + + echo "🔎Technology retrieved for 🦀Rust: '$tech'" + if [[ "$tech" != "rust" ]] + then + echo "❌Incorrect project tech!" >&2 + exit 1 + fi + + - name: Artifact descriptor for Rust crate should be detected + shell: bash + run: | + artifactDescriptor="${{ steps.detect-rust-crate.outputs.artifact-descriptor }}" + + echo "🔎Artifact descriptor retrieved for 🦀Rust: '$artifactDescriptor'" + if [[ "$artifactDescriptor" != "Cargo.toml" ]] + then + echo "❌Incorrect artifact descriptor!" >&2 + exit 1 + fi + + - uses: ./actions/detect-project-tech + id: detect-rust-wasm + with: + project-directory: ./tests/rust-wasm + + - name: Tech for Rust web assembly should be detected + shell: bash + run: | + tech="${{ steps.detect-rust-wasm.outputs.project-tech }}" + + echo "🔎Technology retrieved for 🦀Rust 🌐web assembly: '$tech'" + if [[ "$tech" != "rust" ]] + then + echo "❌Incorrect project tech!" >&2 + exit 1 + fi + + - name: Artifact descriptor for Rust web assembly should be detected + shell: bash + run: | + artifactDescriptor="${{ steps.detect-rust-wasm.outputs.artifact-descriptor }}" + + echo "🔎Artifact descriptor retrieved for 🦀Rust 🌐web assembly: '$artifactDescriptor'" + if [[ "$artifactDescriptor" != "Cargo.toml" ]] + then + echo "❌Incorrect artifact descriptor!" >&2 + exit 1 + fi + + - uses: ./actions/detect-project-tech + id: detect-nodejs-package + with: + project-directory: ./tests/npm-package + + - name: Tech for NodeJS package should be detected + shell: bash + run: | + tech="${{ steps.detect-nodejs-package.outputs.project-tech }}" + + echo "🔎Technology retrieved for 📦NodeJS: '$tech'" + if [[ "$tech" != "nodejs" ]] + then + echo "❌Incorrect project tech!" >&2 + exit 1 + fi + + - name: Artifact descriptor for NodeJS package should be detected + shell: bash + run: | + artifactDescriptor="${{ steps.detect-nodejs-package.outputs.artifact-descriptor }}" + + echo "🔎Artifact descriptor retrieved for 📦NodeJS: '$artifactDescriptor'" + if [[ "$artifactDescriptor" != "package.json" ]] + then + echo "❌Incorrect artifact descriptor!" >&2 + exit 1 + fi + + - uses: ./actions/detect-project-tech + id: detect-unknown-tech + with: + project-directory: ./tests/unknown-tech + + - name: Tech for unknown technology should be an empty string + shell: bash + run: | + tech="${{ steps.detect-unknown-tech.outputs.project-tech }}" + + echo "🔎Technology retrieved for 🎁unknown stack: '$tech'" + if [[ ! -z "$tech" ]] + then + echo "❌Incorrect project tech!" >&2 + exit 1 + fi + + - name: Artifact descriptor for unknown technology should be an empty string + shell: bash + run: | + artifactDescriptor="${{ steps.detect-unknown-tech.outputs.artifact-descriptor }}" + + echo "🔎Artifact descriptor retrieved for 🎁unknown stack: '$artifactDescriptor'" + if [[ ! -z "$artifactDescriptor" ]] + then + echo "❌Incorrect artifact descriptor!" >&2 + exit 1 + fi diff --git a/.github/test-actions/test-install-wasm-pack/action.yml b/.github/test-actions/test-install-wasm-pack/action.yml new file mode 100644 index 000000000..186b026ef --- /dev/null +++ b/.github/test-actions/test-install-wasm-pack/action.yml @@ -0,0 +1,26 @@ +name: Test install-wasm-pack + +runs: + using: composite + steps: + - name: Setup environment variables + shell: bash + run: | + echo "expectedVersion=0.13.0" >> $GITHUB_ENV + + - uses: ./actions/install-wasm-pack + with: + wasm-pack-version: ${{ env.expectedVersion }} + + - name: The expected wasm-pack version should be available + shell: bash + run: | + wasmPackVersion=$(wasm-pack --version | cut -d' ' -f2) + + echo "🔎Detected wasm-pack version: '$wasmPackVersion'" + + if [[ "$wasmPackVersion" != "$expectedVersion" ]] + then + echo "❌The expected wasm-pack version ('$expectedVersion') is not installed!" >&2 + exit 1 + fi diff --git a/.github/test-actions/test-publish-npm-package/action.yml b/.github/test-actions/test-publish-npm-package/action.yml new file mode 100644 index 000000000..10c9560a8 --- /dev/null +++ b/.github/test-actions/test-publish-npm-package/action.yml @@ -0,0 +1,14 @@ +name: Test publish-npm-package + +runs: + using: composite + steps: + - uses: ./actions/inject-branch-version + with: + artifact-descriptor: ./tests/npm-package/package.json + + - uses: ./actions/publish-npm-package + with: + dry-run: true + npm-token: "" + project-directory: ./tests/npm-package diff --git a/.github/test-actions/test-publish-rust-crate/action.yml b/.github/test-actions/test-publish-rust-crate/action.yml new file mode 100644 index 000000000..0da1895cb --- /dev/null +++ b/.github/test-actions/test-publish-rust-crate/action.yml @@ -0,0 +1,14 @@ +name: Test publish-rust-crate + +runs: + using: composite + steps: + - uses: ./actions/inject-branch-version + with: + artifact-descriptor: ./tests/rust-crate/Cargo.toml + + - uses: ./actions/publish-rust-crate + with: + dry-run: true + cargo-token: "" + project-directory: ./tests/rust-crate diff --git a/.github/test-actions/test-publish-rust-wasm/action.yml b/.github/test-actions/test-publish-rust-wasm/action.yml new file mode 100644 index 000000000..6a973261f --- /dev/null +++ b/.github/test-actions/test-publish-rust-wasm/action.yml @@ -0,0 +1,16 @@ +name: Test publish-rust-wasm + +runs: + using: composite + steps: + - uses: ./actions/inject-branch-version + with: + artifact-descriptor: ./tests/rust-wasm/Cargo.toml + + - uses: ./actions/publish-rust-wasm + with: + project-directory: ./tests/rust-wasm + dry-run: true + npm-token: "" + wasm-pack-version: 0.13.0 + npm-scope: giancosta86 diff --git a/.github/test-actions/test-verify-npm-package/action.yml b/.github/test-actions/test-verify-npm-package/action.yml new file mode 100644 index 000000000..0b7518b05 --- /dev/null +++ b/.github/test-actions/test-verify-npm-package/action.yml @@ -0,0 +1,12 @@ +name: Test verify-npm-package + +runs: + using: composite + steps: + - uses: ./actions/inject-branch-version + with: + artifact-descriptor: ./tests/npm-package/package.json + + - uses: ./actions/verify-npm-package + with: + project-directory: ./tests/npm-package diff --git a/.github/test-actions/test-verify-rust-crate/action.yml b/.github/test-actions/test-verify-rust-crate/action.yml new file mode 100644 index 000000000..276bad9a3 --- /dev/null +++ b/.github/test-actions/test-verify-rust-crate/action.yml @@ -0,0 +1,12 @@ +name: Test verify-rust-crate + +runs: + using: composite + steps: + - uses: ./actions/inject-branch-version + with: + artifact-descriptor: ./tests/rust-crate/Cargo.toml + + - uses: ./actions/verify-rust-crate + with: + project-directory: ./tests/rust-crate diff --git a/.github/test-actions/test-verify-rust-wasm/action.yml b/.github/test-actions/test-verify-rust-wasm/action.yml new file mode 100644 index 000000000..9eaa3bae5 --- /dev/null +++ b/.github/test-actions/test-verify-rust-wasm/action.yml @@ -0,0 +1,14 @@ +name: Test verify-rust-wasm + +runs: + using: composite + steps: + - uses: ./actions/inject-branch-version + with: + artifact-descriptor: ./tests/rust-wasm/Cargo.toml + + - uses: ./actions/verify-rust-wasm + with: + project-directory: ./tests/rust-wasm + npm-scope: giancosta86 + wasm-pack-version: 0.13.0 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..723896114 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,19 @@ +name: Publish actions + +on: + pull_request: + types: closed + branches: main + workflow_dispatch: + +jobs: + publish: + if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true) }} + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: ./actions/tag-and-release + with: + set-major-tag: true diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml deleted file mode 100644 index 1626b92e4..000000000 --- a/.github/workflows/validate.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Validate actions - -on: - pull_request: - types: [opened, reopened, synchronize] - branches: main - - workflow_dispatch: - -jobs: - validate: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/check-action-references@v2 diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 000000000..366784e0f --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,112 @@ +name: Verify actions + +on: + pull_request: + types: [opened, reopened, synchronize] + branches: main + workflow_dispatch: + +jobs: + check-preconditions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./actions/check-action-references + + test-detect-branch-version: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-detect-branch-version + + test-install-wasm-pack: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-install-wasm-pack + + test-check-rust-versions: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-check-rust-versions + + test-detect-project-tech: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-detect-project-tech + + test-artifact-version: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-artifact-version + + test-verify-rust-crate: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-verify-rust-crate + + test-publish-rust-crate: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-publish-rust-crate + + test-verify-npm-package: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-verify-npm-package + + test-publish-npm-package: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-publish-npm-package + + test-verify-rust-wasm: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-verify-rust-wasm + + test-publish-rust-wasm: + runs-on: ubuntu-latest + needs: check-preconditions + steps: + - uses: actions/checkout@v4 + - uses: ./.github/test-actions/test-publish-rust-wasm + + verify: + runs-on: ubuntu-latest + needs: + - check-preconditions + - test-detect-branch-version + - test-install-wasm-pack + - test-check-rust-versions + - test-detect-project-tech + - test-artifact-version + - test-verify-rust-crate + - test-publish-rust-crate + - test-verify-npm-package + - test-publish-npm-package + - test-verify-rust-wasm + - test-publish-rust-wasm + + steps: + - name: Test branch + shell: bash + run: echo "✅Verification complete!" diff --git a/README.md b/README.md index e962114ce..a847b05f8 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,53 @@ _Elegant pipelines for GitHub Actions_ -**aurora-github** is a gallery of GitHub actions designed to create elegant and minimalist _pipelines_ for a variety of technologies. +![Schema](docs/schema.png) -In particular, the latest version includes the following actions: +**aurora-github** is a gallery of GitHub actions designed to create elegant and minimalist _pipelines_ for a variety of technologies - focusing on [GitHub flow](https://docs.github.com/en/get-started/using-github/github-flow) best practices such as _default branch protection_, _pull requests_ and _convention-over-configuration_. -- [npm](actions/npm/README.md): pipeline for publishing a **TypeScript** library to [npm](https://www.npmjs.com/) +In particular, the actions can be grouped by technology: + +## 🦀Rust crate + +- [verify-rust-crate](./actions/verify-rust-crate/README.md) + +- [publish-rust-crate](./actions/publish-rust-crate/README.md) + +## 📦NodeJS package + +- [verify-npm-package](./actions/verify-npm-package/README.md) + +- [publish-npm-package](./actions/publish-npm-package/README.md) + +## 🦀Rust 🌐WebAssembly + +- [verify-rust-wasm](./actions/verify-rust-wasm/README.md) + +- [publish-rust-wasm](./actions/publish-rust-wasm/README.md) + +## 😺GitHub Actions library + +- [check-action-references](./actions/check-action-references/README.md) + +## 🏷️Semantic versioning + +- [detect-branch-version](./actions/detect-branch-version/README.md) + +- [inject-branch-version](./actions/inject-branch-version/README.md) + +- [check-artifact-version](./actions/check-artifact-version/README.md) + +- [tag-and-release](./actions/tag-and-release/README.md) + +## 🦀Rust utilities + +- [check-rust-versions](./actions/check-rust-versions/README.md) + +- [install-wasm-pack](./actions/install-wasm-pack/README.md) + +## 🧰General-purpose utilities + +- [detect-project-tech](./actions/detect-project-tech/README.md) ## Further references diff --git a/actions/check-action-references/README.md b/actions/check-action-references/README.md new file mode 100644 index 000000000..dff4b82b4 --- /dev/null +++ b/actions/check-action-references/README.md @@ -0,0 +1,31 @@ +# check-action-references + +Prevents inter-branch `uses:` directives to **GitHub** actions residing below the same root directory. + +## Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/check-action-references@v2 +``` + +## How it works + +When creating actions in a repository acting as a library for GitHub Actions, you could need to reference one action from another: this action ensures that all the above local `@` tags only reference actions on the current branch. + +## Requirements + +- The check is only performed on [composite GitHub actions](https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action), written in files having `.yml` extension and residing below the given `actions-directory`. + +## Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :--------: | :---------------------------------------------------: | :-----------: | +| `actions-directory` | **string** | The root of the directory tree containing the actions | **./actions** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [Composite GitHub actions](https://docs.github.com/en/actions/sharing-automations/creating-actions/creating-a-composite-action) + +- [aurora-github](../../README.md) diff --git a/actions/check-action-references/action.yml b/actions/check-action-references/action.yml new file mode 100644 index 000000000..7ea316eef --- /dev/null +++ b/actions/check-action-references/action.yml @@ -0,0 +1,50 @@ +name: Check GitHub Actions references +description: Prevents inter-branch 'uses:' directives to GitHub actions residing below the same root directory. + +inputs: + actions-directory: + description: The root of the directory tree containing the actions. + required: false + default: ./actions + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Detect branch and version + id: detect-branch-version + uses: giancosta86/aurora-github/actions/detect-branch-version@v2.0.0 + with: + shell: ${{ inputs.shell }} + + - name: Fail on inter-branch local references + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.actions-directory }} + run: | + branch="${{ steps.detect-branch-version.outputs.branch }}" + fullRepo="$GITHUB_REPOSITORY" + + echo "Now in 🌲branch: '$branch'. 🧭Full repository name: '$fullRepo'." + + hasReferencesToOtherBranches=false + + while IFS= read -r referenceLine + do + if [[ "$referenceLine" != *@"${branch}" ]] + then + echo "---> $referenceLine" >&2 + hasReferencesToOtherBranches=true + fi + done < <(find . -name '*.yml' -print | xargs egrep -n "uses:\s+${fullRepo}/") + + if [[ "$hasReferencesToOtherBranches" == "true" ]] + then + echo "❌There are references to actions within '${{ inputs.actions-directory }}' residing in other branches!" >&2 + exit 1 + else + echo "✅No inter-branch action references detected!" + fi diff --git a/actions/check-artifact-version/README.md b/actions/check-artifact-version/README.md new file mode 100644 index 000000000..4518b0ceb --- /dev/null +++ b/actions/check-artifact-version/README.md @@ -0,0 +1,31 @@ +# check-artifact-version + +Ensures the artifact version - expressed according to the project technology - matches the current branch version, detected by [detect-branch-version](../detect-branch-version/README.md); if the project tech cannot be detected via [detect-project-tech](../detect-project-tech/README.md), the action fails. + +## Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/check-artifact-version@v2 +``` + +## Requirements + +- The ones described for [detect-project-tech](../detect-project-tech/README.md) + +- The ones described for [detect-branch-version](../detect-branch-version/README.md) + +## Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :--------: | :----------------------------: | :-----------: | +| `project-directory` | **string** | The project directory | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [detect-project-tech](../detect-project-tech/README.md) + +- [detect-branch-version](../detect-branch-version/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/check-artifact-version/action.yml b/actions/check-artifact-version/action.yml new file mode 100644 index 000000000..e1ea62230 --- /dev/null +++ b/actions/check-artifact-version/action.yml @@ -0,0 +1,49 @@ +name: Check artifact version +description: Ensures the artifact version - expressed according to the project technology - matches the current branch version. + +inputs: + project-directory: + description: The directory containing the project. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Detect project tech + id: detect-project-tech + uses: giancosta86/aurora-github/actions/detect-project-tech@v2.0.0 + with: + project-directory: ${{ inputs.project-directory }} + shell: ${{ inputs.shell }} + + - name: Detect branch and version + id: detect-branch-version + uses: giancosta86/aurora-github/actions/detect-branch-version@v2.0.0 + with: + shell: ${{ inputs.shell }} + + - name: Check Rust crate version + if: ${{ steps.detect-project-tech.outputs.project-tech == 'rust' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: egrep -q '^version\s*=\s*"${{ steps.detect-branch-version.outputs.escaped-version }}"' Cargo.toml + + - name: Check NodeJS package version + if: ${{ steps.detect-project-tech.outputs.project-tech == 'nodejs' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: egrep -q '"version"\s*:\s*"${{ steps.detect-branch-version.outputs.escaped-version }}"' package.json + + - name: Fail on unknown project tech + if: ${{ steps.detect-project-tech.outputs.project-tech == '' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + echo "❌Cannot verify the artifact version for an unknown project tech" >&2 + exit 1 diff --git a/actions/check-rust-versions/README.md b/actions/check-rust-versions/README.md new file mode 100644 index 000000000..14b00e651 --- /dev/null +++ b/actions/check-rust-versions/README.md @@ -0,0 +1,32 @@ +# check-rust-versions + +Displays the current version of the main **Rust** components, after ensuring that `rust-toolchain.toml` is in the project directory. + +## Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/check-rust-versions@v2 +``` + +## Requirements + +- the [toolchain file](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) file must exist within `project-directory`. + + It should include at least the required toolchain version, for example: + + ```toml + [toolchain] + channel = "1.80.0" + ``` + +## Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :--------: | :-----------------------------------: | :-----------: | +| `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [aurora-github](../../README.md) diff --git a/actions/check-rust-versions/action.yml b/actions/check-rust-versions/action.yml new file mode 100644 index 000000000..d32f4f88c --- /dev/null +++ b/actions/check-rust-versions/action.yml @@ -0,0 +1,37 @@ +name: Check Rust version info +description: Displays the versions of the main Rust components, after ensuring that 'rust-toolchain.toml' is in the project directory. + +inputs: + project-directory: + description: The directory containing Cargo.toml. + required: false + default: "." + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Ensure the toolchain file is present + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + toolchainFile="rust-toolchain.toml" + + if [[ ! -f "$toolchainFile" ]] + then + echo "❌Missing toolchain file: '$toolchainFile'" >&2 + exit 1 + fi + + - name: Print Rust tool versions + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + cargo --version + rustc --version + cargo fmt --version + cargo clippy --version diff --git a/actions/detect-branch-version/README.md b/actions/detect-branch-version/README.md new file mode 100644 index 000000000..079e36532 --- /dev/null +++ b/actions/detect-branch-version/README.md @@ -0,0 +1,47 @@ +# detect-branch-version + +Extracts the version from the name of the current **Git** branch, returning both. + +## Example + +```yaml +steps: + - id: detector + uses: giancosta86/aurora-github/actions/detect-branch-version@v2 + + - run: | + branch="${{ steps.detector.outputs.branch }}" + version="${{ steps.detector.outputs.version }}" + escapedVersion="${{ steps.detector.outputs.escaped-version }}" + major="${{ steps.detector.outputs.major }}" + + echo "🔎Detected version '$version' (escaped: '${escapedVersion}') from branch '$branch'" + echo "🔎Major component: '${major}'" +``` + +## Requirements + +- the branch name is read from `github.head_ref` if such variable is available - because the action is especially designed for pull-request workflows - and from `github.ref` otherwise. + +- the branch name should have a [semantic version](https://semver.org/) format, optionally preceded by `v`. For example: `v1.0.2`. + +## Inputs + +| Name | Type | Description | Default value | +| :-----: | :--------: | :----------------------------: | :-----------: | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Outputs + +| Name | Type | Description | Example | +| :---------------: | :--------: | :----------------------------------------------------------: | :---------: | +| `branch` | **string** | The current Git branch | **v2.4.8** | +| `version` | **string** | The version detected from the branch - always without prefix | **2.4.8** | +| `escaped-version` | **string** | The escaped version - for regular expressions | **2\.4\.8** | +| `major` | **string** | The `major` component of the version | **2** | + +## Further references + +- [semantic version](https://semver.org/) + +- [aurora-github](../../README.md) diff --git a/actions/detect-branch-version/action.yml b/actions/detect-branch-version/action.yml new file mode 100644 index 000000000..f493e3ba5 --- /dev/null +++ b/actions/detect-branch-version/action.yml @@ -0,0 +1,52 @@ +name: Detect branch version +description: Extracts the version from the name of the current Git branch, returning both. + +inputs: + shell: + description: The shell used to run commands. + required: false + default: bash + +outputs: + branch: + description: The current Git branch. + value: ${{ steps.detect-version.outputs.branch }} + + version: + description: The version detected from the Git branch - always without prefix. + value: ${{ steps.detect-version.outputs.version }} + + escaped-version: + description: The escaped version - for example, with '\.' in lieu of '.' - suitable for regular expressions. + value: ${{ steps.detect-version.outputs.escaped-version }} + + major: + description: The 'major' component of the version. + value: ${{ steps.detect-version.outputs.major }} + +runs: + using: composite + steps: + - name: Detect version from branch + id: detect-version + shell: ${{ inputs.shell }} + run: | + headRef="${{ github.head_ref }}" + ref="${{ github.ref }}" + + branch="${headRef:-"$ref"}" + echo "🌲Current Git branch: '$branch'" + + version="$(echo "$branch" | xargs basename | sed 's/^v//')" + echo "🦋Detected version: '$version'" + + escapedVersion=$(echo "$version" | sed 's/\./\\\./g') + echo "🧵Escaped version: '$escapedVersion'" + + major="$(echo "$version" | cut -d'.' -f1 | cut -d'-' -f1 | cut -d'+' -f1)" + echo "💎Major component: '$major'" + + echo "branch=$branch" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + echo "escaped-version=$escapedVersion" >> $GITHUB_OUTPUT + echo "major=$major" >> $GITHUB_OUTPUT diff --git a/actions/detect-project-tech/README.md b/actions/detect-project-tech/README.md new file mode 100644 index 000000000..192d05357 --- /dev/null +++ b/actions/detect-project-tech/README.md @@ -0,0 +1,50 @@ +# detect-project-tech + +Tries to infer the current project tech - and related aspects - from the source files. + +## Example + +```yaml +steps: + - id: detector + uses: giancosta86/aurora-github/actions/detect-project-tech@v2 + + - run: | + projectTech="${{ steps.detector.outputs.project-tech }}" + projectArtifact="${{ steps.detector.outputs.project-artifact }}" + + echo "Detected project tech: '$projectTech'" + echo "Detected project artifact: '$projectArtifact'" +``` + +## Requirements + +- a **Rust** crate must have its `Cargo.toml`. + +- a **NodeJS** package must have its `package.json`. + +## Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :--------: | :----------------------------: | :-----------: | +| `project-directory` | **string** | The project directory | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Outputs + +| Name | Type | Description | Supported values | +| :-------------------: | :--------: | :-----------------------: | :-----------------: | +| `project-tech` | **string** | The detected project tech | _(see table below)_ | +| `artifact-descriptor` | **string** | The artifact descriptor | _(see table below)_ | + +### Output values + +| project-tech | artifact-descriptor | Supported project types | +| :--------------: | :-----------------: | :--------------------------: | +| rust | Cargo.toml | _Rust crate or web assembly_ | +| nodejs | package.json | _NodeJS package_ | +| _(empty string)_ | _(empty string)_ | _Unsupported project tech_ | + +## Further references + +- [aurora-github](../../README.md) diff --git a/actions/detect-project-tech/action.yml b/actions/detect-project-tech/action.yml new file mode 100644 index 000000000..25fa9eb5c --- /dev/null +++ b/actions/detect-project-tech/action.yml @@ -0,0 +1,46 @@ +name: Detect project tech +description: Tries to infer the current project tech - and related aspects - from the source files. + +inputs: + project-directory: + description: The directory containing the project. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +outputs: + project-tech: + description: The detected project tech. Can be 'nodejs', 'rust' or empty string. + value: ${{ steps.detect-project-tech.outputs.project-tech }} + + artifact-descriptor: + description: The artifact descriptor. Can be 'Cargo.toml', 'package.json' or empty string. + value: ${{ steps.detect-project-tech.outputs.artifact-descriptor }} + +runs: + using: composite + steps: + - name: Detect project tech + id: detect-project-tech + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + if [[ -f "package.json" ]] + then + echo "📦NodeJS project tech detected" + echo "project-tech=nodejs" >> $GITHUB_OUTPUT + echo "artifact-descriptor=package.json" >> $GITHUB_OUTPUT + elif [[ -f "Cargo.toml" ]] + then + echo "🦀Rust project tech detected" + echo "project-tech=rust" >> $GITHUB_OUTPUT + echo "artifact-descriptor=Cargo.toml" >> $GITHUB_OUTPUT + else + echo "🤔It seems impossible to detect the project tech!" + echo "project-tech=" >> $GITHUB_OUTPUT + echo "artifact-descriptor=" >> $GITHUB_OUTPUT + fi diff --git a/actions/inject-branch-version/README.md b/actions/inject-branch-version/README.md new file mode 100644 index 000000000..74c14511f --- /dev/null +++ b/actions/inject-branch-version/README.md @@ -0,0 +1,36 @@ +# inject-branch-version + +Injects into a descriptor the version detected from the current **Git** branch. + +## Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/inject-branch-version@v2 +``` + +## Requirements + +- The artifact file should contain at least one occurrence of `0.0.0`: they will all be replaced by the version detected from the current Git branch; however, the action won't fail if there are no occurrences. + +- The ones described for [detect-branch-version](../detect-branch-version/README.md). + +- If `artifact-descriptor` is missing, the requirements for [detect-project-tech](../detect-project-tech/README.md) apply. + +## Inputs + +| Name | Type | Description | Default value | +| :-------------------: | :--------: | :--------------------------------------: | :-------------------------: | +| `artifact-descriptor` | **string** | Relative path to the artifact descriptor | _(depends on project tech)_ | +| `project-directory` | **string** | The project directory | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +For details about the default value assigned to the `artifact-descriptor` input, please refer to the related output of [detect-project-tech](../detect-project-tech/README.md). + +## Further references + +- [detect-project-tech](../detect-project-tech/README.md) + +- [detect-branch-version](../detect-branch-version/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/inject-branch-version/action.yml b/actions/inject-branch-version/action.yml new file mode 100644 index 000000000..93b1836ca --- /dev/null +++ b/actions/inject-branch-version/action.yml @@ -0,0 +1,57 @@ +name: Inject branch version +description: Injects into a descriptor the version detected from the current Git branch. + +inputs: + artifact-descriptor: + description: Relative path to the artifact descriptor - such as 'Cargo.toml' or 'package.json'; if not specified, it will be inferred from the project. + required: false + default: "" + + project-directory: + description: The directory containing the project. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - uses: giancosta86/aurora-github/actions/detect-branch-version@v2.0.0 + id: version-detector + with: + shell: ${{ inputs.shell }} + + - uses: giancosta86/aurora-github/actions/detect-project-tech@v2.0.0 + if: ${{ inputs.artifact-descriptor == '' }} + id: tech-detector + with: + project-directory: ${{ inputs.project-directory }} + shell: ${{ inputs.shell }} + + - name: Replace versions + shell: bash + working-directory: ${{ inputs.project-directory }} + run: | + version="${{ steps.version-detector.outputs.version }}" + artifactDescriptor="${{ inputs.artifact-descriptor }}" + + echo "🔎Detected version is: '$version'" + echo "🔎The requested artifact descriptor is: '$artifactDescriptor'" + + if [[ -z "$artifactDescriptor" ]] + then + artifactDescriptor="${{ steps.tech-detector.outputs.artifact-descriptor }}" + echo "🔮The detected artifact descriptor is: '$artifactDescriptor'" + + if [[ -z "$artifactDescriptor" ]] + then + echo "❌Cannot detect the artifact descriptor for version injection!" >&2; + exit 1; + fi + fi + + sed -i "s/0\.0\.0/${version}/g" "$artifactDescriptor" diff --git a/actions/install-wasm-pack/README.md b/actions/install-wasm-pack/README.md new file mode 100644 index 000000000..e05913a7f --- /dev/null +++ b/actions/install-wasm-pack/README.md @@ -0,0 +1,23 @@ +# install-wasm-pack + +Installs [wasm-pack](https://rustwasm.github.io/wasm-pack/), for creating **Rust**-based web assemblies. + +## Example + +```yaml +steps: + - uses: giancosta86/aurora-github/actions/install-wasm-pack@v2 +``` + +## Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :--------: | :------------------------------: | :-----------: | +| `wasm-pack-version` | **string** | The wasm-pack version to install | | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [wasm-pack](https://rustwasm.github.io/wasm-pack/) + +- [aurora-github](../../README.md) diff --git a/actions/install-wasm-pack/action.yml b/actions/install-wasm-pack/action.yml new file mode 100644 index 000000000..4d87b2e67 --- /dev/null +++ b/actions/install-wasm-pack/action.yml @@ -0,0 +1,28 @@ +name: Install wasm-pack +description: Installs wasm-pack, for creating Rust-based web assemblies. + +inputs: + wasm-pack-version: + description: The wasm-pack version to install. + required: true + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Install wasm-pack via pnpm + shell: ${{ inputs.shell }} + run: pnpm add -g "wasm-pack@${{ inputs.wasm-pack-version }}" + + - name: Print wasm-pack version + shell: ${{ inputs.shell }} + run: wasm-pack --version diff --git a/actions/npm/README.md b/actions/npm/README.md deleted file mode 100644 index 7eea7572f..000000000 --- a/actions/npm/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# npm - -The **npm** action executes a [pnpm](https://pnpm.io/)-based pipeline designed to publish a package to the [npm](https://www.npmjs.com/) registry. - -## Requirements - -- The project's package manager must be **pnpm**. - -- The `pnpm-lock.yaml` file must be committed into the repository. - -- The root directory of the project must contain a `.nvmrc` file - declaring the required Node.js version - whose format must be compatible with the `actions/setup-node` action (for example: `vX.Y.Z`). - -- The entire build process for the package must be triggered by the `prepack` script in `package.json` (see the example below). - -## Input parameters - -- `npm-token` (**REQUIRED**): the token for publishing to npm. - -- `project-directory`: the directory containing the `package.json` file. **Defaults to:** the repository's directory. - -- `pnpm-version`: the required **pnpm** version. **Defaults to:** a sensible, modern version. - -- `shell`: the interpreter running the commands. **Defaults to:** `bash`. - -## Example - -The action can be placed right after checking out the source code: - -```yaml -steps: - - uses: actions/checkout@v4 - - - uses: giancosta86/aurora-github/actions/npm@v1 - with: - npm-token: ${{ secrets.NPM_TOKEN }} -``` - -**IMPORTANT**: please, remember to declare your build process in the `prepack` script within `package.json`! For example: - -```json -"scripts": { - "build": "tsc", - "test": "vitest", - "prepack": "pnpm test && pnpm build" -} -``` - -## Further references - -- [aurora-github](../../README.md) diff --git a/actions/npm/action.yml b/actions/npm/action.yml deleted file mode 100644 index 81a80ed43..000000000 --- a/actions/npm/action.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: "Publish npm package" -description: "Publish a package to the npm registry" - -inputs: - npm-token: - description: "The secret authentication token" - required: true - - project-directory: - description: "Directory containing the package.json" - required: false - default: "." - - pnpm-version: - description: "Specific version of pnpm to use" - required: false - default: 9 - - shell: - description: "The shell used to run commands" - required: false - default: "bash" - -runs: - using: "composite" - steps: - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: ${{ inputs.pnpm-version }} - - - name: Setup NodeJS and NPM registry - uses: actions/setup-node@v4 - with: - node-version-file: ".nvmrc" - registry-url: "https://registry.npmjs.org" - cache: "pnpm" - - - name: Install dependencies - shell: ${{ inputs.shell }} - working-directory: ${{ inputs.project-directory }} - run: pnpm install --frozen-lockfile - - - name: Run prepack-based deployment pipeline - shell: ${{ inputs.shell }} - working-directory: ${{ inputs.project-directory }} - run: pnpm publish --no-git-checks --access public - env: - NODE_AUTH_TOKEN: ${{ inputs.npm-token }} diff --git a/actions/publish-npm-package/README.md b/actions/publish-npm-package/README.md new file mode 100644 index 000000000..5d6b3deef --- /dev/null +++ b/actions/publish-npm-package/README.md @@ -0,0 +1,42 @@ +# publish-npm-package + +Publishes a **NodeJS** package to the [npm](https://www.npmjs.com/) registry. + +## Example + +The action can be placed right after checking out the source code: + +```yaml +steps: + - uses: actions/checkout@v4 + + - uses: giancosta86/aurora-github/actions/publish-npm-package@v2 + with: + npm-token: ${{ secrets.NPM_TOKEN }} +``` + +**Please, note**: this action is designed for _publication_ only - not for _verification_: you may want use [verify-npm-package](../verify-npm-package/README.md) for that; as a plus, you can add publication-specific checks via the [pre-/post- hook scripts](https://docs.npmjs.com/cli/v10/using-npm/scripts) of your `package.json` file. + +## Requirements + +- The project's package manager must be [pnpm](https://pnpm.io/) - version `9` or later compatible. + +- The root directory of the project must contain a `.nvmrc` file - declaring the required Node.js version - whose format must be compatible with the `actions/setup-node` action (for example: `vX.Y.Z`). + +- Before the first publication, running with `dry-run` set to **true** is recommended. + +## Inputs + +| Name | Type | Description | Default value | +| :-----------------: | :---------: | :---------------------------------------------: | :-----------: | +| `npm-token` | **string** | The secret token for publishing to npm | | +| `dry-run` | **boolean** | Run a simulated publication via `--dry-run` | **false** | +| `frozen-lockfile` | **boolean** | Fail if `pnpm-lock.yaml` is missing or outdated | **true** | +| `project-directory` | **string** | The directory containing `package.json` | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [verify-npm-package](../verify-npm-package/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/publish-npm-package/action.yml b/actions/publish-npm-package/action.yml new file mode 100644 index 000000000..a6de21bfb --- /dev/null +++ b/actions/publish-npm-package/action.yml @@ -0,0 +1,76 @@ +name: Publish npm package +description: Publishes a NodeJS package to the npm registry. + +inputs: + npm-token: + description: The secret token for publishing to npm. + required: true + + dry-run: + description: Run a simulated publication via --dry-run. + required: false + default: false + + frozen-lockfile: + description: Fail if 'pnpm-lock.yaml' is missing or outdated. + required: false + default: true + + project-directory: + description: The directory containing package.json. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Setup NodeJS and NPM registry + uses: actions/setup-node@v4 + with: + node-version-file: ${{ inputs.project-directory }}/.nvmrc + registry-url: https://registry.npmjs.org + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Install dependencies + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + frozenLockfile="${{ inputs.frozen-lockfile }}" + + if [[ "$frozenLockfile" == "true" ]] + then + pnpm install --frozen-lockfile + else + pnpm install --no-frozen-lockfile + fi + + - name: Display the artifact descriptor + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + echo "The content of your 📦package.json just before publication is:" + cat package.json + + - name: Publish to npm + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + dryRun="${{ inputs.dry-run }}" + + if [[ "$dryRun" == "true" ]] + then + pnpm publish --no-git-checks --access public --dry-run + else + pnpm publish --no-git-checks --access public + fi + env: + NODE_AUTH_TOKEN: ${{ inputs.npm-token }} diff --git a/actions/publish-rust-crate/README.md b/actions/publish-rust-crate/README.md new file mode 100644 index 000000000..b6b974f20 --- /dev/null +++ b/actions/publish-rust-crate/README.md @@ -0,0 +1,38 @@ +# publish-rust-crate + +Publishes a **Rust** crate to [crates.io](https://crates.io/), with all of its features enabled. + +## Example + +```yaml +steps: + - uses: actions/checkout@v4 + + - uses: giancosta86/aurora-github/actions/publish-rust-crate@v2 + with: + cargo-token: ${{ secrets.CARGO_TOKEN }} +``` + +**Please, note**: this action is designed for _publication_ only - not for _verification_: you may want to use [verify-rust-crate](../verify-rust-crate/README.md) for that. + +## Requirements + +- a secret publication token, provided by [crates.io](https://crates.io/). + +- Before the first publication, running with `dry-run` set to **true** is recommended. + +## Inputs + +| Name | Type | Description | Default value | +| :---------------------: | :---------: | :----------------------------------------------------------------: | :-----------: | +| `cargo-token` | **string** | The secret token for publishing to [crates.io](https://crates.io/) | | +| `dry-run` | **boolean** | Run a simulated publication via `--dry-run` | **false** | +| `document-all-features` | **boolean** | Enable [Rustdoc for all features](https://docs.rs/about/metadata) | **true** | +| `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [verify-rust-crate](../verify-rust-crate/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/publish-rust-crate/action.yml b/actions/publish-rust-crate/action.yml new file mode 100644 index 000000000..063907175 --- /dev/null +++ b/actions/publish-rust-crate/action.yml @@ -0,0 +1,63 @@ +name: Publish to crates.io +description: Publishes a Rust crate to crates.io, with all of its features enabled. + +inputs: + cargo-token: + description: The secret token for publishing to crates.io. + required: true + + dry-run: + description: Run a simulated publication via --dry-run. + required: false + default: false + + document-all-features: + description: Enable Rustdoc for all features. + required: false + default: true + + project-directory: + description: The directory containing Cargo.toml. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Enable Rustdoc for all features + if: ${{ inputs.document-all-features == 'true' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + cat << EOF >> Cargo.toml + + [package.metadata.docs.rs] + all-features = true + EOF + + - name: Display the artifact descriptor + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + echo "The content of your 🦀Cargo.toml just before publication is:" + cat Cargo.toml + + - name: Publish to crates.io + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + dryRun="${{ inputs.dry-run }}" + + if [[ "$dryRun" == "true" ]] + then + cargo publish --all-features --allow-dirty --dry-run + else + cargo publish --all-features --allow-dirty + fi + env: + CARGO_REGISTRY_TOKEN: ${{ inputs.cargo-token }} diff --git a/actions/publish-rust-wasm/README.md b/actions/publish-rust-wasm/README.md new file mode 100644 index 000000000..d59365669 --- /dev/null +++ b/actions/publish-rust-wasm/README.md @@ -0,0 +1,45 @@ +# publish-rust-wasm + +Publishes a **Rust** web assembly to the [npm](https://www.npmjs.com/) registry. + +## Example + +The action can be placed right after checking out the source code: + +```yaml +steps: + - uses: actions/checkout@v4 + + - uses: giancosta86/aurora-github/actions/publish-rust-wasm@v2 + with: + npm-token: ${{ secrets.NPM_TOKEN }} + wasm-pack-version: 0.13.0 + npm-scope: your-npm-scope +``` + +**Please, note**: this action is designed for _publication_ only - not for verification: you might want to use [verify-rust-wasm](../verify-rust-wasm/README.md) for that. + +## Requirements + +- You must create a `.nvmrc` file, declaring the required Node.js version, whose format must be compatible with the `actions/setup-node` action (for example: `vX.Y.Z`): the file will most probably reside in a `client-tests` subdirectory - designed for NodeJS tests - but you can customize this aspect via the `node-version-directory` input. + +- Before the first publication, running with `dry-run` set to **true** is recommended. + +## Inputs + +| Name | Type | Description | Default value | +| :----------------------: | :---------: | :----------------------------------------------------------: | :--------------: | +| `npm-token` | **string** | The secret token for publishing to npm | | +| `wasm-pack-version` | **string** | The `wasm-pack` version to install | | +| `npm-scope` | **string** | The npm package scope (**without** the initial `@`) or empty | | +| `dry-run` | **boolean** | Run a simulated publication via `--dry-run` | **false** | +| `wasm-target` | **string** | The target of the `wasm-pack build` command | **web** | +| `node-version-directory` | **string** | Relative directory containing the `.nvmrc` file | **client-tests** | +| `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [verify-rust-wasm](../verify-rust-wasm/README.md) instead + +- [aurora-github](../../README.md) diff --git a/actions/publish-rust-wasm/action.yml b/actions/publish-rust-wasm/action.yml new file mode 100644 index 000000000..add477903 --- /dev/null +++ b/actions/publish-rust-wasm/action.yml @@ -0,0 +1,76 @@ +name: Publish Rust web assembly +description: Publishes a Rust web assembly to the npm registry. + +inputs: + npm-token: + description: The secret token for publishing to npm. + required: true + + wasm-pack-version: + description: The wasm-pack version to install. + required: true + + npm-scope: + description: The npm package scope (without the initial @) or empty. + required: true + + dry-run: + description: Run a simulated publication via --dry-run. + required: false + default: false + + wasm-target: + description: The target of the 'wasm-pack build' command. + required: false + default: web + + node-version-directory: + description: Relative directory containing the .nvmrc file. + required: false + default: client-tests + + project-directory: + description: The directory containing Cargo.toml. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Install wasm-pack + uses: giancosta86/aurora-github/actions/install-wasm-pack@v2.0.0 + with: + wasm-pack-version: ${{ inputs.wasm-pack-version }} + shell: ${{ inputs.shell }} + + - name: Generate the NodeJS package + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + scope="${{ inputs.npm-scope }}" + + if [[ ! -z "$scope" ]] + then + wasm-pack build --release --target "${{ inputs.wasm-target }}" --scope "${{ inputs.npm-scope }}" + else + wasm-pack build --release --target "${{ inputs.wasm-target }}" + fi + + - name: Copy .nvmrc to the generated NodeJS package + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: cp "${{ inputs.node-version-directory }}/.nvmrc" pkg + + - name: Publish NodeJS package + uses: giancosta86/aurora-github/actions/publish-npm-package@v2.0.0 + with: + frozen-lockfile: false + npm-token: ${{ inputs.npm-token }} + dry-run: ${{ inputs.dry-run }} + project-directory: ${{ inputs.project-directory }}/pkg + shell: ${{ inputs.shell }} diff --git a/actions/tag-and-release/README.md b/actions/tag-and-release/README.md new file mode 100644 index 000000000..5ac5c30a9 --- /dev/null +++ b/actions/tag-and-release/README.md @@ -0,0 +1,55 @@ +# tag-and-release + +Creates a **Git** tag and a **GitHub** release, from a Git branch named according to [semver](https://semver.org/); by default, it also deletes the current branch. + +## Example + +This action is designed to be the very last step in a _publication_ workflow: + +```yaml +steps: + - uses: PUBLICATION STEP 1 + + - uses: PUBLICATION STEP 2 + + - uses: PUBLICATION STEP N + + - uses: giancosta86/aurora-github/actions/tag-and-release@v2 +``` + +## Requirements + +- this action requires GitHub Actions to have **read/write** permissions on the repository. + +- this action will not run on the _default_ branch of the repository. + +- the branch name can safely start with `v`, as long as `delete-branch` is **true** (the default), because the tags are created after the deletion of the branch. + +- the ones discussed for [detect-branch-version](../detect-branch-version/README.md). + +## How it works + +1. By default, delete the current Git branch. + +1. Create a new tag - for example, `vX.Y.Z` - containing the semantic version inferred from the branch name. + +1. Create or draft a GitHub release. + +1. Optionally, _create or move_ the tag of the major version related to the current version - for example, `vX`. + +## Inputs + +| Name | Type | Description | Default value | +| :-------------: | :---------: | :-------------------------------------------------------: | :-----------: | +| `draft-only` | **boolean** | Only draft the release | **false** | +| `delete-branch` | **boolean** | Delete the branch after creating the tag | **true** | +| `set-major-tag` | **boolean** | Create/move the `vX` tag to this commit (X=major version) | **false** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [semver](https://semver.org/) + +- [detect-branch-version](../detect-branch-version/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/tag-and-release/action.yml b/actions/tag-and-release/action.yml new file mode 100644 index 000000000..67f406dac --- /dev/null +++ b/actions/tag-and-release/action.yml @@ -0,0 +1,131 @@ +name: Tag and release +description: Creates a Git tag and a GitHub release, from a Git branch named according to semver; by default, it also deletes the current branch. + +inputs: + draft-only: + description: Only draft the release. + required: false + default: false + + delete-branch: + description: Delete the branch after creating the tag. + required: false + default: true + + set-major-tag: + description: Create/move the 'vX' tag to this commit (X=major version) + required: false + default: false + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Detect branch and version + id: detect-branch-version + uses: giancosta86/aurora-github/actions/detect-branch-version@v2.0.0 + with: + shell: ${{ inputs.shell }} + + - name: Verify branch and version + shell: ${{ inputs.shell }} + run: | + branch="${{ steps.detect-branch-version.outputs.branch }}" + version="${{ steps.detect-branch-version.outputs.version }}" + major="${{ steps.detect-branch-version.outputs.major }}" + defaultBranch="${{ github.event.repository.default_branch }}" + setMajorTag=${{ inputs.set-major-tag == 'true' }} + + echo "🌲It seems your default branch is: '$defaultBranch'" + + if [[ -z "$branch" ]] + then + echo "❌The current Git branch could not be detected!" >&2 + exit 1 + fi + + if [[ "$branch" == "$defaultBranch" ]] + then + echo "❌This action cannot be run from the default branch ('$defaultBranch')!" >&2 + exit 1 + fi + + if [[ -z "$version" ]] + then + echo "❌The current version could not be detected from the Git branch ('$branch')!" >&2 + exit 1 + fi + + if [[ "$setMajorTag" == "true" && -z "$major" ]] + then + echo "❌The major version could not be detected from the Git branch or the version!" >&2 + exit 1 + fi + + - name: Delete Git branch + if: ${{ inputs.delete-branch == 'true' }} + shell: ${{ inputs.shell }} + run: | + branch="${{ steps.detect-branch-version.outputs.branch }}" + + echo "Deleting Git 🌲branch '$branch'..." + + git push origin --delete "$branch" + + echo "🌲Branch deleted!" + + - name: Create Git tag + id: create-git-tag + shell: ${{ inputs.shell }} + run: | + version="${{ steps.detect-branch-version.outputs.version }}" + + tag="v${version}" + echo "📌Creating and pushing Git tag '$tag'..." + git tag "$tag" + git push origin "$tag" + echo "📌Tag created and pushed!" + + echo "tag=$tag" >> $GITHUB_OUTPUT + + - name: Create or draft release + shell: ${{ inputs.shell }} + run: | + draftOnly="${{ inputs.draft-only }}" + version="${{ steps.detect-branch-version.outputs.version }}" + tag="${{ steps.create-git-tag.outputs.tag }}" + + repoBasename="$(basename "$GITHUB_REPOSITORY")" + releaseTitle="$repoBasename $version" + + releaseRecap="release '$releaseTitle' from tag '$tag'" + + if [[ "$draftOnly" = true ]] + then + echo "📝Drafting $releaseRecap..." + gh release create "$tag" --title "$releaseTitle" --draft + echo "📝Release drafted!" + else + echo "🌟Creating $releaseRecap..." + gh release create "$tag" --title "$releaseTitle" + echo "🌟Release created!" + fi + env: + GH_TOKEN: ${{ github.token }} + + - name: Create or move major version tag + if: ${{ inputs.set-major-tag == 'true' }} + shell: ${{ inputs.shell }} + run: | + major="${{ steps.detect-branch-version.outputs.major }}" + + majorTag="v${major}" + + echo "🪩Setting major version tag '$majorTag'..." + git tag -f "$majorTag" + git push origin "$majorTag" --force + echo "🪩Major version tag set!" diff --git a/actions/verify-npm-package/README.md b/actions/verify-npm-package/README.md new file mode 100644 index 000000000..6d9b12794 --- /dev/null +++ b/actions/verify-npm-package/README.md @@ -0,0 +1,51 @@ +# verify-npm-package + +Verifies the source files of a **NodeJS** package - by running its `verify` script within the `scripts` section of `package.json`. + +It is worth noting this action can support any technology - as long as you comply with the requirements described below. + +## Example + +The action can be placed right after checking out the source code: + +```yaml +steps: + - uses: actions/checkout@v4 + + - uses: giancosta86/aurora-github/actions/verify-npm-package@v2 +``` + +**IMPORTANT**: please, remember to declare your verification process in the `verify` script within `package.json`! For example: + +```json +"scripts": { + "test": "vitest", + "build": "tsc", + "verify": "pnpm test && pnpm build" +} +``` + +## Requirements + +- The package manager for the project must be [pnpm](https://pnpm.io/) - version `9` or later compatible. + +- The entire verification process for the package must be triggered by the `verify` script in `package.json` (see the example). + +- The root directory of the project must contain a `.nvmrc` file - declaring the required Node.js version - whose format must be compatible with the `actions/setup-node` action (for example: `vX.Y.Z`). + +- The requirements for [check-artifact-version](../check-artifact-version/README.md), if `check-artifact-version` is enabled. + +## Inputs + +| Name | Type | Description | Default value | +| :----------------------: | :---------: | :----------------------------------------------------------: | :-----------: | +| `frozen-lockfile` | **boolean** | Fails if `pnpm-lock.yaml` is missing or outdated | **true** | +| `check-artifact-version` | **boolean** | Ensure the version in `package.json` matches the branch name | **true** | +| `project-directory` | **string** | The directory containing `package.json` | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [check-artifact-version](../check-artifact-version/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/verify-npm-package/action.yml b/actions/verify-npm-package/action.yml new file mode 100644 index 000000000..3c4325bee --- /dev/null +++ b/actions/verify-npm-package/action.yml @@ -0,0 +1,61 @@ +name: Verify npm package +description: Verifies the source files of a NodeJS package - by running its 'verify' script within the 'scripts' section of 'package.json'. + +inputs: + frozen-lockfile: + description: Fails if 'pnpm-lock.yaml' is missing or outdated. + required: false + default: true + + check-artifact-version: + description: Ensure the version in package.json matches the branch name. + required: false + default: true + + project-directory: + description: The directory containing package.json. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Check artifact version + if: ${{ inputs.check-artifact-version == 'true' }} + uses: giancosta86/aurora-github/actions/check-artifact-version@v2.0.0 + with: + project-directory: ${{ inputs.project-directory }} + shell: ${{ inputs.shell }} + + - name: Setup NodeJS + uses: actions/setup-node@v4 + with: + node-version-file: ${{ inputs.project-directory }}/.nvmrc + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Install the dependencies + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + frozenLockfile="${{ inputs.frozen-lockfile }}" + + if [[ "$frozenLockfile" == "true" ]] + then + pnpm install --frozen-lockfile + else + pnpm install --no-frozen-lockfile + fi + + - name: Verify the package + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: pnpm verify diff --git a/actions/verify-rust-crate/README.md b/actions/verify-rust-crate/README.md new file mode 100644 index 000000000..04c6257d3 --- /dev/null +++ b/actions/verify-rust-crate/README.md @@ -0,0 +1,51 @@ +# verify-rust-crate + +Verifies the source files of a **Rust** crate. + +## Example + +The action can be placed right after checking out the source code: + +```yaml +steps: + - uses: actions/checkout@v4 + + - uses: giancosta86/aurora-github/actions/verify-rust-crate@v2 +``` + +## How it works + +1. Optionally run [check-artifact-version](../check-artifact-version/README.md), to ensure that the artifact version in `Cargo.toml` matches the version detected from the name of the current Git branch. + +1. Display the version info for the main components of the Rust toolchain - verifying the existence of `rust-toolchain.toml`. + +1. Check the style of the Rust source files - via `cargo fmt`. + +1. Perform lint checks via `cargo clippy`, enabling all features and targets. All warnings are considered errors. This step can be skipped. + +1. Run `cargo test` with all the project features _disabled_. + +1. Run `cargo test` with all the project features _enabled_. + +## Requirements + +- `rust-toolchain.toml` must be present in `project-directory` - as described in [check-rust-versions](../check-rust-versions/README.md) + +- The requirements for [check-artifact-version](../check-artifact-version/README.md), if `check-artifact-version` is enabled. + +## Inputs + +| Name | Type | Description | Default value | +| :----------------------: | :---------: | :------------------------------------------------------: | :-----------: | +| `run-clippy-checks` | **boolean** | Enable linting via Clippy | **true** | +| `check-artifact-version` | **boolean** | Ensure the version in Cargo.toml matches the branch name | **true** | +| `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [check-artifact-version](../check-artifact-version/README.md) + +- [check-rust-versions](../check-rust-versions/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/verify-rust-crate/action.yml b/actions/verify-rust-crate/action.yml new file mode 100644 index 000000000..7211dd71a --- /dev/null +++ b/actions/verify-rust-crate/action.yml @@ -0,0 +1,60 @@ +name: Verify Rust crate +description: Verifies the source files of a Rust crate. + +inputs: + run-clippy-checks: + description: Enable linting via Clippy. + required: false + default: true + + check-artifact-version: + description: Ensure the version in Cargo.toml matches the branch name. + required: false + default: true + + project-directory: + description: The directory containing Cargo.toml. + required: false + default: . + + shell: + description: The shell used to run commands. + required: false + default: bash + +runs: + using: composite + steps: + - name: Check artifact version + if: ${{ inputs.check-artifact-version == 'true' }} + uses: giancosta86/aurora-github/actions/check-artifact-version@v2.0.0 + with: + project-directory: ${{ inputs.project-directory }} + shell: ${{ inputs.shell }} + + - name: Check Rust versions + uses: giancosta86/aurora-github/actions/check-rust-versions@v2.0.0 + with: + project-directory: ${{ inputs.project-directory }} + shell: ${{ inputs.shell }} + + - name: Check format style + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: cargo fmt --check + + - name: Lint via Clippy - with warnings as errors + if: ${{ inputs.run-clippy-checks == 'true' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: cargo clippy --all-targets --all-features -- -D warnings + + - name: Run vanilla (no features) tests + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: cargo test + + - name: Run full (all features) tests + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: cargo test --all-features diff --git a/actions/verify-rust-wasm/README.md b/actions/verify-rust-wasm/README.md new file mode 100644 index 000000000..5f3da09f8 --- /dev/null +++ b/actions/verify-rust-wasm/README.md @@ -0,0 +1,78 @@ +# verify-rust-wasm + +Verifies the source files of a **Rust** web assembly. + +## Example + +The action can be placed right after checking out the source code: + +```yaml +steps: + - uses: actions/checkout@v4 + + - uses: giancosta86/aurora-github/actions/verify-rust-wasm@v2 + with: + wasm-pack-version: 0.13.0 + npm-scope: your-npm-scope +``` + +## How it works + +1. Invoke the [install-wasm-pack](../install-wasm-pack/README.md) action, passing all the matching inputs, to install the `wasm-pack` command. + +1. Invoke the [verify-rust-crate](../verify-rust-crate/README.md) action, passing all the matching inputs, to perform code analysis over the Rust source code. + +1. Run `wasm-pack test` to run headless browser tests on Chrome. + +1. Run `wasm-pack build` to verify the generation of the NodeJS package source files. + +1. If the `client-tests-directory` input parameter is not an empty string: + + 1. Ensure the directory really exists + + 1. `cd` to that directory + + 1. Install its dependencies + + 1. Execute `pnpm verify` to run the NodeJS-based client tests + +## Requirements + +- `rust-toolchain.toml` must be present in `project-directory` - as described in [check-rust-versions](../check-rust-versions/README.md) + +- if `client-tests-directory` is not an empty string, it must be the **relative path** of a directory containing: + + - a `.nvmrc` file, with the requested Node.js version + + - a `package.json` descriptor having: + + - a `verify` script, in the `scripts` section + + - as usual, all the dependencies required by the tests + + - an updated `pnpm-lock.yaml` lockfile + +## Inputs + +| Name | Type | Description | Default value | +| :----------------------: | :---------: | :----------------------------------------------------------: | :--------------: | +| `wasm-pack-version` | **string** | The `wasm-pack` version to install | | +| `npm-scope` | **string** | The npm package scope (**without** the initial `@`) or empty | | +| `client-tests-directory` | **string** | Relative directory containing the NodeJS-based client tests | **client-tests** | +| `wasm-target` | **string** | The target of the `wasm-pack build` command | **web** | +| `run-clippy-checks` | **boolean** | Enable linting via Clippy | **true** | +| `check-artifact-version` | **boolean** | Ensure the version in Cargo.toml matches the branch name | **true** | +| `project-directory` | **string** | The directory containing `Cargo.toml` | **.** | +| `shell` | **string** | The shell used to run commands | **bash** | + +## Further references + +- [check-rust-versions](../check-rust-versions/README.md) + +- [install-wasm-pack](../install-wasm-pack/README.md) + +- [check-artifact-version](../check-artifact-version/README.md) + +- [verify-rust-crate](../verify-rust-crate/README.md) + +- [aurora-github](../../README.md) diff --git a/actions/verify-rust-wasm/action.yml b/actions/verify-rust-wasm/action.yml new file mode 100644 index 000000000..cff44098c --- /dev/null +++ b/actions/verify-rust-wasm/action.yml @@ -0,0 +1,113 @@ +name: Verify Rust web assembly +description: Verifies the source files of a Rust web assembly. + +inputs: + wasm-pack-version: + description: The wasm-pack version to install. + required: true + + npm-scope: + description: The npm package scope (without the initial @) - or empty. + required: true + + client-tests-directory: + description: Relative directory containing the NodeJS-based client tests. + required: false + default: client-tests + + wasm-target: + description: The target of the 'wasm-pack build' command. + required: false + default: web + + run-clippy-checks: + description: Enable linting via Clippy. + required: false + default: true + + check-artifact-version: + description: Ensure the version in Cargo.toml matches the branch name. + required: false + default: true + + project-directory: + description: The directory containing Cargo.toml. + required: false + default: . + + shell: + description: The shell used to run commands + required: false + default: bash + +runs: + using: composite + steps: + - name: Install wasm-pack + uses: giancosta86/aurora-github/actions/install-wasm-pack@v2.0.0 + with: + wasm-pack-version: ${{ inputs.wasm-pack-version }} + shell: ${{ inputs.shell }} + + - name: Verify Rust source files + uses: giancosta86/aurora-github/actions/verify-rust-crate@v2.0.0 + with: + run-clippy-checks: ${{ inputs.run-clippy-checks }} + check-artifact-version: ${{ inputs.check-artifact-version }} + project-directory: ${{ inputs.project-directory }} + shell: ${{ inputs.shell }} + + - name: Run headless browser tests + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: wasm-pack test --chrome --headless --release + + - name: Generate the NodeJS package source files + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + scope="${{ inputs.npm-scope }}" + + if [[ ! -z "$scope" ]] + then + wasm-pack build --dev --target "${{ inputs.wasm-target }}" --scope "$scope" + else + wasm-pack build --dev --target "${{ inputs.wasm-target }}" + fi + + - name: Ensure test client directory exists + if: ${{ inputs.client-tests-directory != '' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }} + run: | + clientTestsDirectory="${{ inputs.client-tests-directory }}" + + if [[ ! -d "$clientTestsDirectory" ]] + then + echo "❌The client test directory '$clientTestsDirectory' does not exist!" >&2 + exit 1 + fi + + - name: Set up NodeJS + if: ${{ inputs.client-tests-directory != '' }} + uses: actions/setup-node@v4 + with: + node-version-file: ${{ inputs.project-directory }}/${{ inputs.client-tests-directory }}/.nvmrc + + - name: Install pnpm + if: ${{ inputs.client-tests-directory != '' }} + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Install client-side test dependencies + if: ${{ inputs.client-tests-directory != '' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }}/${{ inputs.client-tests-directory }} + run: pnpm install --frozen-lockfile + + - name: Perform client-side tests + if: ${{ inputs.client-tests-directory != '' }} + shell: ${{ inputs.shell }} + working-directory: ${{ inputs.project-directory }}/${{ inputs.client-tests-directory }} + run: pnpm verify diff --git a/docs/schema.drawio b/docs/schema.drawio new file mode 100644 index 000000000..9c4685e59 --- /dev/null +++ b/docs/schema.drawio @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/schema.png b/docs/schema.png new file mode 100644 index 000000000..40386f934 Binary files /dev/null and b/docs/schema.png differ diff --git a/tests/npm-package/.gitignore b/tests/npm-package/.gitignore new file mode 100644 index 000000000..096746c14 --- /dev/null +++ b/tests/npm-package/.gitignore @@ -0,0 +1 @@ +/node_modules/ \ No newline at end of file diff --git a/tests/npm-package/.nvmrc b/tests/npm-package/.nvmrc new file mode 100644 index 000000000..78a949591 --- /dev/null +++ b/tests/npm-package/.nvmrc @@ -0,0 +1 @@ +v20.15.1 \ No newline at end of file diff --git a/tests/npm-package/package.json b/tests/npm-package/package.json new file mode 100644 index 000000000..d85f27fc7 --- /dev/null +++ b/tests/npm-package/package.json @@ -0,0 +1,9 @@ +{ + "name": "npm-package", + "version": "0.0.0", + "description": "Toy npm package", + "scripts": { + "test": "echo '✅NodeJS tests simulated!'", + "verify": "pnpm test" + } +} diff --git a/tests/npm-package/pnpm-lock.yaml b/tests/npm-package/pnpm-lock.yaml new file mode 100644 index 000000000..9b60ae178 --- /dev/null +++ b/tests/npm-package/pnpm-lock.yaml @@ -0,0 +1,9 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: {} diff --git a/tests/rust-crate/.gitignore b/tests/rust-crate/.gitignore new file mode 100644 index 000000000..a6f89c2da --- /dev/null +++ b/tests/rust-crate/.gitignore @@ -0,0 +1 @@ +/target/ \ No newline at end of file diff --git a/tests/rust-crate/Cargo.lock b/tests/rust-crate/Cargo.lock new file mode 100644 index 000000000..d93074b35 --- /dev/null +++ b/tests/rust-crate/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "rust-crate" +version = "0.0.0" diff --git a/tests/rust-crate/Cargo.toml b/tests/rust-crate/Cargo.toml new file mode 100644 index 000000000..8a424e351 --- /dev/null +++ b/tests/rust-crate/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rust-crate" +version = "0.0.0" +edition = "2021" + +[dependencies] diff --git a/tests/rust-crate/rust-toolchain.toml b/tests/rust-crate/rust-toolchain.toml new file mode 100644 index 000000000..4d2dee853 --- /dev/null +++ b/tests/rust-crate/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.80.0" diff --git a/tests/rust-crate/src/lib.rs b/tests/rust-crate/src/lib.rs new file mode 100644 index 000000000..b93cf3ffd --- /dev/null +++ b/tests/rust-crate/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: u64, right: u64) -> u64 { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/tests/rust-wasm/.gitignore b/tests/rust-wasm/.gitignore new file mode 100644 index 000000000..9e9174b5c --- /dev/null +++ b/tests/rust-wasm/.gitignore @@ -0,0 +1,4 @@ +/target/ +/pkg/ +/**/*.rs.bk +/wasm-pack.log diff --git a/tests/rust-wasm/Cargo.lock b/tests/rust-wasm/Cargo.lock new file mode 100644 index 000000000..c858c23db --- /dev/null +++ b/tests/rust-wasm/Cargo.lock @@ -0,0 +1,289 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-wasm" +version = "0.0.0" +dependencies = [ + "tsify", + "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bf62a58e0780af3e852044583deee40983e5886da43a271dd772379987667b" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "web-sys" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +dependencies = [ + "js-sys", + "wasm-bindgen", +] diff --git a/tests/rust-wasm/Cargo.toml b/tests/rust-wasm/Cargo.toml new file mode 100644 index 000000000..07e8afc2b --- /dev/null +++ b/tests/rust-wasm/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "test-wasm" +version = "0.0.0" +publish = false +edition = "2021" +description = "Test web assembly in Rust" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +wasm-bindgen = "0.2.92" + +[dev-dependencies] +tsify = { version = "0.4.5", features = ["json"] } +wasm-bindgen-test = "0.3.42" + +[profile.release] +opt-level = "s" +lto = true diff --git a/tests/rust-wasm/client-tests/.gitignore b/tests/rust-wasm/client-tests/.gitignore new file mode 100644 index 000000000..096746c14 --- /dev/null +++ b/tests/rust-wasm/client-tests/.gitignore @@ -0,0 +1 @@ +/node_modules/ \ No newline at end of file diff --git a/tests/rust-wasm/client-tests/.nvmrc b/tests/rust-wasm/client-tests/.nvmrc new file mode 100644 index 000000000..fb6d291b7 --- /dev/null +++ b/tests/rust-wasm/client-tests/.nvmrc @@ -0,0 +1 @@ +v20.14.0 diff --git a/tests/rust-wasm/client-tests/.prettierignore b/tests/rust-wasm/client-tests/.prettierignore new file mode 100644 index 000000000..999c405a8 --- /dev/null +++ b/tests/rust-wasm/client-tests/.prettierignore @@ -0,0 +1,3 @@ +/node_modules/ +/dist/ +/coverage/ \ No newline at end of file diff --git a/tests/rust-wasm/client-tests/.prettierrc b/tests/rust-wasm/client-tests/.prettierrc new file mode 100644 index 000000000..cefa5134c --- /dev/null +++ b/tests/rust-wasm/client-tests/.prettierrc @@ -0,0 +1,17 @@ +{ + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "quoteProps": "as-needed", + "jsxSingleQuote": false, + "trailingComma": "none", + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "avoid", + "proseWrap": "preserve", + "htmlWhitespaceSensitivity": "css", + "endOfLine": "lf", + "singleAttributePerLine": false +} diff --git a/tests/rust-wasm/client-tests/package.json b/tests/rust-wasm/client-tests/package.json new file mode 100644 index 000000000..dc5b353a2 --- /dev/null +++ b/tests/rust-wasm/client-tests/package.json @@ -0,0 +1,23 @@ +{ + "name": "client-tests", + "type": "module", + "dependencies": { + "@giancosta86/test-wasm": "link:../pkg" + }, + "devDependencies": { + "@types/node": "^20.14.2", + "prettier": "^3.3.1", + "rimraf": "^5.0.7", + "typescript": "^5.3.0", + "vite": "^5.4.3", + "vitest": "^1.6.0" + }, + "scripts": { + "clean": "rimraf node_modules", + "format": "prettier --write .", + "test": "vitest --no-watch", + "test:watch": "vitest", + "verify": "pnpm test" + }, + "private": true +} diff --git a/tests/rust-wasm/client-tests/pnpm-lock.yaml b/tests/rust-wasm/client-tests/pnpm-lock.yaml new file mode 100644 index 000000000..a846c1d6d --- /dev/null +++ b/tests/rust-wasm/client-tests/pnpm-lock.yaml @@ -0,0 +1,1271 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@giancosta86/test-wasm': + specifier: link:../pkg + version: link:../pkg + devDependencies: + '@types/node': + specifier: ^20.14.2 + version: 20.16.5 + prettier: + specifier: ^3.3.1 + version: 3.3.3 + rimraf: + specifier: ^5.0.7 + version: 5.0.10 + typescript: + specifier: ^5.3.0 + version: 5.5.4 + vite: + specifier: ^5.4.3 + version: 5.4.3(@types/node@20.16.5) + vitest: + specifier: ^1.6.0 + version: 1.6.0(@types/node@20.16.5) + +packages: + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@rollup/rollup-android-arm-eabi@4.21.2': + resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.21.2': + resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.21.2': + resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.21.2': + resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.21.2': + resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.21.2': + resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.21.2': + resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.21.2': + resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': + resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.21.2': + resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.21.2': + resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.21.2': + resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.21.2': + resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.21.2': + resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.21.2': + resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.21.2': + resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==} + cpu: [x64] + os: [win32] + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/node@20.16.5': + resolution: {integrity: sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==} + + '@vitest/expect@1.6.0': + resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + + '@vitest/runner@1.6.0': + resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + + '@vitest/snapshot@1.6.0': + resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + + '@vitest/spy@1.6.0': + resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + + '@vitest/utils@1.6.0': + resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + pkg-types@1.2.0: + resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} + + postcss@8.4.45: + resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} + engines: {node: ^10 || ^12 || >=14} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + rollup@4.21.2: + resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + vite-node@1.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.3: + resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@1.6.0: + resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + yocto-queue@1.1.1: + resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} + engines: {node: '>=12.20'} + +snapshots: + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@rollup/rollup-android-arm-eabi@4.21.2': + optional: true + + '@rollup/rollup-android-arm64@4.21.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.21.2': + optional: true + + '@rollup/rollup-darwin-x64@4.21.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.21.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.21.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.21.2': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.21.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.21.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.21.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.21.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.21.2': + optional: true + + '@sinclair/typebox@0.27.8': {} + + '@types/estree@1.0.5': {} + + '@types/node@20.16.5': + dependencies: + undici-types: 6.19.8 + + '@vitest/expect@1.6.0': + dependencies: + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + chai: 4.5.0 + + '@vitest/runner@1.6.0': + dependencies: + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.6.0': + dependencies: + magic-string: 0.30.11 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.6.0': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.6.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + assertion-error@1.1.0: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + cac@6.7.14: {} + + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + confbox@0.1.7: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + + diff-sequences@29.6.3: {} + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + get-func-name@2.0.2: {} + + get-stream@8.0.1: {} + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + human-signals@5.0.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-stream@3.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + js-tokens@9.0.0: {} + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.2.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lru-cache@10.4.3: {} + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + merge-stream@2.0.0: {} + + mimic-fn@4.0.0: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mlly@1.7.1: + dependencies: + acorn: 8.12.1 + pathe: 1.1.2 + pkg-types: 1.2.0 + ufo: 1.5.4 + + ms@2.1.2: {} + + nanoid@3.3.7: {} + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + p-limit@5.0.0: + dependencies: + yocto-queue: 1.1.1 + + package-json-from-dist@1.0.0: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pathe@1.1.2: {} + + pathval@1.1.1: {} + + picocolors@1.1.0: {} + + pkg-types@1.2.0: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + + postcss@8.4.45: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.0 + source-map-js: 1.2.0 + + prettier@3.3.3: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + react-is@18.3.1: {} + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + rollup@4.21.2: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.21.2 + '@rollup/rollup-android-arm64': 4.21.2 + '@rollup/rollup-darwin-arm64': 4.21.2 + '@rollup/rollup-darwin-x64': 4.21.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.2 + '@rollup/rollup-linux-arm-musleabihf': 4.21.2 + '@rollup/rollup-linux-arm64-gnu': 4.21.2 + '@rollup/rollup-linux-arm64-musl': 4.21.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.2 + '@rollup/rollup-linux-riscv64-gnu': 4.21.2 + '@rollup/rollup-linux-s390x-gnu': 4.21.2 + '@rollup/rollup-linux-x64-gnu': 4.21.2 + '@rollup/rollup-linux-x64-musl': 4.21.2 + '@rollup/rollup-win32-arm64-msvc': 4.21.2 + '@rollup/rollup-win32-ia32-msvc': 4.21.2 + '@rollup/rollup-win32-x64-msvc': 4.21.2 + fsevents: 2.3.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + source-map-js@1.2.0: {} + + stackback@0.0.2: {} + + std-env@3.7.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-final-newline@3.0.0: {} + + strip-literal@2.1.0: + dependencies: + js-tokens: 9.0.0 + + tinybench@2.9.0: {} + + tinypool@0.8.4: {} + + tinyspy@2.2.1: {} + + type-detect@4.1.0: {} + + typescript@5.5.4: {} + + ufo@1.5.4: {} + + undici-types@6.19.8: {} + + vite-node@1.6.0(@types/node@20.16.5): + dependencies: + cac: 6.7.14 + debug: 4.3.6 + pathe: 1.1.2 + picocolors: 1.1.0 + vite: 5.4.3(@types/node@20.16.5) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.3(@types/node@20.16.5): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.45 + rollup: 4.21.2 + optionalDependencies: + '@types/node': 20.16.5 + fsevents: 2.3.3 + + vitest@1.6.0(@types/node@20.16.5): + dependencies: + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + acorn-walk: 8.3.3 + chai: 4.5.0 + debug: 4.3.6 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.11 + pathe: 1.1.2 + picocolors: 1.1.0 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.9.0 + tinypool: 0.8.4 + vite: 5.4.3(@types/node@20.16.5) + vite-node: 1.6.0(@types/node@20.16.5) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.16.5 + transitivePeerDependencies: + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + yocto-queue@1.1.1: {} diff --git a/tests/rust-wasm/client-tests/src/lib.test.ts b/tests/rust-wasm/client-tests/src/lib.test.ts new file mode 100644 index 000000000..f1b1a0c2e --- /dev/null +++ b/tests/rust-wasm/client-tests/src/lib.test.ts @@ -0,0 +1,23 @@ +import { describe, it, expect, beforeAll } from "vitest"; +import { readFile } from "node:fs/promises"; +import { fileURLToPath } from "node:url"; +import initTestWasm, { add_ninety } from "@giancosta86/test-wasm"; + +describe("Test WebAssembly", () => { + beforeAll(async () => { + const wasmUrl = new URL( + "../node_modules/@giancosta86/test-wasm/test_wasm_bg.wasm", + import.meta.url + ); + + const wasmPath = fileURLToPath(wasmUrl); + + const buffer = await readFile(wasmPath); + + await initTestWasm(buffer); + }); + + it("should correctly add 90", () => { + expect(add_ninety(5)).toBe(95); + }); +}); diff --git a/tests/rust-wasm/client-tests/tsconfig.json b/tests/rust-wasm/client-tests/tsconfig.json new file mode 100644 index 000000000..f6b05a87b --- /dev/null +++ b/tests/rust-wasm/client-tests/tsconfig.json @@ -0,0 +1,36 @@ +{ + "include": ["./src/**/*"], + + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + + "moduleResolution": "Node", + + "rootDir": "./src", + + "declaration": false, + "declarationMap": false, + "sourceMap": false, + "removeComments": true, + + "forceConsistentCasingInFileNames": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "exactOptionalPropertyTypes": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + + "esModuleInterop": true, + + "baseUrl": "./src", + "paths": { + "@/*": ["./*"] + } + } +} diff --git a/tests/rust-wasm/client-tests/vite.config.ts b/tests/rust-wasm/client-tests/vite.config.ts new file mode 100644 index 000000000..49741f29d --- /dev/null +++ b/tests/rust-wasm/client-tests/vite.config.ts @@ -0,0 +1,12 @@ +import { fileURLToPath, URL } from "node:url"; +import { defineConfig } from "vite"; + +export default defineConfig({ + resolve: { + alias: { + "@giancosta86/test_wasm": fileURLToPath( + new URL("../pkg/test_wasm.js", import.meta.url) + ) + } + } +}); diff --git a/tests/rust-wasm/client-tests/vitest.config.ts b/tests/rust-wasm/client-tests/vitest.config.ts new file mode 100644 index 000000000..8801430c7 --- /dev/null +++ b/tests/rust-wasm/client-tests/vitest.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from "vitest/config"; +import viteConfig from "./vite.config"; + +export default defineConfig({ + ...viteConfig, +}); diff --git a/tests/rust-wasm/rust-toolchain.toml b/tests/rust-wasm/rust-toolchain.toml new file mode 100644 index 000000000..4d2dee853 --- /dev/null +++ b/tests/rust-wasm/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.80.0" diff --git a/tests/rust-wasm/src/lib.rs b/tests/rust-wasm/src/lib.rs new file mode 100644 index 000000000..a4bb3f210 --- /dev/null +++ b/tests/rust-wasm/src/lib.rs @@ -0,0 +1,18 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn add_ninety(x: i32) -> i32 { + x + 90 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + pub fn unit_test_add_ninety() { + let result = add_ninety(8); + + assert_eq!(result, 98); + } +} diff --git a/tests/rust-wasm/tests/web.rs b/tests/rust-wasm/tests/web.rs new file mode 100644 index 000000000..dd1ddffbd --- /dev/null +++ b/tests/rust-wasm/tests/web.rs @@ -0,0 +1,10 @@ +use test_wasm::*; +use wasm_bindgen_test::*; + +wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + +#[wasm_bindgen_test] +fn test_add_ninety() { + let result = add_ninety(2); + assert_eq!(result, 92); +} diff --git a/tests/unknown-tech/some-descriptor.txt b/tests/unknown-tech/some-descriptor.txt new file mode 100644 index 000000000..16c3d360b --- /dev/null +++ b/tests/unknown-tech/some-descriptor.txt @@ -0,0 +1,3 @@ +version: v0.0.0 + +second occurrence: '0.0.0';