diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..ef3543c --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,4 @@ +# Release notes + +See [CONTRIBUTING.md](../CONTRIBUTING.md#releases) for contributing release +notes and preparing a release. diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..4b3a691 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@4.0.1/schema.json", + "baseBranch": "main", + "access": "public", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/lint-workflows.yml b/.github/workflows/lint-workflows.yml index 1065900..9c1cc49 100644 --- a/.github/workflows/lint-workflows.yml +++ b/.github/workflows/lint-workflows.yml @@ -25,10 +25,10 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 5 steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - uses: raven-actions/actionlint@205b530c5d9fa8f44ae9ed59f341a0db994aa6f8 # v2.1.2 + - uses: kjanat/actionlint@08bb2c4f0d039744455b87aef1c647fb8b66d37b # v1.17.0 zizmor: name: zizmor @@ -37,7 +37,7 @@ jobs: permissions: security-events: write steps: - - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 + - uses: zizmorcore/zizmor-action@53290badfa369cb0bf7ad16342cb62c2fa47ac7b # v0.8.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..cb737e7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,222 @@ +name: Release + +on: + push: + branches: [main] + workflow_dispatch: + inputs: + commit: + description: + "Optional 40-character version-bump commit SHA reachable from the + selected ref" + required: false + type: string + +concurrency: + group: ${{ github.workflow }} + queue: max + cancel-in-progress: false + +permissions: {} + +env: + NODE_VERSION: "24.22.1" + +jobs: + plan: + if: github.repository_owner == 'convex' + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + outputs: + sha: ${{ steps.select.outputs.sha }} + name: ${{ steps.select.outputs.name }} + version: ${{ steps.select.outputs.version }} + channel: ${{ steps.select.outputs.channel }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: ${{ env.NODE_VERSION }} + package-manager-cache: false + - id: select + name: Select the latest version-bump commit + env: + RELEASE_COMMIT: ${{ inputs.commit }} + run: | + if [[ "$GITHUB_EVENT_NAME" == workflow_dispatch ]]; then + source="${RELEASE_COMMIT:-$GITHUB_SHA}" + [[ "$source" =~ ^[0-9a-f]{40}$ ]] || { echo 'Expected a 40-character commit SHA' >&2; exit 1; } + git merge-base --is-ancestor "$source" "$GITHUB_SHA" + else + before=$(jq -r .before "$GITHUB_EVENT_PATH") + source='' + candidates=$(git rev-list --first-parent "$before..$GITHUB_SHA" -- package.json) + while read -r candidate && [[ -n "$candidate" ]]; do + current=$(git show "$candidate:package.json" | jq -r .version) + previous=$(git show "$candidate^1:package.json" | jq -r .version) + if [[ "$current" != "$previous" ]]; then source="$candidate"; break; fi + done <<< "$candidates" + if [[ -z "$source" ]]; then echo 'No version bump'; exit 0; fi + fi + name=$(git show "$source:package.json" | jq -r .name) + VERSION=$(git show "$source:package.json" | jq -r .version) + PREVIOUS_VERSION=$(git show "$source^1:package.json" | jq -r .version) + export VERSION PREVIOUS_VERSION + node --input-type=module <<'NODE' + import { execFileSync } from 'node:child_process'; + import { appendFileSync } from 'node:fs'; + import { createRequire } from 'node:module'; + // Use the standard SemVer library bundled with the pinned npm. + const npmRoot = execFileSync('npm', ['root', '-g'], { encoding: 'utf8' }).trim(); + const semver = createRequire(`${npmRoot}/npm/package.json`)('semver'); + const { VERSION: version, PREVIOUS_VERSION: previous, GITHUB_REF: ref } = process.env; + if (semver.valid(version) !== version || !semver.gt(version, previous)) throw new Error('Selected commit must increase the package version'); + const pre = semver.prerelease(version); + const channel = pre ? String(pre[0]) : 'latest'; + if (pre && (!/^[a-z][a-z0-9-]*$/.test(channel) || channel === 'latest' || semver.validRange(channel))) throw new Error('Invalid prerelease channel'); + if (!pre && ref !== 'refs/heads/main') throw new Error('Stable releases require main'); + appendFileSync(process.env.GITHUB_OUTPUT, `channel=${channel}\n`); + NODE + tag="v$VERSION" + if git show-ref --verify --quiet "refs/tags/$tag"; then + [[ "$(git rev-parse "$tag^{commit}")" == "$source" ]] || { echo "$tag points elsewhere" >&2; exit 1; } + if [[ "$GITHUB_EVENT_NAME" != workflow_dispatch ]]; then + echo "$tag was already staged; skipping automatic release" + exit 0 + fi + fi + { + echo "sha=$source" + echo "name=$name" + echo "version=$VERSION" + } >> "$GITHUB_OUTPUT" + + build: + needs: plan + if: needs.plan.outputs.sha != '' + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + outputs: + artifact_id: ${{ steps.upload.outputs.artifact-id }} + sha256: ${{ steps.digest.outputs.sha256 }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ needs.plan.outputs.sha }} + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: ${{ env.NODE_VERSION }} + package-manager-cache: false + - run: npm ci + - name: Validate release notes + run: | + # Compare against this checkout while reading all notes, including prerelease state. + git update-ref refs/heads/main HEAD + npx changeset status --output "$RUNNER_TEMP/changesets.json" + jq -e '.changesets | length == 0' "$RUNNER_TEMP/changesets.json" + version=$(jq -r .version package.json) + awk -v version="$version" '/^## / { active=($0 == "## " version); next } active && !/^#/ && /[[:alnum:]]/ { found=1 } END { exit !found }' CHANGELOG.md + - run: npm run build + - run: npm run check + - name: Run E2E tests and verify generated code + env: + CONVEX_AGENT_MODE: anonymous + CONVEX_DISABLE_TELEMETRY: "1" + run: | + npm run test:e2e + git diff --exit-code -- src/component/_generated example/convex/_generated + test -z "$(git ls-files --others --exclude-standard src/component/_generated example/convex/_generated)" + - name: Pack the tested package + run: | + mkdir -p "$RUNNER_TEMP/npm-release" + npm pack --ignore-scripts --pack-destination "$RUNNER_TEMP/npm-release" + - id: digest + run: + echo "sha256=$(sha256sum "$RUNNER_TEMP"/npm-release/*.tgz | cut -d ' ' + -f 1)" >> "$GITHUB_OUTPUT" + - id: upload + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 + with: + name: npm-release-${{ needs.plan.outputs.sha }} + path: ${{ runner.temp }}/npm-release/*.tgz + if-no-files-found: error + + stage: + needs: [plan, build] + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + id-token: write + steps: + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: ${{ env.NODE_VERSION }} + package-manager-cache: false + - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8 + with: + artifact-ids: ${{ needs.build.outputs.artifact_id }} + path: ${{ runner.temp }}/npm-release + merge-multiple: true + - name: Stage the tested artifact + env: + SOURCE_SHA: ${{ needs.plan.outputs.sha }} + PACKAGE_NAME: ${{ needs.plan.outputs.name }} + VERSION: ${{ needs.plan.outputs.version }} + CHANNEL: ${{ needs.plan.outputs.channel }} + EXPECTED_SHA256: ${{ needs.build.outputs.sha256 }} + run: | + set -o pipefail + set -- "$RUNNER_TEMP"/npm-release/*.tgz + test "$#" -eq 1 + TARBALL="$1" + echo "$EXPECTED_SHA256 $TARBALL" | sha256sum -c - + { + echo "$PACKAGE_NAME@$VERSION — source $SOURCE_SHA — npm channel $CHANNEL" + echo "Review on npm's Staged Packages page, then approve with 2FA or npm stage approve ." + } >> "$GITHUB_STEP_SUMMARY" + # npm reads GITHUB_SHA for provenance; checkout alone does not change it. + GITHUB_SHA="$SOURCE_SHA" npm stage publish "$TARBALL" \ + --ignore-scripts --provenance --access public --tag "$CHANNEL" \ + 2>&1 | tee "$RUNNER_TEMP/npm-stage.log" + - name: Preserve staging output and stage ID + if: always() + run: | + if test -f "$RUNNER_TEMP/npm-stage.log"; then + cat "$RUNNER_TEMP/npm-stage.log" >> "$GITHUB_STEP_SUMMARY" + fi + + tag: + needs: [plan, stage] + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + ref: ${{ needs.plan.outputs.sha }} + fetch-depth: 0 + persist-credentials: false + - name: Tag the staged source + env: + GH_TOKEN: ${{ github.token }} + SOURCE_SHA: ${{ needs.plan.outputs.sha }} + VERSION: ${{ needs.plan.outputs.version }} + run: | + tag="v$VERSION" + if git show-ref --verify --quiet "refs/tags/$tag"; then + test "$(git rev-parse "$tag^{commit}")" = "$SOURCE_SHA" + else + git tag "$tag" "$SOURCE_SHA" + gh auth setup-git + git push origin "refs/tags/$tag" + fi diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9a2817a..9b5b09d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,6 +4,7 @@ concurrency: cancel-in-progress: true on: + workflow_dispatch: push: branches: [main] pull_request: @@ -16,29 +17,35 @@ jobs: name: Test and lint runs-on: ubuntu-latest timeout-minutes: 30 + permissions: + contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: + fetch-depth: 0 persist-credentials: false - name: Node setup - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 with: cache-dependency-path: package.json - node-version: "20.x" + node-version: "24.22.1" cache: "npm" - name: Install and build run: | - npm i + npm ci npm run build - - name: Publish package for testing branch - run: - npx pkg-pr-new publish || echo "Have you set up pkg-pr-new for this - repo?" - name: Test + run: npm run check + - name: Run E2E smoke test and verify generated code + env: + CONVEX_AGENT_MODE: anonymous + CONVEX_DISABLE_TELEMETRY: "1" run: | - npm run test - npm run typecheck - npm run lint + npm run test:e2e + git diff --exit-code -- src/component/_generated example/convex/_generated + test -z "$(git ls-files --others --exclude-standard src/component/_generated example/convex/_generated)" + - name: Publish package for testing branch + run: npx pkg-pr-new publish || echo "pkg-pr-new failed" diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml new file mode 100644 index 0000000..11448c7 --- /dev/null +++ b/.github/workflows/version.yml @@ -0,0 +1,59 @@ +name: Update release PR + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: {} + +jobs: + version: + name: Update release PR + if: github.repository_owner == 'convex' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.sha }} + fetch-depth: 0 + persist-credentials: false + - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: "24.22.1" + package-manager-cache: false + - run: npm ci --ignore-scripts + - name: Check whether a version PR is needed + id: mode + uses: changesets/action/select-mode@ae32849d5ba541f9ae29e40e22a623bc13562f51 # v2.1.2 + - name: Check main is still at this run's commit + if: steps.mode.outputs.mode == 'version' + id: freshness + env: + GH_TOKEN: ${{ github.token }} + run: | + main_sha="$(gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/main" --jq '.object.sha')" + if [[ "$main_sha" == "$GITHUB_SHA" ]]; then + echo "current=true" >> "$GITHUB_OUTPUT" + else + echo "current=false" >> "$GITHUB_OUTPUT" + echo "Skipping release PR update: main has moved beyond this run's commit." + fi + - name: Create or update the release PR + if: + steps.mode.outputs.mode == 'version' && + steps.freshness.outputs.current == 'true' + uses: changesets/action/version@ae32849d5ba541f9ae29e40e22a623bc13562f51 # v2.1.2 + with: + github-token: ${{ github.token }} + pr-title: "Prepare next release" + commit-message: "Version packages" + pr-base-branch: main diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b59c18f..f4042cd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,38 +3,85 @@ ## Running locally ```sh -npm i +npm ci npm run dev ``` ## Testing ```sh -npm run clean npm run build -npm run typecheck -npm run lint -npm run test +npm run check +npm run test:e2e +``` + +When component APIs change, regenerate and commit the generated files: + +```sh +npm run build:codegen ``` -## Deploying +## Releases -### Building a one-off package +Include a changeset with changes that need a release: ```sh -npm run clean -npm ci -npm pack +npx changeset ``` -### Deploying a new version +Choose the version bump, describe the user-visible change, and commit the +generated file with your implementation. Docs-only and development-tooling +changes do not need a changeset. + +Review and merge the release PR when ready. A PR opened by the Changesets +workflow may have no automatic checks. Run +[Test and lint](./.github/workflows/test.yml) on its `changeset-release/main` +branch and wait for the required check to pass. To refresh the release PR, run +[Update release PR](./.github/workflows/version.yml) on main. + +After staging, review the package on npm's **Staged Packages** page and approve +with 2FA, or run: ```sh -npm run release +npm stage approve ``` -or for alpha release: +Use the stage ID from the workflow log. Approve versions in order to avoid +moving `latest` backward. + +### Local preparation and prereleases + +To prepare a release locally instead of using the bot: ```sh -npm run alpha +npm ci +npm run build +npm run check +npx changeset version ``` + +Review and commit the version, changelog, and consumed changesets, then merge +through a checked PR. A push to main stages the latest version-bump commit in +that push. + +For a branch prerelease, prepare a prerelease version with Changesets and +dispatch **Release** from the Actions page on that branch. The first prerelease +identifier selects the npm channel, such as `alpha`. Stable releases require +main. + +### Recovery + +If staging has not been attempted, dispatch **Release** on the appropriate ref +with the 40-character SHA of a version-bump commit reachable from that ref. Once +staging starts, inspect npm before retrying: dispatching **Release** runs +`npm stage publish` again. If the package is already staged, retry only the +failed tag job or, after verifying the staged version, create its source tag at +the version-bump commit. + +| Failure | Recovery | +| ----------------------------------------------- | -------------------------------------------------------------------------------- | +| Failure before staging was attempted | Retry failed jobs for the same commit. | +| Staging succeeded; tagging failed | Retry only the failed tag job, or create the source tag after verifying staging. | +| Upload outcome uncertain | Inspect npm; retry staging only if absent, or recover the tag if already staged. | +| Fix requires changing the release commit's code | Prepare a new version-bump commit. | +| Candidate rejected after staging | Leave its tag and prepare a new version. | diff --git a/example/convex/_generated/dataModel.d.ts b/example/convex/_generated/dataModel.d.ts index 8541f31..f97fd19 100644 --- a/example/convex/_generated/dataModel.d.ts +++ b/example/convex/_generated/dataModel.d.ts @@ -38,7 +38,7 @@ export type Doc = DocumentByName< * Convex documents are uniquely identified by their `Id`, which is accessible * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). * - * Documents can be loaded using `db.get(id)` in query and mutation functions. + * Documents can be loaded using `db.get(tableName, id)` in query and mutation functions. * * IDs are just strings at runtime, but this type can be used to distinguish them from other * strings when type checking. diff --git a/example/convex/_generated/server.d.ts b/example/convex/_generated/server.d.ts index bec05e6..f235db4 100644 --- a/example/convex/_generated/server.d.ts +++ b/example/convex/_generated/server.d.ts @@ -21,6 +21,17 @@ import { } from "convex/server"; import type { DataModel } from "./dataModel.js"; +/** + * Typesafe environment variables. + * + * This includes platform-provided env vars and any variables declared in + * `convex.config.ts`. + */ +type Env = { + readonly CONVEX_CLOUD_URL: string; + readonly CONVEX_SITE_URL: string; +}; + /** * Define a query in this Convex app's public API. * @@ -95,6 +106,14 @@ export declare const internalAction: ActionBuilder; */ export declare const httpAction: HttpActionBuilder; +/** + * Typesafe environment variables. + * + * This includes platform-provided env vars and any variables declared in + * `convex.config.ts`. + */ +export declare const env: Env; + /** * A set of services for use within Convex query functions. * diff --git a/example/convex/_generated/server.js b/example/convex/_generated/server.js index bf3d25a..2dbe0db 100644 --- a/example/convex/_generated/server.js +++ b/example/convex/_generated/server.js @@ -91,3 +91,11 @@ export const internalAction = internalActionGeneric; * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. */ export const httpAction = httpActionGeneric; + +/** + * Typesafe environment variables. + * + * This includes platform-provided env vars and any variables declared in + * `convex.config.ts`. + */ +export const env = process.env; diff --git a/package-lock.json b/package-lock.json index 3a72150..05f12e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "lodash-es": "^4.17.21" }, "devDependencies": { + "@changesets/cli": "3.0.3", "@convex-dev/eslint-plugin": "^5.0.0", "@edge-runtime/vm": "5.0.0", "@eslint/js": "^9.9.1", @@ -386,6 +387,345 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@changesets/apply-release-plan": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-8.1.1.tgz", + "integrity": "sha512-nk2Hbq3M9NeHMdaIRBDvawKrQJzXB9sGyBUE5yWnIKtvdcNCPj75zBekJYr0gTT2ecJH3eFeTrc8eisPImcv0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/config": "^4.0.1", + "@changesets/format": "^0.1.2", + "@changesets/git": "^4.0.1", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "import-meta-resolve": "^4.2.0", + "jsonc-parser": "^3.3.1", + "semver": "^7.8.1" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-7.0.0.tgz", + "integrity": "sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^1.0.0", + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "semver": "^7.8.1" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-1.0.0.tgz", + "integrity": "sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/cli": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-3.0.3.tgz", + "integrity": "sha512-L1i67bMfkK6iC/kDejuNO4pFgTRcWIObsD6Qof2woP1I4M8tj17DGlcpRaTzTv1DYSP5EMwWdEtR8X0Pj5Jg3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/apply-release-plan": "^8.1.1", + "@changesets/assemble-release-plan": "^7.0.0", + "@changesets/changelog-git": "^1.0.0", + "@changesets/config": "^4.0.1", + "@changesets/errors": "^1.0.0", + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/git": "^4.0.1", + "@changesets/pre": "^3.0.0", + "@changesets/read": "^1.0.1", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "@changesets/write": "^1.0.1", + "@clack/prompts": "^1.7.0", + "@manypkg/get-packages": "^3.1.0", + "@pnpm/deps.graph-sequencer": "^1100.0.1", + "cac": "^7.0.0", + "import-meta-resolve": "^4.2.0", + "launch-editor": "^2.14.1", + "package-manager-detector": "^1.6.0", + "semver": "^7.8.1", + "tinyexec": "^1.3.1" + }, + "bin": { + "changeset": "bin.js" + }, + "engines": { + "node": "^22.11 || ^24 || >=26", + "npm": ">=10.9.0", + "pnpm": ">=10.0.0", + "yarn": ">=4.5.2" + } + }, + "node_modules/@changesets/cli/node_modules/cac": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cac/-/cac-7.1.0.tgz", + "integrity": "sha512-LMDU/U2yA4IPIY8KT0NsNPWEYZvAMkbgyspxJ6btJaYV+WMDOHAZCmB0lsTObiHaRS1V/ztKAl7+TSkTqXyeoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@changesets/cli/node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@changesets/config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-4.0.1.tgz", + "integrity": "sha512-PxpxSQLQSLDjceAgRq+4FWlU+HflDIw03mmPVipxoQx9xrXFUjmqTy3SE+n/2t+DqPdpPiLWVr5NRiLZvjyLwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/get-dependents-graph": "^3.0.0", + "@changesets/should-skip-package": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0", + "picomatch": "^4.0.7" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/config/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@changesets/errors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-1.0.0.tgz", + "integrity": "sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/format": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@changesets/format/-/format-0.1.3.tgz", + "integrity": "sha512-zTZrJbfY81+/MsXsey6i3jQjpApz4PqRQ+nouHGDJhCa5sKCExwR9mZFQ/67lMsqZDNy2G2v3wTbzOmZ56EtaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.8.0", + "tinyexec": "^1.3.1" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/format/node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-3.0.0.tgz", + "integrity": "sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0", + "semver": "^7.8.1" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/git": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-4.0.1.tgz", + "integrity": "sha512-6vWpIAC4LkpmlqaIu37ViT5enyd9+uBwAiGqCGhASvkSHBgx4PrtTGXWTMFYpDmZbjgyonyVgMciPrW4MqtJsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0", + "picomatch": "^4.0.4", + "tinyexec": "^1.3.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/git/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@changesets/git/node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@changesets/parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-1.0.0.tgz", + "integrity": "sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0", + "yaml": "^2.9.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/pre": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-3.0.0.tgz", + "integrity": "sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/errors": "^1.0.0", + "@changesets/types": "^7.0.0", + "@manypkg/get-packages": "^3.1.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/read": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-1.0.1.tgz", + "integrity": "sha512-nzvSC6RcTiWf/dsuwZFXpLzGGsRHYCL68U3uHV7srsulU93aVWY7u2GEJiDZ+4GIIElfaW5EqtKC0UHroY+LTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/git": "^4.0.1", + "@changesets/parse": "^1.0.0", + "@changesets/types": "^7.0.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-1.0.0.tgz", + "integrity": "sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/types": "^7.0.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/types": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-7.0.0.tgz", + "integrity": "sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@changesets/write": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-1.0.1.tgz", + "integrity": "sha512-q/ThtP9gcnEP6xlv7LrY26C2mHqdGBti/MmOVngt/M/oIGYkssmQGxPK9WzBNt2juVcH/vml2WQ+ra8LXYOTaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@changesets/format": "^0.1.1", + "@changesets/types": "^7.0.0", + "human-id": "^4.2.0" + }, + "engines": { + "node": "^22.11 || ^24 || >=26" + } + }, + "node_modules/@clack/core": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.1.tgz", + "integrity": "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, + "node_modules/@clack/prompts": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.1.tgz", + "integrity": "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@clack/core": "1.5.1", + "fast-string-width": "^3.0.2", + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, "node_modules/@convex-dev/eslint-plugin": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@convex-dev/eslint-plugin/-/eslint-plugin-5.0.0.tgz", @@ -1501,6 +1841,48 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/@manypkg/find-root": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-3.1.0.tgz", + "integrity": "sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@manypkg/tools": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-3.1.0.tgz", + "integrity": "sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@manypkg/find-root": "^3.1.0", + "@manypkg/tools": "^2.1.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@manypkg/tools": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@manypkg/tools/-/tools-2.1.2.tgz", + "integrity": "sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jju": "^1.4.0", + "tinyglobby": "^0.2.13", + "yaml": "^2.9.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1547,6 +1929,19 @@ "node": ">=14" } }, + "node_modules/@pnpm/deps.graph-sequencer": { + "version": "1100.0.1", + "resolved": "https://registry.npmjs.org/@pnpm/deps.graph-sequencer/-/deps.graph-sequencer-1100.0.1.tgz", + "integrity": "sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.13" + }, + "funding": { + "url": "https://opencollective.com/pnpm" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.43", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz", @@ -4056,6 +4451,33 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", + "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -4262,6 +4684,16 @@ "dev": true, "license": "MIT" }, + "node_modules/human-id": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.2.2.tgz", + "integrity": "sha512-Z+8unD6em/MJwyrkWQ2M3wygRGI1+MztbutiNwk1DCuEPXOZRWGjtcMPZYP1exY9iNZMhd7ZOSMQSo9WYtiQRw==", + "dev": true, + "license": "MIT", + "bin": { + "human-id": "dist/cli.js" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -4288,6 +4720,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4426,6 +4869,13 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4484,6 +4934,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -4493,6 +4950,17 @@ "json-buffer": "3.0.1" } }, + "node_modules/launch-editor": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.2.tgz", + "integrity": "sha512-NHJEb30MGBCkmZXLZwz25t37QR4aY03ZzPYUJXOJaOa92uWwExI9SBQUuIznBYc1xkD7cJNGX7oc3Nl3sq2kQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.1", + "shell-quote": "^1.10.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -4843,6 +5311,13 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/package-manager-detector": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.9.0.tgz", + "integrity": "sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==", + "dev": true, + "license": "MIT" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5218,9 +5693,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", - "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.6.tgz", + "integrity": "sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==", "dev": true, "license": "ISC", "bin": { @@ -5291,6 +5766,13 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -7136,6 +7618,22 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz", + "integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", diff --git a/package.json b/package.json index fd06cd5..73c9045 100644 --- a/package.json +++ b/package.json @@ -22,18 +22,17 @@ "dev:build": "chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial", "predev": "convex init && npm run build:codegen", "build": "tsc --project ./tsconfig.build.json && ./scripts/replace-version.sh .", + "prepack": "npm run build", "build:codegen": "npx convex codegen --component-dir ./src/component && npm run build", "build:clean": "rm -rf dist *.tsbuildinfo && npm run build:codegen", "typecheck": "tsc --noEmit && tsc -p example && tsc -p example/convex", "lint": "eslint .", "test": "vitest run --typecheck", + "check": "npm run test && npm run typecheck && npm run lint", + "test:e2e": "convex dev --once --typecheck-components", "test:watch": "vitest --typecheck --clearScreen false", "test:debug": "vitest --inspect-brk --no-file-parallelism", - "test:coverage": "vitest run --coverage --coverage.reporter=text", - "preversion": "npm ci && npm run build:clean && npm run test && npm run lint && npm run typecheck", - "alpha": "npm version prerelease --preid alpha && npm publish --tag alpha && git push --follow-tags", - "release": "npm version patch && npm publish && git push --follow-tags && git push", - "version": "(npm whoami || npm login) && vim -c 'normal o' -c 'normal o## '$npm_package_version CHANGELOG.md && prettier -w CHANGELOG.md && git add CHANGELOG.md" + "test:coverage": "vitest run --coverage --coverage.reporter=text" }, "files": [ "dist", @@ -75,7 +74,8 @@ "typescript": "5.8.3", "typescript-eslint": "^8.4.0", "vite": "^7.1.12", - "vitest": "^2.1.1" + "vitest": "^2.1.1", + "@changesets/cli": "3.0.3" }, "exports": { "./package.json": "./package.json",