diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c32b64a..d2330cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,18 +46,30 @@ jobs: - run: yarn install - run: yarn typecheck - test: + test-matrix: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: [22, 24] steps: - uses: actions/checkout@v7 - run: corepack enable - uses: actions/setup-node@v6 with: - node-version-file: .node-version + node-version: ${{ matrix.node-version }} cache: yarn - run: yarn install - run: yarn test + test: + needs: test-matrix + if: always() + runs-on: ubuntu-latest + steps: + - if: needs.test-matrix.result != 'success' + run: exit 1 + build: runs-on: ubuntu-latest steps: diff --git a/CLAUDE.md b/CLAUDE.md index fd95661..177cbf6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ Dual-target ESM TypeScript library `@proof.com/proof-vc-common`. Browser entry e 2. **Prompt before publishing.** Never bump version, push tags, create a Release, or trigger the publish workflow without explicit confirmation. Publishes are permanent. 3. **Run `yarn check-all` before any commit or push.** Composes format, lint, typecheck, publint. 4. **Keep `yarn publint` on `--pack npm`.** `--pack auto` picks yarn-1 mode and reports false-positive errors. -5. **Don't lower `engines.node` below `>=24.0.0`.** Node 24 is the active LTS; older LTS lines (20, 22) are EOL or near it. `@sd-jwt/*` requires Node 20+. +5. **Keep `engines.node` at `>=22.0.0` and keep the CI `test-matrix` covering that floor.** Node 22 is the oldest maintained LTS (Node 20 is EOL; `@sd-jwt/*` needs 20+). `>=22` is a lower bound, so it still allows 24 and newer. The floor is checked at runtime by the `test-matrix` job (`yarn test` on Node 22 and 24); `@types/node` tracks the dev runtime (24, from `.node-version`), not the floor. Invariant: the `test-matrix` low entry must equal the `engines.node` floor, so raise the floor by bumping both together. If you drop the matrix, pin `@types/node` to the floor major so typecheck guards it instead. 6. **Never use `eslint-disable` as a workaround.** If a lint rule fires, fix the underlying code or surface the rule to the user for a config decision — do not silence it inline. Same applies to `@ts-ignore` / `@ts-expect-error` and other suppression comments. ## Browser Graph diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 806ac97..74e913a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ ## Requirements -- `node` >= 24.0.0 (active LTS) +- `node` >= 22.0.0 (minimum supported, the `engines.node` floor). Develop on Node 24 (active LTS), pinned in `.node-version`. - `yarn` 4 - run `corepack enable`; the version is pinned via `packageManager` in `package.json`. ## Design Principles @@ -34,6 +34,8 @@ To submit a pull request: - Include a clear title and description explaining what changed and why. - Keep changes focused, try to limit one issue or feature per PR. +CI runs `test` on a matrix of Node 22 (the `engines.node` floor) and Node 24 (active LTS). The other jobs run on Node 24 from `.node-version`. + ## Code of conduct This project follows the [Contributor Covenant Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). By participating, you are expected to uphold this standard. diff --git a/package.json b/package.json index d508e77..b4d2eb7 100644 --- a/package.json +++ b/package.json @@ -67,11 +67,11 @@ "prettier-plugin-packagejson": "^3.0.2", "publint": "^0.3.21", "typescript": "^6.0.3", - "typescript-eslint": "^8.61.1" + "typescript-eslint": "^8.62.0" }, "packageManager": "yarn@4.17.0", "engines": { - "node": ">=24.0.0" + "node": ">=22.0.0" }, "publishConfig": { "access": "public" diff --git a/yarn.lock b/yarn.lock index 499288a..5ec4038 100644 --- a/yarn.lock +++ b/yarn.lock @@ -149,7 +149,7 @@ __metadata: prettier-plugin-packagejson: "npm:^3.0.2" publint: "npm:^0.3.21" typescript: "npm:^6.0.3" - typescript-eslint: "npm:^8.61.1" + typescript-eslint: "npm:^8.62.0" languageName: unknown linkType: soft @@ -263,105 +263,105 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/eslint-plugin@npm:8.61.1" +"@typescript-eslint/eslint-plugin@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.62.0" dependencies: "@eslint-community/regexpp": "npm:^4.12.2" - "@typescript-eslint/scope-manager": "npm:8.61.1" - "@typescript-eslint/type-utils": "npm:8.61.1" - "@typescript-eslint/utils": "npm:8.61.1" - "@typescript-eslint/visitor-keys": "npm:8.61.1" + "@typescript-eslint/scope-manager": "npm:8.62.0" + "@typescript-eslint/type-utils": "npm:8.62.0" + "@typescript-eslint/utils": "npm:8.62.0" + "@typescript-eslint/visitor-keys": "npm:8.62.0" ignore: "npm:^7.0.5" natural-compare: "npm:^1.4.0" ts-api-utils: "npm:^2.5.0" peerDependencies: - "@typescript-eslint/parser": ^8.61.1 + "@typescript-eslint/parser": ^8.62.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/3cb445622907283fb23e78f8bde4d1b04cca96da181a0c549b2775954c5dfa59f20e34c27f73ae3e189420e36637f59145bd97ce45c55017a6c3ac1871197951 + checksum: 10c0/2f257bb53a3b9b8b6f56f6b85c68ce193c7ba4cddf7d2d1995b0aec0591230859f808b3a1a85f0b7ed581f938a88efeacccc730aec307e80e1c14fc669222f9a languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/parser@npm:8.61.1" +"@typescript-eslint/parser@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/parser@npm:8.62.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.61.1" - "@typescript-eslint/types": "npm:8.61.1" - "@typescript-eslint/typescript-estree": "npm:8.61.1" - "@typescript-eslint/visitor-keys": "npm:8.61.1" + "@typescript-eslint/scope-manager": "npm:8.62.0" + "@typescript-eslint/types": "npm:8.62.0" + "@typescript-eslint/typescript-estree": "npm:8.62.0" + "@typescript-eslint/visitor-keys": "npm:8.62.0" debug: "npm:^4.4.3" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/6515afed5df24fd56fd0c96f94b2fc951236fc805e5d5ec925cbcae1319e5a41caea44284cd35b21f5ce7b812e567185c9dfe0882607135b947895509f23b253 + checksum: 10c0/eab526557fb679c862a0462e841581e3ca24a88b8f19764630e7d10e01ba01143906100a051c8bede36e3c6eb6bef21c14ac7dccf9d41e04c84448c058450a94 languageName: node linkType: hard -"@typescript-eslint/project-service@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/project-service@npm:8.61.1" +"@typescript-eslint/project-service@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/project-service@npm:8.62.0" dependencies: - "@typescript-eslint/tsconfig-utils": "npm:^8.61.1" - "@typescript-eslint/types": "npm:^8.61.1" + "@typescript-eslint/tsconfig-utils": "npm:^8.62.0" + "@typescript-eslint/types": "npm:^8.62.0" debug: "npm:^4.4.3" peerDependencies: typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/4ced4f96cbe6b4b1f1f53d02e0e5d1efcb6ca02316d8ea11f9b328f7b3783a76e59b72ebbe233a00452de7466ac176f9836afe8a99c63acc94e8e2d1d31d370b + checksum: 10c0/4369e9ec0c8b2ce6e6cf90142ad781ef99b57350beb4ae48751871e8894e95a8f929de2f56d73849ec0166d2cdb345e3e7a42d30ea8463d3f1b65607648ac582 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/scope-manager@npm:8.61.1" +"@typescript-eslint/scope-manager@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/scope-manager@npm:8.62.0" dependencies: - "@typescript-eslint/types": "npm:8.61.1" - "@typescript-eslint/visitor-keys": "npm:8.61.1" - checksum: 10c0/8558b56629acc28da1b90a8254eaf9862a38bf49c0a04680c767ea542f49d683c8c60c43676e0348491d1eac9af25cc67abe0a1bb3cfe90add42523faf48b029 + "@typescript-eslint/types": "npm:8.62.0" + "@typescript-eslint/visitor-keys": "npm:8.62.0" + checksum: 10c0/1e7192b6bf18955ee76861321a92e08815f1bc3feab23861b6330dde8343dfb346a47c7c8bf3d94b0897a98184adcf283568b5857a0e5d509ce0c21c6cf4cc44 languageName: node linkType: hard -"@typescript-eslint/tsconfig-utils@npm:8.61.1, @typescript-eslint/tsconfig-utils@npm:^8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/tsconfig-utils@npm:8.61.1" +"@typescript-eslint/tsconfig-utils@npm:8.62.0, @typescript-eslint/tsconfig-utils@npm:^8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.62.0" peerDependencies: typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/ab732f3c329f0ee8ea9e7d6c7c7d91b508cc0cf6c48c17d95e5df348d3e475730bd7ce63ac1f90260c80a9339a8a6f2eec8f2a35e1793e956a447130291bb5e3 + checksum: 10c0/9423908009e95b8bba8ac2ad1e4bf4bc9dd7052fa44be613659f81aad363787bf7fa1ea017eb9dcb059fed41866bc2d8e50f1cf41c7dfad25a4431c333fbf2fa languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/type-utils@npm:8.61.1" +"@typescript-eslint/type-utils@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/type-utils@npm:8.62.0" dependencies: - "@typescript-eslint/types": "npm:8.61.1" - "@typescript-eslint/typescript-estree": "npm:8.61.1" - "@typescript-eslint/utils": "npm:8.61.1" + "@typescript-eslint/types": "npm:8.62.0" + "@typescript-eslint/typescript-estree": "npm:8.62.0" + "@typescript-eslint/utils": "npm:8.62.0" debug: "npm:^4.4.3" ts-api-utils: "npm:^2.5.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/c6d112e80e82de3ad5a4f8a875c5caf267fa856df2eb97e3ef945de7b62ad07eff02e1dd9e8943cc2e1388180d4f31f1d97e0300d2e5e662245e322205af67dc + checksum: 10c0/caf6a0072ff48e9351564dbc856c095fd5233bf2176daf9e8361a534be9ded6835c984ff8867365ca3cba158189074b14cc199b19c1a2e20d09682170c3784db languageName: node linkType: hard -"@typescript-eslint/types@npm:8.61.1, @typescript-eslint/types@npm:^8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/types@npm:8.61.1" - checksum: 10c0/165c3f0d3f4e1d04b310fe2a918c1012d037a0f0913895096eed40895fa72638e414a69e36182fc1bcc78efb9a4b7d81654b8768d8f1c3f43f3f2792694dfa49 +"@typescript-eslint/types@npm:8.62.0, @typescript-eslint/types@npm:^8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/types@npm:8.62.0" + checksum: 10c0/28d7a6851cb79301ef1ee004fb8d75811e52eb2a7258d7f8ad2f234886ab2faaf1888cbf5a71cb53afd4d1024c51f71ea359f3103ea70d6f7ccd626ffbfd49c1 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.61.1" +"@typescript-eslint/typescript-estree@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.62.0" dependencies: - "@typescript-eslint/project-service": "npm:8.61.1" - "@typescript-eslint/tsconfig-utils": "npm:8.61.1" - "@typescript-eslint/types": "npm:8.61.1" - "@typescript-eslint/visitor-keys": "npm:8.61.1" + "@typescript-eslint/project-service": "npm:8.62.0" + "@typescript-eslint/tsconfig-utils": "npm:8.62.0" + "@typescript-eslint/types": "npm:8.62.0" + "@typescript-eslint/visitor-keys": "npm:8.62.0" debug: "npm:^4.4.3" minimatch: "npm:^10.2.2" semver: "npm:^7.7.3" @@ -369,32 +369,32 @@ __metadata: ts-api-utils: "npm:^2.5.0" peerDependencies: typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/cc3f15e8e30dee0522e9f8b5879824cfe3d98aad6a64e863bf0a21c26eedb3b0e5c82c2b73d59f9d5bc1b66f67305132c7c71f11a542e04e152f92b58599b358 + checksum: 10c0/c1b76203f37870e66487379c75b1d1a9af0a9c88e8e58a3d2fc106427ce42dce9bd7358a3d2cb7d344004cbb693dba899abf19391d853bbb9f345aa8683635c4 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/utils@npm:8.61.1" +"@typescript-eslint/utils@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/utils@npm:8.62.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.9.1" - "@typescript-eslint/scope-manager": "npm:8.61.1" - "@typescript-eslint/types": "npm:8.61.1" - "@typescript-eslint/typescript-estree": "npm:8.61.1" + "@typescript-eslint/scope-manager": "npm:8.62.0" + "@typescript-eslint/types": "npm:8.62.0" + "@typescript-eslint/typescript-estree": "npm:8.62.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/afb5e6f39da3ee34c11cfc73a64045a0e5dadd74ae2a2fcf01d9494e3be00c849a3b9ca8b23570f596726611f00598a198d66cd82e3753f63b8bde69ead0e507 + checksum: 10c0/5c5d1dd2c37d43ec913e4d144d071058701bf3548733671a05025fae306f7afdc4fdc3d9867d0eae32537eb68ecba046ab8aa6111a5d97497ec78fee98a25809 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.61.1": - version: 8.61.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.61.1" +"@typescript-eslint/visitor-keys@npm:8.62.0": + version: 8.62.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.62.0" dependencies: - "@typescript-eslint/types": "npm:8.61.1" + "@typescript-eslint/types": "npm:8.62.0" eslint-visitor-keys: "npm:^5.0.0" - checksum: 10c0/fa2075b891076fe640cfc36fd68299985f35c9b6782ff35cf231c1418e38dba56b28412bc6fced7fb8fabbd91444a02643f62e1ebe424aa45a885b8a8e60fbfd + checksum: 10c0/29102828fab6b060e607effee0d7666bc82aef269241c7c5c44ffb3386b3cb69ea585bf7c5d88d428c489f46d5888cbe90677e15cbad8cb27acfa1fc1661bd5b languageName: node linkType: hard @@ -1055,18 +1055,18 @@ __metadata: languageName: node linkType: hard -"typescript-eslint@npm:^8.61.1": - version: 8.61.1 - resolution: "typescript-eslint@npm:8.61.1" +"typescript-eslint@npm:^8.62.0": + version: 8.62.0 + resolution: "typescript-eslint@npm:8.62.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.61.1" - "@typescript-eslint/parser": "npm:8.61.1" - "@typescript-eslint/typescript-estree": "npm:8.61.1" - "@typescript-eslint/utils": "npm:8.61.1" + "@typescript-eslint/eslint-plugin": "npm:8.62.0" + "@typescript-eslint/parser": "npm:8.62.0" + "@typescript-eslint/typescript-estree": "npm:8.62.0" + "@typescript-eslint/utils": "npm:8.62.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ">=4.8.4 <6.1.0" - checksum: 10c0/cf27a5c25a6d492a77ee72d98ff0e708b25553c4450483c627018556bee5b7b17066c0696947aa968ed24fd07ebc095b449dea79f8a7a4c65bccdb6aaf8dc09d + checksum: 10c0/263056d927b79c17b0c84849953642af202106e55914c5a606a4c76445b6428b2412e2d08cc20318b8aed9d1988e2a0cea60387e18ef0862beae13e8bc1df690 languageName: node linkType: hard