diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..e6a2595 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @bounded-systems/maintainers diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e1dce9c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: ci + +# Quality gate: build, test, and a JSR publish dry-run on every PR and push to +# main. Trust is mechanical — the publish path is validated before a release tag +# is ever cut. + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + build-test: + runs-on: ubuntu-latest + steps: + - name: Harden runner + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: 1.3.14 + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Build (tsc) + run: bun run build + + - name: Test + run: bun test + + - name: JSR publish dry-run + run: bunx jsr publish --dry-run --allow-slow-types diff --git a/.github/workflows/publish-jsr.yml b/.github/workflows/publish-jsr.yml new file mode 100644 index 0000000..4839e12 --- /dev/null +++ b/.github/workflows/publish-jsr.yml @@ -0,0 +1,46 @@ +name: publish-jsr + +# Publish @bounded-systems/verbspec to JSR (https://jsr.io) via tokenless OIDC. +# JSR exchanges the GitHub OIDC token (id-token: write) for publish rights, +# verified against the package's linked GitHub repo (bounded-systems/verbspec) — +# no token or secret. +# +# Trigger: push a release tag `v` (matching package.json/jsr.json), or +# run manually via workflow_dispatch. +# +# JSR publishes the TypeScript source directly (no dist build). --allow-slow-types +# keeps parity with the monorepo: a package without explicit public-API types +# still publishes (lower JSR score, not a hard block). + +on: + workflow_dispatch: + push: + tags: + - "v*" + +permissions: + contents: read + id-token: write # tokenless JSR publish (OIDC) + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Harden runner + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + - name: Setup Bun + uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0 + with: + bun-version: 1.3.14 + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Publish to JSR + run: bunx jsr publish --allow-slow-types diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f4e2c6d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +*.tsbuildinfo diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..f9e9203 --- /dev/null +++ b/bun.lock @@ -0,0 +1,30 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "@bounded-systems/verbspec", + "devDependencies": { + "@types/bun": "^1.3.14", + "typescript": "^6.0.3", + "zod": "^4.4.3", + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0", + }, + }, + }, + "packages": { + "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], + + "@types/node": ["@types/node@26.0.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA=="], + + "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], + + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], + + "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + } +} diff --git a/package.json b/package.json index e43e3e7..8829151 100644 --- a/package.json +++ b/package.json @@ -51,5 +51,10 @@ }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" + }, + "devDependencies": { + "@types/bun": "^1.3.14", + "typescript": "^6.0.3", + "zod": "^4.4.3" } } diff --git a/tsconfig.build.json b/tsconfig.build.json index 4157bca..a0982da 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.json", + "extends": "./tsconfig.json", "compilerOptions": { "noEmit": false, "module": "NodeNext", @@ -12,5 +12,5 @@ "rootDir": "./src" }, "include": ["src/**/*.ts"], - "exclude": ["src/**/__tests__/**"] + "exclude": ["src/**/__tests__/**", "**/*.test.ts"] } diff --git a/tsconfig.json b/tsconfig.json index a5cb75c..cf52b33 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,18 @@ { - "extends": "../../tsconfig.json", + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "exactOptionalPropertyTypes": true, + "noUncheckedIndexedAccess": true, + "noEmit": true, + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "verbatimModuleSyntax": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "types": ["bun"] + }, "include": ["src/**/*.ts"] }