From ab4c2e6f36b524e8997096d814686936e41d5abd Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 10:53:24 +0100 Subject: [PATCH 01/15] Migrate to tsdown --- packages/eslint-plugin/package.json | 3 ++- packages/eslint-plugin/tsup.config.ts | 9 +++------ pnpm-lock.yaml | 4 ++++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 5a111ecd85..a2bff3b55e 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -10,7 +10,7 @@ } }, "scripts": { - "build": "tsup", + "build": "tsdown", "test:types": "pnpm tsc --p ./tsconfig.json --noEmit", "test": "vitest" }, @@ -27,6 +27,7 @@ "@types/node": "^25.0.10", "@typescript-eslint/rule-tester": "^8.53.1", "eslint": "^9.39.2", + "tsdown": "^0.20.3", "typescript": "^5.9.3", "vitest": "^4.0.17" } diff --git a/packages/eslint-plugin/tsup.config.ts b/packages/eslint-plugin/tsup.config.ts index e06072d65f..3ec1155cc3 100644 --- a/packages/eslint-plugin/tsup.config.ts +++ b/packages/eslint-plugin/tsup.config.ts @@ -1,12 +1,9 @@ -import { defineConfig, type Options } from 'tsup'; +import { defineConfig } from 'tsdown'; -const config: Options = { +export default defineConfig({ entry: ['src/index.ts'], format: ['esm'], dts: true, clean: true, - splitting: true, sourcemap: true, -}; - -export default defineConfig(config); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a06f6bd1fc..a7104bb092 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -378,6 +378,9 @@ importers: eslint: specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) + tsdown: + specifier: ^0.20.3 + version: 0.20.3(typescript@5.9.3) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -6008,6 +6011,7 @@ packages: prebuild-install@7.1.3: resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. hasBin: true prelude-ls@1.2.1: From c5760f92da7f3b0f73fe7fb759019afd7a73b065 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 10:57:32 +0100 Subject: [PATCH 02/15] Add plugin dependency --- .oxlintrc.json | 1 + package.json | 1 + pnpm-lock.yaml | 3 +++ 3 files changed, 5 insertions(+) diff --git a/.oxlintrc.json b/.oxlintrc.json index b09593d448..98f11e7b47 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,6 +1,7 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", "plugins": ["eslint", "typescript", "import", "unicorn", "oxc"], + "jsPlugins": ["eslint-plugin-typegpu"], "categories": { "correctness": "warn", "suspicious": "warn" diff --git a/package.json b/package.json index b9c1f6f002..f38b673c13 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "pkg-pr-new": "^0.0.62", "typescript": "catalog:types", "unplugin-typegpu": "workspace:*", + "eslint-plugin-typegpu": "workspace:*", "vite-imagetools": "catalog:frontend", "vitest": "catalog:test" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7104bb092..8ff9d5007e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,6 +68,9 @@ importers: dpdm: specifier: ^3.14.0 version: 3.14.0 + eslint-plugin-typegpu: + specifier: workspace:* + version: link:packages/eslint-plugin jiti: specifier: catalog:build version: 2.6.1 From b1a920272e7ed139c56066ae6ca9787e485b0df1 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 11:22:00 +0100 Subject: [PATCH 03/15] Finish migration --- packages/eslint-plugin/package.json | 4 ++-- packages/eslint-plugin/{tsup.config.ts => tsdown.config.ts} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename packages/eslint-plugin/{tsup.config.ts => tsdown.config.ts} (100%) diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index a2bff3b55e..63c90abe61 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -5,8 +5,8 @@ "type": "module", "exports": { ".": { - "types": "./dist/index.d.ts", - "import": "./dist/index.js" + "types": "./dist/index.d.mjs", + "import": "./dist/index.mjs" } }, "scripts": { diff --git a/packages/eslint-plugin/tsup.config.ts b/packages/eslint-plugin/tsdown.config.ts similarity index 100% rename from packages/eslint-plugin/tsup.config.ts rename to packages/eslint-plugin/tsdown.config.ts From ee4b30b3c0aa7a3e49c92c73333520d86d78a0ca Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 11:29:08 +0100 Subject: [PATCH 04/15] Enable typegpu rule --- .oxlintrc.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.oxlintrc.json b/.oxlintrc.json index 98f11e7b47..d3b08654b5 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -7,6 +7,7 @@ "suspicious": "warn" }, "rules": { + "typegpu/integer-division": "warn", "typescript/no-explicit-any": "error", "typescript/no-non-null-assertion": "error", "eslint-plugin-unicorn/prefer-add-event-listener": "off", From 2116b5282d5baf095bd1ae362a158ee68c264348 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 11:31:34 +0100 Subject: [PATCH 05/15] Limit warnings to 0 in scripts --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f38b673c13..0d0f741634 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "test": "pnpm run test:types && pnpm run test:style && pnpm run test:unit-and-attest && pnpm run test:circular-deps", "test:circular-deps": "pnpm dpdm -T --exit-code circular:1 packages/**/index.ts", "test:types": "pnpm run -r --parallel test:types", - "test:style": "oxlint && deno fmt --check", + "test:style": "oxlint --max-warnings=0 && deno fmt --check", "test:unit-and-attest": "vitest run --project=!browser", "test:unit": "ATTEST_skipTypes=1 vitest run --project=!browser", "test:unit:watch": "ATTEST_skipTypes=1 vitest --project=!browser", From c4fcfc43a7a5b48d753b97f8149140f2f7fe1e48 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 11:41:31 +0100 Subject: [PATCH 06/15] Bump oxlint --- package.json | 4 +- pnpm-lock.yaml | 204 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 167 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 0d0f741634..8c2d2a63b9 100644 --- a/package.json +++ b/package.json @@ -43,12 +43,12 @@ "@vitest/coverage-v8": "3.1.2", "@webgpu/types": "catalog:types", "dpdm": "^3.14.0", + "eslint-plugin-typegpu": "workspace:*", "jiti": "catalog:build", - "oxlint": "^1.43.0", + "oxlint": "^1.49.0", "pkg-pr-new": "^0.0.62", "typescript": "catalog:types", "unplugin-typegpu": "workspace:*", - "eslint-plugin-typegpu": "workspace:*", "vite-imagetools": "catalog:frontend", "vitest": "catalog:test" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ff9d5007e..a297e6a6ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,8 +75,8 @@ importers: specifier: catalog:build version: 2.6.1 oxlint: - specifier: ^1.43.0 - version: 1.43.0 + specifier: ^1.49.0 + version: 1.49.0 pkg-pr-new: specifier: ^0.0.62 version: 0.0.62 @@ -2034,43 +2034,117 @@ packages: '@oxc-project/types@0.95.0': resolution: {integrity: sha512-vACy7vhpMPhjEJhULNxrdR0D943TkA/MigMpJCHmBHvMXxRStRi/dPtTlfQ3uDwWSzRpT8z+7ImjZVf8JWBocQ==} - '@oxlint/darwin-arm64@1.43.0': - resolution: {integrity: sha512-C/GhObv/pQZg34NOzB6Mk8x0wc9AKj8fXzJF8ZRKTsBPyHusC6AZ6bba0QG0TUufw1KWuD0j++oebQfWeiFXNw==} + '@oxlint/binding-android-arm-eabi@1.49.0': + resolution: {integrity: sha512-2WPoh/2oK9r/i2R4o4J18AOrm3HVlWiHZ8TnuCaS4dX8m5ZzRmHW0I3eLxEurQLHWVruhQN7fHgZnah+ag5iQg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxlint/binding-android-arm64@1.49.0': + resolution: {integrity: sha512-YqJAGvNB11EzoKm1euVhZntb79alhMvWW/j12bYqdvVxn6xzEQWrEDCJg9BPo3A3tBCSUBKH7bVkAiCBqK/L1w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxlint/binding-darwin-arm64@1.49.0': + resolution: {integrity: sha512-WFocCRlvVkMhChCJ2qpJfp1Gj/IjvyjuifH9Pex8m8yHonxxQa3d8DZYreuDQU3T4jvSY8rqhoRqnpc61Nlbxw==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/darwin-x64@1.43.0': - resolution: {integrity: sha512-4NjfUtEEH8ewRQ2KlZGmm6DyrvypMdHwBnQT92vD0dLScNOQzr0V9O8Ua4IWXdeCNl/XMVhAV3h4/3YEYern5A==} + '@oxlint/binding-darwin-x64@1.49.0': + resolution: {integrity: sha512-BN0KniwvehbUfYztOMwEDkYoojGm/narf5oJf+/ap+6PnzMeWLezMaVARNIS0j3OdMkjHTEP8s3+GdPJ7WDywQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/linux-arm64-gnu@1.43.0': - resolution: {integrity: sha512-75tf1HvwdZ3ebk83yMbSB+moAEWK98mYqpXiaFAi6Zshie7r+Cx5PLXZFUEqkscenoZ+fcNXakHxfn94V6nf1g==} + '@oxlint/binding-freebsd-x64@1.49.0': + resolution: {integrity: sha512-SnkAc/DPIY6joMCiP/+53Q+N2UOGMU6ULvbztpmvPJNF/jYPGhNbKtN982uj2Gs6fpbxYkmyj08QnpkD4fbHJA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxlint/binding-linux-arm-gnueabihf@1.49.0': + resolution: {integrity: sha512-6Z3EzRvpQVIpO7uFhdiGhdE8Mh3S2VWKLL9xuxVqD6fzPhyI3ugthpYXlCChXzO8FzcYIZ3t1+Kau+h2NY1hqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm-musleabihf@1.49.0': + resolution: {integrity: sha512-wdjXaQYAL/L25732mLlngfst4Jdmi/HLPVHb3yfCoP5mE3lO/pFFrmOJpqWodgv29suWY74Ij+RmJ/YIG5VuzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm64-gnu@1.49.0': + resolution: {integrity: sha512-oSHpm8zmSvAG1BWUumbDRSg7moJbnwoEXKAkwDf/xTQJOzvbUknq95NVQdw/AduZr5dePftalB8rzJNGBogUMg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/linux-arm64-musl@1.43.0': - resolution: {integrity: sha512-BHV4fb36T2p/7bpA9fiJ5ayt7oJbiYX10nklW5arYp4l9/9yG/FQC5J4G1evzbJ/YbipF9UH0vYBAm5xbqGrvw==} + '@oxlint/binding-linux-arm64-musl@1.49.0': + resolution: {integrity: sha512-xeqkMOARgGBlEg9BQuPDf6ZW711X6BT5qjDyeM5XNowCJeTSdmMhpePJjTEiVbbr3t21sIlK8RE6X5bc04nWyQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@oxlint/linux-x64-gnu@1.43.0': - resolution: {integrity: sha512-1l3nvnzWWse1YHibzZ4HQXdF/ibfbKZhp9IguElni3bBqEyPEyurzZ0ikWynDxKGXqZa+UNXTFuU1NRVX1RJ3g==} + '@oxlint/binding-linux-ppc64-gnu@1.49.0': + resolution: {integrity: sha512-uvcqRO6PnlJGbL7TeePhTK5+7/JXbxGbN+C6FVmfICDeeRomgQqrfVjf0lUrVpUU8ii8TSkIbNdft3M+oNlOsQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@oxlint/binding-linux-riscv64-gnu@1.49.0': + resolution: {integrity: sha512-Dw1HkdXAwHNH+ZDserHP2RzXQmhHtpsYYI0hf8fuGAVCIVwvS6w1+InLxpPMY25P8ASRNiFN3hADtoh6lI+4lg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxlint/binding-linux-riscv64-musl@1.49.0': + resolution: {integrity: sha512-EPlMYaA05tJ9km/0dI9K57iuMq3Tw+nHst7TNIegAJZrBPtsOtYaMFZEaWj02HA8FI5QvSnRHMt+CI+RIhXJBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxlint/binding-linux-s390x-gnu@1.49.0': + resolution: {integrity: sha512-yZiQL9qEwse34aMbnMb5VqiAWfDY+fLFuoJbHOuzB1OaJZbN1MRF9Nk+W89PIpGr5DNPDipwjZb8+Q7wOywoUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@oxlint/binding-linux-x64-gnu@1.49.0': + resolution: {integrity: sha512-CcCDwMMXSchNkhdgvhVn3DLZ4EnBXAD8o8+gRzahg+IdSt/72y19xBgShJgadIRF0TsRcV/MhDUMwL5N/W54aQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/linux-x64-musl@1.43.0': - resolution: {integrity: sha512-+jNYgLGRFTJxJuaSOZJBwlYo5M0TWRw0+3y5MHOL4ArrIdHyCthg6r4RbVWrsR1qUfUE1VSSHQ2bfbC99RXqMg==} + '@oxlint/binding-linux-x64-musl@1.49.0': + resolution: {integrity: sha512-u3HfKV8BV6t6UCCbN0RRiyqcymhrnpunVmLFI8sEa5S/EBu+p/0bJ3D7LZ2KT6PsBbrB71SWq4DeFrskOVgIZg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@oxlint/win32-arm64@1.43.0': - resolution: {integrity: sha512-dvs1C/HCjCyGTURMagiHprsOvVTT3omDiSzi5Qw0D4QFJ1pEaNlfBhVnOUYgUfS6O7Mcmj4+G+sidRsQcWQ/kA==} + '@oxlint/binding-openharmony-arm64@1.49.0': + resolution: {integrity: sha512-dRDpH9fw+oeUMpM4br0taYCFpW6jQtOuEIec89rOgDA1YhqwmeRcx0XYeCv7U48p57qJ1XZHeMGM9LdItIjfzA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxlint/binding-win32-arm64-msvc@1.49.0': + resolution: {integrity: sha512-6rrKe/wL9tn0qnOy76i1/0f4Dc3dtQnibGlU4HqR/brVHlVjzLSoaH0gAFnLnznh9yQ6gcFTBFOPrcN/eKPDGA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/win32-x64@1.43.0': - resolution: {integrity: sha512-bSuItSU8mTSDsvmmLTepTdCL2FkJI6dwt9tot/k0EmiYF+ArRzmsl4lXVLssJNRV5lJEc5IViyTrh7oiwrjUqA==} + '@oxlint/binding-win32-ia32-msvc@1.49.0': + resolution: {integrity: sha512-CXHLWAtLs2xG/aVy1OZiYJzrULlq0QkYpI6cd7VKMrab+qur4fXVE/B1Bp1m0h1qKTj5/FTGg6oU4qaXMjS/ug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxlint/binding-win32-x64-msvc@1.49.0': + resolution: {integrity: sha512-VteIelt78kwzSglOozaQcs6BCS4Lk0j+QA+hGV0W8UeyaqQ3XpbZRhDU55NW1PPvCy1tg4VXsTlEaPovqto7nQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -5667,12 +5741,12 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - oxlint@1.43.0: - resolution: {integrity: sha512-xiqTCsKZch+R61DPCjyqUVP2MhkQlRRYxLRBeBDi+dtQJ90MOgdcjIktvDCgXz0bgtx94EQzHEndsizZjMX2OA==} + oxlint@1.49.0: + resolution: {integrity: sha512-YZffp0gM+63CJoRhHjtjRnwKtAgUnXM6j63YQ++aigji2NVvLGsUlrXo9gJUXZOdcbfShLYtA6RuTu8GZ4lzOQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.11.2' + oxlint-tsgolint: '>=0.14.1' peerDependenciesMeta: oxlint-tsgolint: optional: true @@ -6423,6 +6497,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} @@ -9100,28 +9179,61 @@ snapshots: '@oxc-project/types@0.95.0': {} - '@oxlint/darwin-arm64@1.43.0': + '@oxlint/binding-android-arm-eabi@1.49.0': + optional: true + + '@oxlint/binding-android-arm64@1.49.0': + optional: true + + '@oxlint/binding-darwin-arm64@1.49.0': + optional: true + + '@oxlint/binding-darwin-x64@1.49.0': + optional: true + + '@oxlint/binding-freebsd-x64@1.49.0': + optional: true + + '@oxlint/binding-linux-arm-gnueabihf@1.49.0': + optional: true + + '@oxlint/binding-linux-arm-musleabihf@1.49.0': + optional: true + + '@oxlint/binding-linux-arm64-gnu@1.49.0': + optional: true + + '@oxlint/binding-linux-arm64-musl@1.49.0': + optional: true + + '@oxlint/binding-linux-ppc64-gnu@1.49.0': + optional: true + + '@oxlint/binding-linux-riscv64-gnu@1.49.0': optional: true - '@oxlint/darwin-x64@1.43.0': + '@oxlint/binding-linux-riscv64-musl@1.49.0': optional: true - '@oxlint/linux-arm64-gnu@1.43.0': + '@oxlint/binding-linux-s390x-gnu@1.49.0': optional: true - '@oxlint/linux-arm64-musl@1.43.0': + '@oxlint/binding-linux-x64-gnu@1.49.0': optional: true - '@oxlint/linux-x64-gnu@1.43.0': + '@oxlint/binding-linux-x64-musl@1.49.0': optional: true - '@oxlint/linux-x64-musl@1.43.0': + '@oxlint/binding-openharmony-arm64@1.49.0': optional: true - '@oxlint/win32-arm64@1.43.0': + '@oxlint/binding-win32-arm64-msvc@1.49.0': optional: true - '@oxlint/win32-x64@1.43.0': + '@oxlint/binding-win32-ia32-msvc@1.49.0': + optional: true + + '@oxlint/binding-win32-x64-msvc@1.49.0': optional: true '@pagefind/darwin-arm64@1.3.0': @@ -13145,7 +13257,7 @@ snapshots: node-abi@3.87.0: dependencies: - semver: 7.7.3 + semver: 7.7.4 optional: true node-addon-api@7.1.1: @@ -13235,16 +13347,27 @@ snapshots: outvariant@1.4.3: optional: true - oxlint@1.43.0: + oxlint@1.49.0: optionalDependencies: - '@oxlint/darwin-arm64': 1.43.0 - '@oxlint/darwin-x64': 1.43.0 - '@oxlint/linux-arm64-gnu': 1.43.0 - '@oxlint/linux-arm64-musl': 1.43.0 - '@oxlint/linux-x64-gnu': 1.43.0 - '@oxlint/linux-x64-musl': 1.43.0 - '@oxlint/win32-arm64': 1.43.0 - '@oxlint/win32-x64': 1.43.0 + '@oxlint/binding-android-arm-eabi': 1.49.0 + '@oxlint/binding-android-arm64': 1.49.0 + '@oxlint/binding-darwin-arm64': 1.49.0 + '@oxlint/binding-darwin-x64': 1.49.0 + '@oxlint/binding-freebsd-x64': 1.49.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.49.0 + '@oxlint/binding-linux-arm-musleabihf': 1.49.0 + '@oxlint/binding-linux-arm64-gnu': 1.49.0 + '@oxlint/binding-linux-arm64-musl': 1.49.0 + '@oxlint/binding-linux-ppc64-gnu': 1.49.0 + '@oxlint/binding-linux-riscv64-gnu': 1.49.0 + '@oxlint/binding-linux-riscv64-musl': 1.49.0 + '@oxlint/binding-linux-s390x-gnu': 1.49.0 + '@oxlint/binding-linux-x64-gnu': 1.49.0 + '@oxlint/binding-linux-x64-musl': 1.49.0 + '@oxlint/binding-openharmony-arm64': 1.49.0 + '@oxlint/binding-win32-arm64-msvc': 1.49.0 + '@oxlint/binding-win32-ia32-msvc': 1.49.0 + '@oxlint/binding-win32-x64-msvc': 1.49.0 p-limit@2.3.0: dependencies: @@ -14131,6 +14254,9 @@ snapshots: semver@7.7.3: {} + semver@7.7.4: + optional: true + serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 From f3d5d6519b5141c0db0ba81671d09f6f9e7fd27a Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 11:48:43 +0100 Subject: [PATCH 07/15] Move to dynamic config --- .oxlintrc.json | 69 ---------------------------------------------- oxlint.config.ts | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 69 deletions(-) delete mode 100644 .oxlintrc.json create mode 100644 oxlint.config.ts diff --git a/.oxlintrc.json b/.oxlintrc.json deleted file mode 100644 index d3b08654b5..0000000000 --- a/.oxlintrc.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "$schema": "./node_modules/oxlint/configuration_schema.json", - "plugins": ["eslint", "typescript", "import", "unicorn", "oxc"], - "jsPlugins": ["eslint-plugin-typegpu"], - "categories": { - "correctness": "warn", - "suspicious": "warn" - }, - "rules": { - "typegpu/integer-division": "warn", - "typescript/no-explicit-any": "error", - "typescript/no-non-null-assertion": "error", - "eslint-plugin-unicorn/prefer-add-event-listener": "off", - "eslint-plugin-import/no-named-as-default": "off", - "eslint-plugin-import/no-named-as-default-member": "off", - "eslint-plugin-import/extensions": [ - "error", - "always", - { "ignorePackages": true } - ] - }, - "ignorePatterns": ["**/*.astro"], - "overrides": [ - { - "files": ["**/*.test.ts", "**/tests/**"], - "rules": { - "typescript/no-non-null-assertion": "off", - "eslint/no-unused-vars": "off", - "eslint/no-unused-expressions": "off", - "eslint-plugin-unicorn/consistent-function-scoping": "off", - "eslint/no-unsafe-optional-chaining": "off", - "eslint/no-constant-condition": "off" - } - } - ], - "settings": { - "jsx-a11y": { - "polymorphicPropName": null, - "components": {}, - "attributes": {} - }, - "next": { - "rootDir": [] - }, - "react": { - "formComponents": [], - "linkComponents": [], - "version": null, - "componentWrapperFunctions": [] - }, - "jsdoc": { - "ignorePrivate": false, - "ignoreInternal": false, - "ignoreReplacesDocs": true, - "overrideReplacesDocs": true, - "augmentsExtendsReplacesDocs": false, - "implementsReplacesDocs": false, - "exemptDestructuredRootsFromChecks": false, - "tagNamePreference": {} - }, - "vitest": { - "typecheck": false - } - }, - "env": { - "builtin": true - }, - "globals": {} -} diff --git a/oxlint.config.ts b/oxlint.config.ts new file mode 100644 index 0000000000..94920d0849 --- /dev/null +++ b/oxlint.config.ts @@ -0,0 +1,71 @@ +import { defineConfig } from 'oxlint'; + +export default defineConfig({ + plugins: ['eslint', 'typescript', 'import', 'unicorn', 'oxc'], + jsPlugins: ['eslint-plugin-typegpu'], + categories: { + correctness: 'warn', + suspicious: 'warn', + }, + rules: { + 'typegpu/integer-division': 'warn', + 'typescript/no-explicit-any': 'error', + 'typescript/no-non-null-assertion': 'error', + 'eslint/no-shadow': 'off', + 'eslint-plugin-unicorn/prefer-add-event-listener': 'off', + 'eslint-plugin-import/no-named-as-default': 'off', + 'eslint-plugin-import/no-named-as-default-member': 'off', + 'eslint-plugin-import/extensions': [ + 'error', + 'always', + { ignorePackages: true }, + ], + }, + ignorePatterns: ['**/*.astro'], + overrides: [ + { + files: ['**/*.test.ts', '**/tests/**'], + rules: { + 'typescript/no-non-null-assertion': 'off', + 'eslint/no-unused-vars': 'off', + 'eslint/no-unused-expressions': 'off', + 'eslint-plugin-unicorn/consistent-function-scoping': 'off', + 'eslint/no-unsafe-optional-chaining': 'off', + 'eslint/no-constant-condition': 'off', + }, + }, + ], + settings: { + 'jsx-a11y': { + polymorphicPropName: null, + components: {}, + attributes: {}, + }, + next: { + rootDir: [], + }, + react: { + formComponents: [], + linkComponents: [], + version: null, + componentWrapperFunctions: [], + }, + jsdoc: { + ignorePrivate: false, + ignoreInternal: false, + ignoreReplacesDocs: true, + overrideReplacesDocs: true, + augmentsExtendsReplacesDocs: false, + implementsReplacesDocs: false, + exemptDestructuredRootsFromChecks: false, + tagNamePreference: {}, + }, + vitest: { + typecheck: false, + }, + }, + env: { + builtin: true, + }, + globals: {}, +}); From 9a88e236e57cb37dd2da5a94905fb1539ea4fa0a Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 12:00:19 +0100 Subject: [PATCH 08/15] Import rules dynamically --- oxlint.config.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/oxlint.config.ts b/oxlint.config.ts index 94920d0849..98ba0a4903 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -1,4 +1,10 @@ import { defineConfig } from 'oxlint'; +import typegpu from 'eslint-plugin-typegpu'; + +const typegpuPreset = typegpu.configs?.recommended; +const typegpuRules = typegpuPreset && 'rules' in typegpuPreset + ? typegpuPreset.rules + : {}; export default defineConfig({ plugins: ['eslint', 'typescript', 'import', 'unicorn', 'oxc'], @@ -8,7 +14,7 @@ export default defineConfig({ suspicious: 'warn', }, rules: { - 'typegpu/integer-division': 'warn', + ...typegpuRules, 'typescript/no-explicit-any': 'error', 'typescript/no-non-null-assertion': 'error', 'eslint/no-shadow': 'off', From fc0afa486dd10dd3745462d75fba47ac78b34971 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 12:00:33 +0100 Subject: [PATCH 09/15] Address new rules --- packages/typegpu-three/src/typegpu-node.ts | 2 +- packages/typegpu/tests/std/numeric/div.test.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/typegpu-three/src/typegpu-node.ts b/packages/typegpu-three/src/typegpu-node.ts index 4f53622ef9..9e6e8fa7ad 100644 --- a/packages/typegpu-three/src/typegpu-node.ts +++ b/packages/typegpu-three/src/typegpu-node.ts @@ -396,7 +396,7 @@ export const fromTSL = tgpu.comptime( let nodeType: string | null = null; try { // sometimes it needs information (overrideNodes) from compilation context which is not present nodeType = node.getNodeType(sharedBuilder); - } catch (e) { + } catch { console.warn( `fromTSL: failed to infer node type via getNodeType; skipping type comparison.`, ); diff --git a/packages/typegpu/tests/std/numeric/div.test.ts b/packages/typegpu/tests/std/numeric/div.test.ts index 993efee171..685ccae449 100644 --- a/packages/typegpu/tests/std/numeric/div.test.ts +++ b/packages/typegpu/tests/std/numeric/div.test.ts @@ -83,6 +83,7 @@ describe('div', () => { }); it('const u32 / const u32', () => { + // oxlint-disable-next-line typegpu/integer-division const foo = tgpu.fn([], d.f32)(() => d.u32(1) / d.u32(2)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` @@ -93,6 +94,7 @@ describe('div', () => { }); it('const i32 / const i32', () => { + // oxlint-disable-next-line typegpu/integer-division const foo = tgpu.fn([], d.f32)(() => d.i32(1) / d.i32(2)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` @@ -133,6 +135,7 @@ describe('div', () => { }); it('const f32 / const i32', () => { + // oxlint-disable-next-line typegpu/integer-division const foo = tgpu.fn([], d.f32)(() => d.f32(1.0) / d.i32(2.0)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` @@ -143,6 +146,7 @@ describe('div', () => { }); it('const u32 / const i32', () => { + // oxlint-disable-next-line typegpu/integer-division const foo = tgpu.fn([], d.f32)(() => d.u32(1) / d.i32(2)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` From 405e92a9a9faf6f62e8ea79dbf03350834c24ba6 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 12:07:15 +0100 Subject: [PATCH 10/15] Remove unnecessary settings --- oxlint.config.ts | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/oxlint.config.ts b/oxlint.config.ts index 98ba0a4903..9f09f538a7 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -41,37 +41,7 @@ export default defineConfig({ }, }, ], - settings: { - 'jsx-a11y': { - polymorphicPropName: null, - components: {}, - attributes: {}, - }, - next: { - rootDir: [], - }, - react: { - formComponents: [], - linkComponents: [], - version: null, - componentWrapperFunctions: [], - }, - jsdoc: { - ignorePrivate: false, - ignoreInternal: false, - ignoreReplacesDocs: true, - overrideReplacesDocs: true, - augmentsExtendsReplacesDocs: false, - implementsReplacesDocs: false, - exemptDestructuredRootsFromChecks: false, - tagNamePreference: {}, - }, - vitest: { - typecheck: false, - }, - }, env: { builtin: true, }, - globals: {}, }); From 8373d37b4ef34dfdbb152984eca62cccb41b6497 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 12:15:52 +0100 Subject: [PATCH 11/15] Build plugin before running oxlint --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c2d2a63b9..138e30a5bd 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "test": "pnpm run test:types && pnpm run test:style && pnpm run test:unit-and-attest && pnpm run test:circular-deps", "test:circular-deps": "pnpm dpdm -T --exit-code circular:1 packages/**/index.ts", "test:types": "pnpm run -r --parallel test:types", - "test:style": "oxlint --max-warnings=0 && deno fmt --check", + "test:style": "pnpm --filter eslint-plugin-typegpu build && oxlint --max-warnings=0 && deno fmt --check", "test:unit-and-attest": "vitest run --project=!browser", "test:unit": "ATTEST_skipTypes=1 vitest run --project=!browser", "test:unit:watch": "ATTEST_skipTypes=1 vitest --project=!browser", From 2b0061726a7b75a16583a6f8e6cde115a05a296d Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 14:18:01 +0100 Subject: [PATCH 12/15] Update package.json --- package.json | 2 +- packages/eslint-plugin/package.json | 12 ++++++++++-- packages/eslint-plugin/src/index.ts | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 138e30a5bd..8c2d2a63b9 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "test": "pnpm run test:types && pnpm run test:style && pnpm run test:unit-and-attest && pnpm run test:circular-deps", "test:circular-deps": "pnpm dpdm -T --exit-code circular:1 packages/**/index.ts", "test:types": "pnpm run -r --parallel test:types", - "test:style": "pnpm --filter eslint-plugin-typegpu build && oxlint --max-warnings=0 && deno fmt --check", + "test:style": "oxlint --max-warnings=0 && deno fmt --check", "test:unit-and-attest": "vitest run --project=!browser", "test:unit": "ATTEST_skipTypes=1 vitest run --project=!browser", "test:unit:watch": "ATTEST_skipTypes=1 vitest --project=!browser", diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 63c90abe61..f68ec84afb 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -5,8 +5,16 @@ "type": "module", "exports": { ".": { - "types": "./dist/index.d.mjs", - "import": "./dist/index.mjs" + "types": "./src/index.ts", + "import": "./src/index.ts" + } + }, + "publishConfig": { + "exports": { + ".": { + "types": "./dist/index.d.mts", + "import": "./dist/index.mjs" + } } }, "scripts": { diff --git a/packages/eslint-plugin/src/index.ts b/packages/eslint-plugin/src/index.ts index 7a3dfcf2bb..08763811d3 100644 --- a/packages/eslint-plugin/src/index.ts +++ b/packages/eslint-plugin/src/index.ts @@ -1,4 +1,4 @@ -import pkg from '../package.json'; +import pkg from '../package.json' with { type: 'json' }; import type { TSESLint } from '@typescript-eslint/utils'; import { allRules, recommendedRules, rules } from './configs.ts'; From 28665733526a8ce1d6bae27a906fa47d4bdf1a3f Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Fri, 20 Feb 2026 14:35:03 +0100 Subject: [PATCH 13/15] Update ignores --- packages/typegpu/tests/std/numeric/div.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/typegpu/tests/std/numeric/div.test.ts b/packages/typegpu/tests/std/numeric/div.test.ts index 685ccae449..94f5ba7921 100644 --- a/packages/typegpu/tests/std/numeric/div.test.ts +++ b/packages/typegpu/tests/std/numeric/div.test.ts @@ -83,7 +83,7 @@ describe('div', () => { }); it('const u32 / const u32', () => { - // oxlint-disable-next-line typegpu/integer-division + // oxlint-disable-next-line typegpu/integer-division it's a test const foo = tgpu.fn([], d.f32)(() => d.u32(1) / d.u32(2)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` @@ -94,7 +94,7 @@ describe('div', () => { }); it('const i32 / const i32', () => { - // oxlint-disable-next-line typegpu/integer-division + // oxlint-disable-next-line typegpu/integer-division it's a test const foo = tgpu.fn([], d.f32)(() => d.i32(1) / d.i32(2)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` @@ -135,7 +135,7 @@ describe('div', () => { }); it('const f32 / const i32', () => { - // oxlint-disable-next-line typegpu/integer-division + // oxlint-disable-next-line typegpu/integer-division it's a test const foo = tgpu.fn([], d.f32)(() => d.f32(1.0) / d.i32(2.0)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` @@ -146,7 +146,7 @@ describe('div', () => { }); it('const u32 / const i32', () => { - // oxlint-disable-next-line typegpu/integer-division + // oxlint-disable-next-line typegpu/integer-division it's a test const foo = tgpu.fn([], d.f32)(() => d.u32(1) / d.i32(2)); expect(foo()).toBe(0.5); expect(tgpu.resolve([foo])).toMatchInlineSnapshot(` From a2761e380709c5558d7987c9e5c8b46a4d3d5f2d Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Tue, 24 Feb 2026 10:46:00 +0100 Subject: [PATCH 14/15] Fix new errors --- .../src/examples/algorithms/concurrent-chart/index.ts | 2 +- .../src/examples/common/setup-first-person-camera.ts | 2 +- apps/typegpu-docs/src/examples/tests/prefix-scan/functions.ts | 2 +- apps/typegpu-docs/src/examples/tests/prefix-scan/index.ts | 2 +- apps/typegpu-docs/src/examples/threejs/varyings/index.ts | 2 +- oxlint.config.ts | 1 + packages/typegpu/tests/offsetUtils.test.ts | 4 ++-- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/typegpu-docs/src/examples/algorithms/concurrent-chart/index.ts b/apps/typegpu-docs/src/examples/algorithms/concurrent-chart/index.ts index a6c772abd5..e2624f2036 100644 --- a/apps/typegpu-docs/src/examples/algorithms/concurrent-chart/index.ts +++ b/apps/typegpu-docs/src/examples/algorithms/concurrent-chart/index.ts @@ -72,7 +72,7 @@ async function runBenchmarks() { drawCharts(); } -runBenchmarks(); +void runBenchmarks(); // #region Example controls & Cleanup diff --git a/apps/typegpu-docs/src/examples/common/setup-first-person-camera.ts b/apps/typegpu-docs/src/examples/common/setup-first-person-camera.ts index b6e6d331f7..37c4f2aaa1 100644 --- a/apps/typegpu-docs/src/examples/common/setup-first-person-camera.ts +++ b/apps/typegpu-docs/src/examples/common/setup-first-person-camera.ts @@ -106,7 +106,7 @@ export function setupFirstPersonCamera( // mouse events canvas.addEventListener('mousedown', () => { - canvas.requestPointerLock(); + void canvas.requestPointerLock(); }); canvas.addEventListener('mousemove', (event: MouseEvent) => { diff --git a/apps/typegpu-docs/src/examples/tests/prefix-scan/functions.ts b/apps/typegpu-docs/src/examples/tests/prefix-scan/functions.ts index 7ef8cbfcc4..abf698bb49 100644 --- a/apps/typegpu-docs/src/examples/tests/prefix-scan/functions.ts +++ b/apps/typegpu-docs/src/examples/tests/prefix-scan/functions.ts @@ -37,7 +37,7 @@ function applyOp( a: number | undefined, b: number | undefined, ): number { - return op.operation(a as number & d.F32, b as number & d.F32) as number; + return op.operation(a as number & d.F32, b as number & d.F32); } export function prefixScanJS(arr: number[], op: BinaryOp) { diff --git a/apps/typegpu-docs/src/examples/tests/prefix-scan/index.ts b/apps/typegpu-docs/src/examples/tests/prefix-scan/index.ts index 88baaa5e18..0a662f3348 100644 --- a/apps/typegpu-docs/src/examples/tests/prefix-scan/index.ts +++ b/apps/typegpu-docs/src/examples/tests/prefix-scan/index.ts @@ -263,7 +263,7 @@ const table = document.querySelector('.result'); if (!table) { throw new Error('Nowhere to display the results'); } -runTests().then((result) => { +void runTests().then((result) => { table.innerText = `Tests ${result ? 'succeeded' : 'failed'}.`; }); diff --git a/apps/typegpu-docs/src/examples/threejs/varyings/index.ts b/apps/typegpu-docs/src/examples/threejs/varyings/index.ts index 68adc98939..d680ceb451 100644 --- a/apps/typegpu-docs/src/examples/threejs/varyings/index.ts +++ b/apps/typegpu-docs/src/examples/threejs/varyings/index.ts @@ -82,7 +82,7 @@ dirLight.position.set(-7, 10, 0); scene.add(dirLight); scene.add(new THREE.AmbientLight(0x444444)); -renderer.setAnimationLoop(() => { +void renderer.setAnimationLoop(() => { renderer.render(scene, camera); }); diff --git a/oxlint.config.ts b/oxlint.config.ts index 220219cd28..160ee6ddca 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -15,6 +15,7 @@ export default defineConfig({ }, rules: { ...typegpuRules, + 'typescript/no-unsafe-enum-comparison': 'off', 'typescript/restrict-template-expressions': 'off', 'typescript/no-unsafe-type-assertion': 'off', 'typescript/no-explicit-any': 'error', diff --git a/packages/typegpu/tests/offsetUtils.test.ts b/packages/typegpu/tests/offsetUtils.test.ts index baf87d7274..d12d3a9edf 100644 --- a/packages/typegpu/tests/offsetUtils.test.ts +++ b/packages/typegpu/tests/offsetUtils.test.ts @@ -33,7 +33,7 @@ describe('getOffsetInfoAt (vectors)', () => { }); it('supports numeric component access', () => { - const info = getOffsetInfoAt(d.vec3f, (v) => v[1] as number); + const info = getOffsetInfoAt(d.vec3f, (v) => v[1]); expect(info.offset).toBe(4); expect(info.contiguous).toBe(8); @@ -172,7 +172,7 @@ describe('getOffsetInfoAt (edge cases)', () => { const info = getOffsetInfoAt( S, - (s) => s.l.vec.z as number, + (s) => s.l.vec.z, ); expect(info.offset).toBe(8); From b81ba6b61a497fe92b463e6fa2e6ea133ac080f7 Mon Sep 17 00:00:00 2001 From: Aleksander Katan Date: Tue, 24 Feb 2026 11:45:30 +0100 Subject: [PATCH 15/15] Merge fixes --- packages/typegpu/src/data/wgslTypes.ts | 1 + packages/unplugin-typegpu/src/babel.ts | 6 +++--- pnpm-lock.yaml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/typegpu/src/data/wgslTypes.ts b/packages/typegpu/src/data/wgslTypes.ts index b37a0d9d48..3914039367 100644 --- a/packages/typegpu/src/data/wgslTypes.ts +++ b/packages/typegpu/src/data/wgslTypes.ts @@ -1,3 +1,4 @@ +// oxlint-disable-next-line no-unused-vars it is used import type { Operator } from 'tsover-runtime'; import type { TgpuNamable } from '../shared/meta.ts'; import type { diff --git a/packages/unplugin-typegpu/src/babel.ts b/packages/unplugin-typegpu/src/babel.ts index 9a72f056ce..c00aa7e040 100644 --- a/packages/unplugin-typegpu/src/babel.ts +++ b/packages/unplugin-typegpu/src/babel.ts @@ -161,7 +161,7 @@ function functionVisitor(ctx: Context): TraverseOptions { path.node.left, types.callExpression(types.identifier(runtimeFn), [ path.node.left as babel.Expression, - path.node.right as babel.Expression, + path.node.right, ]), ), ); @@ -202,7 +202,7 @@ function functionVisitor(ctx: Context): TraverseOptions { path.replaceWith( types.callExpression(types.identifier(runtimeFn), [ path.node.left as babel.Expression, - path.node.right as babel.Expression, + path.node.right, ]), ); } @@ -306,7 +306,7 @@ function functionVisitor(ctx: Context): TraverseOptions { const transpiled = functionToTranspiled( implementation, null, - ) as babel.CallExpression; + ); path.replaceWith( types.callExpression(node.callee, [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b38a04519e..ae169c0a43 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -390,7 +390,7 @@ importers: version: 9.39.2(jiti@2.6.1) tsdown: specifier: ^0.20.3 - version: 0.20.3(typescript@5.9.3) + version: 0.20.3(tsover@5.9.11) typescript: specifier: npm:tsover@^5.9.11 version: tsover@5.9.11