diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 000000000..7d9cabfc5 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,372 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": [ + "typescript" + ], + "categories": { + "correctness": "off" + }, + "options": { + "typeAware": true, + "maxWarnings": 0 + }, + "env": { + "builtin": true + }, + "ignorePatterns": [ + "addons/*/src/third-party/*.ts", + "**/out/*", + "**/out-test/*", + "**/out-esbuild/*", + "**/out-esbuild-test/*", + "**/inwasm-sdks/*", + "**/typings/*.d.ts", + "**/node_modules", + "**/*.js", + "**/*.mjs" + ], + "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-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-unused-vars": "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", + "no-array-constructor": "error", + "no-unused-expressions": "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" + }, + "overrides": [ + { + "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-unreachable": "off", + "no-unsafe-negation": "off", + "no-var": "error", + "no-with": "off", + "prefer-const": "error", + "prefer-rest-params": "error", + "prefer-spread": "error" + } + }, + { + "files": [ + "**/*.ts" + ], + "jsPlugins": [ + "@stylistic/eslint-plugin", + { + "name": "jsdoc-js", + "specifier": "eslint-plugin-jsdoc" + }, + "oxlint-plugin-eslint" + ], + "rules": { + "@stylistic/comma-spacing": [ + "warn", + { + "before": false, + "after": true + } + ], + "@stylistic/indent": [ + "warn", + 2 + ], + "@stylistic/semi": [ + "warn", + "always" + ], + "@stylistic/quotes": [ + "warn", + "single", + { + "allowTemplateLiterals": "always" + } + ], + "@stylistic/member-delimiter-style": [ + "warn", + { + "multiline": { + "delimiter": "semi", + "requireLast": true + }, + "singleline": { + "delimiter": "comma", + "requireLast": false + } + } + ], + "@stylistic/type-annotation-spacing": "warn", + "@stylistic/space-unary-ops": "warn", + "@stylistic/keyword-spacing": "warn", + "@stylistic/max-len": [ + "warn", + { + "code": 1000, + "comments": 100, + "ignoreTrailingComments": true, + "ignoreUrls": true, + "ignorePattern": "^ *((?(//|\\*) @vt)|(?\\* \\| )|(?// ))" + } + ], + "@stylistic/new-parens": "warn", + "@stylistic/no-extra-semi": "error", + "@stylistic/no-trailing-spaces": "warn", + "eslint-js/object-curly-spacing": [ + "warn", + "always" + ], + "@stylistic/spaced-comment": [ + "warn", + "always", + { + "markers": [ + "/" + ], + "exceptions": [ + "-" + ] + } + ], + "jsdoc-js/check-alignment": "warn", + "jsdoc-js/check-param-names": "warn", + "jsdoc-js/multiline-blocks": "warn", + "jsdoc-js/no-multi-asterisks": "warn", + "eslint-js/one-var": [ + "warn", + "never" + ], + "eslint-js/no-restricted-syntax": [ + "warn", + { + "selector": "CallExpression[callee.name='requestAnimationFrame']", + "message": "The global requestAnimationFrame() should be avoided, call it on the parent window from ICoreBrowserService." + }, + { + "selector": "CallExpression[callee.name='cancelAnimationFrame']", + "message": "The global cancelAnimationFrame() should be avoided, call it on the parent window from ICoreBrowserService." + }, + { + "selector": "CallExpression > MemberExpression[object.name='window'][property.name='requestAnimationFrame']", + "message": "window.requestAnimationFrame() should be avoided, call it on the parent window from ICoreBrowserService." + }, + { + "selector": "CallExpression > MemberExpression[object.name='window'][property.name='cancelAnimationFrame']", + "message": "window.cancelAnimationFrame() should be avoided, call it on the parent window from ICoreBrowserService." + }, + { + "selector": "MemberExpression[object.name='window'][property.name='devicePixelRatio']", + "message": "window.devicePixelRatio should be avoided, get it from ICoreBrowserService." + } + ], + "curly": [ + "warn", + "multi-line" + ], + "eqeqeq": [ + "warn", + "always" + ], + "no-duplicate-imports": "warn", + "no-else-return": [ + "warn", + { + "allowElseIf": false + } + ], + "no-eval": "warn", + "no-irregular-whitespace": "warn", + "no-restricted-imports": [ + "warn", + { + "patterns": [ + ".*\\/out\\/.*" + ] + } + ], + "no-unsafe-finally": "warn", + "no-unused-vars": "off", + "no-var": "warn", + "no-empty": "off", + "no-empty-pattern": "off", + "no-cond-assign": "off", + "no-case-declarations": "off", + "for-direction": "off", + "no-prototype-builtins": "off", + "no-useless-escape": "off", + "no-self-assign": "off", + "no-async-promise-executor": "off", + "prefer-rest-params": "off", + "no-control-regex": "off", + "no-fallthrough": "off", + "prefer-spread": "off", + "prefer-const": "warn", + "no-unused-expressions": "off", + "typescript/array-type": [ + "warn", + { + "default": "array", + "readonly": "generic" + } + ], + "typescript/consistent-type-assertions": "warn", + "typescript/consistent-type-definitions": "warn", + "typescript/explicit-function-return-type": [ + "warn", + { + "allowExpressions": true + } + ], + "typescript/explicit-member-accessibility": [ + "warn", + { + "accessibility": "explicit", + "overrides": { + "constructors": "off" + } + } + ], + "typescript/no-confusing-void-expression": [ + "warn", + { + "ignoreArrowShorthand": true + } + ], + "typescript/no-useless-constructor": "warn", + "typescript/prefer-nullish-coalescing": [ + "warn", + { + "ignorePrimitives": true + } + ], + "typescript/prefer-namespace-keyword": "warn", + "typescript/no-unused-vars": [ + "warn", + { + "vars": "all", + "args": "none" + } + ], + "typescript/no-require-imports": "off", + "typescript/no-explicit-any": "off", + "typescript/no-wrapper-object-types": "off", + "typescript/no-empty-object-type": "off", + "typescript/no-unsafe-function-type": "off", + "typescript/no-this-alias": "off", + "typescript/no-namespace": "off", + "typescript/no-duplicate-enum-values": "off" + } + }, + { + "files": [ + "**/*.api.ts", + "**/*.test.ts" + ], + "rules": { + "eslint-js/object-curly-spacing": "off", + "@stylistic/max-len": "off", + "typescript/no-unused-vars": "off", + "typescript/explicit-function-return-type": "off", + "typescript/explicit-member-accessibility": "off" + } + }, + { + "files": [ + "demo/**/*.ts", + "**/*.benchmark.ts" + ], + "rules": { + "typescript/prefer-nullish-coalescing": "off" + } + } + ] +} diff --git a/.oxlintrc.typings.json b/.oxlintrc.typings.json new file mode 100644 index 000000000..d3dd28e01 --- /dev/null +++ b/.oxlintrc.typings.json @@ -0,0 +1,120 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "options": { + "maxWarnings": 0 + }, + "env": { + "builtin": true + }, + "overrides": [ + { + "files": [ + "typings/**/*.d.ts" + ], + "plugins": [ + "typescript" + ], + "jsPlugins": [ + "@stylistic/eslint-plugin", + { + "name": "jsdoc-js", + "specifier": "eslint-plugin-jsdoc" + }, + "oxlint-plugin-eslint" + ], + "rules": { + "@stylistic/indent": [ + "warn", + 2 + ], + "@stylistic/semi": [ + "warn", + "always" + ], + "@stylistic/quotes": [ + "warn", + "single", + { + "allowTemplateLiterals": "always" + } + ], + "@stylistic/member-delimiter-style": [ + "warn", + { + "multiline": { + "delimiter": "semi", + "requireLast": true + }, + "singleline": { + "delimiter": "comma", + "requireLast": false + } + } + ], + "@stylistic/type-annotation-spacing": "warn", + "@stylistic/keyword-spacing": "warn", + "@stylistic/max-len": [ + "warn", + { + "code": 1000, + "comments": 80, + "ignoreUrls": true, + "ignorePattern": "^ *(?\\* Ps=)" + } + ], + "@stylistic/no-extra-semi": "error", + "@stylistic/no-trailing-spaces": "warn", + "eslint-js/object-curly-spacing": [ + "warn", + "always" + ], + "@stylistic/spaced-comment": [ + "warn", + "always", + { + "markers": [ + "/" + ], + "exceptions": [ + "-" + ] + } + ], + "@stylistic/comma-dangle": [ + "warn", + { + "objects": "never", + "arrays": "never", + "functions": "never" + } + ], + "@stylistic/eol-last": "warn", + "curly": [ + "warn", + "multi-line" + ], + "eqeqeq": [ + "warn", + "always" + ], + "jsdoc-js/check-alignment": "warn", + "jsdoc-js/check-param-names": "warn", + "no-irregular-whitespace": "warn", + "typescript/array-type": [ + "warn", + { + "default": "array", + "readonly": "generic" + } + ], + "typescript/explicit-function-return-type": [ + "warn", + { + "allowExpressions": true + } + ], + "typescript/prefer-namespace-keyword": "warn" + } + } + ] +} diff --git a/AGENTS.md b/AGENTS.md index 5b07ce824..e32bae54c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -26,6 +26,7 @@ npm run build && npm run esbuild # Build all TypeScript and bundle - Integration tests: `npm run test-integration` (Playwright across Chrome/Firefox/WebKit) - Integration tests by file: `npm run test-integration -- test/playwright/InputHandler.test.ts`. Never use grep to filter tests, it doesn't work - Integration tests by addon: `npm run test-integration -- --suite=addon-search`. Suites always follow the format `addon-` +- Lint: `npm run lint` (oxlint with type-aware rules, then ESLint for `naming-convention` only), `npm run lint-api` for `typings/`, `npm run lint-fix` for oxlint auto-fix - Lint changes: `npm run lint-changes` to lint only changed files, `npm run lint-changes-fix` to fix them ## Addon Development Pattern diff --git a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts index c35299809..cf8dd2493 100644 --- a/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts +++ b/addons/addon-webgl/src/customGlyphs/CustomGlyphDefinitions.ts @@ -5,7 +5,7 @@ import { CustomGlyphDefinitionType, CustomGlyphScaleType, CustomGlyphVectorType, type CustomGlyphCharacterDefinition, type CustomGlyphDefinitionPart, type CustomGlyphPathDrawFunctionDefinition } from './Types'; -/* eslint-disable max-len */ +/* oxlint-disable @stylistic/max-len -- generated glyph path data */ const enum Shapes { /** │ */ TOP_TO_BOTTOM = 'M.5,0 L.5,1', diff --git a/bin/lint_changes.js b/bin/lint_changes.js index 6ed7ae5fa..b7571c5e3 100644 --- a/bin/lint_changes.js +++ b/bin/lint_changes.js @@ -33,17 +33,47 @@ if (files.length === 0) { console.log(`Linting ${files.length} changed file(s)...`); -const eslintArgs = ['--max-warnings', '0', '--no-warn-ignored']; -if (fix) { - eslintArgs.push('--fix'); +const cwd = path.join(__dirname, '..'); +const isWin = process.platform === 'win32'; + +/** + * @param {string} command + * @param {string[]} args + * @returns {Promise} + */ +function run(command, args) { + return new Promise(/** @type {(resolve: () => void, reject: (reason: Error) => void) => void} */ ((resolve, reject) => { + const child = spawn(command, args, { + stdio: 'inherit', + cwd, + shell: isWin + }); + child.on('close', code => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`${command} exited with code ${code}`)); + } + }); + })); } -eslintArgs.push(...files); -const eslint = process.platform === 'win32' ? 'eslint.cmd' : 'eslint'; -const child = spawn(eslint, eslintArgs, { - stdio: 'inherit', - cwd: path.join(__dirname, '..'), - shell: process.platform === 'win32' +async function main() { + const oxlintArgs = ['--type-aware', '--max-warnings', '0']; + if (fix) { + oxlintArgs.push('--fix'); + } + oxlintArgs.push(...files); + + const oxlint = isWin ? 'oxlint.cmd' : 'oxlint'; + await run(oxlint, oxlintArgs); + + const eslintArgs = ['--config', 'eslint.config.naming.mjs', '--max-warnings', '0', ...files]; + const eslint = isWin ? 'eslint.cmd' : 'eslint'; + await run(eslint, eslintArgs); +} + +main().catch(err => { + console.error(err.message); + process.exit(1); }); - -child.on('close', code => process.exit(code ?? 0)); diff --git a/demo/client/components/window/gpuWindow.ts b/demo/client/components/window/gpuWindow.ts index ac7b2c3db..382056aba 100644 --- a/demo/client/components/window/gpuWindow.ts +++ b/demo/client/components/window/gpuWindow.ts @@ -43,7 +43,7 @@ export class GpuWindow extends BaseWindow implements IControlWindow { } private _styleAtlasPage(canvas: HTMLCanvasElement): void { - // eslint-disable-next-line no-restricted-syntax + // oxlint-disable-next-line eslint-js/no-restricted-syntax const dpr = window.devicePixelRatio; canvas.style.width = `${canvas.width / dpr}px`; canvas.style.height = `${canvas.height / dpr}px`; diff --git a/demo/client/components/window/webglWindow.ts b/demo/client/components/window/webglWindow.ts index b61be231f..2886c3b57 100644 --- a/demo/client/components/window/webglWindow.ts +++ b/demo/client/components/window/webglWindow.ts @@ -43,7 +43,7 @@ export class WebglWindow extends BaseWindow implements IControlWindow { } private _styleAtlasPage(canvas: HTMLCanvasElement): void { - // eslint-disable-next-line no-restricted-syntax + // oxlint-disable-next-line eslint-js/no-restricted-syntax const dpr = window.devicePixelRatio; canvas.style.width = `${canvas.width / dpr}px`; canvas.style.height = `${canvas.height / dpr}px`; diff --git a/eslint.config.naming.mjs b/eslint.config.naming.mjs new file mode 100644 index 000000000..043f903c4 --- /dev/null +++ b/eslint.config.naming.mjs @@ -0,0 +1,71 @@ +// @ts-check +import tseslint from 'typescript-eslint'; + +const ignores = [ + 'addons/*/src/third-party/*.ts', + '**/out/*', + '**/out-test/*', + '**/out-esbuild/*', + '**/out-esbuild-test/*', + '**/inwasm-sdks/*', + '**/node_modules', + '**/*.js', + '**/*.mjs' +]; + +const namingConventionMain = [ + 'warn', + { selector: 'default', format: ['camelCase'], filter: { regex: '^[a-z]', match: true } }, + { selector: 'variable', format: ['camelCase', 'UPPER_CASE'] }, + { selector: 'variable', filter: '^I.+Service$', format: ['PascalCase'], prefix: ['I'] }, + { selector: 'memberLike', modifiers: ['private'], format: ['camelCase'], leadingUnderscore: 'require' }, + { selector: 'memberLike', modifiers: ['protected'], format: ['camelCase'], leadingUnderscore: 'require' }, + { selector: 'enumMember', format: ['UPPER_CASE'] }, + { selector: 'property', modifiers: ['public'], format: ['camelCase', 'UPPER_CASE'], filter: { regex: '^[a-z]', match: true } }, + { selector: 'method', modifiers: ['public'], format: ['camelCase', 'UPPER_CASE'], custom: { regex: '^on[A-Z].+', match: false } }, + { selector: 'method', modifiers: ['private'], format: ['camelCase'], leadingUnderscore: 'require', custom: { regex: '^on[A-Z].+', match: false } }, + { selector: 'method', modifiers: ['protected'], format: ['camelCase'], leadingUnderscore: 'require', custom: { regex: '^on[A-Z].+', match: false } }, + { selector: 'typeLike', format: ['PascalCase'] }, + { selector: 'interface', format: ['PascalCase'], prefix: ['I'] } +]; + +const namingConventionTypings = [ + 'warn', + { selector: 'typeLike', format: ['PascalCase'] }, + { selector: 'interface', format: ['PascalCase'], prefix: ['I'] } +]; + +export default tseslint.config( + { + ignores + }, + { + files: ['**/*.ts'], + ignores: ['typings/**/*.d.ts', 'addons/**/typings/**'], + plugins: { + '@typescript-eslint': tseslint.plugin + }, + languageOptions: { + parser: tseslint.parser, + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname + } + }, + rules: { + '@typescript-eslint/naming-convention': namingConventionMain + } + }, + { + files: ['typings/**/*.d.ts'], + plugins: { + '@typescript-eslint': tseslint.plugin + }, + languageOptions: { + parser: tseslint.parser + }, + rules: { + '@typescript-eslint/naming-convention': namingConventionTypings + } + } +); diff --git a/package-lock.json b/package-lock.json index 4c3c6f552..c3d4c0f77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "esbuild": "^0.28.0", "eslint": "^10.3.0", "eslint-plugin-jsdoc": "^62.9.0", + "eslint-plugin-oxlint": "^1.67.0", "express": "^5.2.1", "express-ws": "^5.0.2", "jsdom": "^29.1.1", @@ -39,6 +40,9 @@ "mustache": "^4.2.0", "node-pty": "^1.2.0-beta.9", "nyc": "^18.0.0", + "oxlint": "^1.67.0", + "oxlint-plugin-eslint": "^1.67.0", + "oxlint-tsgolint": "^0.23.0", "source-map-loader": "^5.0.0", "source-map-support": "^0.5.20", "ts-loader": "^9.5.7", @@ -1508,6 +1512,413 @@ "pako": "^2.0.4" } }, + "node_modules/@oxlint-tsgolint/darwin-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-arm64/-/darwin-arm64-0.23.0.tgz", + "integrity": "sha512-gOs9PVr2wEg4ox9z0aJo+RKhhImW86YL5N6yav8BK/rgPsIrwN/igSZ+pbRr723NFvUNKde9fgMhRA6JrXAOZw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint-tsgolint/darwin-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-x64/-/darwin-x64-0.23.0.tgz", + "integrity": "sha512-kjJ8B+7n4tB9VJdxS5A9GdJt6/bYpzbu4lXp2uO1S3sRmCB5gDEABlGoiePNApRWaW+xqL4b4xgiE727jSLhuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@oxlint-tsgolint/linux-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-arm64/-/linux-arm64-0.23.0.tgz", + "integrity": "sha512-6dCZuKNu135seMXilkRk9SpCx6i1XgmiipYGalLij5WVRX6ZYS8c4xI7preN/zv9fCXhsQclTIMDu2Y/cytTjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint-tsgolint/linux-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-x64/-/linux-x64-0.23.0.tgz", + "integrity": "sha512-3bdilnyA7kmSTjK27rvjIjSxL5SIg3wt7vwNiRkouWB83ytssyKnuGvxSYJxgMEmFpSutzaBzcCUM2jDtPGcgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint-tsgolint/win32-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-arm64/-/win32-arm64-0.23.0.tgz", + "integrity": "sha512-j+OEp44SVYiQ+ZD+uttsX7u6L9SvmbbQ77SO1pSFCcJlsVMeCk8qZsjhKfGKuT/jIA+ipOJMVs/+pqUfObBWNw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint-tsgolint/win32-x64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-x64/-/win32-x64-0.23.0.tgz", + "integrity": "sha512-5MyjFuqf+g8OUPJBSGWHJtmoWnzFJYyOg4To9WMQshZYEWig/vtu7JtJ03VWnzHv9LJkAUeApY0gVCOywFR/iQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint/binding-android-arm-eabi": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.67.0.tgz", + "integrity": "sha512-VrSi571rDv1N8HaEDM+DEX8nmT0y9jJo8tzzW13vsOWTx59xQczCIJx68n2zWOXRT5YKZsOZXp4qkHN/10x4mw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-android-arm64": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.67.0.tgz", + "integrity": "sha512-l6+NdYxMoRohix5r5bbigW16LPicceCwGcQ6LKKuE1kUdjgFfQolJjrJsQYPFetIs78Gxj/G/f5TEGoTCwj9nQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-darwin-arm64": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.67.0.tgz", + "integrity": "sha512-jOzXxS1AxFxhImLIRbtGIMrEwaXcgMw3gR57WB1cRk8ai+vpr6726kxXqVvlNsrXtJ/FrmOm8RxlC0m8SW24Qg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-darwin-x64": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.67.0.tgz", + "integrity": "sha512-3DFAVY94OqjIZHXIPz37yGRSWwOFTAqChQ64/M69GYLawzP0KiwdhDNfqdKKYT0bTR/DNxmMnQsj3ns+8+X/Lg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-freebsd-x64": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.67.0.tgz", + "integrity": "sha512-e4dDKZuLu8TR9DEBssWSDahlPgZBwojTTHZUvnjBRJfJJbpxYCjfjKfi0Z1+CSLMiJBwI2yCDtRM1XJQaARjmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm-gnueabihf": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.67.0.tgz", + "integrity": "sha512-BKytFdcQzbITV3xlnzDUDTEDtbUMCCiC4EaNTDZ4FyT8gdNvBC4gfiLucXp/sQl0XU3p7syTlorUWVVVBZab2g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm-musleabihf": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.67.0.tgz", + "integrity": "sha512-XYAv0esBDX7BpTzRDjVX2Vdj+zndd8ll2dFQiaeQ6zTZr7A8GRDTN7fH3FP3jU+O0vCDx85oH/EtG7BzPgAXuw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm64-gnu": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.67.0.tgz", + "integrity": "sha512-zizRMjA0i6u/2B0evgda04iycu+MoNuf1pBy6Eh+1CjC5wMEG7qN5zdDKTCvFc0KSYSDM9QTG3gjZHirgtQuKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-arm64-musl": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.67.0.tgz", + "integrity": "sha512-zB/Tf6sUjmmvvbva9Gj3JTJ8rJ9t4I8/U0o6vSRtd0DRIsIuyegBwJAzhSUFQHdMijIRJkW0exs/yBhpw2S20w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-ppc64-gnu": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.67.0.tgz", + "integrity": "sha512-kgU40Gt74CK0TCsF51KZymkIwN9U0BajKsMijB52zPqOeZU9NAHkA/NSQkZDHEaCakx42DxhXkODiAqf2b4Gug==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-riscv64-gnu": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.67.0.tgz", + "integrity": "sha512-tOYhkk/iaG9aD3FvGpBFd1Lrw0x0RaVoJBxjUkfNzS50rC5NS5BteNCwgr8A2zCdADrIIoze6D7u6U5Ic++/iQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-riscv64-musl": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.67.0.tgz", + "integrity": "sha512-sEtywrPb+0b+tHYl1SDCrw903fiC4eyKoNqzP3v+f2JT3Xcv4NEYG+P8rj+eEnX7IWhqV/xj8/JmcmVj21CXaA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-s390x-gnu": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.67.0.tgz", + "integrity": "sha512-BvR8Moa0zCLxroOx4vZaZN9nUfwAUpSTwjZdxZyKy4bv3PrzrXrxKR/ZQ0L9wNSvlPhnMJeZfa3q5w6ZCTuN6Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-x64-gnu": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.67.0.tgz", + "integrity": "sha512-mm2cxM6fksOpq6l0uFws8BUGKAR4dNa/cZCn37Npq7PFbhD5HDJqWfnoIvTaeRKMy5XdS2tO0MA0qbHDrnXAAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-linux-x64-musl": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.67.0.tgz", + "integrity": "sha512-WmbMuLapKyDlobMkXAaAL0Y+Uczh4LETfIfQsUpbId4Ip8Ai82/jqeYTOoUCkuuhBFapgqP253+d83tLKOksJg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-openharmony-arm64": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.67.0.tgz", + "integrity": "sha512-9g/PqxYJelzzTAOR5Y+RiRqdeydhEuXv2KxNeFcAKQ7UsvnWSY1OP4MsuPMbTO2Pf70tz7mFhl1j13H3fyh+8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-arm64-msvc": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.67.0.tgz", + "integrity": "sha512-2VhwE6Gatb0vJGnN0TBuQMbKCOiZlSQ/zJvVWYLK4a9d4iDiJOen/yVQkGpmsJ90MuH66fzi0kEKI0jRQMDxGA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-ia32-msvc": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.67.0.tgz", + "integrity": "sha512-EQ3VExXfeM1InbE5+JjufhZZTWy+kHUwgt3yZR7gQ47Je/mE0WspQPan0OJznh493L5anM210YNJtH1PXjTSFg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxlint/binding-win32-x64-msvc": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.67.0.tgz", + "integrity": "sha512-bw24y+/1MHS4QDkons3YyHkPT9uCMoLHHgQhb+mb8NOjTYwub1CZ+K9Ngr8aO5DMrDrkqHwTzlTwFP2vS8Y/ZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -3652,6 +4063,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-plugin-oxlint": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-oxlint/-/eslint-plugin-oxlint-1.67.0.tgz", + "integrity": "sha512-tS/RGy8x2+rIUp7gV8ICgEeSAgFH6Qg7phzCbUblW/dPUsqXkcedrzO0nOaKhce4fvUVDR9uTmWlLkCNSDKcsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.3.1" + }, + "peerDependencies": { + "oxlint": "~1.67.0" + } + }, "node_modules/eslint-scope": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", @@ -5045,6 +5469,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5797,6 +6228,86 @@ "node": ">= 0.8.0" } }, + "node_modules/oxlint": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.67.0.tgz", + "integrity": "sha512-blwwaHPdoH8piQ5/z0KHeoHFR7FZgl12WluKJfu4qFLPkZl6mK04PkLE45Fw1NxfBRSlh40Gu7MkxHUw++ociQ==", + "dev": true, + "license": "MIT", + "bin": { + "oxlint": "bin/oxlint" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxlint/binding-android-arm-eabi": "1.67.0", + "@oxlint/binding-android-arm64": "1.67.0", + "@oxlint/binding-darwin-arm64": "1.67.0", + "@oxlint/binding-darwin-x64": "1.67.0", + "@oxlint/binding-freebsd-x64": "1.67.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.67.0", + "@oxlint/binding-linux-arm-musleabihf": "1.67.0", + "@oxlint/binding-linux-arm64-gnu": "1.67.0", + "@oxlint/binding-linux-arm64-musl": "1.67.0", + "@oxlint/binding-linux-ppc64-gnu": "1.67.0", + "@oxlint/binding-linux-riscv64-gnu": "1.67.0", + "@oxlint/binding-linux-riscv64-musl": "1.67.0", + "@oxlint/binding-linux-s390x-gnu": "1.67.0", + "@oxlint/binding-linux-x64-gnu": "1.67.0", + "@oxlint/binding-linux-x64-musl": "1.67.0", + "@oxlint/binding-openharmony-arm64": "1.67.0", + "@oxlint/binding-win32-arm64-msvc": "1.67.0", + "@oxlint/binding-win32-ia32-msvc": "1.67.0", + "@oxlint/binding-win32-x64-msvc": "1.67.0" + }, + "peerDependencies": { + "oxlint-tsgolint": ">=0.22.1", + "vite-plus": "*" + }, + "peerDependenciesMeta": { + "oxlint-tsgolint": { + "optional": true + }, + "vite-plus": { + "optional": true + } + } + }, + "node_modules/oxlint-plugin-eslint": { + "version": "1.67.0", + "resolved": "https://registry.npmjs.org/oxlint-plugin-eslint/-/oxlint-plugin-eslint-1.67.0.tgz", + "integrity": "sha512-MfpO9t/l/1qWVKym4sTkz0bhErAkUn/cOOQsFegI5ngQkR1cZEp6G23FKIhGcALoYytPBRmu47yjiEa6XWFBRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/oxlint-tsgolint": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/oxlint-tsgolint/-/oxlint-tsgolint-0.23.0.tgz", + "integrity": "sha512-3mBv3CoPbh8dFbzfDGIWa2ytZjn2v+3EX4aKRXjIhsoGFzG8GCjfRirz3rwZf1wYbZzsNLTSgpw8VjQuWdp/jA==", + "dev": true, + "license": "MIT", + "bin": { + "tsgolint": "bin/tsgolint.js" + }, + "optionalDependencies": { + "@oxlint-tsgolint/darwin-arm64": "0.23.0", + "@oxlint-tsgolint/darwin-x64": "0.23.0", + "@oxlint-tsgolint/linux-arm64": "0.23.0", + "@oxlint-tsgolint/linux-x64": "0.23.0", + "@oxlint-tsgolint/win32-arm64": "0.23.0", + "@oxlint-tsgolint/win32-x64": "0.23.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", diff --git a/package.json b/package.json index ae4e9fb87..43e569d02 100644 --- a/package.json +++ b/package.json @@ -48,11 +48,11 @@ "esbuild-demo-server-watch": "node bin/esbuild.mjs --demo-server --watch", "test": "npm run test-unit", "posttest": "npm run lint", - "lint": "eslint --max-warnings 0 src/ addons/ demo/ test/", + "lint": "oxlint --type-aware --max-warnings 0 src addons demo test && eslint --config eslint.config.naming.mjs --max-warnings 0 src addons demo test", "lint-changes": "node ./bin/lint_changes.js", "lint-changes-fix": "node ./bin/lint_changes.js --fix", - "lint-fix": "eslint --fix src/ addons/ demo/ test/", - "lint-api": "eslint --config eslint.config.typings.mjs --max-warnings 0 typings/", + "lint-fix": "oxlint --type-aware --fix --max-warnings 0 src addons demo test", + "lint-api": "oxlint --max-warnings 0 -c .oxlintrc.typings.json typings && eslint --config eslint.config.naming.mjs --max-warnings 0 typings", "test-unit": "node ./bin/test_unit.js", "test-unit-slow-tests": "npm run test-unit | grep \"ms)\"", "test-unit-coverage": "node ./bin/test_unit.js --coverage", @@ -95,6 +95,7 @@ "esbuild": "^0.28.0", "eslint": "^10.3.0", "eslint-plugin-jsdoc": "^62.9.0", + "eslint-plugin-oxlint": "^1.67.0", "express": "^5.2.1", "express-ws": "^5.0.2", "jsdom": "^29.1.1", @@ -102,6 +103,9 @@ "mustache": "^4.2.0", "node-pty": "^1.2.0-beta.9", "nyc": "^18.0.0", + "oxlint": "^1.67.0", + "oxlint-plugin-eslint": "^1.67.0", + "oxlint-tsgolint": "^0.23.0", "source-map-loader": "^5.0.0", "source-map-support": "^0.5.20", "ts-loader": "^9.5.7", diff --git a/src/browser/renderer/dom/DomRendererRowFactory.ts b/src/browser/renderer/dom/DomRendererRowFactory.ts index 7d2e8ed9b..baa5af801 100644 --- a/src/browser/renderer/dom/DomRendererRowFactory.ts +++ b/src/browser/renderer/dom/DomRendererRowFactory.ts @@ -231,7 +231,6 @@ export class DomRendererRowFactory { } charElement = this._document.createElement('span'); cellAmount = 0; - // eslint-disable-next-line no-useless-assignment text = ''; } }