diff --git a/benchmarks/typescript/src/main.ts b/benchmarks/typescript/src/main.ts index ba728238..e442c8fc 100644 --- a/benchmarks/typescript/src/main.ts +++ b/benchmarks/typescript/src/main.ts @@ -1,4 +1,5 @@ -import { hrtime } from 'process'; +// oxlint-disable no-console -- The benchmark reports measurements to stdout. +import { hrtime } from 'node:process'; import { Message, Struct } from '../generated/types'; const pathologicalIterations = 5_000; @@ -66,10 +67,10 @@ const s64TestValues: bigint[] = [ s64Max, ]; -function benchmark( +function benchmark( atlas: (message: T) => V, serializeWithAtlasUnsafe: (dataView: DataView, offset: number, message: T, atlas: V) => number, - deserialize: (dataView: DataView) => U, + deserialize: (dataView: DataView) => unknown, message: T, iterations: number, ): void { diff --git a/benchmarks/typescript/tsconfig.json b/benchmarks/typescript/tsconfig.json index e2839564..0f209d84 100644 --- a/benchmarks/typescript/tsconfig.json +++ b/benchmarks/typescript/tsconfig.json @@ -1,8 +1,14 @@ { "compilerOptions": { + "target": "es2023", "module": "nodenext", + "moduleDetection": "force", "outDir": "dist", - "types": ["node"] + "types": ["node"], + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "strict": true }, - "include": ["src"] + "include": ["src", "vite.config.ts"] } diff --git a/benchmarks/typescript/vite.config.ts b/benchmarks/typescript/vite.config.ts index ee99f03e..e7d6ca25 100644 --- a/benchmarks/typescript/vite.config.ts +++ b/benchmarks/typescript/vite.config.ts @@ -2,11 +2,15 @@ import { defineConfig } from 'vite-plus'; export default defineConfig({ fmt: { + ignorePatterns: ['**/*.md'], singleQuote: true, }, lint: { categories: { correctness: 'deny', + perf: 'deny', + restriction: 'deny', + suspicious: 'deny', }, jsPlugins: [ { @@ -18,126 +22,10 @@ export default defineConfig({ typeAware: true, typeCheck: true, }, - overrides: [ - { - files: ['**/*.{js,mjs,cjs,ts,mts,cts}'], - rules: { - 'constructor-super': 'error', - 'for-direction': 'error', - 'getter-return': 'error', - 'no-async-promise-executor': 'error', - 'no-case-declarations': 'error', - 'no-class-assign': 'error', - 'no-compare-neg-zero': 'error', - 'no-cond-assign': 'error', - 'no-const-assign': 'error', - 'no-constant-binary-expression': 'error', - 'no-constant-condition': 'error', - 'no-control-regex': 'error', - 'no-debugger': 'error', - 'no-delete-var': 'error', - 'no-dupe-class-members': 'error', - 'no-dupe-else-if': 'error', - 'no-dupe-keys': 'error', - 'no-duplicate-case': 'error', - 'no-empty': 'error', - 'no-empty-character-class': 'error', - 'no-empty-pattern': 'error', - 'no-empty-static-block': 'error', - 'no-ex-assign': 'error', - 'no-extra-boolean-cast': 'error', - 'no-fallthrough': 'error', - 'no-func-assign': 'error', - 'no-global-assign': 'error', - 'no-import-assign': 'error', - 'no-invalid-regexp': 'error', - 'no-irregular-whitespace': 'error', - 'no-loss-of-precision': 'error', - 'no-misleading-character-class': 'error', - 'no-new-native-nonconstructor': 'error', - 'no-nonoctal-decimal-escape': 'error', - 'no-obj-calls': 'error', - 'no-prototype-builtins': 'error', - 'no-redeclare': 'error', - 'no-regex-spaces': 'error', - 'no-self-assign': 'error', - 'no-setter-return': 'error', - 'no-shadow-restricted-names': 'error', - 'no-sparse-arrays': 'error', - 'no-this-before-super': 'error', - 'no-unassigned-vars': 'error', - 'no-undef': 'error', - 'no-unexpected-multiline': 'error', - 'no-unreachable': 'error', - 'no-unsafe-finally': 'error', - 'no-unsafe-negation': 'error', - 'no-unsafe-optional-chaining': 'error', - 'no-unused-labels': 'error', - 'no-unused-private-class-members': 'error', - 'no-useless-assignment': 'error', - 'no-useless-backreference': 'error', - 'no-useless-catch': 'error', - 'no-useless-escape': 'error', - 'no-with': 'error', - 'preserve-caught-error': 'error', - 'require-yield': 'error', - 'use-isnan': 'error', - 'valid-typeof': 'error', - }, - env: { - node: true, - }, - }, - { - files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'], - rules: { - 'constructor-super': 'off', - 'getter-return': 'off', - 'no-class-assign': 'off', - 'no-const-assign': 'off', - 'no-dupe-class-members': 'off', - 'no-dupe-keys': 'off', - 'no-func-assign': 'off', - 'no-import-assign': 'off', - 'no-new-native-nonconstructor': 'off', - 'no-obj-calls': 'off', - 'no-redeclare': 'off', - 'no-setter-return': 'off', - 'no-this-before-super': 'off', - 'no-undef': 'off', - 'no-unreachable': 'off', - 'no-unsafe-negation': 'off', - 'no-var': 'error', - 'no-with': 'off', - 'prefer-const': 'error', - 'prefer-rest-params': 'error', - 'prefer-spread': 'error', - }, - }, - ], plugins: ['oxc', 'typescript', 'unicorn'], rules: { - 'no-array-constructor': 'error', - 'no-unused-expressions': 'error', - 'no-unused-vars': 'error', - 'typescript/ban-ts-comment': 'error', - 'typescript/no-duplicate-enum-values': 'error', - 'typescript/no-empty-object-type': 'error', - 'typescript/no-explicit-any': 'error', - 'typescript/no-extra-non-null-assertion': 'error', - 'typescript/no-misused-new': 'error', - 'typescript/no-namespace': 'error', - 'typescript/no-non-null-asserted-optional-chain': 'error', - 'typescript/no-require-imports': 'error', - 'typescript/no-this-alias': 'error', - 'typescript/no-unnecessary-type-constraint': 'error', - 'typescript/no-unsafe-declaration-merging': 'error', - 'typescript/no-unsafe-function-type': 'error', - 'typescript/no-wrapper-object-types': 'error', - 'typescript/prefer-as-const': 'error', - 'typescript/prefer-namespace-keyword': 'error', - 'typescript/triple-slash-reference': 'error', - 'vite-plus/prefer-vite-plus-imports': 'error', + 'no-undefined': 'allow', + 'oxc/no-async-await': 'allow', }, }, }); diff --git a/examples/typescript/src/main.ts b/examples/typescript/src/main.ts index ad9a955f..cdeb6a48 100644 --- a/examples/typescript/src/main.ts +++ b/examples/typescript/src/main.ts @@ -1,4 +1,5 @@ -import { readFileSync, writeFileSync, unlinkSync } from 'fs'; +// oxlint-disable no-console -- This example prints its observable output to stdout. +import { readFileSync, unlinkSync, writeFileSync } from 'node:fs'; import { unreachable } from '../generated/common'; import { SendEmailRequest, SendEmailResponse } from '../generated/types'; diff --git a/examples/typescript/tsconfig.json b/examples/typescript/tsconfig.json index e2839564..0f209d84 100644 --- a/examples/typescript/tsconfig.json +++ b/examples/typescript/tsconfig.json @@ -1,8 +1,14 @@ { "compilerOptions": { + "target": "es2023", "module": "nodenext", + "moduleDetection": "force", "outDir": "dist", - "types": ["node"] + "types": ["node"], + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "strict": true }, - "include": ["src"] + "include": ["src", "vite.config.ts"] } diff --git a/examples/typescript/vite.config.ts b/examples/typescript/vite.config.ts index ee99f03e..e7d6ca25 100644 --- a/examples/typescript/vite.config.ts +++ b/examples/typescript/vite.config.ts @@ -2,11 +2,15 @@ import { defineConfig } from 'vite-plus'; export default defineConfig({ fmt: { + ignorePatterns: ['**/*.md'], singleQuote: true, }, lint: { categories: { correctness: 'deny', + perf: 'deny', + restriction: 'deny', + suspicious: 'deny', }, jsPlugins: [ { @@ -18,126 +22,10 @@ export default defineConfig({ typeAware: true, typeCheck: true, }, - overrides: [ - { - files: ['**/*.{js,mjs,cjs,ts,mts,cts}'], - rules: { - 'constructor-super': 'error', - 'for-direction': 'error', - 'getter-return': 'error', - 'no-async-promise-executor': 'error', - 'no-case-declarations': 'error', - 'no-class-assign': 'error', - 'no-compare-neg-zero': 'error', - 'no-cond-assign': 'error', - 'no-const-assign': 'error', - 'no-constant-binary-expression': 'error', - 'no-constant-condition': 'error', - 'no-control-regex': 'error', - 'no-debugger': 'error', - 'no-delete-var': 'error', - 'no-dupe-class-members': 'error', - 'no-dupe-else-if': 'error', - 'no-dupe-keys': 'error', - 'no-duplicate-case': 'error', - 'no-empty': 'error', - 'no-empty-character-class': 'error', - 'no-empty-pattern': 'error', - 'no-empty-static-block': 'error', - 'no-ex-assign': 'error', - 'no-extra-boolean-cast': 'error', - 'no-fallthrough': 'error', - 'no-func-assign': 'error', - 'no-global-assign': 'error', - 'no-import-assign': 'error', - 'no-invalid-regexp': 'error', - 'no-irregular-whitespace': 'error', - 'no-loss-of-precision': 'error', - 'no-misleading-character-class': 'error', - 'no-new-native-nonconstructor': 'error', - 'no-nonoctal-decimal-escape': 'error', - 'no-obj-calls': 'error', - 'no-prototype-builtins': 'error', - 'no-redeclare': 'error', - 'no-regex-spaces': 'error', - 'no-self-assign': 'error', - 'no-setter-return': 'error', - 'no-shadow-restricted-names': 'error', - 'no-sparse-arrays': 'error', - 'no-this-before-super': 'error', - 'no-unassigned-vars': 'error', - 'no-undef': 'error', - 'no-unexpected-multiline': 'error', - 'no-unreachable': 'error', - 'no-unsafe-finally': 'error', - 'no-unsafe-negation': 'error', - 'no-unsafe-optional-chaining': 'error', - 'no-unused-labels': 'error', - 'no-unused-private-class-members': 'error', - 'no-useless-assignment': 'error', - 'no-useless-backreference': 'error', - 'no-useless-catch': 'error', - 'no-useless-escape': 'error', - 'no-with': 'error', - 'preserve-caught-error': 'error', - 'require-yield': 'error', - 'use-isnan': 'error', - 'valid-typeof': 'error', - }, - env: { - node: true, - }, - }, - { - files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'], - rules: { - 'constructor-super': 'off', - 'getter-return': 'off', - 'no-class-assign': 'off', - 'no-const-assign': 'off', - 'no-dupe-class-members': 'off', - 'no-dupe-keys': 'off', - 'no-func-assign': 'off', - 'no-import-assign': 'off', - 'no-new-native-nonconstructor': 'off', - 'no-obj-calls': 'off', - 'no-redeclare': 'off', - 'no-setter-return': 'off', - 'no-this-before-super': 'off', - 'no-undef': 'off', - 'no-unreachable': 'off', - 'no-unsafe-negation': 'off', - 'no-var': 'error', - 'no-with': 'off', - 'prefer-const': 'error', - 'prefer-rest-params': 'error', - 'prefer-spread': 'error', - }, - }, - ], plugins: ['oxc', 'typescript', 'unicorn'], rules: { - 'no-array-constructor': 'error', - 'no-unused-expressions': 'error', - 'no-unused-vars': 'error', - 'typescript/ban-ts-comment': 'error', - 'typescript/no-duplicate-enum-values': 'error', - 'typescript/no-empty-object-type': 'error', - 'typescript/no-explicit-any': 'error', - 'typescript/no-extra-non-null-assertion': 'error', - 'typescript/no-misused-new': 'error', - 'typescript/no-namespace': 'error', - 'typescript/no-non-null-asserted-optional-chain': 'error', - 'typescript/no-require-imports': 'error', - 'typescript/no-this-alias': 'error', - 'typescript/no-unnecessary-type-constraint': 'error', - 'typescript/no-unsafe-declaration-merging': 'error', - 'typescript/no-unsafe-function-type': 'error', - 'typescript/no-wrapper-object-types': 'error', - 'typescript/prefer-as-const': 'error', - 'typescript/prefer-namespace-keyword': 'error', - 'typescript/triple-slash-reference': 'error', - 'vite-plus/prefer-vite-plus-imports': 'error', + 'no-undefined': 'allow', + 'oxc/no-async-await': 'allow', }, }, }); diff --git a/integration_tests/typescript_node/src/assertions.ts b/integration_tests/typescript_node/src/assertions.ts index 50da320e..20aea76c 100644 --- a/integration_tests/typescript_node/src/assertions.ts +++ b/integration_tests/typescript_node/src/assertions.ts @@ -1,5 +1,6 @@ -import { deepStrictEqual } from 'assert'; -import { unlinkSync, writeFileSync } from 'fs'; +// oxlint-disable no-console -- Integration tests print serialized messages for diagnostics. +import { deepStrictEqual } from 'node:assert'; +import { unlinkSync, writeFileSync } from 'node:fs'; // The "omnifile" records the bytes of every message serialized by the exported functions below. // It's used to validate that the TypeScript code generator encodes data identically to other code @@ -8,15 +9,14 @@ const omnifilePath = '/tmp/omnifile-typescript'; try { unlinkSync(omnifilePath); - // oxlint-disable-next-line @typescript-eslint/no-unused-vars -} catch (_) { +} catch { // Attempting to delete the file will fail if the file doesn't exist. This is harmless. } -export function assertMatch( +export function assertMatch( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (bytes: ArrayBuffer) => I, + deserialize: (bytes: ArrayBuffer) => unknown, actual: O, expected: unknown, ): void { @@ -37,11 +37,11 @@ export function assertMatch( console.log('Message deserialized from those bytes:', replica); } -export function assertRoundTrip( +export function assertRoundTrip( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (bytes: ArrayBuffer) => I, - message: V, + deserialize: (bytes: ArrayBuffer) => unknown, + message: O, ): void { assertMatch(size, serialize, deserialize, message, message); } diff --git a/integration_tests/typescript_node/src/circular-dependency.ts b/integration_tests/typescript_node/src/circular-dependency.ts index 6639f3a7..e716f0de 100644 --- a/integration_tests/typescript_node/src/circular-dependency.ts +++ b/integration_tests/typescript_node/src/circular-dependency.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Integration tests print progress between cases. import { StructFromBelow } from '../generated/circular_dependency/dependency/types'; import { StructFromAbove } from '../generated/circular_dependency/types'; import { assertRoundTrip } from './assertions'; diff --git a/integration_tests/typescript_node/src/comprehensive.ts b/integration_tests/typescript_node/src/comprehensive.ts index 8ee6980b..b59e4c7a 100644 --- a/integration_tests/typescript_node/src/comprehensive.ts +++ b/integration_tests/typescript_node/src/comprehensive.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Integration fixtures print diagnostics. import { Bar, Foo } from '../generated/comprehensive/types'; import { assertMatch, assertRoundTrip } from './assertions'; @@ -306,26 +307,26 @@ export default function run(): void { aRequired: null, }); - f64TestValues.forEach((bRequired) => { + for (const bRequired of f64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'bRequired', bRequired, }); - }); + } - u64TestValues.forEach((cRequired) => { + for (const cRequired of u64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'cRequired', cRequired, }); - }); + } - s64TestValues.forEach((dRequired) => { + for (const dRequired of s64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'dRequired', dRequired, }); - }); + } assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'eRequired', @@ -883,7 +884,7 @@ export default function run(): void { }, ); - f64TestValues.forEach((bAsymmetric) => { + for (const bAsymmetric of f64TestValues) { assertMatch( Bar.size, Bar.serialize, @@ -898,9 +899,9 @@ export default function run(): void { bAsymmetric, }, ); - }); + } - u64TestValues.forEach((cAsymmetric) => { + for (const cAsymmetric of u64TestValues) { assertMatch( Bar.size, Bar.serialize, @@ -915,9 +916,9 @@ export default function run(): void { cAsymmetric, }, ); - }); + } - s64TestValues.forEach((dAsymmetric) => { + for (const dAsymmetric of s64TestValues) { assertMatch( Bar.size, Bar.serialize, @@ -932,7 +933,7 @@ export default function run(): void { dAsymmetric, }, ); - }); + } assertMatch( Bar.size, @@ -2538,29 +2539,29 @@ export default function run(): void { $fallback, }); - f64TestValues.forEach((bOptional) => { + for (const bOptional of f64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'bOptional', bOptional, $fallback, }); - }); + } - u64TestValues.forEach((cOptional) => { + for (const cOptional of u64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'cOptional', cOptional, $fallback, }); - }); + } - s64TestValues.forEach((dOptional) => { + for (const dOptional of s64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'dOptional', dOptional, $fallback, }); - }); + } assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'eOptional', diff --git a/integration_tests/typescript_node/src/degenerate.ts b/integration_tests/typescript_node/src/degenerate.ts index 1a990a13..db6cd023 100644 --- a/integration_tests/typescript_node/src/degenerate.ts +++ b/integration_tests/typescript_node/src/degenerate.ts @@ -7,23 +7,19 @@ import { } from '../generated/degenerate/types'; import { assertRoundTrip } from './assertions'; -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function initialIn(x: EmptyChoiceIn): T { +export function initialIn(x: EmptyChoiceIn): never { return x; } -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function initialOut(x: EmptyChoiceOut): T { +export function initialOut(x: EmptyChoiceOut): never { return x; } -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function terminalIn(x: T): EmptyStructIn { +export function terminalIn(_x: unknown): EmptyStructIn { return {}; } -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function terminalOut(x: T): EmptyStructOut { +export function terminalOut(_x: unknown): EmptyStructOut { return {}; } diff --git a/integration_tests/typescript_node/src/main.ts b/integration_tests/typescript_node/src/main.ts index db2cba21..f5e1e654 100644 --- a/integration_tests/typescript_node/src/main.ts +++ b/integration_tests/typescript_node/src/main.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Integration tests print progress between cases. import runCircularDependency from './circular-dependency'; import runComprehensive from './comprehensive'; import runDegenerate from './degenerate'; diff --git a/integration_tests/typescript_node/src/schema-evolution.ts b/integration_tests/typescript_node/src/schema-evolution.ts index 5c12a665..ae39644c 100644 --- a/integration_tests/typescript_node/src/schema-evolution.ts +++ b/integration_tests/typescript_node/src/schema-evolution.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Schema evolution tests print progress between cases. import { ExampleChoice as AfterExampleChoice, type ExampleChoiceIn as AfterExampleChoiceIn, diff --git a/integration_tests/typescript_node/tsconfig.json b/integration_tests/typescript_node/tsconfig.json index e2839564..0f209d84 100644 --- a/integration_tests/typescript_node/tsconfig.json +++ b/integration_tests/typescript_node/tsconfig.json @@ -1,8 +1,14 @@ { "compilerOptions": { + "target": "es2023", "module": "nodenext", + "moduleDetection": "force", "outDir": "dist", - "types": ["node"] + "types": ["node"], + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "strict": true }, - "include": ["src"] + "include": ["src", "vite.config.ts"] } diff --git a/integration_tests/typescript_node/vite.config.ts b/integration_tests/typescript_node/vite.config.ts index ee99f03e..e7d6ca25 100644 --- a/integration_tests/typescript_node/vite.config.ts +++ b/integration_tests/typescript_node/vite.config.ts @@ -2,11 +2,15 @@ import { defineConfig } from 'vite-plus'; export default defineConfig({ fmt: { + ignorePatterns: ['**/*.md'], singleQuote: true, }, lint: { categories: { correctness: 'deny', + perf: 'deny', + restriction: 'deny', + suspicious: 'deny', }, jsPlugins: [ { @@ -18,126 +22,10 @@ export default defineConfig({ typeAware: true, typeCheck: true, }, - overrides: [ - { - files: ['**/*.{js,mjs,cjs,ts,mts,cts}'], - rules: { - 'constructor-super': 'error', - 'for-direction': 'error', - 'getter-return': 'error', - 'no-async-promise-executor': 'error', - 'no-case-declarations': 'error', - 'no-class-assign': 'error', - 'no-compare-neg-zero': 'error', - 'no-cond-assign': 'error', - 'no-const-assign': 'error', - 'no-constant-binary-expression': 'error', - 'no-constant-condition': 'error', - 'no-control-regex': 'error', - 'no-debugger': 'error', - 'no-delete-var': 'error', - 'no-dupe-class-members': 'error', - 'no-dupe-else-if': 'error', - 'no-dupe-keys': 'error', - 'no-duplicate-case': 'error', - 'no-empty': 'error', - 'no-empty-character-class': 'error', - 'no-empty-pattern': 'error', - 'no-empty-static-block': 'error', - 'no-ex-assign': 'error', - 'no-extra-boolean-cast': 'error', - 'no-fallthrough': 'error', - 'no-func-assign': 'error', - 'no-global-assign': 'error', - 'no-import-assign': 'error', - 'no-invalid-regexp': 'error', - 'no-irregular-whitespace': 'error', - 'no-loss-of-precision': 'error', - 'no-misleading-character-class': 'error', - 'no-new-native-nonconstructor': 'error', - 'no-nonoctal-decimal-escape': 'error', - 'no-obj-calls': 'error', - 'no-prototype-builtins': 'error', - 'no-redeclare': 'error', - 'no-regex-spaces': 'error', - 'no-self-assign': 'error', - 'no-setter-return': 'error', - 'no-shadow-restricted-names': 'error', - 'no-sparse-arrays': 'error', - 'no-this-before-super': 'error', - 'no-unassigned-vars': 'error', - 'no-undef': 'error', - 'no-unexpected-multiline': 'error', - 'no-unreachable': 'error', - 'no-unsafe-finally': 'error', - 'no-unsafe-negation': 'error', - 'no-unsafe-optional-chaining': 'error', - 'no-unused-labels': 'error', - 'no-unused-private-class-members': 'error', - 'no-useless-assignment': 'error', - 'no-useless-backreference': 'error', - 'no-useless-catch': 'error', - 'no-useless-escape': 'error', - 'no-with': 'error', - 'preserve-caught-error': 'error', - 'require-yield': 'error', - 'use-isnan': 'error', - 'valid-typeof': 'error', - }, - env: { - node: true, - }, - }, - { - files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'], - rules: { - 'constructor-super': 'off', - 'getter-return': 'off', - 'no-class-assign': 'off', - 'no-const-assign': 'off', - 'no-dupe-class-members': 'off', - 'no-dupe-keys': 'off', - 'no-func-assign': 'off', - 'no-import-assign': 'off', - 'no-new-native-nonconstructor': 'off', - 'no-obj-calls': 'off', - 'no-redeclare': 'off', - 'no-setter-return': 'off', - 'no-this-before-super': 'off', - 'no-undef': 'off', - 'no-unreachable': 'off', - 'no-unsafe-negation': 'off', - 'no-var': 'error', - 'no-with': 'off', - 'prefer-const': 'error', - 'prefer-rest-params': 'error', - 'prefer-spread': 'error', - }, - }, - ], plugins: ['oxc', 'typescript', 'unicorn'], rules: { - 'no-array-constructor': 'error', - 'no-unused-expressions': 'error', - 'no-unused-vars': 'error', - 'typescript/ban-ts-comment': 'error', - 'typescript/no-duplicate-enum-values': 'error', - 'typescript/no-empty-object-type': 'error', - 'typescript/no-explicit-any': 'error', - 'typescript/no-extra-non-null-assertion': 'error', - 'typescript/no-misused-new': 'error', - 'typescript/no-namespace': 'error', - 'typescript/no-non-null-asserted-optional-chain': 'error', - 'typescript/no-require-imports': 'error', - 'typescript/no-this-alias': 'error', - 'typescript/no-unnecessary-type-constraint': 'error', - 'typescript/no-unsafe-declaration-merging': 'error', - 'typescript/no-unsafe-function-type': 'error', - 'typescript/no-wrapper-object-types': 'error', - 'typescript/prefer-as-const': 'error', - 'typescript/prefer-namespace-keyword': 'error', - 'typescript/triple-slash-reference': 'error', - 'vite-plus/prefer-vite-plus-imports': 'error', + 'no-undefined': 'allow', + 'oxc/no-async-await': 'allow', }, }, }); diff --git a/integration_tests/typescript_web/src/assertions.ts b/integration_tests/typescript_web/src/assertions.ts index 30c9649c..db742285 100644 --- a/integration_tests/typescript_web/src/assertions.ts +++ b/integration_tests/typescript_web/src/assertions.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Integration tests print serialized messages for diagnostics. import { isEqual } from 'lodash'; import { sha256 } from 'js-sha256'; @@ -10,16 +11,16 @@ const omnifileBuffer = new ArrayBuffer(omnifileSize); const omnifileArray = new Uint8Array(omnifileBuffer); let omnifileOffset = 0; -function deepStrictEqual(x: T, y: U): void { +function deepStrictEqual(x: unknown, y: unknown): void { if (!isEqual(x, y)) { throw new Error('Mismatch!'); } } -export function assertMatch( +export function assertMatch( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (bytes: ArrayBuffer) => I, + deserialize: (bytes: ArrayBuffer) => unknown, actual: O, expected: unknown, ): void { @@ -42,11 +43,11 @@ export function assertMatch( console.log('Message deserialized from those bytes:', replica); } -export function assertRoundTrip( +export function assertRoundTrip( size: (message: O) => number, serialize: (message: O) => ArrayBuffer, - deserialize: (bytes: ArrayBuffer) => I, - message: V, + deserialize: (bytes: ArrayBuffer) => unknown, + message: O, ): void { assertMatch(size, serialize, deserialize, message, message); } diff --git a/integration_tests/typescript_web/src/circular-dependency.ts b/integration_tests/typescript_web/src/circular-dependency.ts index 6639f3a7..e716f0de 100644 --- a/integration_tests/typescript_web/src/circular-dependency.ts +++ b/integration_tests/typescript_web/src/circular-dependency.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Integration tests print progress between cases. import { StructFromBelow } from '../generated/circular_dependency/dependency/types'; import { StructFromAbove } from '../generated/circular_dependency/types'; import { assertRoundTrip } from './assertions'; diff --git a/integration_tests/typescript_web/src/comprehensive.ts b/integration_tests/typescript_web/src/comprehensive.ts index 8ee6980b..b59e4c7a 100644 --- a/integration_tests/typescript_web/src/comprehensive.ts +++ b/integration_tests/typescript_web/src/comprehensive.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Integration fixtures print diagnostics. import { Bar, Foo } from '../generated/comprehensive/types'; import { assertMatch, assertRoundTrip } from './assertions'; @@ -306,26 +307,26 @@ export default function run(): void { aRequired: null, }); - f64TestValues.forEach((bRequired) => { + for (const bRequired of f64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'bRequired', bRequired, }); - }); + } - u64TestValues.forEach((cRequired) => { + for (const cRequired of u64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'cRequired', cRequired, }); - }); + } - s64TestValues.forEach((dRequired) => { + for (const dRequired of s64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'dRequired', dRequired, }); - }); + } assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'eRequired', @@ -883,7 +884,7 @@ export default function run(): void { }, ); - f64TestValues.forEach((bAsymmetric) => { + for (const bAsymmetric of f64TestValues) { assertMatch( Bar.size, Bar.serialize, @@ -898,9 +899,9 @@ export default function run(): void { bAsymmetric, }, ); - }); + } - u64TestValues.forEach((cAsymmetric) => { + for (const cAsymmetric of u64TestValues) { assertMatch( Bar.size, Bar.serialize, @@ -915,9 +916,9 @@ export default function run(): void { cAsymmetric, }, ); - }); + } - s64TestValues.forEach((dAsymmetric) => { + for (const dAsymmetric of s64TestValues) { assertMatch( Bar.size, Bar.serialize, @@ -932,7 +933,7 @@ export default function run(): void { dAsymmetric, }, ); - }); + } assertMatch( Bar.size, @@ -2538,29 +2539,29 @@ export default function run(): void { $fallback, }); - f64TestValues.forEach((bOptional) => { + for (const bOptional of f64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'bOptional', bOptional, $fallback, }); - }); + } - u64TestValues.forEach((cOptional) => { + for (const cOptional of u64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'cOptional', cOptional, $fallback, }); - }); + } - s64TestValues.forEach((dOptional) => { + for (const dOptional of s64TestValues) { assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'dOptional', dOptional, $fallback, }); - }); + } assertRoundTrip(Bar.size, Bar.serialize, Bar.deserialize, { $field: 'eOptional', diff --git a/integration_tests/typescript_web/src/degenerate.ts b/integration_tests/typescript_web/src/degenerate.ts index 1a990a13..db6cd023 100644 --- a/integration_tests/typescript_web/src/degenerate.ts +++ b/integration_tests/typescript_web/src/degenerate.ts @@ -7,23 +7,19 @@ import { } from '../generated/degenerate/types'; import { assertRoundTrip } from './assertions'; -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function initialIn(x: EmptyChoiceIn): T { +export function initialIn(x: EmptyChoiceIn): never { return x; } -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function initialOut(x: EmptyChoiceOut): T { +export function initialOut(x: EmptyChoiceOut): never { return x; } -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function terminalIn(x: T): EmptyStructIn { +export function terminalIn(_x: unknown): EmptyStructIn { return {}; } -// oxlint-disable-next-line @typescript-eslint/no-unused-vars -- We only care that it type checks. -function terminalOut(x: T): EmptyStructOut { +export function terminalOut(_x: unknown): EmptyStructOut { return {}; } diff --git a/integration_tests/typescript_web/src/main.ts b/integration_tests/typescript_web/src/main.ts index e42c32a3..5986e7fe 100644 --- a/integration_tests/typescript_web/src/main.ts +++ b/integration_tests/typescript_web/src/main.ts @@ -1,10 +1,21 @@ +// oxlint-disable no-console -- Integration tests print progress between cases. import runCircularDependency from './circular-dependency'; import runComprehensive from './comprehensive'; import runDegenerate from './degenerate'; import runSchemaEvolution from './schema-evolution'; import { verifyOmnifile } from './assertions'; -document.querySelector('#app')!.innerHTML = 'Running integration tests\u2026'; +function setStatus(message: string): void { + const app = document.querySelector('#app'); + + if (app === null) { + throw new Error('Missing app element.'); + } + + app.innerHTML = message; +} + +setStatus('Running integration tests\u2026'); window.requestAnimationFrame(() => { try { @@ -30,5 +41,5 @@ window.requestAnimationFrame(() => { throw e; } - document.querySelector('#app')!.innerHTML = 'Integration tests passed.'; + setStatus('Integration tests passed.'); }); diff --git a/integration_tests/typescript_web/src/schema-evolution.ts b/integration_tests/typescript_web/src/schema-evolution.ts index 5c12a665..ae39644c 100644 --- a/integration_tests/typescript_web/src/schema-evolution.ts +++ b/integration_tests/typescript_web/src/schema-evolution.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-console -- Schema evolution tests print progress between cases. import { ExampleChoice as AfterExampleChoice, type ExampleChoiceIn as AfterExampleChoiceIn, diff --git a/integration_tests/typescript_web/tsconfig.json b/integration_tests/typescript_web/tsconfig.json index b57a6ccf..c18c46dd 100644 --- a/integration_tests/typescript_web/tsconfig.json +++ b/integration_tests/typescript_web/tsconfig.json @@ -1,9 +1,16 @@ { "compilerOptions": { + "target": "es2023", "module": "esnext", "moduleResolution": "bundler", + "types": ["vite-plus/client"], + "erasableSyntaxOnly": true, + "moduleDetection": "force", "noEmit": true, - "types": ["vite-plus/client"] + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "strict": true, + "verbatimModuleSyntax": true }, - "include": ["src"] + "include": ["src", "vite.config.ts"] } diff --git a/integration_tests/typescript_web/vite.config.ts b/integration_tests/typescript_web/vite.config.ts index e1d5fe23..e7d6ca25 100644 --- a/integration_tests/typescript_web/vite.config.ts +++ b/integration_tests/typescript_web/vite.config.ts @@ -2,11 +2,15 @@ import { defineConfig } from 'vite-plus'; export default defineConfig({ fmt: { + ignorePatterns: ['**/*.md'], singleQuote: true, }, lint: { categories: { correctness: 'deny', + perf: 'deny', + restriction: 'deny', + suspicious: 'deny', }, jsPlugins: [ { @@ -18,126 +22,10 @@ export default defineConfig({ typeAware: true, typeCheck: true, }, - overrides: [ - { - files: ['**/*.{js,mjs,cjs,ts,mts,cts}'], - rules: { - 'constructor-super': 'error', - 'for-direction': 'error', - 'getter-return': 'error', - 'no-async-promise-executor': 'error', - 'no-case-declarations': 'error', - 'no-class-assign': 'error', - 'no-compare-neg-zero': 'error', - 'no-cond-assign': 'error', - 'no-const-assign': 'error', - 'no-constant-binary-expression': 'error', - 'no-constant-condition': 'error', - 'no-control-regex': 'error', - 'no-debugger': 'error', - 'no-delete-var': 'error', - 'no-dupe-class-members': 'error', - 'no-dupe-else-if': 'error', - 'no-dupe-keys': 'error', - 'no-duplicate-case': 'error', - 'no-empty': 'error', - 'no-empty-character-class': 'error', - 'no-empty-pattern': 'error', - 'no-empty-static-block': 'error', - 'no-ex-assign': 'error', - 'no-extra-boolean-cast': 'error', - 'no-fallthrough': 'error', - 'no-func-assign': 'error', - 'no-global-assign': 'error', - 'no-import-assign': 'error', - 'no-invalid-regexp': 'error', - 'no-irregular-whitespace': 'error', - 'no-loss-of-precision': 'error', - 'no-misleading-character-class': 'error', - 'no-new-native-nonconstructor': 'error', - 'no-nonoctal-decimal-escape': 'error', - 'no-obj-calls': 'error', - 'no-prototype-builtins': 'error', - 'no-redeclare': 'error', - 'no-regex-spaces': 'error', - 'no-self-assign': 'error', - 'no-setter-return': 'error', - 'no-shadow-restricted-names': 'error', - 'no-sparse-arrays': 'error', - 'no-this-before-super': 'error', - 'no-unassigned-vars': 'error', - 'no-undef': 'error', - 'no-unexpected-multiline': 'error', - 'no-unreachable': 'error', - 'no-unsafe-finally': 'error', - 'no-unsafe-negation': 'error', - 'no-unsafe-optional-chaining': 'error', - 'no-unused-labels': 'error', - 'no-unused-private-class-members': 'error', - 'no-useless-assignment': 'error', - 'no-useless-backreference': 'error', - 'no-useless-catch': 'error', - 'no-useless-escape': 'error', - 'no-with': 'error', - 'preserve-caught-error': 'error', - 'require-yield': 'error', - 'use-isnan': 'error', - 'valid-typeof': 'error', - }, - env: { - browser: true, - }, - }, - { - files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'], - rules: { - 'constructor-super': 'off', - 'getter-return': 'off', - 'no-class-assign': 'off', - 'no-const-assign': 'off', - 'no-dupe-class-members': 'off', - 'no-dupe-keys': 'off', - 'no-func-assign': 'off', - 'no-import-assign': 'off', - 'no-new-native-nonconstructor': 'off', - 'no-obj-calls': 'off', - 'no-redeclare': 'off', - 'no-setter-return': 'off', - 'no-this-before-super': 'off', - 'no-undef': 'off', - 'no-unreachable': 'off', - 'no-unsafe-negation': 'off', - 'no-var': 'error', - 'no-with': 'off', - 'prefer-const': 'error', - 'prefer-rest-params': 'error', - 'prefer-spread': 'error', - }, - }, - ], plugins: ['oxc', 'typescript', 'unicorn'], rules: { - 'no-array-constructor': 'error', - 'no-unused-expressions': 'error', - 'no-unused-vars': 'error', - 'typescript/ban-ts-comment': 'error', - 'typescript/no-duplicate-enum-values': 'error', - 'typescript/no-empty-object-type': 'error', - 'typescript/no-explicit-any': 'error', - 'typescript/no-extra-non-null-assertion': 'error', - 'typescript/no-misused-new': 'error', - 'typescript/no-namespace': 'error', - 'typescript/no-non-null-asserted-optional-chain': 'error', - 'typescript/no-require-imports': 'error', - 'typescript/no-this-alias': 'error', - 'typescript/no-unnecessary-type-constraint': 'error', - 'typescript/no-unsafe-declaration-merging': 'error', - 'typescript/no-unsafe-function-type': 'error', - 'typescript/no-wrapper-object-types': 'error', - 'typescript/prefer-as-const': 'error', - 'typescript/prefer-namespace-keyword': 'error', - 'typescript/triple-slash-reference': 'error', - 'vite-plus/prefer-vite-plus-imports': 'error', + 'no-undefined': 'allow', + 'oxc/no-async-await': 'allow', }, }, });