diff --git a/.github/actions/check-version-change/action.yml b/.github/actions/check-version-change/action.yml new file mode 100644 index 0000000..0ea75c7 --- /dev/null +++ b/.github/actions/check-version-change/action.yml @@ -0,0 +1,18 @@ +name: Check version change +description: Detect whether the package.json version changed since the previous commit + +outputs: + changed: + description: 'true if the version changed since HEAD^' + value: ${{ steps.check.outputs.changed }} + current: + description: 'The current version in package.json' + value: ${{ steps.check.outputs.current }} + +runs: + using: composite + steps: + - name: Run check + id: check + shell: bash + run: yarn tsx "$GITHUB_ACTION_PATH/check-version-change.ts" diff --git a/.github/actions/check-version-change/check-version-change.ts b/.github/actions/check-version-change/check-version-change.ts new file mode 100644 index 0000000..926ad4b --- /dev/null +++ b/.github/actions/check-version-change/check-version-change.ts @@ -0,0 +1,44 @@ +import { execSync } from 'node:child_process'; +import { readFileSync } from 'node:fs'; +import * as core from '@actions/core'; +import semver from 'semver'; + +const readVersion = (json: string, source: string): string => { + const parsed: unknown = JSON.parse(json); + if ( + typeof parsed !== 'object' || + parsed === null || + !('version' in parsed) || + typeof parsed.version !== 'string' + ) { + throw new Error(`${source} is missing a string "version" field`); + } + const valid = semver.valid(parsed.version); + if (valid === null) { + throw new Error(`${source} has invalid semver version "${parsed.version}"`); + } + return valid; +}; + +try { + const current = readVersion( + readFileSync('package.json', 'utf8'), + 'package.json', + ); + const previous = readVersion( + execSync('git show HEAD^:package.json', { encoding: 'utf8' }), + 'package.json@HEAD^', + ); + const changed = !semver.eq(current, previous); + + core.info( + changed + ? `Version changed: ${previous} -> ${current}` + : `Version unchanged (${current}); skipping publish.`, + ); + + core.setOutput('current', current); + core.setOutput('changed', changed); +} catch (error) { + core.setFailed(error instanceof Error ? error : 'An unknown error occurred'); +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1eb4ef0..e0b4695 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,3 +74,60 @@ jobs: - name: Run test run: yarn test + + version-check: + name: Version check + needs: [format, lint, types, build, test] + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + outputs: + changed: ${{ steps.version.outputs.changed }} + current: ${{ steps.version.outputs.current }} + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + fetch-depth: 2 + + - name: Setup node + uses: ./.github/actions/setup-node + + - name: Check for version change + id: version + uses: ./.github/actions/check-version-change + + publish: + name: Publish + needs: version-check + if: needs.version-check.outputs.changed == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + env: + VERSION: ${{ needs.version-check.outputs.current }} + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Setup node + uses: ./.github/actions/setup-node + + - name: Build + run: yarn build + + - name: Publish to npm + run: yarn npm publish + env: + YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Create git tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git tag -a "v$VERSION" -m "v$VERSION" + git push origin "v$VERSION" + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: gh release create "v$VERSION" --title "v$VERSION" --generate-notes diff --git a/package.json b/package.json index 2e46a28..58a1b97 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "scripts": { "build": "tsdown", "build:watch": "tsdown --watch", + "bump": "tsx scripts/bump-version.ts", "format": "yarn oxfmt", "lint": "yarn oxlint", "precommit": "lint-staged", @@ -34,9 +35,12 @@ } }, "devDependencies": { + "@actions/core": "^3.0.1", "@arethetypeswrong/core": "^0.18.2", + "@inquirer/prompts": "^8.4.2", "@types/node": "^24.0.0", "@types/react": "^19.0.0", + "@types/semver": "^7.7.1", "@vitest/browser-playwright": "^4.1.5", "lint-staged": "^16.4.0", "oxfmt": "^0.38.0", @@ -44,7 +48,9 @@ "oxlint-tsgolint": "^0.16.0", "playwright": "^1.49.0", "publint": "^0.3.18", + "semver": "^7.7.4", "tsdown": "^0.21.10", + "tsx": "^4.21.0", "typescript": "^6.0.2", "unplugin-unused": "^0.5.7", "vitest": "^4.1.5" diff --git a/scripts/bump-version.ts b/scripts/bump-version.ts new file mode 100644 index 0000000..d095f6a --- /dev/null +++ b/scripts/bump-version.ts @@ -0,0 +1,124 @@ +import { readFileSync, writeFileSync } from 'node:fs'; + +import { select } from '@inquirer/prompts'; +import * as semver from 'semver'; + +type BaseBump = 'patch' | 'minor' | 'major'; +type Choice = { label: string; next: string }; + +const PACKAGE_JSON_PATH = 'package.json'; +const PRE_TAG = 'pre'; + +const PREBUMP: Record = { + patch: 'prepatch', + minor: 'preminor', + major: 'premajor', +}; + +const isPrerelease = (parsed: semver.SemVer): boolean => { + if (parsed.prerelease.length === 0) return false; + const [tag, counter, ...rest] = parsed.prerelease; + if (tag !== PRE_TAG || typeof counter !== 'number' || rest.length > 0) { + throw new Error( + `Unsupported prerelease "${parsed.version}"; expected x.y.z-${PRE_TAG}.N`, + ); + } + return true; +}; + +const baseStable = (parsed: semver.SemVer): string => + `${parsed.major}.${parsed.minor}.${parsed.patch}`; + +const inc = ( + version: string, + release: semver.ReleaseType, + identifier?: typeof PRE_TAG, +): string => { + const result = + identifier === undefined + ? semver.inc(version, release) + : semver.inc(version, release, identifier); + if (result === null) { + throw new Error(`semver.inc failed: inc("${version}", "${release}")`); + } + return result; +}; + +const buildChoices = (current: semver.SemVer): Choice[] => { + const choices: Choice[] = []; + + if (isPrerelease(current)) { + choices.push({ + label: 'prerelease', + next: inc(current.version, 'prerelease'), + }); + choices.push({ label: 'release', next: baseStable(current) }); + } + + const stable = baseStable(current); + for (const bump of ['patch', 'minor', 'major'] as const) { + choices.push({ label: bump, next: inc(stable, bump) }); + choices.push({ + label: `${bump} (${PRE_TAG})`, + next: inc(stable, PREBUMP[bump], PRE_TAG), + }); + } + + return choices; +}; + +const promptChoice = async ( + current: string, + choices: Choice[], +): Promise => { + const labelWidth = Math.max(...choices.map(c => c.label.length)); + return select({ + message: `Select a bump (current: ${current}):`, + choices: choices.map(c => ({ + name: `${c.label.padEnd(labelWidth)} -> ${c.next}`, + value: c, + })), + }); +}; + +const readCurrentVersion = (): semver.SemVer => { + const pkg: unknown = JSON.parse(readFileSync(PACKAGE_JSON_PATH, 'utf8')); + if ( + typeof pkg !== 'object' || + pkg === null || + !('version' in pkg) || + typeof pkg.version !== 'string' + ) { + throw new Error('package.json is missing a string "version" field'); + } + const parsed = semver.parse(pkg.version); + if (parsed === null) { + throw new Error(`Invalid semver version in package.json: "${pkg.version}"`); + } + return parsed; +}; + +const writeNewVersion = (version: string): void => { + const raw = readFileSync(PACKAGE_JSON_PATH, 'utf8'); + const updated = raw.replace(/("version"\s*:\s*")[^"]+(")/, `$1${version}$2`); + if (updated === raw) { + throw new Error('Failed to locate "version" field in package.json'); + } + writeFileSync(PACKAGE_JSON_PATH, updated); +}; + +const main = async (): Promise => { + const current = readCurrentVersion(); + const choices = buildChoices(current); + const choice = await promptChoice(current.version, choices); + writeNewVersion(choice.next); + console.log(`Bumped ${current.version} -> ${choice.next}`); +}; + +main().catch((error: unknown) => { + if (error instanceof Error && error.name === 'ExitPromptError') { + process.exit(130); + } + console.error(error instanceof Error ? error.message : error); + process.exit(1); +}); diff --git a/tsconfig.json b/tsconfig.json index 250fae3..341370e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,5 +16,11 @@ "skipLibCheck": true, "types": ["vitest/globals"] }, - "include": ["src", "vitest.config.ts", "tsdown.config.ts"] + "include": [ + "src", + "scripts", + ".github/actions/**/*.ts", + "vitest.config.ts", + "tsdown.config.ts" + ] } diff --git a/yarn.lock b/yarn.lock index cee98c9..45d3d16 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,42 @@ __metadata: version: 8 cacheKey: 10c0 +"@actions/core@npm:^3.0.1": + version: 3.0.1 + resolution: "@actions/core@npm:3.0.1" + dependencies: + "@actions/exec": "npm:^3.0.0" + "@actions/http-client": "npm:^4.0.0" + checksum: 10c0/c1b86364e923e8b1bdcd338943d453c114b2cd8eb9507e07b7614679ea15ddf938b3bb75484aaf363bc3aa55ba926b9514ec08d79811a991f75c732a76c4d854 + languageName: node + linkType: hard + +"@actions/exec@npm:^3.0.0": + version: 3.0.0 + resolution: "@actions/exec@npm:3.0.0" + dependencies: + "@actions/io": "npm:^3.0.2" + checksum: 10c0/5e4357cd8538ae8d94ffef653559202e7d18db18c5ecccd2c943b4aab989df9cf4e466fcc3c4405887a3c30b88e87b89fb7c7f5b179622d1192525ec891f0274 + languageName: node + linkType: hard + +"@actions/http-client@npm:^4.0.0": + version: 4.0.1 + resolution: "@actions/http-client@npm:4.0.1" + dependencies: + tunnel: "npm:^0.0.6" + undici: "npm:^6.23.0" + checksum: 10c0/2470880a461e00bfeee13462f05f089542af2a6da02bfd73422c549119a5078fbf2cc0c6d3f64d4e5a9df5aeef7f0cf08925a41793c136631ac2ec55dc7a697d + languageName: node + linkType: hard + +"@actions/io@npm:^3.0.2": + version: 3.0.2 + resolution: "@actions/io@npm:3.0.2" + checksum: 10c0/25fae323886544f965e90ab9655e3fb60816eb379c78418c4b06a5dc9da27810eb5b0bd0629146dbd5482a03e3c60a5b8713223e4f789abede23df643ddcae8c + languageName: node + linkType: hard + "@andrewbranch/untar.js@npm:^1.0.3": version: 1.0.3 resolution: "@andrewbranch/untar.js@npm:1.0.3" @@ -147,6 +183,429 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/aix-ppc64@npm:0.27.7" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-arm64@npm:0.27.7" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-arm@npm:0.27.7" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-x64@npm:0.27.7" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/darwin-arm64@npm:0.27.7" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/darwin-x64@npm:0.27.7" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/freebsd-arm64@npm:0.27.7" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/freebsd-x64@npm:0.27.7" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-arm64@npm:0.27.7" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-arm@npm:0.27.7" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-ia32@npm:0.27.7" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-loong64@npm:0.27.7" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-mips64el@npm:0.27.7" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-ppc64@npm:0.27.7" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-riscv64@npm:0.27.7" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-s390x@npm:0.27.7" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-x64@npm:0.27.7" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/netbsd-arm64@npm:0.27.7" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/netbsd-x64@npm:0.27.7" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openbsd-arm64@npm:0.27.7" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openbsd-x64@npm:0.27.7" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openharmony-arm64@npm:0.27.7" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/sunos-x64@npm:0.27.7" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-arm64@npm:0.27.7" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-ia32@npm:0.27.7" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-x64@npm:0.27.7" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@inquirer/ansi@npm:^2.0.5": + version: 2.0.5 + resolution: "@inquirer/ansi@npm:2.0.5" + checksum: 10c0/ad61532e5bb47473e3d987c32d4015499a8ce5f4f86e46467e8e672fc52670beb303905d6b324e453935a61671f59f3b9b1b6a1edbbe1f64085e2bb87735e295 + languageName: node + linkType: hard + +"@inquirer/checkbox@npm:^5.1.4": + version: 5.1.4 + resolution: "@inquirer/checkbox@npm:5.1.4" + dependencies: + "@inquirer/ansi": "npm:^2.0.5" + "@inquirer/core": "npm:^11.1.9" + "@inquirer/figures": "npm:^2.0.5" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/38d6c8b49c392307c29fbb252d5dd09a819aecc34c83f01a7652efa09d7b8b901c448216496eda3962e319209243297ec575eff4e081a758bb08adb805f7e3d4 + languageName: node + linkType: hard + +"@inquirer/confirm@npm:^6.0.12": + version: 6.0.12 + resolution: "@inquirer/confirm@npm:6.0.12" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/36e9b1ef60e08562f07bcbcd78ba0a681b2fa3e5f54fa5e12303fc5982e8ba875ed782c24161e2295028b2b404ba690e841837303d16eeeb28df7aa9eb8aa835 + languageName: node + linkType: hard + +"@inquirer/core@npm:^11.1.9": + version: 11.1.9 + resolution: "@inquirer/core@npm:11.1.9" + dependencies: + "@inquirer/ansi": "npm:^2.0.5" + "@inquirer/figures": "npm:^2.0.5" + "@inquirer/type": "npm:^4.0.5" + cli-width: "npm:^4.1.0" + fast-wrap-ansi: "npm:^0.2.0" + mute-stream: "npm:^3.0.0" + signal-exit: "npm:^4.1.0" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/f7b162ce5f67fb75aab00a3668fdd8c8629aec790087840ea66ee8ead6009ab2066bec9cbf5bcc394ccdf130e6139051d6bace334b3a66c4f05349585213172c + languageName: node + linkType: hard + +"@inquirer/editor@npm:^5.1.1": + version: 5.1.1 + resolution: "@inquirer/editor@npm:5.1.1" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/external-editor": "npm:^3.0.0" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/d9506fc4d16362ee060df0c8aa722ee85eae79e0be373253ecc49d0f51569f886bf0d09da9ae9910e3d5f79dca10767a5c1711c799af41c668b2a97866470221 + languageName: node + linkType: hard + +"@inquirer/expand@npm:^5.0.13": + version: 5.0.13 + resolution: "@inquirer/expand@npm:5.0.13" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/108055f24dc4348a4981003003ca41fe793c7b3292ff80f583a1e1f1097bee64a0c2e5795cae969bcf77d4f34f03a3feeaa6315363eb01554f1c1eae6769c9f5 + languageName: node + linkType: hard + +"@inquirer/external-editor@npm:^3.0.0": + version: 3.0.0 + resolution: "@inquirer/external-editor@npm:3.0.0" + dependencies: + chardet: "npm:^2.1.1" + iconv-lite: "npm:^0.7.2" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/120910c954869c73c54aee825abef6f4c4aa8620cafa831d56b218586b1ee02c12ad0a17b8d701784fb9d33fa8fd63ee155d9c718c90533ff4d8086b99986e1d + languageName: node + linkType: hard + +"@inquirer/figures@npm:^2.0.5": + version: 2.0.5 + resolution: "@inquirer/figures@npm:2.0.5" + checksum: 10c0/139671b88f33f059aec85ed3fdf464999115573350c6dea61141adc1cfd43d14742b6cb68150c2ca9baf5a1bae618f990ed89b4430ae768d415bbd19944c56df + languageName: node + linkType: hard + +"@inquirer/input@npm:^5.0.12": + version: 5.0.12 + resolution: "@inquirer/input@npm:5.0.12" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/bb8273925c774bc5dffd93d6edc9e24391ab03c3ddd0c604987abbb74a7efcf03ca10b3bd0607ccf6613369e004417b14cf3c031327601118cff2cc98c5098e6 + languageName: node + linkType: hard + +"@inquirer/number@npm:^4.0.12": + version: 4.0.12 + resolution: "@inquirer/number@npm:4.0.12" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/e933967d9879792775d4ac8f4abcc9c2f263107a1e3c1cdd5ce85dd446a03bed2f6cb01c41ed1a3b45b80f385eb3a991d1442703d9816416c79c0ca6f20e57f3 + languageName: node + linkType: hard + +"@inquirer/password@npm:^5.0.12": + version: 5.0.12 + resolution: "@inquirer/password@npm:5.0.12" + dependencies: + "@inquirer/ansi": "npm:^2.0.5" + "@inquirer/core": "npm:^11.1.9" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/e1399196f01ff5fadc1d3e1bc6946a4f53a5753ccf8e39b2f11f1dae5c51fdb85e33ef44760d83c5b58dacc442de603f32e9c991b2e5f2f8a2a451ff62e1fe48 + languageName: node + linkType: hard + +"@inquirer/prompts@npm:^8.4.2": + version: 8.4.2 + resolution: "@inquirer/prompts@npm:8.4.2" + dependencies: + "@inquirer/checkbox": "npm:^5.1.4" + "@inquirer/confirm": "npm:^6.0.12" + "@inquirer/editor": "npm:^5.1.1" + "@inquirer/expand": "npm:^5.0.13" + "@inquirer/input": "npm:^5.0.12" + "@inquirer/number": "npm:^4.0.12" + "@inquirer/password": "npm:^5.0.12" + "@inquirer/rawlist": "npm:^5.2.8" + "@inquirer/search": "npm:^4.1.8" + "@inquirer/select": "npm:^5.1.4" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/0519d6a52e195e24b03949afda1ad7fc2ae752c72a7ba554d4bdbbac844fd47dc83d79e67f732c6bf3c56a407e3171b92bd3b0dc334fd35eea446a889d1100f7 + languageName: node + linkType: hard + +"@inquirer/rawlist@npm:^5.2.8": + version: 5.2.8 + resolution: "@inquirer/rawlist@npm:5.2.8" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/35b0a9e29972342669365af70ea8feebc4e13ce688ce53c1fae723cbd02a7082294553eeb49ee443f5e993c1a97be31fcbe366f7cb573c075557316717792527 + languageName: node + linkType: hard + +"@inquirer/search@npm:^4.1.8": + version: 4.1.8 + resolution: "@inquirer/search@npm:4.1.8" + dependencies: + "@inquirer/core": "npm:^11.1.9" + "@inquirer/figures": "npm:^2.0.5" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/7281c59e8953aa4663c5afe3d6a3b558ec3e97867569f29dcc0a67e89ff05b37f374ac34ebc7356a7137f76a5172d52c60469cadcc323cc733b4d635b5cf3334 + languageName: node + linkType: hard + +"@inquirer/select@npm:^5.1.4": + version: 5.1.4 + resolution: "@inquirer/select@npm:5.1.4" + dependencies: + "@inquirer/ansi": "npm:^2.0.5" + "@inquirer/core": "npm:^11.1.9" + "@inquirer/figures": "npm:^2.0.5" + "@inquirer/type": "npm:^4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/30b6b061acd08f3f4cfde08a626446d308271e32569acec03f8c87a17e04c21aeccbecf354c8b254a2decfbe7d2189d8ae4443bf10d0be4a2aedeb4e850574c2 + languageName: node + linkType: hard + +"@inquirer/type@npm:^4.0.5": + version: 4.0.5 + resolution: "@inquirer/type@npm:4.0.5" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/390edb0fd1f027f9c8dc26bac28486d38bbde6c19974ef1588ea187f54a2cb58db639ebca31fa81a8fe4a4e84c2f0953ab3f5a6768ba86649368c5e806148a6f + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -713,9 +1172,12 @@ __metadata: version: 0.0.0-use.local resolution: "@sigmacomputing/plugin@workspace:." dependencies: + "@actions/core": "npm:^3.0.1" "@arethetypeswrong/core": "npm:^0.18.2" + "@inquirer/prompts": "npm:^8.4.2" "@types/node": "npm:^24.0.0" "@types/react": "npm:^19.0.0" + "@types/semver": "npm:^7.7.1" "@vitest/browser-playwright": "npm:^4.1.5" lint-staged: "npm:^16.4.0" oxfmt: "npm:^0.38.0" @@ -723,7 +1185,9 @@ __metadata: oxlint-tsgolint: "npm:^0.16.0" playwright: "npm:^1.49.0" publint: "npm:^0.3.18" + semver: "npm:^7.7.4" tsdown: "npm:^0.21.10" + tsx: "npm:^4.21.0" typescript: "npm:^6.0.2" unplugin-unused: "npm:^0.5.7" vitest: "npm:^4.1.5" @@ -800,6 +1264,13 @@ __metadata: languageName: node linkType: hard +"@types/semver@npm:^7.7.1": + version: 7.7.1 + resolution: "@types/semver@npm:7.7.1" + checksum: 10c0/c938aef3bf79a73f0f3f6037c16e2e759ff40c54122ddf0b2583703393d8d3127130823facb880e694caa324eb6845628186aac1997ee8b31dc2d18fafe26268 + languageName: node + linkType: hard + "@vitest/browser-playwright@npm:^4.1.5": version: 4.1.5 resolution: "@vitest/browser-playwright@npm:4.1.5" @@ -1078,6 +1549,13 @@ __metadata: languageName: node linkType: hard +"chardet@npm:^2.1.1": + version: 2.1.1 + resolution: "chardet@npm:2.1.1" + checksum: 10c0/d8391dd412338442b3de0d3a488aa9327f8bcf74b62b8723d6bd0b85c4084d50b731320e0a7c710edb1d44de75969995d2784b80e4c13b004a6c7a0db4c6e793 + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -1118,6 +1596,13 @@ __metadata: languageName: node linkType: hard +"cli-width@npm:^4.1.0": + version: 4.1.0 + resolution: "cli-width@npm:4.1.0" + checksum: 10c0/1fbd56413578f6117abcaf858903ba1f4ad78370a4032f916745fa2c7e390183a9d9029cf837df320b0fdce8137668e522f60a30a5f3d6529ff3872d265a955f + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -1283,6 +1768,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:~0.27.0": + version: 0.27.7 + resolution: "esbuild@npm:0.27.7" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.7" + "@esbuild/android-arm": "npm:0.27.7" + "@esbuild/android-arm64": "npm:0.27.7" + "@esbuild/android-x64": "npm:0.27.7" + "@esbuild/darwin-arm64": "npm:0.27.7" + "@esbuild/darwin-x64": "npm:0.27.7" + "@esbuild/freebsd-arm64": "npm:0.27.7" + "@esbuild/freebsd-x64": "npm:0.27.7" + "@esbuild/linux-arm": "npm:0.27.7" + "@esbuild/linux-arm64": "npm:0.27.7" + "@esbuild/linux-ia32": "npm:0.27.7" + "@esbuild/linux-loong64": "npm:0.27.7" + "@esbuild/linux-mips64el": "npm:0.27.7" + "@esbuild/linux-ppc64": "npm:0.27.7" + "@esbuild/linux-riscv64": "npm:0.27.7" + "@esbuild/linux-s390x": "npm:0.27.7" + "@esbuild/linux-x64": "npm:0.27.7" + "@esbuild/netbsd-arm64": "npm:0.27.7" + "@esbuild/netbsd-x64": "npm:0.27.7" + "@esbuild/openbsd-arm64": "npm:0.27.7" + "@esbuild/openbsd-x64": "npm:0.27.7" + "@esbuild/openharmony-arm64": "npm:0.27.7" + "@esbuild/sunos-x64": "npm:0.27.7" + "@esbuild/win32-arm64": "npm:0.27.7" + "@esbuild/win32-ia32": "npm:0.27.7" + "@esbuild/win32-x64": "npm:0.27.7" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/ccd51f0555708bc9ff4ec9dc3ac92d3daacd45ecaac949ca8645984c5c323bf8cefe98c2df307418685e0b4ce37f9a3bdbfe8e3651fe632a0059a436195a17d4 + languageName: node + linkType: hard + "escape-string-regexp@npm:^5.0.0": version: 5.0.0 resolution: "escape-string-regexp@npm:5.0.0" @@ -1320,6 +1894,31 @@ __metadata: languageName: node linkType: hard +"fast-string-truncated-width@npm:^3.0.2": + version: 3.0.3 + resolution: "fast-string-truncated-width@npm:3.0.3" + checksum: 10c0/043b8663397d14a3880ce4f3407bcda60b40db9bbeafe62863a35d1f9c69ea17c8da3fcd72de235553e6c9cd053128cde9e24ca0d4a7463208f48db3cd23d981 + languageName: node + linkType: hard + +"fast-string-width@npm:^3.0.2": + version: 3.0.2 + resolution: "fast-string-width@npm:3.0.2" + dependencies: + fast-string-truncated-width: "npm:^3.0.2" + checksum: 10c0/c8822d175315bb353ebe782b65214ac53b13e3bf704e03b132ea7bdfa8de6a636375b3ab7a4097545393d109381c37c4f387c72a462c90b61412dbc4632f39a7 + languageName: node + linkType: hard + +"fast-wrap-ansi@npm:^0.2.0": + version: 0.2.0 + resolution: "fast-wrap-ansi@npm:0.2.0" + dependencies: + fast-string-width: "npm:^3.0.2" + checksum: 10c0/c0eb6debee565c5dbb9132dddff5c4d4aba5eb02185ae4dab285acd6186018cffca04264e92f373cbf592a9bcd1c33d65dba036030a8f3baeff1169969a1b59b + languageName: node + linkType: hard + "fdir@npm:^6.5.0": version: 6.5.0 resolution: "fdir@npm:6.5.0" @@ -1412,7 +2011,7 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.13.7": +"get-tsconfig@npm:^4.13.7, get-tsconfig@npm:^4.7.5": version: 4.14.0 resolution: "get-tsconfig@npm:4.14.0" dependencies: @@ -1487,6 +2086,15 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:^0.7.2": + version: 0.7.2 + resolution: "iconv-lite@npm:0.7.2" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/3c228920f3bd307f56bf8363706a776f4a060eb042f131cd23855ceca962951b264d0997ab38a1ad340e1c5df8499ed26e1f4f0db6b2a2ad9befaff22f14b722 + languageName: node + linkType: hard + "import-without-cache@npm:^0.3.3": version: 0.3.3 resolution: "import-without-cache@npm:0.3.3" @@ -1927,6 +2535,13 @@ __metadata: languageName: node linkType: hard +"mute-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "mute-stream@npm:3.0.0" + checksum: 10c0/12cdb36a101694c7a6b296632e6d93a30b74401873cf7507c88861441a090c71c77a58f213acadad03bc0c8fa186639dec99d68a14497773a8744320c136e701 + languageName: node + linkType: hard + "nanoid@npm:^3.3.11": version: 3.3.12 resolution: "nanoid@npm:3.3.12" @@ -2792,6 +3407,29 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.21.0": + version: 4.21.0 + resolution: "tsx@npm:4.21.0" + dependencies: + esbuild: "npm:~0.27.0" + fsevents: "npm:~2.3.3" + get-tsconfig: "npm:^4.7.5" + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 10c0/f5072923cd8459a1f9a26df87823a2ab5754641739d69df2a20b415f61814322b751fa6be85db7c6ec73cf68ba8fac2fd1cfc76bdb0aa86ded984d84d5d2126b + languageName: node + linkType: hard + +"tunnel@npm:^0.0.6": + version: 0.0.6 + resolution: "tunnel@npm:0.0.6" + checksum: 10c0/e27e7e896f2426c1c747325b5f54efebc1a004647d853fad892b46d64e37591ccd0b97439470795e5262b5c0748d22beb4489a04a0a448029636670bfd801b75 + languageName: node + linkType: hard + "typescript@npm:5.6.1-rc": version: 5.6.1-rc resolution: "typescript@npm:5.6.1-rc" @@ -2849,6 +3487,13 @@ __metadata: languageName: node linkType: hard +"undici@npm:^6.23.0": + version: 6.25.0 + resolution: "undici@npm:6.25.0" + checksum: 10c0/2597cc6689bdb02c210c557b1f85febbfda65becae6e6fc1061508e2f33734d25207f81cd8af56ada9956329eb3a7bd7431e87dcfeceba20ee87059b57dcf985 + languageName: node + linkType: hard + "unique-filename@npm:^3.0.0": version: 3.0.0 resolution: "unique-filename@npm:3.0.0"