mirror of
https://github.com/supabase/setup-cli.git
synced 2026-06-28 09:57:03 +00:00
Compare commits
1 Commits
v2.1.1
...
feat/cachi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9da7121816 |
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
@@ -52,7 +52,6 @@ jobs:
|
|||||||
- uses: ./
|
- uses: ./
|
||||||
with:
|
with:
|
||||||
version: ${{ matrix.version }}
|
version: ${{ matrix.version }}
|
||||||
github-token: ${{ github.token }}
|
|
||||||
- run: supabase -h
|
- run: supabase -h
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
|
|||||||
4
.github/workflows/dependabot.yml
vendored
4
.github/workflows/dependabot.yml
vendored
@@ -20,14 +20,14 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# Metadata drives the non-major gating used for approval and auto-merge.
|
# Metadata drives the non-major gating used for approval and auto-merge.
|
||||||
- id: meta
|
- id: meta
|
||||||
uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
|
uses: dependabot/fetch-metadata@ffa630c65fa7e0ecfa0625b5ceda64399aea1b36 # v3.0.0
|
||||||
with:
|
with:
|
||||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
- name: Generate token
|
- name: Generate token
|
||||||
id: app-token
|
id: app-token
|
||||||
if: ${{ steps.meta.outputs.update-type == null || steps.meta.outputs.update-type == 'version-update:semver-patch' || steps.meta.outputs.update-type == 'version-update:semver-minor' }}
|
if: ${{ steps.meta.outputs.update-type == null || steps.meta.outputs.update-type == 'version-update:semver-patch' || steps.meta.outputs.update-type == 'version-update:semver-minor' }}
|
||||||
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.APP_ID }}
|
app-id: ${{ secrets.APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
|
|||||||
15
.github/workflows/licensed.yml
vendored
15
.github/workflows/licensed.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
# This workflow refreshes and checks dependency license records used in this
|
# This workflow checks the statuses of cached dependencies used in this action
|
||||||
# action with the help of the Licensed tool. If any licenses are invalid or
|
# with the help of the Licensed tool. If any licenses are invalid or missing,
|
||||||
# missing, this workflow will fail. See: https://github.com/licensee/licensed
|
# this workflow will fail. See: https://github.com/licensee/licensed
|
||||||
|
|
||||||
name: Licensed
|
name: Licensed
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ jobs:
|
|||||||
- name: Setup Ruby
|
- name: Setup Ruby
|
||||||
id: setup-ruby
|
id: setup-ruby
|
||||||
if: steps.license-inputs.outputs.changed == 'true'
|
if: steps.license-inputs.outputs.changed == 'true'
|
||||||
uses: ruby/setup-ruby@97ecb7b512899eb71ab1bf2310a624c6f1589ac6 # v1.308.0
|
uses: ruby/setup-ruby@e65c17d16e57e481586a6a5a0282698790062f92 # v1.300.0
|
||||||
with:
|
with:
|
||||||
ruby-version: ruby
|
ruby-version: ruby
|
||||||
|
|
||||||
@@ -81,11 +81,6 @@ jobs:
|
|||||||
version: 4.x
|
version: 4.x
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Refresh License Cache
|
|
||||||
id: refresh-license-cache
|
|
||||||
if: steps.license-inputs.outputs.changed == 'true'
|
|
||||||
run: licensed cache
|
|
||||||
|
|
||||||
- name: Check Licenses
|
- name: Check Licenses
|
||||||
id: check-licenses
|
id: check-licenses
|
||||||
if: steps.license-inputs.outputs.changed == 'true'
|
if: steps.license-inputs.outputs.changed == 'true'
|
||||||
@@ -116,7 +111,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Setup Ruby
|
- name: Setup Ruby
|
||||||
id: setup-ruby
|
id: setup-ruby
|
||||||
uses: ruby/setup-ruby@97ecb7b512899eb71ab1bf2310a624c6f1589ac6 # v1.308.0
|
uses: ruby/setup-ruby@e65c17d16e57e481586a6a5a0282698790062f92 # v1.300.0
|
||||||
with:
|
with:
|
||||||
ruby-version: ruby
|
ruby-version: ruby
|
||||||
|
|
||||||
|
|||||||
58
README.md
58
README.md
@@ -40,6 +40,22 @@ steps:
|
|||||||
version: 2.84.2
|
version: 2.84.2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Cache Docker images used by `supabase start` across workflow runs:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- uses: supabase/setup-cli@v2
|
||||||
|
with:
|
||||||
|
version: 2.84.2
|
||||||
|
cache: true
|
||||||
|
- run: supabase start
|
||||||
|
```
|
||||||
|
|
||||||
|
The first run still pulls images from the registry. Later runs can restore the
|
||||||
|
same image set from the GitHub Actions cache before `supabase start` runs, and
|
||||||
|
the action saves newly pulled Supabase images at the end of a successful job.
|
||||||
|
|
||||||
Run `supabase db start` to execute all migrations on a fresh database:
|
Run `supabase db start` to execute all migrations on a fresh database:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -47,7 +63,6 @@ steps:
|
|||||||
- uses: supabase/setup-cli@v2
|
- uses: supabase/setup-cli@v2
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
github-token: ${{ github.token }}
|
|
||||||
- run: supabase init
|
- run: supabase init
|
||||||
- run: supabase db start
|
- run: supabase db start
|
||||||
```
|
```
|
||||||
@@ -59,10 +74,18 @@ on Windows and macOS runners.
|
|||||||
|
|
||||||
The action supports the following inputs:
|
The action supports the following inputs:
|
||||||
|
|
||||||
| Name | Type | Description | Default | Required |
|
| Name | Type | Description | Default | Required |
|
||||||
| -------------- | ------ | -------------------------------------------------------------------------- | --------------------------------- | -------- |
|
| ----------- | ------- | ------------------------------------------------------ | --------------------------------- | -------- |
|
||||||
| `version` | String | Supabase CLI version (or `latest`) | Root lockfile version or `latest` | false |
|
| `version` | String | Supabase CLI version (or `latest`) | Root lockfile version or `latest` | false |
|
||||||
| `github-token` | String | GitHub token used to resolve `latest` without unauthenticated API limiting | | false |
|
| `cache` | Boolean | Cache Docker images used by Supabase local development | `false` | false |
|
||||||
|
| `cache-key` | String | Explicit cache key for Supabase Docker images | Generated from runner and config | false |
|
||||||
|
|
||||||
|
The action exposes these outputs:
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
| ----------- | ------------------------------------------------------ |
|
||||||
|
| `version` | Version of installed Supabase CLI |
|
||||||
|
| `cache-hit` | Whether an exact Supabase Docker image cache was found |
|
||||||
|
|
||||||
## Advanced Usage
|
## Advanced Usage
|
||||||
|
|
||||||
@@ -103,6 +126,8 @@ Export local Supabase env vars for app tests:
|
|||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: supabase/setup-cli@v2
|
- uses: supabase/setup-cli@v2
|
||||||
|
with:
|
||||||
|
cache: true
|
||||||
- run: supabase init
|
- run: supabase init
|
||||||
- run: supabase start
|
- run: supabase start
|
||||||
- name: Export local Supabase env vars
|
- name: Export local Supabase env vars
|
||||||
@@ -115,6 +140,22 @@ steps:
|
|||||||
- run: bun test
|
- run: bun test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Customize the Docker image cache key when the image set depends on your workflow
|
||||||
|
flags, generated config, or monorepo layout:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
- uses: supabase/setup-cli@v2
|
||||||
|
with:
|
||||||
|
cache: true
|
||||||
|
cache-key: supabase-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('supabase/config.toml') }}-start-all
|
||||||
|
- run: supabase start
|
||||||
|
```
|
||||||
|
|
||||||
|
Avoid running `docker system prune -a` before the job ends if you want the
|
||||||
|
post-action cache save to include images pulled by `supabase start`.
|
||||||
|
|
||||||
## Develop
|
## Develop
|
||||||
|
|
||||||
After you've cloned the repository to your local machine or codespace, you'll
|
After you've cloned the repository to your local machine or codespace, you'll
|
||||||
@@ -138,6 +179,12 @@ need to perform a few setup steps before you can work on the action.
|
|||||||
bun test
|
bun test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
1. :package: Build the bundled action entrypoints
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run build
|
||||||
|
```
|
||||||
|
|
||||||
1. :mag: Run the full local CI suite
|
1. :mag: Run the full local CI suite
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -164,7 +211,6 @@ steps:
|
|||||||
- uses: ./
|
- uses: ./
|
||||||
with:
|
with:
|
||||||
version: latest
|
version: latest
|
||||||
github-token: ${{ github.token }}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The CI workflow provides fast smoke coverage across GitHub-hosted runners, and
|
The CI workflow provides fast smoke coverage across GitHub-hosted runners, and
|
||||||
|
|||||||
116
action.yml
116
action.yml
@@ -5,112 +5,20 @@ inputs:
|
|||||||
version:
|
version:
|
||||||
description: Version of Supabase CLI to install. If omitted, detect from the root lockfile and otherwise use latest.
|
description: Version of Supabase CLI to install. If omitted, detect from the root lockfile and otherwise use latest.
|
||||||
required: false
|
required: false
|
||||||
github-token:
|
cache:
|
||||||
description: GitHub token used to resolve the latest Supabase CLI release without hitting unauthenticated API limits.
|
description: Cache Docker images used by Supabase local development commands.
|
||||||
|
required: false
|
||||||
|
default: "false"
|
||||||
|
cache-key:
|
||||||
|
description: Optional explicit cache key for Supabase Docker images.
|
||||||
required: false
|
required: false
|
||||||
outputs:
|
outputs:
|
||||||
version:
|
version:
|
||||||
description: Version of installed Supabase CLI
|
description: Version of installed Supabase CLI
|
||||||
value: ${{ steps.setup-cli.outputs.version }}
|
cache-hit:
|
||||||
|
description: Whether an exact Supabase Docker image cache was restored.
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: node24
|
||||||
steps:
|
main: dist/main.js
|
||||||
- id: bun-download
|
post: dist/post.js
|
||||||
name: Resolve Bun Download URL
|
post-if: success()
|
||||||
shell: sh
|
|
||||||
working-directory: ${{ github.action_path }}
|
|
||||||
run: |
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
if [ "${RUNNER_OS}" != "Linux" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# setup-bun does not detect Linux musl yet, so Alpine-like containers need the musl asset explicitly.
|
|
||||||
is_musl=false
|
|
||||||
if [ -f /etc/alpine-release ]; then
|
|
||||||
is_musl=true
|
|
||||||
elif command -v ldd >/dev/null 2>&1 && ldd --version 2>&1 | grep -qi musl; then
|
|
||||||
is_musl=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${is_musl}" != "true" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
version="$(cat .bun-version)"
|
|
||||||
case "$(uname -m)" in
|
|
||||||
x86_64) arch="x64" ;;
|
|
||||||
aarch64|arm64) arch="aarch64" ;;
|
|
||||||
*)
|
|
||||||
echo "Unsupported Linux musl architecture: $(uname -m)" >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo "url=https://github.com/oven-sh/bun/releases/download/bun-v${version}/bun-linux-${arch}-musl.zip" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: Install Alpine Runtime Dependencies
|
|
||||||
shell: sh
|
|
||||||
run: |
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
if [ "${RUNNER_OS}" != "Linux" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
is_musl=false
|
|
||||||
if [ -f /etc/alpine-release ]; then
|
|
||||||
is_musl=true
|
|
||||||
elif command -v ldd >/dev/null 2>&1 && ldd --version 2>&1 | grep -qi musl; then
|
|
||||||
is_musl=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${is_musl}" != "true" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Bun's musl binary and the Supabase CLI shim both dynamically link libstdc++ and libgcc.
|
|
||||||
if command -v apk >/dev/null 2>&1; then
|
|
||||||
missing_packages=""
|
|
||||||
for package in libstdc++ libgcc; do
|
|
||||||
if ! apk info -e "${package}" >/dev/null 2>&1; then
|
|
||||||
missing_packages="${missing_packages} ${package}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "${missing_packages}" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$(id -u)" != "0" ]; then
|
|
||||||
echo "::error::Alpine/musl containers need${missing_packages} to run Supabase CLI. Add 'apk add --no-cache${missing_packages}' before supabase/setup-cli, or run this job container as root."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
apk add --no-cache ${missing_packages}
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "::error::Linux musl containers need libstdc++ and libgcc to run Supabase CLI. Install them before supabase/setup-cli."
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
- name: Setup Bun
|
|
||||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
|
||||||
with:
|
|
||||||
bun-version-file: ${{ github.action_path }}/.bun-version
|
|
||||||
bun-download-url: ${{ steps.bun-download.outputs.url }}
|
|
||||||
|
|
||||||
- name: Install Action Dependencies
|
|
||||||
shell: sh
|
|
||||||
working-directory: ${{ github.action_path }}
|
|
||||||
run: bun install --frozen-lockfile --production
|
|
||||||
|
|
||||||
- id: setup-cli
|
|
||||||
name: Setup Supabase CLI
|
|
||||||
shell: sh
|
|
||||||
working-directory: ${{ github.action_path }}
|
|
||||||
env:
|
|
||||||
INPUT_VERSION: ${{ inputs.version }}
|
|
||||||
SUPABASE_CLI_GITHUB_TOKEN: ${{ inputs.github-token }}
|
|
||||||
run: bun src/main.ts
|
|
||||||
|
|||||||
216
bun.lock
216
bun.lock
@@ -5,158 +5,240 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "setup-cli",
|
"name": "setup-cli",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^3.0.1",
|
"@actions/cache": "^6.0.0",
|
||||||
|
"@actions/core": "^3.0.0",
|
||||||
"@actions/tool-cache": "^4.0.0",
|
"@actions/tool-cache": "^4.0.0",
|
||||||
|
"js-yaml": "^4.1.1",
|
||||||
|
"semver": "^7.7.4",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/bun": "^1.0.10",
|
"@tsconfig/bun": "^1.0.10",
|
||||||
"@types/bun": "^1.3.14",
|
"@types/bun": "^1.3.11",
|
||||||
"@typescript/native-preview": "^7.0.0-dev.20260410.1",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"oxfmt": "^0.49.0",
|
"@types/node": "^24",
|
||||||
"oxlint": "^1.64.0",
|
"@types/semver": "^7.7.1",
|
||||||
"oxlint-tsgolint": "^0.22.1",
|
"@typescript/native-preview": "^7.0.0-dev.20260409.1",
|
||||||
|
"oxfmt": "^0.44.0",
|
||||||
|
"oxlint": "^1.59.0",
|
||||||
|
"oxlint-tsgolint": "^0.20.0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
"@actions/core": ["@actions/core@3.0.1", "", { "dependencies": { "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0" } }, "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA=="],
|
"@actions/cache": ["@actions/cache@6.0.0", "", { "dependencies": { "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/glob": "^0.6.1", "@actions/http-client": "^4.0.0", "@actions/io": "^3.0.0", "@azure/core-rest-pipeline": "^1.22.0", "@azure/storage-blob": "^12.30.0", "@protobuf-ts/runtime-rpc": "^2.11.1", "semver": "^7.7.3" } }, "sha512-+tCs634SyGBQJ3KU1rtAVabmN/gYiT9WgzTSJzWwdPCLmM3zWrdbysaErKv8HyI6OozClrxNvDgPjJimbHZZvw=="],
|
||||||
|
|
||||||
|
"@actions/core": ["@actions/core@3.0.0", "", { "dependencies": { "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0" } }, "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg=="],
|
||||||
|
|
||||||
"@actions/exec": ["@actions/exec@3.0.0", "", { "dependencies": { "@actions/io": "^3.0.2" } }, "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw=="],
|
"@actions/exec": ["@actions/exec@3.0.0", "", { "dependencies": { "@actions/io": "^3.0.2" } }, "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw=="],
|
||||||
|
|
||||||
|
"@actions/glob": ["@actions/glob@0.6.1", "", { "dependencies": { "@actions/core": "^3.0.0", "minimatch": "^3.0.4" } }, "sha512-K4+2Ac5ILcf2ySdJCha+Pop9NcKjxqCL4xL4zI50dgB2PbXgC0+AcP011xfH4Of6b4QEJJg8dyZYv7zl4byTsw=="],
|
||||||
|
|
||||||
"@actions/http-client": ["@actions/http-client@4.0.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^6.23.0" } }, "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g=="],
|
"@actions/http-client": ["@actions/http-client@4.0.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^6.23.0" } }, "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g=="],
|
||||||
|
|
||||||
"@actions/io": ["@actions/io@3.0.2", "", {}, "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="],
|
"@actions/io": ["@actions/io@3.0.2", "", {}, "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="],
|
||||||
|
|
||||||
"@actions/tool-cache": ["@actions/tool-cache@4.0.0", "", { "dependencies": { "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0", "@actions/io": "^3.0.0", "semver": "^7.7.3" } }, "sha512-L8P9HbXvpvqjZDveb/fdsa55IVC0trfPgQ4ZwGo6r5af6YDVdM9vMGPZ7rgY2fAT9gGj4PSYd6bYlg3p3jD78A=="],
|
"@actions/tool-cache": ["@actions/tool-cache@4.0.0", "", { "dependencies": { "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0", "@actions/io": "^3.0.0", "semver": "^7.7.3" } }, "sha512-L8P9HbXvpvqjZDveb/fdsa55IVC0trfPgQ4ZwGo6r5af6YDVdM9vMGPZ7rgY2fAT9gGj4PSYd6bYlg3p3jD78A=="],
|
||||||
|
|
||||||
"@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.49.0", "", { "os": "android", "cpu": "arm" }, "sha512-HbifJ84prIh9+55CTPAU35JdRQrwg47y16cGerCC+iejSKOuHXYo2WDql6l7cQlzrYVtc3f4UWY+dBj2lRmOeA=="],
|
"@azure/abort-controller": ["@azure/abort-controller@2.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA=="],
|
||||||
|
|
||||||
"@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.49.0", "", { "os": "android", "cpu": "arm64" }, "sha512-Ef7SKJqAaH2d7E6eXZZa2OffIShbhFMxnGK0zd93p4qiyTJr75B0qf7lrPD+qQOwcf04BrjYJ0JUxq8d5+yZwg=="],
|
"@azure/core-auth": ["@azure/core-auth@1.10.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" } }, "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg=="],
|
||||||
|
|
||||||
"@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.49.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-8x5DN9CsFfb432sHa9NyqX5XisGUdA53LPEGSdv/VniS+v4uEOR8Orv7A9QSB98Xxgp0t6r31DzQA/wpIobGqQ=="],
|
"@azure/core-client": ["@azure/core-client@1.10.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0", "@azure/core-tracing": "^1.3.0", "@azure/core-util": "^1.13.0", "@azure/logger": "^1.3.0", "tslib": "^2.6.2" } }, "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w=="],
|
||||||
|
|
||||||
"@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.49.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-e0+DSVzk4ewhMVKNYDaRTmP81jNMBWR1X9al0cVKWS+hDM/dElNqD5zjTOCuLOZc4oOdp2Gx2ldrVL+yYo9TZQ=="],
|
"@azure/core-http-compat": ["@azure/core-http-compat@2.4.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2" }, "peerDependencies": { "@azure/core-client": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0" } }, "sha512-f1P96IB399YiN2ARYHP7EpZi3Bf3wH4SN2lGzrw7JVwm7bbsVYtf2iKSBwTywD2P62NOPZGHFSZi+6jjb75JuA=="],
|
||||||
|
|
||||||
"@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.49.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-W+mjtYtrQvFbXT/uNT+221OBhGRZ8UqNsLxjTWsjZ4GsQnRdvRC/N2NCK86BcamWr7lsTxwpwN3PULnr78sgcQ=="],
|
"@azure/core-lro": ["@azure/core-lro@2.7.2", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", "tslib": "^2.6.2" } }, "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.49.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Rtv6UevV7czDlLqil+NZUe4d8gs8jQo/zScSpumwyf7I+fSdLc+hc8AF3MQC7ymxSMMD9+vfiqQlsIf7wOAzXA=="],
|
"@azure/core-paging": ["@azure/core-paging@1.6.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.49.0", "", { "os": "linux", "cpu": "arm" }, "sha512-sBi+8C/Q/MdKa5FL8ibAUCdhFBGFH7HFN/Qoyd5xQbZ/0ky3NMPpKfIBpaH0lhK2dXkGLczVQUoZ+xuNSerCdQ=="],
|
"@azure/core-rest-pipeline": ["@azure/core-rest-pipeline@1.23.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.10.0", "@azure/core-tracing": "^1.3.0", "@azure/core-util": "^1.13.0", "@azure/logger": "^1.3.0", "@typespec/ts-http-runtime": "^0.3.4", "tslib": "^2.6.2" } }, "sha512-Evs1INHo+jUjwHi1T6SG6Ua/LHOQBCLuKEEE6efIpt4ZOoNonaT1kP32GoOcdNDbfqsD2445CPri3MubBy5DEQ=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.49.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-JIfWenFhlzx+O8YygyZhoHFzTsdgDhxhbDRnE2iJLnnM5pWKScFvPECO2vOlA7JqJ/9S1g3uzEKuRCkHFwTjvA=="],
|
"@azure/core-tracing": ["@azure/core-tracing@1.3.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.49.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-iNzkMPG18jPkwBOZ4/HEjwqfzAjq4RrUQ0CgId/fC1ENvYD5jLVAaU/gWgpiqP1ys07kxSsSggDd1fp3E7mQHw=="],
|
"@azure/core-util": ["@azure/core-util@1.13.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.49.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-BPHA/NN3LvoIXiid+iz3BHt5V0Rzx0tXAqRUovwE1NsbDaLG9e8mtv7evDGRIkVQacqTDBv0XL25THHsxSJosQ=="],
|
"@azure/core-xml": ["@azure/core-xml@1.5.1", "", { "dependencies": { "fast-xml-parser": "^5.5.9", "tslib": "^2.8.1" } }, "sha512-xcNRHqCoSp4AunOALEae6A8f3qATb83gSrm31Iqb01OzblvC3/W/bfXozcq78EzIdzZzuH1bZ2NvRR0TdX709w=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.49.0", "", { "os": "linux", "cpu": "none" }, "sha512-3Eroshe+s69htC9JIL0+zLGQczLtRKezkMhwqQC21VC5Z/fuLvzLfbAOLgJLUq601H8gDYjy7deYycfOBjCvWg=="],
|
"@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.49.0", "", { "os": "linux", "cpu": "none" }, "sha512-fnaERGgsxGm0lKAmO72EYR4BA3qBnzBTJBTi6EtUMq1D4R7EexRBMU4voXnx4TXla3SEDl9x4uNp/18SbkPjGg=="],
|
"@azure/storage-blob": ["@azure/storage-blob@12.31.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.3", "@azure/core-http-compat": "^2.2.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/core-xml": "^1.4.5", "@azure/logger": "^1.1.4", "@azure/storage-common": "^12.3.0", "events": "^3.0.0", "tslib": "^2.8.1" } }, "sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.49.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-rBwasMl1Uul1MCCeTGEFKnOTL7VUxHf+634jWStrQAbzpBJgd5Yz5m4F7exVCsoI8PHn57dNjssXagXLCLB5yA=="],
|
"@azure/storage-common": ["@azure/storage-common@12.3.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-http-compat": "^2.2.0", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.1.4", "events": "^3.3.0", "tslib": "^2.8.1" } }, "sha512-/OFHhy86aG5Pe8dP5tsp+BuJ25JOAl9yaMU3WZbkeoiFMHFtJ7tu5ili7qEdBXNW9G5lDB19trwyI6V49F/8iQ=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.49.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BoC/F9xHe2y/deuBGA5Aw7bes07OD2gcL2wlpzTrfImR92vPP7S/k3LBTyspQZCNIVNdagkELcqKELwMLGIfAg=="],
|
"@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.44.0", "", { "os": "android", "cpu": "arm" }, "sha512-5UvghMd9SA/yvKTWCAxMAPXS1d2i054UeOf4iFjZjfayTwCINcC3oaSXjtbZfCaEpxgJod7XiOjTtby5yEv/BQ=="],
|
||||||
|
|
||||||
"@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.49.0", "", { "os": "linux", "cpu": "x64" }, "sha512-umY6jFADAo/oztFKl8D/S6vSrG6oBpEskcentiRuz42kZVU2kfDXMWCYavxyZR2bwPjqkHpcHZ6EZFiH3Qj9ZA=="],
|
"@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.44.0", "", { "os": "android", "cpu": "arm64" }, "sha512-IVudM1BWfvrYO++Khtzr8q9n5Rxu7msUvoFMqzGJVdX7HfUXUDHwaH2zHZNB58svx2J56pmCUzophyaPFkcG/A=="],
|
||||||
|
|
||||||
"@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.49.0", "", { "os": "none", "cpu": "arm64" }, "sha512-J85zQMiw2pXiGPK+OusmDvSnJ/dgpgN7VgmB2zOBtgS8F+nsOUfSg9ZEBrwbQscjZ7tkPbm38CG4VF5f53MsiA=="],
|
"@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.44.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eWCLAIKAHfx88EqEP1Ga2yz7qVcqDU5lemn4xck+07bH182hDdprOHjbogyk0In1Djys3T0/pO2JepFnRJ41Mg=="],
|
||||||
|
|
||||||
"@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.49.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-38K67XR++CoFFORDd4sMFwUVAnD6msYBdGTei+qvKGrRPO6S2PbrYPNL/eQQ1RgnnxOegNba0YQwg6uRkNcw6A=="],
|
"@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.44.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-eHTBznHLM49++dwz07MblQ2cOXyIgeedmE3Wgy4ptUESj38/qYZyRi1MPwC9olQJWssMeY6WI3UZ7YmU5ggvyQ=="],
|
||||||
|
|
||||||
"@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.49.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-rXVe0HICwQF0dBgbQtBCoYf8x/SidPIdhyQl+iPuJlV7suV+qDv7yUEB3wQ4qC3nOeNxz287SwFXKzyr0kWgEg=="],
|
"@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.44.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jLMmbj0u0Ft43QpkUVr/0v1ZfQCGWAvU+WznEHcN3wZC/q6ox7XeSJtk9P36CCpiDSUf3sGnzbIuG1KdEMEDJQ=="],
|
||||||
|
|
||||||
"@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.49.0", "", { "os": "win32", "cpu": "x64" }, "sha512-gwWLwSEmBBfIK/Wh7GGd658161o4RKAvHWRaRQbJm571iQXGKfyr7UKsI1vsWvDlNLc30CxJDc8mMmCvJ/kczQ=="],
|
"@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.44.0", "", { "os": "linux", "cpu": "arm" }, "sha512-n+A/u/ByK1qV8FVGOwyaSpw5NPNl0qlZfgTBqHeGIqr8Qzq1tyWZ4lAaxPoe5mZqE3w88vn3+jZtMxriHPE7tg=="],
|
||||||
|
|
||||||
"@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.22.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4150Lpgc1YM09GcjA6GSrra1JoPjC7aOpfywLjWEY4vW0Sd1qKzqHF1WRaiw0/qUZ40OATYdv3aRd7ipPkWQbw=="],
|
"@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.44.0", "", { "os": "linux", "cpu": "arm" }, "sha512-5eax+FkxyCqAi3Rw0mrZFr7+KTt/XweFsbALR+B5ljWBLBl8nHe4ADrUnb1gLEfQCJLl+Ca5FIVD4xEt95AwIw=="],
|
||||||
|
|
||||||
"@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.22.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-vFWcPWYOgZs4HWcgS1EjUZg33NLcNfEYU49KGImmCfZWkflENrmBYV4HN/C0YeAPum6ZZ/goPSvQrB/cOD+NfA=="],
|
"@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.44.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-58l8JaHxSGOmOMOG2CIrNsnkRJAj0YcHQCmvNACniOa/vd1iRHhlPajczegzS5jwMENlqgreyiTR9iNlke8qCw=="],
|
||||||
|
|
||||||
"@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.22.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-6LiUpP0Zir3+29FvBm7Y28q/dBjSHqTZ5MhG1Ckw4fGhI4cAvbcwXaKvbjx1TP7rRmBNOoq/M5xdpHjTb+GAew=="],
|
"@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.44.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-AlObQIXyVRZ96LbtVljtFq0JqH5B92NU+BQeDFrXWBUWlCKAM0wF5GLfIhCLT5kQ3Sl+U0YjRJ7Alqj5hGQaCg=="],
|
||||||
|
|
||||||
"@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.22.1", "", { "os": "linux", "cpu": "x64" }, "sha512-fuX1hEQfpHauUbXADsfqVhRzrUrGabzGXbj5wsp2vKhV5uk/Rze8Mba9GdjFGECzvXudMGqHqxB4r6jGRdhxVA=="],
|
"@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.44.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-YcFE8/q/BbrCiIiM5piwbkA6GwJc5QqhMQp2yDrqQ2fuVkZ7CInb1aIijZ/k8EXc72qXMSwKpVlBv1w/MsGO/A=="],
|
||||||
|
|
||||||
"@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.22.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SZidAj+jrbZf9ZjBEYW0tiNZ+KasqB2zgW26qdiPpQSF/DzURnPmXz651IeA9YsmbVdHGIooEHUmev6QJdquA=="],
|
"@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-eOdzs6RqkRzuqNHUX5C8ISN5xfGh4xDww8OEd9YAmc3OWN8oAe5bmlIqQ+rrHLpv58/0BuU48bxkhnIGjA/ATQ=="],
|
||||||
|
|
||||||
"@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.22.1", "", { "os": "win32", "cpu": "x64" }, "sha512-QweSk9H5lFh5Y+WUf2Kq/OAN88V6+62ZwGhP38gqdRotI90luXSMkruFTj7Q2rYrzH4ZVNaSqx7NY8JpSfIzqg=="],
|
"@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.44.0", "", { "os": "linux", "cpu": "none" }, "sha512-YBgNTxntD/QvlFUfgvh8bEdwOhXiquX8gaofZJAwYa/Xp1S1DQrFVZEeck7GFktr24DztsSp8N8WtWCBwxs0Hw=="],
|
||||||
|
|
||||||
"@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.64.0", "", { "os": "android", "cpu": "arm" }, "sha512-2r6Nq3XXGLHEXKkSj8JtmJ6N4gDw431DPFOg0ZoJHlNjnG6HVMm/ksQ10m0HJ8WBvwgMe1L50UHPaYZutCRPCw=="],
|
"@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.44.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-GLIh1R6WHWshl/i4QQDNgj0WtT25aRO4HNUWEoitxiywyRdhTFmFEYT2rXlcl9U6/26vhmOqG5cRlMLG3ocaIA=="],
|
||||||
|
|
||||||
"@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.64.0", "", { "os": "android", "cpu": "arm64" }, "sha512-ePJMpePgg7fBv+L/hVx1xXRU5/5gd5m0obLA6hPEfLXF3GjpR8idIDbY1dhQYhyz1ms2wdTccSboo6KEd2Oxtg=="],
|
"@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.44.0", "", { "os": "linux", "cpu": "x64" }, "sha512-gZOpgTlOsLcLfAF9qgpTr7FIIFSKnQN3hDf/0JvQ4CIwMY7h+eilNjxq/CorqvYcEOu+LRt1W4ZS7KccEHLOdA=="],
|
||||||
|
|
||||||
"@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.64.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-U4DMLQd10gJLuoSTLSGbfv3bGjTlUNsScm9Dgb8wwBqmCzidf1pE1pXV4doGNxqwH3KtVng1AGTINA0NvkGLvQ=="],
|
"@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.44.0", "", { "os": "linux", "cpu": "x64" }, "sha512-1CyS9JTB+pCUFYFI6pkQGGZaT/AY5gnhHVrQQLhFba6idP9AzVYm1xbdWfywoldTYvjxQJV6x4SuduCIfP3W+A=="],
|
||||||
|
|
||||||
"@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.64.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-GoRIL48QWm4/TAvjN8pB1nAG+1/uqc9EdnWT9zqHeb6wsmjZtywj8VRe5aGW47Fdb64YtLOsdLqVxOvQuz98Wg=="],
|
"@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.44.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bmEv70Ak6jLr1xotCbF5TxIKjsmQaiX+jFRtnGtfA03tJPf6VG3cKh96S21boAt3JZc+Vjx8PYcDuLj39vM2Pw=="],
|
||||||
|
|
||||||
"@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.64.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5dFkv4tkg7PxJJGS9/OjrJwjhuHczrd3OQOkRE0wHcLM+ncUnULtzEPWjqGOxTXxZnLWcB91bGiIznx89TVXyQ=="],
|
"@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.44.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-yWzB+oCpSnP/dmw85eFLAT5o35Ve5pkGS2uF/UCISpIwDqf1xa7OpmtomiqY/Vzg8VyvMbuf6vroF2khF/+1Vg=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.64.0", "", { "os": "linux", "cpu": "arm" }, "sha512-jsBqMLl/uOL5+Kq/+BtK9FrmiNGUbx8SiyZXv+WlUxA45KuwcLu9BfiSIL3I3DBDgWM3yZizDITnTK9BcqNBQg=="],
|
"@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.44.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-TcWpo18xEIE3AmIG2kpr3kz5IEhQgnx0lazl2+8L+3eTopOAUevQcmlr4nhguImNWz0OMeOZrYZOhJNCf16nlQ=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.64.0", "", { "os": "linux", "cpu": "arm" }, "sha512-1lrj8At/Uuc9GhjrVFBQo0NEjfBrTkzpmtHIGAhNnIXqn1CAyGL+qrztUsXb2GIluJrpl9Q7qRLJOb/NqydacQ=="],
|
"@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.44.0", "", { "os": "win32", "cpu": "x64" }, "sha512-oj8aLkPJZppIM4CMQNsyir9ybM1Xw/CfGPTSsTnzpVGyljgfbdP0EVUlURiGM0BDrmw5psQ6ArmGCcUY/yABaQ=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.64.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-HpSQbubwh03mMhAdy2BYtad/fsY8vDFHDAb6bUwuCYg2VD3xCQgn6ArKcO0oZyLCheacKTv4PrF3Mfu5hgoE2g=="],
|
"@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.20.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KKQcIHZHMxqpHUA1VXIbOG6chNCFkUWbQy6M+AFVtPKkA/3xAeJkJ3njoV66bfzwPHRcWQO+kcj5XqtbkjakoA=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.64.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-00QQ0h0Y7u0G69BgiH3+ky2aaq/QvkDL6DYok8htIuJHxybiux5aQ8jwmg8qIk9wha6UagUP2BAwAzbemcJbpg=="],
|
"@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.20.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-7HeVMuclGfG+NLZi2ybY0T4fMI7/XxO/208rJk+zEIloKkVnlh11Wd241JMGwgNFXn+MLJbOqOfojDb2Dt4L1g=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.64.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-2GaimTV6EMW+s5HS0An3oGbQme3BgHswvfVdGk3EB57Xe9+/gyT+Qd7lNVzb3rtir52vbIPzXfaYArzs5b5zcw=="],
|
"@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.20.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zxhUwz+WSxE6oWlZLK2z2ps9yC6ebmgoYmjAl0Oa48+GqkZ56NVgo+wb8DURNv6xrggzHStQxqQxe3mK51HZag=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.64.0", "", { "os": "linux", "cpu": "none" }, "sha512-H46AtFb9wypjoVwGdlxrm0DsD809NGmtiK9HiyPKTxkSte2YjhC4S+00rOIrwCaxcyPiGid3Y3OMXp5KMAkGZw=="],
|
"@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.20.0", "", { "os": "linux", "cpu": "x64" }, "sha512-/1l6FnahC9im8PK+Ekkx/V3yetO/PzZnJegE2FXcv/iXEhbeVxP/ouiTYcUQu9shT1FWJCSNti1VJHH+21Y1dg=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.64.0", "", { "os": "linux", "cpu": "none" }, "sha512-HEgsidjjvvyzdg82icYkuFCf7REDV7B9JFwbIMbVwrKLBY0MrXX+bku3POn/hduZ2yW91IyVDUMq0Bf02KwXQw=="],
|
"@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.20.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-oPZ5Yz8sVdo7P/5q+i3IKeix31eFZ55JAPa1+RGPoe9PoaYVsdMvR6Jvib6YtrqoJnFPlg3fjEjlEPL8VBKYJA=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.64.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Axvm8qryotmKN00P5w4JapaSjvP2LOSbdbBJiX+2SuHd3QzhW7TUc8skqgw+ahQZ5DmzEYeHCqauvW8f32Ns6Q=="],
|
"@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.20.0", "", { "os": "win32", "cpu": "x64" }, "sha512-4stx8RHj3SP9vQyRF/yZbz5igtPvYMEUR8CUoha4BVNZihi39DpCR8qkU7lpjB5Ga1DRMo2pHaA4bdTOMaY4mw=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.64.0", "", { "os": "linux", "cpu": "x64" }, "sha512-cR60vSd7+m+KRZ3GQGfDxWwahW5RMXg0qlGvAluZr0fTUYvw0H9N9AXAF/M/PMqgytyqvVNmBAkJG9l7U30Y1g=="],
|
"@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-etYDw/UaEv936AQUd/CRMBVd+e+XuuU6wC+VzOv1STvsTyZenLChepLWqLtnyTTp4YMlM22ypzogDDwqYxv5cg=="],
|
||||||
|
|
||||||
"@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.64.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2u/aPZ9pEg7HnvZPDsHxUGNnrpr4qaHi+mCgLgpt+LYRzPrS4Px4wPfkIdRdr2GvKnaYyt+XSlto0Vm5sbStTg=="],
|
"@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-TgLc7XVLKH2a4h8j3vn1MDjfK33i9MY60f/bKhRGWyVzbk5LCZ4X01VZG7iHrMmi5vYbAp8//Ponigx03CLsdw=="],
|
||||||
|
|
||||||
"@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.64.0", "", { "os": "none", "cpu": "arm64" }, "sha512-kfhkGfCdoXLSxEkrhDlJrvBYajGmq+ma4EMc53dsOWTq+rIBOlI0vTBmpZNnM5oH2LY/K/w1HAK+UQEgjgpVUg=="],
|
"@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DXyFPf5ZKldMLloRHx/B9fsxsiTQomaw7cmEW3YIJko2HgCh+GUhp9gGYwHrqlLJPsEe3dYj9JebjX92D3j3AA=="],
|
||||||
|
|
||||||
"@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.64.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-r/cNKBFieONoVu2bb1KkVouq9W+edDUgHumXJGphCRRj+U0xaD4nanrw8ZOqo0IsutPkEM4vCcGBpak6x5aXMg=="],
|
"@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-LgvrsdgVLX1qWqIEmNsSmMXJhpAWdtUQ0M+oR0CySwi+9IHWyOGuIL8w8+u/kbZNMyZr4WUyYB5i0+D+AKgkLg=="],
|
||||||
|
|
||||||
"@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.64.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-tUw0xUUwEFVZbpJoeCblkv8SJA4Xz3CdXCJbAnBsiNLyxDrk2tLcxEAS6M73Q7hHHDg3OtwI8vZVK3t5RJt4Gw=="],
|
"@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-bOJhqX/ny4hrFuTPlyk8foSRx/vLRpxJh0jOOKN2NWW6FScXHPAA5rQbrwdQPcgGB5V8Ua51RS03fke8ssBcug=="],
|
||||||
|
|
||||||
"@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.64.0", "", { "os": "win32", "cpu": "x64" }, "sha512-9CBR+LO0JVST87fNTzzNxS5I29jIUO5gxT9i9+M3SDHHALElj9sY1Prf12tad3vIRC6OD7Ehtvvh+sn13vSwHw=="],
|
"@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-vVUXxYMF9trXCsz4m9H6U0IjehosVHxBzVgJUxly1uz4W1PdDyicaBnpC0KRXsHYretLVe+uS9pJy8iM57Kujw=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-TULQW8YBPGRWg5yZpFPL54HLOnJ3/HiX6VenDPi6YfxB/jlItwSMFh3/hCeSNbh+DAMaE1Py0j5MOaivHkI/9Q=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Gt54Y4eqSgYJ90xipm24xeyaPV854706o/kiT8oZvUt3VDY7qqxdqyGqchMaujd87ib+/MXvnl9WkK8Cc1BExg=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-3CtsKp7NFB3OfqQzbuAecrY7GIZeiv7AD+xutU4tefVQzlfmTI7/ygWLrvkzsDEjTlMq41rYHxgsn6Yh8tybmA=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-K0diOpT3ncDmOfl9I1HuvpEsAuTxkts0VYwIv/w6Xiy9CdwyPBVX88Ga9l8VlGgMrwBMnSY4xIvVlVY/fkQk7Q=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-xAU7+QDU6kTJJ7mJLOGgo7oOjtAtkKyFZ0Yjdb5cEo3DiCCPFLvyr08rWiQh6evZ7RiUTf+o65NY/bqttzJiQQ=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-KUmZmKlTTyauOnvUNVxK7G40sSSx0+w5l1UhaGsC6KPpOYHenx2oqJTnabmpLJicok7IC+3Y6fXAUOMyexaeJQ=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-4usRxC8gS0PGdkHnRmwJt/4zrQNZyk6vL0trCxwZSsAKM+OxhB8nKiR+mhjdBbl8lbMh2gc3bZpNN/ik8c4c2A=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-s/rNE2gDmbwAOOP493xk2X7M8LZfI1LJFSSW1+yanz3vuQCFPiHkx4GY+O1HuLUDtkzGlhtMrIcxxzyYLv308w=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-+yYj1udJa2UvvIUmEm0IcKgc0UlPMgz0nsSTvkPL2y6n0uU5LgIHSwVu4AHhrve6j9BpVSoRksnz8c9QcvITJA=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bUplUb48LYsB3hHlQXP2ZMOenpieWoOyppLAnnAhuPag3MGPnt+7caxE3w/Vl9wpQsTA3gzLntQi9rxWrs7Xqg=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-/HLsLuz42rWl7h7ePdmMTpHm2HIDmPtcEMYgm5BBEHiEiuNOrzMaUpd2z7UnNni5LGN9obJy2YoAYBLXQwazrA=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-rUPy+JnanpPwV/aJCPnxAD1fW50+XPI0VkWr7f0vEbqcdsS8NpB24Rw6RsS7SdpFv8Dw+8ugCwao5nCFbqOUSg=="],
|
||||||
|
|
||||||
|
"@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-xkE7puteDS/vUyRngLXW0t8WgdWoS/tfxXjhP/P7SMqPDx+hs44SpssO3h3qmTqECYEuXBUPzcAw5257Ka+ofA=="],
|
||||||
|
|
||||||
|
"@protobuf-ts/runtime": ["@protobuf-ts/runtime@2.11.1", "", {}, "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ=="],
|
||||||
|
|
||||||
|
"@protobuf-ts/runtime-rpc": ["@protobuf-ts/runtime-rpc@2.11.1", "", { "dependencies": { "@protobuf-ts/runtime": "^2.11.1" } }, "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ=="],
|
||||||
|
|
||||||
"@tsconfig/bun": ["@tsconfig/bun@1.0.10", "", {}, "sha512-5AV5YknQjNyoYzZ/8NG0dawqew/wH+x7ANiCfCIn29qo0cdbd1EryvFD1k5NSZWLBMOI/fGqMIaxi58GPIP9Cg=="],
|
"@tsconfig/bun": ["@tsconfig/bun@1.0.10", "", {}, "sha512-5AV5YknQjNyoYzZ/8NG0dawqew/wH+x7ANiCfCIn29qo0cdbd1EryvFD1k5NSZWLBMOI/fGqMIaxi58GPIP9Cg=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
"@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
|
"@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="],
|
||||||
|
|
||||||
"@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260410.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260410.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260410.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260410.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260410.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260410.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260410.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260410.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-K3TIwBw4XGQM33wW8KUqRU7r6ZY1IqB8chk1u1kT+CDj4iu+eQ6jCXgU7EDxmpJ++gbNcIf8iBYgWgYNssrhZQ=="],
|
"@types/node": ["@types/node@24.12.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g=="],
|
||||||
|
|
||||||
"@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260410.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bpLYm6woXd8BECzV9AQvPqISVeohpekK1qwpRopvNIxydhRQ4fEjZsS7EtDYpqHAW4/u1uEv07P9/iS6TAL1fQ=="],
|
"@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="],
|
||||||
|
|
||||||
"@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260410.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-V8bW8g5hgu+bAwGvTqF1kilkkoDgxhxi5egrdMUeWQkR+MIisoBQeaAupqMpLoSkqZsc/kKucM0zwBNC/KRU3Q=="],
|
"@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260409.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260409.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260409.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260409.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-CV1HEMGo1xCySwUJbCQOF+mmrTue8KTJ1Od2kKWhcbOpu8fPBfaqIpbAM6tGLcNEykEjMMTYHc/VTLbMgxdScQ=="],
|
||||||
|
|
||||||
"@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260410.1", "", { "os": "linux", "cpu": "arm" }, "sha512-NO6Ci65ADadOCr2ycTxOyCgC5kyk+Ryjl8k5c78mz9sKDxYqwEtryFFjLqitAG+rejtJbnUq897WRICjAOwslA=="],
|
"@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260409.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GcRRnaoeZVrbC47woQ/2t3vPoQcTSjsWPEAQGtwNSdw7Z9TKxG4ES22ghJIQXd3ncTRCMJ+XELnnuqxVutkJ9w=="],
|
||||||
|
|
||||||
"@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260410.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MOluRRAhv46s9ScFmePa0InMHmpZ/z0Evc11RrTKsg+bN8BR7sWoAtFq6IujEDK9WVP7YmEYtBRgEfMLuqVojw=="],
|
"@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260409.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-7s8DXAa0Xpu/8PEjYIc4I36Ju7eVpoz9k3E+3WQdOF8pIPWYohiOj+zi68m9XYQck+rnkjUFo26ThVKqVetoMA=="],
|
||||||
|
|
||||||
"@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260410.1", "", { "os": "linux", "cpu": "x64" }, "sha512-IofIUrMGjXmZKDEMaRgshzOne0EQZtx9vE/6URHfgmDnWLDKWzz9eQ2qWmvsFD2vOBbgc6GwVWEq6XTHMEfx2A=="],
|
"@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "arm" }, "sha512-fOa07JBUXQpEPq+024g346inYZ2xp63ELuoRq6J0jwDWQ/ftCCuvdQNMncwFhsm1qlMdKT3S68NrnSxX16hiaw=="],
|
||||||
|
|
||||||
"@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260410.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-TXmE+wovQqRo+qAhaewB0MPB9esgayvSHr6vFlCpHykHqbDl3FUucuC4F8yU6zVOA3UqXTk4/GHeLsAvU7YEgQ=="],
|
"@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cGTzTUqRGlIDwdtkDy6qTrvrqpe27W4CdgnFn0FpxpiWnaIi3wqjlzQ1grtqrqainw/yuPy5hn/I86sQgN6nvA=="],
|
||||||
|
|
||||||
"@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260410.1", "", { "os": "win32", "cpu": "x64" }, "sha512-dMFT4tdHBe2vVA2WPQMjorT+fzCURRtillevQzz8/bwCEz2uXSnpu4oLRLS5045ppGE0wCFELE+Hq5z2oRddDw=="],
|
"@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260409.1", "", { "os": "linux", "cpu": "x64" }, "sha512-lQrbc/BJKBxQrR1ttBDU5sYY1Hb2moFQgHL20T6nbapNqGpK4pzy64p+NK39O93D4omiCSk04pkchBCVrMPSAg=="],
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
|
"@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260409.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-kmCafMo1xZlYx+9WnfpeZJ2tnB/CcJdR8QPX7j9vqcpe51D7b7Intmr921dD48KGpVh5YgjQ1MEFE5mjGqGMaA=="],
|
||||||
|
|
||||||
"oxfmt": ["oxfmt@0.49.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.49.0", "@oxfmt/binding-android-arm64": "0.49.0", "@oxfmt/binding-darwin-arm64": "0.49.0", "@oxfmt/binding-darwin-x64": "0.49.0", "@oxfmt/binding-freebsd-x64": "0.49.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.49.0", "@oxfmt/binding-linux-arm-musleabihf": "0.49.0", "@oxfmt/binding-linux-arm64-gnu": "0.49.0", "@oxfmt/binding-linux-arm64-musl": "0.49.0", "@oxfmt/binding-linux-ppc64-gnu": "0.49.0", "@oxfmt/binding-linux-riscv64-gnu": "0.49.0", "@oxfmt/binding-linux-riscv64-musl": "0.49.0", "@oxfmt/binding-linux-s390x-gnu": "0.49.0", "@oxfmt/binding-linux-x64-gnu": "0.49.0", "@oxfmt/binding-linux-x64-musl": "0.49.0", "@oxfmt/binding-openharmony-arm64": "0.49.0", "@oxfmt/binding-win32-arm64-msvc": "0.49.0", "@oxfmt/binding-win32-ia32-msvc": "0.49.0", "@oxfmt/binding-win32-x64-msvc": "0.49.0" }, "peerDependencies": { "svelte": "^5.0.0" }, "optionalPeers": ["svelte"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-IAHFMdlJSWe+oAr65dx22UvjCtV9DBMisAuLnKpDqMQrctzCkGnj3QRwNHm0d+uwSWPalsDF8ZYLz9rh6nH2IQ=="],
|
"@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260409.1", "", { "os": "win32", "cpu": "x64" }, "sha512-WRd+JpQipTsE15QgYr3w7J0f1NKvGcq2QEgmcq8hB0WZA1X2WhQopNu+MpPQ3tdDD42VjMhm8ZoB8HpuOoXK5w=="],
|
||||||
|
|
||||||
"oxlint": ["oxlint@1.64.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.64.0", "@oxlint/binding-android-arm64": "1.64.0", "@oxlint/binding-darwin-arm64": "1.64.0", "@oxlint/binding-darwin-x64": "1.64.0", "@oxlint/binding-freebsd-x64": "1.64.0", "@oxlint/binding-linux-arm-gnueabihf": "1.64.0", "@oxlint/binding-linux-arm-musleabihf": "1.64.0", "@oxlint/binding-linux-arm64-gnu": "1.64.0", "@oxlint/binding-linux-arm64-musl": "1.64.0", "@oxlint/binding-linux-ppc64-gnu": "1.64.0", "@oxlint/binding-linux-riscv64-gnu": "1.64.0", "@oxlint/binding-linux-riscv64-musl": "1.64.0", "@oxlint/binding-linux-s390x-gnu": "1.64.0", "@oxlint/binding-linux-x64-gnu": "1.64.0", "@oxlint/binding-linux-x64-musl": "1.64.0", "@oxlint/binding-openharmony-arm64": "1.64.0", "@oxlint/binding-win32-arm64-msvc": "1.64.0", "@oxlint/binding-win32-ia32-msvc": "1.64.0", "@oxlint/binding-win32-x64-msvc": "1.64.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-Star3SNpWPeWFPw7kRXIhXUSn6fdiAl25q15CQzH/9WaOtG6e9CWTc25vNZOCr4PE1yEP1GtKJKIKglhj3OmEQ=="],
|
"@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.3.5", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-yURCknZhvywvQItHMMmFSo+fq5arCUIyz/CVk7jD89MSai7dkaX8ufjCWp3NttLojoTVbcE72ri+be/TnEbMHw=="],
|
||||||
|
|
||||||
"oxlint-tsgolint": ["oxlint-tsgolint@0.22.1", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.22.1", "@oxlint-tsgolint/darwin-x64": "0.22.1", "@oxlint-tsgolint/linux-arm64": "0.22.1", "@oxlint-tsgolint/linux-x64": "0.22.1", "@oxlint-tsgolint/win32-arm64": "0.22.1", "@oxlint-tsgolint/win32-x64": "0.22.1" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-YUSGSLUnoolsu8gxISEDio3q1rtsCozwfOzASUn3DT2mR2EeQ93uEEnen7s+6LpF+lyTQFln1pQfqwBh/fsVEg=="],
|
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
||||||
|
|
||||||
|
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||||
|
|
||||||
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="],
|
||||||
|
|
||||||
|
"bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
|
||||||
|
|
||||||
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
|
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||||
|
|
||||||
|
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
|
||||||
|
|
||||||
|
"fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="],
|
||||||
|
|
||||||
|
"fast-xml-parser": ["fast-xml-parser@5.5.11", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.4.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QL0eb0YbSTVWF6tTf1+LEMSgtCEjBYPpnAjoLC8SscESlAjXEIRJ7cHtLG0pLeDFaZLa4VKZLArtA/60ZS7vyA=="],
|
||||||
|
|
||||||
|
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
|
||||||
|
|
||||||
|
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||||
|
|
||||||
|
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
|
||||||
|
|
||||||
|
"minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
|
"oxfmt": ["oxfmt@0.44.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.44.0", "@oxfmt/binding-android-arm64": "0.44.0", "@oxfmt/binding-darwin-arm64": "0.44.0", "@oxfmt/binding-darwin-x64": "0.44.0", "@oxfmt/binding-freebsd-x64": "0.44.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.44.0", "@oxfmt/binding-linux-arm-musleabihf": "0.44.0", "@oxfmt/binding-linux-arm64-gnu": "0.44.0", "@oxfmt/binding-linux-arm64-musl": "0.44.0", "@oxfmt/binding-linux-ppc64-gnu": "0.44.0", "@oxfmt/binding-linux-riscv64-gnu": "0.44.0", "@oxfmt/binding-linux-riscv64-musl": "0.44.0", "@oxfmt/binding-linux-s390x-gnu": "0.44.0", "@oxfmt/binding-linux-x64-gnu": "0.44.0", "@oxfmt/binding-linux-x64-musl": "0.44.0", "@oxfmt/binding-openharmony-arm64": "0.44.0", "@oxfmt/binding-win32-arm64-msvc": "0.44.0", "@oxfmt/binding-win32-ia32-msvc": "0.44.0", "@oxfmt/binding-win32-x64-msvc": "0.44.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-lnncqvHewyRvaqdrnntVIrZV2tEddz8lbvPsQzG/zlkfvgZkwy0HP1p/2u1aCDToeg1jb9zBpbJdfkV73Itw+w=="],
|
||||||
|
|
||||||
|
"oxlint": ["oxlint@1.59.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.59.0", "@oxlint/binding-android-arm64": "1.59.0", "@oxlint/binding-darwin-arm64": "1.59.0", "@oxlint/binding-darwin-x64": "1.59.0", "@oxlint/binding-freebsd-x64": "1.59.0", "@oxlint/binding-linux-arm-gnueabihf": "1.59.0", "@oxlint/binding-linux-arm-musleabihf": "1.59.0", "@oxlint/binding-linux-arm64-gnu": "1.59.0", "@oxlint/binding-linux-arm64-musl": "1.59.0", "@oxlint/binding-linux-ppc64-gnu": "1.59.0", "@oxlint/binding-linux-riscv64-gnu": "1.59.0", "@oxlint/binding-linux-riscv64-musl": "1.59.0", "@oxlint/binding-linux-s390x-gnu": "1.59.0", "@oxlint/binding-linux-x64-gnu": "1.59.0", "@oxlint/binding-linux-x64-musl": "1.59.0", "@oxlint/binding-openharmony-arm64": "1.59.0", "@oxlint/binding-win32-arm64-msvc": "1.59.0", "@oxlint/binding-win32-ia32-msvc": "1.59.0", "@oxlint/binding-win32-x64-msvc": "1.59.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-0xBLeGGjP4vD9pygRo8iuOkOzEU1MqOnfiOl7KYezL/QvWL8NUg6n03zXc7ZVqltiOpUxBk2zgHI3PnRIEdAvw=="],
|
||||||
|
|
||||||
|
"oxlint-tsgolint": ["oxlint-tsgolint@0.20.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.20.0", "@oxlint-tsgolint/darwin-x64": "0.20.0", "@oxlint-tsgolint/linux-arm64": "0.20.0", "@oxlint-tsgolint/linux-x64": "0.20.0", "@oxlint-tsgolint/win32-arm64": "0.20.0", "@oxlint-tsgolint/win32-x64": "0.20.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-/Uc9TQyN1l8w9QNvXtVHYtz+SzDJHKpb5X0UnHodl0BVzijUPk0LPlDOHAvogd1UI+iy9ZSF6gQxEqfzUxCULQ=="],
|
||||||
|
|
||||||
|
"path-expression-matcher": ["path-expression-matcher@1.5.0", "", {}, "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ=="],
|
||||||
|
|
||||||
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
|
"strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="],
|
||||||
|
|
||||||
"tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="],
|
"tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="],
|
||||||
|
|
||||||
|
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
|
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
|
||||||
|
|
||||||
"undici": ["undici@6.24.1", "", {}, "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA=="],
|
"undici": ["undici@6.24.1", "", {}, "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA=="],
|
||||||
|
|
||||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||||
|
|
||||||
"@actions/tool-cache/@actions/core": ["@actions/core@3.0.0", "", { "dependencies": { "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0" } }, "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg=="],
|
"bun-types/@types/node": ["@types/node@20.19.37", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw=="],
|
||||||
|
|
||||||
|
"bun-types/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
94560
dist/main.js
vendored
Normal file
94560
dist/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
73430
dist/post.js
vendored
Normal file
73430
dist/post.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -37,6 +37,21 @@ To pin a specific CLI version:
|
|||||||
version: 2.84.2
|
version: 2.84.2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To cache the Docker images pulled by `supabase start`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: supabase/setup-cli@v2
|
||||||
|
with:
|
||||||
|
version: 2.84.2
|
||||||
|
cache: true
|
||||||
|
- run: supabase start
|
||||||
|
```
|
||||||
|
|
||||||
|
The first run pulls the images from the registry. Later runs can restore the
|
||||||
|
same image archive from the GitHub Actions cache before `supabase start` runs.
|
||||||
|
Use `cache-key` when your workflow flags or generated config change the image
|
||||||
|
set.
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
- **Source Code**: <https://github.com/supabase/setup-cli>
|
- **Source Code**: <https://github.com/supabase/setup-cli>
|
||||||
|
|||||||
29
package.json
29
package.json
@@ -14,26 +14,33 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"all": "bun run format && bun run lint && bun run coverage",
|
"all": "bun run format && bun run lint && bun run coverage && bun run build",
|
||||||
"ci": "bun run format:check && bun run lint && bun run coverage",
|
"build": "bun build src/main.ts src/post.ts --target=node --format=esm --outdir=dist",
|
||||||
|
"ci": "bun run format:check && bun run lint && bun run coverage && bun run build",
|
||||||
"coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov",
|
"coverage": "bun test --coverage --coverage-reporter=text --coverage-reporter=lcov",
|
||||||
"format": "bun x oxfmt --write . '!coverage/**'",
|
"format": "bun x oxfmt --write . '!coverage/**' '!dist/**'",
|
||||||
"format:check": "bun x oxfmt --check . '!coverage/**'",
|
"format:check": "bun x oxfmt --check . '!coverage/**' '!dist/**'",
|
||||||
"lint": "bun x oxlint --deny-warnings --type-aware --type-check --tsconfig tsconfig.json src",
|
"lint": "bun x oxlint --deny-warnings --type-aware --type-check --tsconfig tsconfig.json src",
|
||||||
"test": "bun test",
|
"test": "bun test",
|
||||||
"typecheck": "bun x tsgo -p tsconfig.json --noEmit"
|
"typecheck": "bun x tsgo -p tsconfig.json --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^3.0.1",
|
"@actions/cache": "^6.0.0",
|
||||||
"@actions/tool-cache": "^4.0.0"
|
"@actions/core": "^3.0.0",
|
||||||
|
"@actions/tool-cache": "^4.0.0",
|
||||||
|
"js-yaml": "^4.1.1",
|
||||||
|
"semver": "^7.7.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/bun": "^1.0.10",
|
"@tsconfig/bun": "^1.0.10",
|
||||||
"@types/bun": "^1.3.14",
|
"@types/bun": "^1.3.11",
|
||||||
"@typescript/native-preview": "^7.0.0-dev.20260410.1",
|
"@types/js-yaml": "^4.0.9",
|
||||||
"oxfmt": "^0.49.0",
|
"@types/node": "^24",
|
||||||
"oxlint": "^1.64.0",
|
"@types/semver": "^7.7.1",
|
||||||
"oxlint-tsgolint": "^0.22.1"
|
"@typescript/native-preview": "^7.0.0-dev.20260409.1",
|
||||||
|
"oxfmt": "^0.44.0",
|
||||||
|
"oxlint": "^1.59.0",
|
||||||
|
"oxlint-tsgolint": "^0.20.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"bun": ">=1.3.10"
|
"bun": ">=1.3.10"
|
||||||
|
|||||||
168
src/cache.test.ts
Normal file
168
src/cache.test.ts
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||||
|
import os from "node:os";
|
||||||
|
import path from "node:path";
|
||||||
|
import { afterEach, expect, mock, spyOn, test } from "bun:test";
|
||||||
|
import * as cacheAction from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
import {
|
||||||
|
collectDockerImageRefs,
|
||||||
|
createDockerImageCacheKey,
|
||||||
|
restoreDockerImageCache,
|
||||||
|
saveDockerImageCache,
|
||||||
|
} from "./cache";
|
||||||
|
|
||||||
|
const originalRunnerTemp = process.env.RUNNER_TEMP;
|
||||||
|
const originalWorkspace = process.env.GITHUB_WORKSPACE;
|
||||||
|
const tempDirs = new Set<string>();
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
mock.restore();
|
||||||
|
process.env.RUNNER_TEMP = originalRunnerTemp;
|
||||||
|
process.env.GITHUB_WORKSPACE = originalWorkspace;
|
||||||
|
|
||||||
|
for (const dir of tempDirs) {
|
||||||
|
rmSync(dir, { force: true, recursive: true });
|
||||||
|
}
|
||||||
|
tempDirs.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
function createTempDir(prefix: string): string {
|
||||||
|
const dir = mkdtempSync(path.join(os.tmpdir(), prefix));
|
||||||
|
tempDirs.add(dir);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
test("creates a docker image cache key from runner, version, registry, and config", () => {
|
||||||
|
const workspace = createTempDir("setup-cli-workspace-");
|
||||||
|
mkdirSync(path.join(workspace, "supabase"), { recursive: true });
|
||||||
|
writeFileSync(path.join(workspace, "supabase", "config.toml"), 'project_id = "test"\n');
|
||||||
|
process.env.GITHUB_WORKSPACE = workspace;
|
||||||
|
|
||||||
|
const key = createDockerImageCacheKey("supabase 2.84.2", "ghcr.io");
|
||||||
|
|
||||||
|
expect(key).toStartWith(`supabase-cli-containers-v1-${process.platform}-${process.arch}-`);
|
||||||
|
expect(key).toContain("supabase-2.84.2-ghcr.io-");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("collects images from labeled containers and Supabase image repositories", async () => {
|
||||||
|
const run = mock(async (_file: string, args: string[]) => {
|
||||||
|
if (args[0] === "ps") {
|
||||||
|
return {
|
||||||
|
stdout: "ghcr.io/supabase/postgres:15.8.1\ncustom/image:latest\n",
|
||||||
|
stderr: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
stdout:
|
||||||
|
"ghcr.io/supabase/studio:2026.04.08\npublic.ecr.aws/supabase/kong:2.8.1\nlibrary/postgres:16\n<none>:<none>\n",
|
||||||
|
stderr: "",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await collectDockerImageRefs(run)).toEqual([
|
||||||
|
"custom/image:latest",
|
||||||
|
"ghcr.io/supabase/postgres:15.8.1",
|
||||||
|
"ghcr.io/supabase/studio:2026.04.08",
|
||||||
|
"public.ecr.aws/supabase/kong:2.8.1",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore skips docker and cache calls when cache input is disabled", async () => {
|
||||||
|
const run = mock(async () => ({ stdout: "", stderr: "" }));
|
||||||
|
const restoreCache = spyOn(cacheAction, "restoreCache").mockImplementation(async () => undefined);
|
||||||
|
const spies = {
|
||||||
|
getBooleanInput: spyOn(core, "getBooleanInput").mockImplementation(() => false),
|
||||||
|
getInput: spyOn(core, "getInput").mockImplementation(() => ""),
|
||||||
|
setOutput: spyOn(core, "setOutput").mockImplementation(() => {}),
|
||||||
|
saveState: spyOn(core, "saveState").mockImplementation(() => {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
await restoreDockerImageCache("supabase 2.84.2", "ghcr.io", run);
|
||||||
|
|
||||||
|
expect(spies.setOutput).toHaveBeenCalledWith("cache-hit", "false");
|
||||||
|
expect(spies.saveState).toHaveBeenCalledWith("cache-enabled", "false");
|
||||||
|
expect(run).not.toHaveBeenCalled();
|
||||||
|
expect(restoreCache).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("restore loads a docker archive on exact cache hit", async () => {
|
||||||
|
const temp = createTempDir("setup-cli-runner-");
|
||||||
|
process.env.RUNNER_TEMP = temp;
|
||||||
|
const calls: string[][] = [];
|
||||||
|
const run = mock(async (_file: string, args: string[]) => {
|
||||||
|
calls.push(args);
|
||||||
|
return { stdout: "ok\n", stderr: "" };
|
||||||
|
});
|
||||||
|
const restoreCache = spyOn(cacheAction, "restoreCache").mockImplementation(
|
||||||
|
async (paths: string[], key: string) => {
|
||||||
|
writeFileSync(paths[0]!, "archive");
|
||||||
|
return key;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const spies = {
|
||||||
|
getBooleanInput: spyOn(core, "getBooleanInput").mockImplementation(() => true),
|
||||||
|
getInput: spyOn(core, "getInput").mockImplementation((name: string) =>
|
||||||
|
name === "cache-key" ? "cache-key" : "",
|
||||||
|
),
|
||||||
|
setOutput: spyOn(core, "setOutput").mockImplementation(() => {}),
|
||||||
|
saveState: spyOn(core, "saveState").mockImplementation(() => {}),
|
||||||
|
info: spyOn(core, "info").mockImplementation(() => {}),
|
||||||
|
warning: spyOn(core, "warning").mockImplementation(() => {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
await restoreDockerImageCache("supabase 2.84.2", "ghcr.io", run);
|
||||||
|
|
||||||
|
expect(restoreCache).toHaveBeenCalledWith(
|
||||||
|
[path.join(temp, "setup-supabase-cli", "supabase-cli-docker-images.tar")],
|
||||||
|
"cache-key",
|
||||||
|
);
|
||||||
|
expect(spies.setOutput).toHaveBeenCalledWith("cache-hit", "true");
|
||||||
|
expect(spies.saveState).toHaveBeenCalledWith("cache-hit", "true");
|
||||||
|
expect(calls).toContainEqual([
|
||||||
|
"load",
|
||||||
|
"-i",
|
||||||
|
path.join(temp, "setup-supabase-cli", "supabase-cli-docker-images.tar"),
|
||||||
|
]);
|
||||||
|
expect(spies.warning).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("post saves collected Supabase docker images", async () => {
|
||||||
|
const temp = createTempDir("setup-cli-runner-");
|
||||||
|
process.env.RUNNER_TEMP = temp;
|
||||||
|
const calls: string[][] = [];
|
||||||
|
const run = mock(async (_file: string, args: string[]) => {
|
||||||
|
calls.push(args);
|
||||||
|
if (args[0] === "ps") {
|
||||||
|
return { stdout: "ghcr.io/supabase/postgres:15.8.1\n", stderr: "" };
|
||||||
|
}
|
||||||
|
if (args[0] === "image") {
|
||||||
|
return { stdout: "ghcr.io/supabase/studio:2026.04.08\n", stderr: "" };
|
||||||
|
}
|
||||||
|
return { stdout: "ok\n", stderr: "" };
|
||||||
|
});
|
||||||
|
const saveCache = spyOn(cacheAction, "saveCache").mockImplementation(async () => 1);
|
||||||
|
const state = new Map([
|
||||||
|
["cache-enabled", "true"],
|
||||||
|
["cache-hit", "false"],
|
||||||
|
["cache-primary-key", "cache-key"],
|
||||||
|
["cache-archive-path", path.join(temp, "setup-supabase-cli", "supabase-cli-docker-images.tar")],
|
||||||
|
]);
|
||||||
|
spyOn(core, "getState").mockImplementation((name: string) => state.get(name) ?? "");
|
||||||
|
spyOn(core, "info").mockImplementation(() => {});
|
||||||
|
spyOn(core, "warning").mockImplementation(() => {});
|
||||||
|
|
||||||
|
await saveDockerImageCache(run);
|
||||||
|
|
||||||
|
expect(calls).toContainEqual([
|
||||||
|
"save",
|
||||||
|
"-o",
|
||||||
|
path.join(temp, "setup-supabase-cli", "supabase-cli-docker-images.tar"),
|
||||||
|
"ghcr.io/supabase/postgres:15.8.1",
|
||||||
|
"ghcr.io/supabase/studio:2026.04.08",
|
||||||
|
]);
|
||||||
|
expect(saveCache).toHaveBeenCalledWith(
|
||||||
|
[path.join(temp, "setup-supabase-cli", "supabase-cli-docker-images.tar")],
|
||||||
|
"cache-key",
|
||||||
|
);
|
||||||
|
});
|
||||||
254
src/cache.ts
Normal file
254
src/cache.ts
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
import * as cache from "@actions/cache";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
import { execFile as execFileCallback } from "node:child_process";
|
||||||
|
import { createHash } from "node:crypto";
|
||||||
|
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
||||||
|
import os from "node:os";
|
||||||
|
import path from "node:path";
|
||||||
|
import { promisify } from "node:util";
|
||||||
|
|
||||||
|
const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY";
|
||||||
|
const CACHE_ARCHIVE = "supabase-cli-docker-images.tar";
|
||||||
|
const CACHE_DIR = "setup-supabase-cli";
|
||||||
|
const CACHE_KEY_VERSION = "v1";
|
||||||
|
const DEFAULT_REGISTRY = "public.ecr.aws";
|
||||||
|
const GHCR_REGISTRY = "ghcr.io";
|
||||||
|
const CACHE_INPUT = "cache";
|
||||||
|
const CACHE_KEY_INPUT = "cache-key";
|
||||||
|
const CACHE_HIT_OUTPUT = "cache-hit";
|
||||||
|
const STATE_ENABLED = "cache-enabled";
|
||||||
|
const STATE_PRIMARY_KEY = "cache-primary-key";
|
||||||
|
const STATE_ARCHIVE_PATH = "cache-archive-path";
|
||||||
|
const STATE_CACHE_HIT = "cache-hit";
|
||||||
|
const CLI_PROJECT_LABEL = "com.supabase.cli.project";
|
||||||
|
const SUPABASE_IMAGE_PREFIXES = ["ghcr.io/supabase/", "public.ecr.aws/supabase/", "supabase/"];
|
||||||
|
|
||||||
|
type ExecFile = (
|
||||||
|
file: string,
|
||||||
|
args: string[],
|
||||||
|
options?: { maxBuffer?: number },
|
||||||
|
) => Promise<{ stdout: string; stderr: string }>;
|
||||||
|
|
||||||
|
const execFile = promisify(execFileCallback) as ExecFile;
|
||||||
|
|
||||||
|
function sanitizeCacheKeyPart(value: string): string {
|
||||||
|
return value.replace(/[^A-Za-z0-9_.-]/g, "-").replace(/-+/g, "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
function hashFile(filePath: string): string | null {
|
||||||
|
if (!existsSync(filePath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return createHash("sha256").update(readFileSync(filePath)).digest("hex");
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConfigHash(): string {
|
||||||
|
const workspaceRoot = process.env.GITHUB_WORKSPACE?.trim();
|
||||||
|
if (!workspaceRoot) {
|
||||||
|
return "no-config";
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashFile(path.join(workspaceRoot, "supabase", "config.toml")) ?? "no-config";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCacheArchivePath(): string {
|
||||||
|
const runnerTemp = process.env.RUNNER_TEMP?.trim() || os.tmpdir();
|
||||||
|
return path.join(runnerTemp, CACHE_DIR, CACHE_ARCHIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getImageRegistry(): string {
|
||||||
|
return process.env[CLI_CONFIG_REGISTRY]?.trim() || DEFAULT_REGISTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGhcrImageRegistry(): string {
|
||||||
|
return GHCR_REGISTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDockerImageCacheKey(installedVersion: string, registry: string): string {
|
||||||
|
return [
|
||||||
|
"supabase-cli-containers",
|
||||||
|
CACHE_KEY_VERSION,
|
||||||
|
sanitizeCacheKeyPart(process.platform),
|
||||||
|
sanitizeCacheKeyPart(process.arch),
|
||||||
|
sanitizeCacheKeyPart(installedVersion),
|
||||||
|
sanitizeCacheKeyPart(registry),
|
||||||
|
getConfigHash(),
|
||||||
|
].join("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPrimaryCacheKey(installedVersion: string, registry: string): string {
|
||||||
|
const cacheKeyInput = core.getInput(CACHE_KEY_INPUT).trim();
|
||||||
|
if (cacheKeyInput) {
|
||||||
|
return cacheKeyInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createDockerImageCacheKey(installedVersion, registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function isDockerAvailable(run: ExecFile = execFile): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await run("docker", ["version"]);
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runDocker(args: string[], run: ExecFile = execFile): Promise<string> {
|
||||||
|
const { stdout } = await run("docker", args, { maxBuffer: 1024 * 1024 * 16 });
|
||||||
|
return stdout;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeImageRefs(output: string): string[] {
|
||||||
|
return output
|
||||||
|
.split(/\r?\n/)
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.filter((line) => line.length > 0 && !line.includes("<none>"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSupabaseImageRef(ref: string): boolean {
|
||||||
|
return SUPABASE_IMAGE_PREFIXES.some((prefix) => ref.startsWith(prefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function collectDockerImageRefs(run: ExecFile = execFile): Promise<string[]> {
|
||||||
|
const refs = new Set<string>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const output = await runDocker(
|
||||||
|
["ps", "-a", "--filter", `label=${CLI_PROJECT_LABEL}`, "--format", "{{.Image}}"],
|
||||||
|
run,
|
||||||
|
);
|
||||||
|
for (const ref of normalizeImageRefs(output)) {
|
||||||
|
refs.add(ref);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(
|
||||||
|
`Could not list Supabase CLI containers for Docker image cache: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const output = await runDocker(["image", "ls", "--format", "{{.Repository}}:{{.Tag}}"], run);
|
||||||
|
for (const ref of normalizeImageRefs(output).filter(isSupabaseImageRef)) {
|
||||||
|
refs.add(ref);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(
|
||||||
|
`Could not list Docker images for Supabase image cache: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [...refs].sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function restoreDockerImageCache(
|
||||||
|
installedVersion: string,
|
||||||
|
registry: string,
|
||||||
|
run: ExecFile = execFile,
|
||||||
|
): Promise<void> {
|
||||||
|
const enabled = core.getBooleanInput(CACHE_INPUT);
|
||||||
|
core.setOutput(CACHE_HIT_OUTPUT, "false");
|
||||||
|
core.saveState(STATE_ENABLED, String(enabled));
|
||||||
|
|
||||||
|
if (!enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const archivePath = getCacheArchivePath();
|
||||||
|
const primaryKey = getPrimaryCacheKey(installedVersion, registry);
|
||||||
|
mkdirSync(path.dirname(archivePath), { recursive: true });
|
||||||
|
core.saveState(STATE_PRIMARY_KEY, primaryKey);
|
||||||
|
core.saveState(STATE_ARCHIVE_PATH, archivePath);
|
||||||
|
core.saveState(STATE_CACHE_HIT, "false");
|
||||||
|
|
||||||
|
if (!(await isDockerAvailable(run))) {
|
||||||
|
core.warning("Docker is not available. Skipping Supabase Docker image cache restore.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let matchedKey: string | undefined;
|
||||||
|
try {
|
||||||
|
matchedKey = await cache.restoreCache([archivePath], primaryKey);
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(
|
||||||
|
`Could not restore Supabase Docker image cache: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchedKey) {
|
||||||
|
core.info("No Supabase Docker image cache found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheHit = matchedKey === primaryKey;
|
||||||
|
core.setOutput(CACHE_HIT_OUTPUT, String(cacheHit));
|
||||||
|
core.saveState(STATE_CACHE_HIT, String(cacheHit));
|
||||||
|
|
||||||
|
if (!existsSync(archivePath)) {
|
||||||
|
core.warning("Supabase Docker image cache was restored, but the archive is missing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await runDocker(["load", "-i", archivePath], run);
|
||||||
|
core.info("Loaded Supabase Docker images from cache.");
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(
|
||||||
|
`Could not load Supabase Docker image cache: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveDockerImageCache(run: ExecFile = execFile): Promise<void> {
|
||||||
|
if (core.getState(STATE_ENABLED) !== "true") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core.getState(STATE_CACHE_HIT) === "true") {
|
||||||
|
core.info("Supabase Docker image cache hit. Skipping cache save.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const primaryKey = core.getState(STATE_PRIMARY_KEY);
|
||||||
|
const archivePath = core.getState(STATE_ARCHIVE_PATH) || getCacheArchivePath();
|
||||||
|
if (!primaryKey) {
|
||||||
|
core.warning("Supabase Docker image cache key is missing. Skipping cache save.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await isDockerAvailable(run))) {
|
||||||
|
core.warning("Docker is not available. Skipping Supabase Docker image cache save.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageRefs = await collectDockerImageRefs(run);
|
||||||
|
if (imageRefs.length === 0) {
|
||||||
|
core.warning("No Supabase Docker images found to cache.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdirSync(path.dirname(archivePath), { recursive: true });
|
||||||
|
try {
|
||||||
|
await runDocker(["save", "-o", archivePath, ...imageRefs], run);
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(
|
||||||
|
`Could not create Supabase Docker image archive: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await cache.saveCache([archivePath], primaryKey);
|
||||||
|
core.info(`Saved ${imageRefs.length} Supabase Docker image(s) to cache.`);
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(
|
||||||
|
`Could not save Supabase Docker image cache: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
141
src/main.test.ts
141
src/main.test.ts
@@ -10,21 +10,13 @@ import * as tc from "@actions/tool-cache";
|
|||||||
const repo = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
const repo = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
||||||
const defaultEntrypoint = fileURLToPath(new URL("./main.ts", import.meta.url));
|
const defaultEntrypoint = fileURLToPath(new URL("./main.ts", import.meta.url));
|
||||||
const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY";
|
const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY";
|
||||||
const GITHUB_RELEASES_API = "https://api.github.com/repos/supabase/cli/releases/latest";
|
|
||||||
const GITHUB_TOKEN_ENV = "SUPABASE_CLI_GITHUB_TOKEN";
|
|
||||||
const originalWorkspace = process.env.GITHUB_WORKSPACE;
|
const originalWorkspace = process.env.GITHUB_WORKSPACE;
|
||||||
const originalGithubToken = process.env[GITHUB_TOKEN_ENV];
|
|
||||||
const tempDirs = new Set<string>();
|
const tempDirs = new Set<string>();
|
||||||
let mainModule: typeof import("./main.ts") | null = null;
|
let mainModule: typeof import("./main.ts") | null = null;
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
mock.restore();
|
mock.restore();
|
||||||
process.env.GITHUB_WORKSPACE = originalWorkspace;
|
process.env.GITHUB_WORKSPACE = originalWorkspace;
|
||||||
if (originalGithubToken === undefined) {
|
|
||||||
delete process.env[GITHUB_TOKEN_ENV];
|
|
||||||
} else {
|
|
||||||
process.env[GITHUB_TOKEN_ENV] = originalGithubToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const dir of tempDirs) {
|
for (const dir of tempDirs) {
|
||||||
rmSync(dir, { force: true, recursive: true });
|
rmSync(dir, { force: true, recursive: true });
|
||||||
@@ -154,29 +146,25 @@ function createPackageLock(version: string): string {
|
|||||||
|
|
||||||
function createActionSpies(inputVersion: string, cliDir: string, expectedUrlFragment: string) {
|
function createActionSpies(inputVersion: string, cliDir: string, expectedUrlFragment: string) {
|
||||||
return {
|
return {
|
||||||
getInput: spyOn(core, "getInput").mockReturnValue(inputVersion),
|
getInput: spyOn(core, "getInput").mockImplementation((name: string) =>
|
||||||
|
name === "version" ? inputVersion : "",
|
||||||
|
),
|
||||||
|
getBooleanInput: spyOn(core, "getBooleanInput").mockImplementation(() => false),
|
||||||
setOutput: spyOn(core, "setOutput").mockImplementation(() => {}),
|
setOutput: spyOn(core, "setOutput").mockImplementation(() => {}),
|
||||||
addPath: spyOn(core, "addPath").mockImplementation(() => {}),
|
addPath: spyOn(core, "addPath").mockImplementation(() => {}),
|
||||||
exportVariable: spyOn(core, "exportVariable").mockImplementation(() => {}),
|
exportVariable: spyOn(core, "exportVariable").mockImplementation(() => {}),
|
||||||
|
saveState: spyOn(core, "saveState").mockImplementation(() => {}),
|
||||||
|
info: spyOn(core, "info").mockImplementation(() => {}),
|
||||||
|
warning: spyOn(core, "warning").mockImplementation(() => {}),
|
||||||
setFailed: spyOn(core, "setFailed").mockImplementation(() => {}),
|
setFailed: spyOn(core, "setFailed").mockImplementation(() => {}),
|
||||||
downloadTool: spyOn(tc, "downloadTool").mockImplementation(async (url: string) => {
|
downloadTool: spyOn(tc, "downloadTool").mockImplementation(async (url: string) => {
|
||||||
expect(url).toContain(expectedUrlFragment);
|
expect(url).toContain(expectedUrlFragment);
|
||||||
return path.join(os.tmpdir(), "supabase-cli.tar.gz");
|
return path.join(os.tmpdir(), "supabase-cli.tar.gz");
|
||||||
}),
|
}),
|
||||||
extractTar: spyOn(tc, "extractTar").mockImplementation(async () => cliDir),
|
extractTar: spyOn(tc, "extractTar").mockImplementation(async () => cliDir),
|
||||||
extractZip: spyOn(tc, "extractZip").mockImplementation(async () => cliDir),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockLatestRelease(version = "v2.99.0") {
|
|
||||||
return spyOn(globalThis, "fetch").mockResolvedValue(
|
|
||||||
new Response(JSON.stringify({ tag_name: version }), {
|
|
||||||
status: 200,
|
|
||||||
statusText: "OK",
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getMainModule(): Promise<typeof import("./main.ts")> {
|
async function getMainModule(): Promise<typeof import("./main.ts")> {
|
||||||
if (!mainModule) {
|
if (!mainModule) {
|
||||||
mainModule = await import("./main.ts");
|
mainModule = await import("./main.ts");
|
||||||
@@ -185,100 +173,8 @@ async function getMainModule(): Promise<typeof import("./main.ts")> {
|
|||||||
return mainModule;
|
return mainModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
test("uses versioned tar archives for Supabase CLI v2.99.0 and later", async () => {
|
|
||||||
const { getDownloadArchive } = await getMainModule();
|
|
||||||
|
|
||||||
const archive = await getDownloadArchive("2.99.0", "linux", "x64");
|
|
||||||
|
|
||||||
expect(archive).toEqual({
|
|
||||||
url: "https://github.com/supabase/cli/releases/download/v2.99.0/supabase_2.99.0_linux_amd64.tar.gz",
|
|
||||||
format: "tar",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("uses apk archives for Supabase CLI v2.99.0 and later on Linux musl", async () => {
|
|
||||||
const { getDownloadArchive } = await getMainModule();
|
|
||||||
|
|
||||||
const archive = await getDownloadArchive("2.100.1", "linux", "x64", true);
|
|
||||||
|
|
||||||
expect(archive).toEqual({
|
|
||||||
url: "https://github.com/supabase/cli/releases/download/v2.100.1/supabase_2.100.1_linux_amd64.apk",
|
|
||||||
format: "apk",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("keeps tar archives before Supabase CLI v2.99.0 on Linux musl", async () => {
|
|
||||||
const { getDownloadArchive } = await getMainModule();
|
|
||||||
|
|
||||||
const archive = await getDownloadArchive("2.98.2", "linux", "x64", true);
|
|
||||||
|
|
||||||
expect(archive).toEqual({
|
|
||||||
url: "https://github.com/supabase/cli/releases/download/v2.98.2/supabase_linux_amd64.tar.gz",
|
|
||||||
format: "tar",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("uses usr/bin as the CLI path for apk archives", async () => {
|
|
||||||
const { getCliPath } = await getMainModule();
|
|
||||||
|
|
||||||
expect(getCliPath("/tmp/extracted", "apk")).toBe(path.join("/tmp/extracted", "usr", "bin"));
|
|
||||||
expect(getCliPath("/tmp/extracted", "tar")).toBe("/tmp/extracted");
|
|
||||||
expect(getCliPath("/tmp/extracted", "zip")).toBe("/tmp/extracted");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("keeps the unversioned tar archive layout before Supabase CLI v2.99.0", async () => {
|
|
||||||
const { getDownloadArchive } = await getMainModule();
|
|
||||||
|
|
||||||
const archive = await getDownloadArchive("2.98.2", "linux", "x64");
|
|
||||||
|
|
||||||
expect(archive).toEqual({
|
|
||||||
url: "https://github.com/supabase/cli/releases/download/v2.98.2/supabase_linux_amd64.tar.gz",
|
|
||||||
format: "tar",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("uses versioned zip archives for Windows Supabase CLI v2.99.0 and later", async () => {
|
|
||||||
const { getDownloadArchive } = await getMainModule();
|
|
||||||
|
|
||||||
const archive = await getDownloadArchive("2.99.0", "win32", "x64");
|
|
||||||
|
|
||||||
expect(archive).toEqual({
|
|
||||||
url: "https://github.com/supabase/cli/releases/download/v2.99.0/supabase_2.99.0_windows_amd64.zip",
|
|
||||||
format: "zip",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("resolves latest before choosing a versioned Supabase CLI archive", async () => {
|
|
||||||
mockLatestRelease("v2.99.0");
|
|
||||||
const { getDownloadArchive } = await getMainModule();
|
|
||||||
|
|
||||||
const archive = await getDownloadArchive("latest", "darwin", "arm64");
|
|
||||||
|
|
||||||
expect(archive).toEqual({
|
|
||||||
url: "https://github.com/supabase/cli/releases/download/v2.99.0/supabase_2.99.0_darwin_arm64.tar.gz",
|
|
||||||
format: "tar",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("authenticates latest release lookup when a GitHub token is provided", async () => {
|
|
||||||
process.env[GITHUB_TOKEN_ENV] = "ghs_test-token";
|
|
||||||
const fetch = mockLatestRelease("v2.99.0");
|
|
||||||
const { getDownloadArchive } = await getMainModule();
|
|
||||||
|
|
||||||
await getDownloadArchive("latest", "darwin", "arm64");
|
|
||||||
|
|
||||||
expect(fetch).toHaveBeenCalledWith(GITHUB_RELEASES_API, {
|
|
||||||
headers: expect.objectContaining({
|
|
||||||
Accept: "application/vnd.github+json",
|
|
||||||
Authorization: "Bearer ghs_test-token",
|
|
||||||
"X-GitHub-Api-Version": "2022-11-28",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test("awaits the action entrypoint with omitted version and latest fallback", async () => {
|
test("awaits the action entrypoint with omitted version and latest fallback", async () => {
|
||||||
process.env.GITHUB_WORKSPACE = repo;
|
process.env.GITHUB_WORKSPACE = repo;
|
||||||
mockLatestRelease();
|
|
||||||
const cliDir = createFakeCli("supabase 2.84.2");
|
const cliDir = createFakeCli("supabase 2.84.2");
|
||||||
let startDownload!: () => void;
|
let startDownload!: () => void;
|
||||||
let finishDownload!: () => void;
|
let finishDownload!: () => void;
|
||||||
@@ -289,18 +185,23 @@ test("awaits the action entrypoint with omitted version and latest fallback", as
|
|||||||
finishDownload = () => resolve(path.join(os.tmpdir(), "supabase-cli.tar.gz"));
|
finishDownload = () => resolve(path.join(os.tmpdir(), "supabase-cli.tar.gz"));
|
||||||
});
|
});
|
||||||
const spies = {
|
const spies = {
|
||||||
getInput: spyOn(core, "getInput").mockReturnValue(""),
|
getInput: spyOn(core, "getInput").mockImplementation((name: string) =>
|
||||||
|
name === "version" ? "" : "",
|
||||||
|
),
|
||||||
|
getBooleanInput: spyOn(core, "getBooleanInput").mockImplementation(() => false),
|
||||||
setOutput: spyOn(core, "setOutput").mockImplementation(() => {}),
|
setOutput: spyOn(core, "setOutput").mockImplementation(() => {}),
|
||||||
addPath: spyOn(core, "addPath").mockImplementation(() => {}),
|
addPath: spyOn(core, "addPath").mockImplementation(() => {}),
|
||||||
exportVariable: spyOn(core, "exportVariable").mockImplementation(() => {}),
|
exportVariable: spyOn(core, "exportVariable").mockImplementation(() => {}),
|
||||||
|
saveState: spyOn(core, "saveState").mockImplementation(() => {}),
|
||||||
|
info: spyOn(core, "info").mockImplementation(() => {}),
|
||||||
|
warning: spyOn(core, "warning").mockImplementation(() => {}),
|
||||||
setFailed: spyOn(core, "setFailed").mockImplementation(() => {}),
|
setFailed: spyOn(core, "setFailed").mockImplementation(() => {}),
|
||||||
downloadTool: spyOn(tc, "downloadTool").mockImplementation(async (url: string) => {
|
downloadTool: spyOn(tc, "downloadTool").mockImplementation(async (url: string) => {
|
||||||
expect(url).toContain("/download/v2.99.0/supabase_2.99.0_");
|
expect(url).toContain("/latest/download/");
|
||||||
startDownload();
|
startDownload();
|
||||||
return downloadFinished;
|
return downloadFinished;
|
||||||
}),
|
}),
|
||||||
extractTar: spyOn(tc, "extractTar").mockImplementation(async () => cliDir),
|
extractTar: spyOn(tc, "extractTar").mockImplementation(async () => cliDir),
|
||||||
extractZip: spyOn(tc, "extractZip").mockImplementation(async () => cliDir),
|
|
||||||
};
|
};
|
||||||
const originalArgv1 = process.argv[1];
|
const originalArgv1 = process.argv[1];
|
||||||
process.argv[1] = defaultEntrypoint;
|
process.argv[1] = defaultEntrypoint;
|
||||||
@@ -394,9 +295,8 @@ test("falls back to latest when version is omitted and no supported root lockfil
|
|||||||
process.env.GITHUB_WORKSPACE = createWorkspace({
|
process.env.GITHUB_WORKSPACE = createWorkspace({
|
||||||
"README.md": "# app\n",
|
"README.md": "# app\n",
|
||||||
});
|
});
|
||||||
mockLatestRelease();
|
|
||||||
const cliDir = createFakeCli("supabase 2.84.2");
|
const cliDir = createFakeCli("supabase 2.84.2");
|
||||||
const spies = createActionSpies("", cliDir, "/download/v2.99.0/supabase_2.99.0_");
|
const spies = createActionSpies("", cliDir, "/latest/download/");
|
||||||
const { run } = await getMainModule();
|
const { run } = await getMainModule();
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
@@ -408,9 +308,8 @@ test("falls back to latest when version is omitted and no supported root lockfil
|
|||||||
|
|
||||||
test("falls back to latest when version is omitted and no workspace is available", async () => {
|
test("falls back to latest when version is omitted and no workspace is available", async () => {
|
||||||
delete process.env.GITHUB_WORKSPACE;
|
delete process.env.GITHUB_WORKSPACE;
|
||||||
mockLatestRelease();
|
|
||||||
const cliDir = createFakeCli("supabase 2.84.2");
|
const cliDir = createFakeCli("supabase 2.84.2");
|
||||||
const spies = createActionSpies("", cliDir, "/download/v2.99.0/supabase_2.99.0_");
|
const spies = createActionSpies("", cliDir, "/latest/download/");
|
||||||
const { run } = await getMainModule();
|
const { run } = await getMainModule();
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
@@ -473,9 +372,8 @@ test("falls through unreadable bun.lock paths and malformed package-lock files t
|
|||||||
});
|
});
|
||||||
mkdirSync(path.join(workspace, "bun.lock"), { recursive: true });
|
mkdirSync(path.join(workspace, "bun.lock"), { recursive: true });
|
||||||
process.env.GITHUB_WORKSPACE = workspace;
|
process.env.GITHUB_WORKSPACE = workspace;
|
||||||
mockLatestRelease();
|
|
||||||
const cliDir = createFakeCli("supabase 2.84.2");
|
const cliDir = createFakeCli("supabase 2.84.2");
|
||||||
const spies = createActionSpies("", cliDir, "/download/v2.99.0/supabase_2.99.0_");
|
const spies = createActionSpies("", cliDir, "/latest/download/");
|
||||||
const { run } = await getMainModule();
|
const { run } = await getMainModule();
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
@@ -489,9 +387,8 @@ test("falls back to latest when a pnpm dependency entry has no concrete version"
|
|||||||
process.env.GITHUB_WORKSPACE = createWorkspace({
|
process.env.GITHUB_WORKSPACE = createWorkspace({
|
||||||
"pnpm-lock.yaml": createPnpmLock("2.49.0", { includeVersion: false }),
|
"pnpm-lock.yaml": createPnpmLock("2.49.0", { includeVersion: false }),
|
||||||
});
|
});
|
||||||
mockLatestRelease();
|
|
||||||
const cliDir = createFakeCli("supabase 2.84.2");
|
const cliDir = createFakeCli("supabase 2.84.2");
|
||||||
const spies = createActionSpies("", cliDir, "/download/v2.99.0/supabase_2.99.0_");
|
const spies = createActionSpies("", cliDir, "/latest/download/");
|
||||||
const { run } = await getMainModule();
|
const { run } = await getMainModule();
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
|
|||||||
175
src/main.ts
175
src/main.ts
@@ -1,23 +1,18 @@
|
|||||||
import { $, semver } from "bun";
|
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import * as tc from "@actions/tool-cache";
|
import * as tc from "@actions/tool-cache";
|
||||||
|
import { load as loadYaml } from "js-yaml";
|
||||||
|
import * as semver from "semver";
|
||||||
|
import { execFile as execFileCallback } from "node:child_process";
|
||||||
import { existsSync, readFileSync } from "node:fs";
|
import { existsSync, readFileSync } from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { fileURLToPath } from "node:url";
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { promisify } from "node:util";
|
||||||
|
import { getGhcrImageRegistry, getImageRegistry, restoreDockerImageCache } from "./cache";
|
||||||
|
|
||||||
export const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY";
|
export const CLI_CONFIG_REGISTRY = "SUPABASE_INTERNAL_IMAGE_REGISTRY";
|
||||||
const REGISTRY_VERSION = "1.28.0";
|
const REGISTRY_VERSION = "1.28.0";
|
||||||
const VERSIONED_ARCHIVE_VERSION = "2.99.0";
|
|
||||||
const DEFAULT_VERSION = "latest";
|
const DEFAULT_VERSION = "latest";
|
||||||
const GITHUB_RELEASES_API = "https://api.github.com/repos/supabase/cli/releases/latest";
|
const execFile = promisify(execFileCallback);
|
||||||
const GITHUB_TOKEN_ENV = "SUPABASE_CLI_GITHUB_TOKEN";
|
|
||||||
|
|
||||||
type ArchiveFormat = "apk" | "tar" | "zip";
|
|
||||||
|
|
||||||
type DownloadArchive = {
|
|
||||||
url: string;
|
|
||||||
format: ArchiveFormat;
|
|
||||||
};
|
|
||||||
|
|
||||||
type BunLock = {
|
type BunLock = {
|
||||||
workspaces?: {
|
workspaces?: {
|
||||||
@@ -66,10 +61,6 @@ function extractConcreteVersion(raw: string | undefined): string | null {
|
|||||||
return match?.[0] ?? null;
|
return match?.[0] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeVersion(version: string): string {
|
|
||||||
return version.replace(/^v/i, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
function readWorkspaceLockfile(workspaceRoot: string, filename: string): string | null {
|
function readWorkspaceLockfile(workspaceRoot: string, filename: string): string | null {
|
||||||
const filePath = path.join(workspaceRoot, filename);
|
const filePath = path.join(workspaceRoot, filename);
|
||||||
|
|
||||||
@@ -120,7 +111,7 @@ function detectVersionFromPnpmLock(workspaceRoot: string): string | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const lockfile = Bun.YAML.parse(text) as PnpmLock;
|
const lockfile = loadYaml(text) as PnpmLock;
|
||||||
const rootImporter = lockfile.importers?.["."];
|
const rootImporter = lockfile.importers?.["."];
|
||||||
const dependency =
|
const dependency =
|
||||||
rootImporter?.dependencies?.supabase ?? rootImporter?.devDependencies?.supabase;
|
rootImporter?.dependencies?.supabase ?? rootImporter?.devDependencies?.supabase;
|
||||||
@@ -175,138 +166,39 @@ function resolveVersion(inputVersion: string): string {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolveLatestVersion(): Promise<string> {
|
export function getDownloadUrl(version: string): string {
|
||||||
const headers: Record<string, string> = {
|
const platform = getArchivePlatform(process.platform);
|
||||||
Accept: "application/vnd.github+json",
|
const arch = getArchiveArch(process.arch);
|
||||||
"X-GitHub-Api-Version": "2022-11-28",
|
const filename = `supabase_${platform}_${arch}.tar.gz`;
|
||||||
};
|
|
||||||
const githubToken = process.env[GITHUB_TOKEN_ENV]?.trim();
|
|
||||||
|
|
||||||
if (githubToken) {
|
if (version.toLowerCase() === "latest") {
|
||||||
headers.Authorization = `Bearer ${githubToken}`;
|
return `https://github.com/supabase/cli/releases/latest/download/${filename}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(GITHUB_RELEASES_API, { headers });
|
if (semver.compare(version, REGISTRY_VERSION) === -1) {
|
||||||
if (!response.ok) {
|
return `https://github.com/supabase/cli/releases/download/v${version}/supabase_${version}_${platform}_${arch}.tar.gz`;
|
||||||
throw new Error(`Failed to resolve latest Supabase CLI release: ${response.statusText}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const release = (await response.json()) as { tag_name?: unknown };
|
return `https://github.com/supabase/cli/releases/download/v${version}/${filename}`;
|
||||||
if (typeof release.tag_name !== "string") {
|
|
||||||
throw new Error("Failed to resolve latest Supabase CLI release: missing tag name");
|
|
||||||
}
|
|
||||||
|
|
||||||
return normalizeVersion(release.tag_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArchiveFormat(
|
function getSupabaseExecutable(cliPath: string): string {
|
||||||
version: string,
|
const names =
|
||||||
platform: NodeJS.Platform,
|
process.platform === "win32" ? ["supabase.exe", "supabase.cmd", "supabase"] : ["supabase"];
|
||||||
isMuslLinux: boolean,
|
|
||||||
): ArchiveFormat {
|
|
||||||
if (
|
|
||||||
platform === "linux" &&
|
|
||||||
isMuslLinux &&
|
|
||||||
semver.order(version, VERSIONED_ARCHIVE_VERSION) >= 0
|
|
||||||
) {
|
|
||||||
return "apk";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platform === "win32" && semver.order(version, VERSIONED_ARCHIVE_VERSION) >= 0) {
|
for (const name of names) {
|
||||||
return "zip";
|
const executable = path.join(cliPath, name);
|
||||||
}
|
if (existsSync(executable)) {
|
||||||
|
return executable;
|
||||||
return "tar";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function getArchiveFilename(
|
|
||||||
version: string,
|
|
||||||
platform: NodeJS.Platform,
|
|
||||||
arch: NodeJS.Architecture,
|
|
||||||
archiveFormat: ArchiveFormat,
|
|
||||||
): string {
|
|
||||||
const archivePlatform = getArchivePlatform(platform);
|
|
||||||
const archiveArch = getArchiveArch(arch);
|
|
||||||
|
|
||||||
if (semver.order(version, REGISTRY_VERSION) === -1) {
|
|
||||||
return `supabase_${version}_${archivePlatform}_${archiveArch}.tar.gz`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platform === "linux" && archiveFormat === "apk") {
|
|
||||||
return `supabase_${version}_${archivePlatform}_${archiveArch}.apk`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (semver.order(version, VERSIONED_ARCHIVE_VERSION) >= 0) {
|
|
||||||
const extension = platform === "win32" ? "zip" : "tar.gz";
|
|
||||||
return `supabase_${version}_${archivePlatform}_${archiveArch}.${extension}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `supabase_${archivePlatform}_${archiveArch}.tar.gz`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDownloadArchive(
|
|
||||||
version: string,
|
|
||||||
platform = process.platform,
|
|
||||||
arch = process.arch,
|
|
||||||
isMuslLinux?: boolean,
|
|
||||||
): Promise<DownloadArchive> {
|
|
||||||
const resolvedVersion =
|
|
||||||
version.toLowerCase() === "latest" ? await resolveLatestVersion() : normalizeVersion(version);
|
|
||||||
const format = getArchiveFormat(
|
|
||||||
resolvedVersion,
|
|
||||||
platform,
|
|
||||||
isMuslLinux ?? (await detectMuslLinux(platform)),
|
|
||||||
);
|
|
||||||
const filename = getArchiveFilename(resolvedVersion, platform, arch, format);
|
|
||||||
|
|
||||||
return {
|
|
||||||
url: `https://github.com/supabase/cli/releases/download/v${resolvedVersion}/${filename}`,
|
|
||||||
format,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function detectMuslLinux(platform = process.platform): Promise<boolean> {
|
|
||||||
if (platform !== "linux") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existsSync("/etc/alpine-release")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const output = await $`ldd --version`.quiet().text();
|
|
||||||
return output.toLowerCase().includes("musl");
|
|
||||||
} catch (error) {
|
|
||||||
const output = error instanceof Error ? error.message : String(error);
|
|
||||||
return output.toLowerCase().includes("musl");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCliPath(extractedPath: string, archiveFormat: ArchiveFormat): string {
|
|
||||||
return archiveFormat === "apk" ? path.join(extractedPath, "usr", "bin") : extractedPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCliExecutablePath(cliPath: string): string {
|
|
||||||
if (process.platform !== "win32") {
|
|
||||||
return path.join(cliPath, "supabase");
|
|
||||||
}
|
|
||||||
|
|
||||||
const exePath = path.join(cliPath, "supabase.exe");
|
|
||||||
if (existsSync(exePath)) {
|
|
||||||
return exePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cmdPath = path.join(cliPath, "supabase.cmd");
|
|
||||||
if (existsSync(cmdPath)) {
|
|
||||||
return cmdPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return path.join(cliPath, "supabase");
|
return path.join(cliPath, "supabase");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function determineInstalledVersion(cliPath: string): Promise<string> {
|
export async function determineInstalledVersion(cliPath: string): Promise<string> {
|
||||||
const version = (await $`${getCliExecutablePath(cliPath)} --version`.text()).trim();
|
const { stdout } = await execFile(getSupabaseExecutable(cliPath), ["--version"]);
|
||||||
|
const version = stdout.trim();
|
||||||
if (!version) {
|
if (!version) {
|
||||||
throw new Error("Could not determine installed Supabase CLI version");
|
throw new Error("Could not determine installed Supabase CLI version");
|
||||||
}
|
}
|
||||||
@@ -317,20 +209,17 @@ export async function determineInstalledVersion(cliPath: string): Promise<string
|
|||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const version = resolveVersion(core.getInput("version"));
|
const version = resolveVersion(core.getInput("version"));
|
||||||
const archive = await getDownloadArchive(version);
|
const tarball = await tc.downloadTool(getDownloadUrl(version));
|
||||||
const archivePath = await tc.downloadTool(archive.url);
|
const cliPath = await tc.extractTar(tarball);
|
||||||
const extractedPath =
|
|
||||||
archive.format === "zip"
|
|
||||||
? await tc.extractZip(archivePath)
|
|
||||||
: await tc.extractTar(archivePath);
|
|
||||||
const cliPath = getCliPath(extractedPath, archive.format);
|
|
||||||
const installedVersion = await determineInstalledVersion(cliPath);
|
const installedVersion = await determineInstalledVersion(cliPath);
|
||||||
core.setOutput("version", installedVersion);
|
core.setOutput("version", installedVersion);
|
||||||
core.addPath(cliPath);
|
core.addPath(cliPath);
|
||||||
|
|
||||||
if (version.toLowerCase() === "latest" || semver.order(version, REGISTRY_VERSION) >= 0) {
|
if (version.toLowerCase() === "latest" || semver.compare(version, REGISTRY_VERSION) >= 0) {
|
||||||
core.exportVariable(CLI_CONFIG_REGISTRY, "ghcr.io");
|
core.exportVariable(CLI_CONFIG_REGISTRY, getGhcrImageRegistry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await restoreDockerImageCache(installedVersion, getImageRegistry());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error instanceof Error ? error.message : String(error));
|
core.setFailed(error instanceof Error ? error.message : String(error));
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/post.ts
Normal file
17
src/post.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import * as core from "@actions/core";
|
||||||
|
import { fileURLToPath } from "node:url";
|
||||||
|
import { saveDockerImageCache } from "./cache";
|
||||||
|
|
||||||
|
export async function run(): Promise<void> {
|
||||||
|
try {
|
||||||
|
await saveDockerImageCache();
|
||||||
|
} catch (error) {
|
||||||
|
core.warning(
|
||||||
|
`Supabase Docker image cache post step failed: ${error instanceof Error ? error.message : String(error)}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||||
|
await run();
|
||||||
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "@tsconfig/bun/tsconfig.json",
|
"extends": "@tsconfig/bun/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": ["bun", "node"]
|
||||||
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user