From ef1c2b3b40984fd63ac0470f26478ad67229f399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 15 Dec 2025 10:18:18 +0100 Subject: [PATCH 1/2] ran Oxlint migrate --- .oxlintrc.json | 967 +++++++++++++++++++++++++++++-- .oxlintrc.json.bak | 76 +++ .pre-migrate-oxlintrc.json | 76 +++ libs/eslint/components/index.mjs | 3 + libs/eslint/platform/index.mjs | 3 + 5 files changed, 1070 insertions(+), 55 deletions(-) create mode 100644 .oxlintrc.json.bak create mode 100644 .pre-migrate-oxlintrc.json diff --git a/.oxlintrc.json b/.oxlintrc.json index 89b0604b4c6..64c6d6ed06f 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,57 +1,15 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", - "plugins": ["eslint", "typescript", "import"], - "jsPlugins": [ - "eslint-plugin-storybook", - "eslint-plugin-rxjs", - "eslint-plugin-rxjs-angular", - "eslint-plugin-tailwindcss", - "@angular-eslint/eslint-plugin", - "@angular-eslint/eslint-plugin-template", - "./libs/eslint/platform/index.mjs", - "./libs/eslint/components/index.mjs" - ], + "plugins": [], "categories": { - "correctness": "error" + "correctness": "off" }, "rules": { - "curly": ["error", "all"], - "no-console": "error", - // Disabled: false positives on test variables assigned in beforeEach - "no-unassigned-vars": "allow", - // Disabled: ESLint uses allowTernary option which oxlint doesn't support - "no-unused-expressions": "allow", - // Disabled: use typescript/no-unused-vars for .ts files instead - "no-unused-vars": "allow", - // Disabled: not enabled in ESLint config - "no-useless-rename": "allow", - // Disabled: not enabled in ESLint config "no-useless-catch": "allow", - // Disabled: not enabled in ESLint config - "no-unnecessary-parameter-property-assignment": "allow", - // Disabled: BOM characters slip through ESLint - "no-irregular-whitespace": "allow", - // Disabled: matches ESLint config (rule is off) - "typescript/no-explicit-any": "allow", - // Disabled: oxlint doesn't support allowedNames option, ESLint allows "self" - "typescript/no-this-alias": "allow", - // Disabled: oxlint's args:"none" doesn't work for rest parameters (...args) - // See: https://github.com/oxc-project/oxc/issues/11147 - // Let ESLint's @typescript-eslint/no-unused-vars handle this instead - "typescript/no-unused-vars": "allow", - // Requires --type-aware flag to work - "typescript/no-misused-promises": "error", - "no-restricted-imports": [ - "error", - { - "paths": [ - { - "name": "@bitwarden/commercial-sdk-internal", - "message": "Use @bitwarden/sdk-internal instead." - } - ] - } - ] + "no-useless-rename": "allow" + }, + "env": { + "builtin": true }, "ignorePatterns": [ "**/build/", @@ -62,15 +20,914 @@ "**/node_modules/", "**/webpack.*.js", "**/jest.config.js", - "**/config/*.js", - "apps/*/config.js", + "apps/browser/config/config.js", + "apps/browser/src/auth/scripts/duo.js", + "apps/browser/webpack/manifest.js", "apps/desktop/desktop_native", - "apps/desktop/src/auth/scripts/*.js", + "apps/desktop/src/auth/scripts/duo.js", + "apps/web/config.js", + "apps/web/scripts/*.js", + "apps/web/tailwind.config.js", + "apps/cli/config/config.js", + "tailwind.config.js", + "libs/components/tailwind.config.base.js", + "libs/components/tailwind.config.js", "scripts/**", "jest.preset.js", - "tailwind.config.js", - "libs/components/tailwind.config.*.js", - "libs/nx-plugin/**", - "**/*.mjs" + "**/spec-data/**" + ], + "overrides": [ + { + "files": ["**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)", "**/*.story.@(ts|tsx|js|jsx|mjs|cjs)"], + "rules": { + "react-hooks/rules-of-hooks": "off", + "import/no-anonymous-default-export": "off", + "storybook/await-interactions": "error", + "storybook/context-in-play-function": "error", + "storybook/default-exports": "error", + "storybook/hierarchy-separator": "warn", + "storybook/no-redundant-story-name": "warn", + "storybook/no-renderer-packages": "error", + "storybook/prefer-pascal-case": "warn", + "storybook/story-exports": "error", + "storybook/use-storybook-expect": "error", + "storybook/use-storybook-testing-library": "error" + }, + "jsPlugins": ["eslint-plugin-storybook"], + "plugins": ["react", "import"] + }, + { + "files": [".storybook/main.@(js|cjs|mjs|ts)"], + "rules": { + "storybook/no-uninstalled-addons": "error" + }, + "jsPlugins": ["eslint-plugin-storybook"] + }, + { + "files": ["**/*.ts", "**/*.js"], + "rules": { + "for-direction": "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-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-unexpected-multiline": "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": "off", + "no-useless-backreference": "error", + "no-useless-escape": "error", + "no-with": "error", + "require-yield": "error", + "use-isnan": "error", + "valid-typeof": "error" + } + }, + { + "files": ["**/*.ts", "**/*.js"], + "rules": { + "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-unsafe-negation": "off", + "no-var": "error", + "no-with": "off", + "prefer-rest-params": "error", + "prefer-spread": "error" + } + }, + { + "files": ["**/*.ts", "**/*.js"], + "rules": { + "@typescript-eslint/ban-ts-comment": "error", + "no-array-constructor": "error", + "@typescript-eslint/no-duplicate-enum-values": "error", + "@typescript-eslint/no-empty-object-type": "error", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-non-null-asserted-optional-chain": "error", + "@typescript-eslint/no-require-imports": "error", + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/no-unnecessary-type-constraint": "error", + "@typescript-eslint/no-unsafe-declaration-merging": "error", + "@typescript-eslint/no-unsafe-function-type": "error", + "no-unused-expressions": "error", + "no-unused-vars": "off", + "@typescript-eslint/no-wrapper-object-types": "error", + "@typescript-eslint/prefer-as-const": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/no-unnecessary-parameter-property-assignment": "off" // Not enabled in ESLint config + }, + "plugins": ["typescript"] + }, + { + "files": ["**/*.ts", "**/*.js"], + "rules": { + "@angular-eslint/contextual-lifecycle": "error", + "@angular-eslint/no-empty-lifecycle-method": "off", + "@angular-eslint/no-input-rename": "off", + "@angular-eslint/no-inputs-metadata-property": "error", + "@angular-eslint/no-output-native": "off", + "@angular-eslint/no-output-on-prefix": "off", + "@angular-eslint/no-output-rename": "error", + "@angular-eslint/no-outputs-metadata-property": "error", + "@angular-eslint/prefer-inject": "off", + "@angular-eslint/prefer-standalone": "off", + "@angular-eslint/use-pipe-transform-interface": "off", + "@angular-eslint/use-lifecycle-interface": "error" + }, + "jsPlugins": ["@angular-eslint/eslint-plugin"] + }, + { + "files": ["**/*.ts", "**/*.js"], + "rules": { + "import/namespace": "error", + "import/default": "error", + "import/no-named-as-default": "warn", + "import/no-named-as-default-member": "warn", + "import/no-duplicates": "warn" + }, + "env": { + "es2018": true + }, + "plugins": ["import"] + }, + { + "files": ["**/*.ts", "**/*.js"], + "rules": { + "@angular-eslint/component-class-suffix": "error", + "@angular-eslint/contextual-lifecycle": "error", + "@angular-eslint/directive-class-suffix": "error", + "@angular-eslint/no-inputs-metadata-property": "error", + "@angular-eslint/no-output-rename": "error", + "@angular-eslint/no-outputs-metadata-property": "error", + "@angular-eslint/prefer-on-push-component-change-detection": "error", + "@angular-eslint/prefer-output-emitter-ref": "error", + "@angular-eslint/prefer-signals": "error", + "@angular-eslint/use-lifecycle-interface": "error", + "bitwarden-platform/required-using": "off", // Requires type-aware linting, let ESLint handle + "bitwarden-platform/no-enums": "off", // JS plugins don't respect eslint-disable, let ESLint handle + "bitwarden-platform/no-page-script-url-leakage": "off", // JS plugins don't respect eslint-disable, let ESLint handle + "bitwarden-components/require-theme-colors-in-svg": "off", // Bug in rule's location reporting with oxlint + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-misused-promises": [ + "error", + { + "checksVoidReturn": false + } + ], + "@typescript-eslint/no-this-alias": "off", // oxlint doesn't support allowedNames option + "curly": ["error", "all"], + "no-console": "error", + "import/namespace": ["off"], + "no-unused-expressions": [ + "error", + { + "allowTernary": true + } + ], + "no-unused-vars": "off", + "no-unassigned-vars": "off" // False positives in test files where vars are assigned in beforeEach + }, + "jsPlugins": [ + "@angular-eslint/eslint-plugin", + "./libs/eslint/platform/index.mjs", + "./libs/eslint/components/index.mjs" + ], + "plugins": ["typescript", "import"] + }, + { + "files": ["**/*.html"], + "rules": { + "button-has-type": "error", + "tailwindcss/no-custom-classname": [ + "error", + { + "whitelist": ["(?!(tw)\\-).*", "tw-app-region-drag", "tw-app-region-no-drag"] + } + ], + "tailwindcss/enforces-negative-arbitrary-values": "error", + "tailwindcss/enforces-shorthand": "error", + "tailwindcss/no-contradicting-classname": "error", + "bitwarden-components/require-label-on-biticonbutton": [ + "error", + { + "ignoreIfHas": ["bitPasswordInputToggle"] + } + ] + }, + "jsPlugins": [ + "@angular-eslint/eslint-plugin-template", + "eslint-plugin-tailwindcss", + "./libs/eslint/components/index.mjs" + ] + }, + { + "files": ["**/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": ["**/platform/**/internal", "**/platform/messaging/**", "**/src/**/*"] + } + ] + } + }, + { + "files": ["apps/browser/src/**/*.ts"], + "ignorePatterns": [ + "apps/browser/src/**/{content,popup,spec}/**/*.ts", + "apps/browser/src/**/autofill/{notification,overlay}/**/*.ts", + "apps/browser/src/**/*.spec.ts" + ], + "rules": { + "no-restricted-globals": "off" + } + }, + { + "files": ["bitwarden_license/bit-common/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/bit-common/*" + ] + } + ] + } + }, + { + "files": ["apps/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "bitwarden_license/**", + "@bitwarden/bit-common/*", + "@bitwarden/bit-web/*" + ] + } + ] + } + }, + { + "files": ["apps/web/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "bitwarden_license/**", + "@bitwarden/bit-common/*", + "@bitwarden/bit-web/*", + "**/app/core/*", + "**/reports/*", + "**/app/shared/*", + "**/organizations/settings/*", + "**/organizations/policies/*" + ] + } + ] + } + }, + { + "files": ["apps/browser/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@angular", + "bitwarden_license/**", + "@bitwarden/bit-common/*", + "@bitwarden/bit-web/*", + "**/popup/*" + ] + } + ] + } + }, + { + "files": ["apps/browser/src/**/popup/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "bitwarden_license/**", + "@bitwarden/bit-common/*", + "@bitwarden/bit-web/*" + ] + } + ] + } + }, + { + "files": ["libs/nx-plugin/**/*.ts", "libs/nx-plugin/**/*.js"], + "rules": { + "no-console": "off" + } + }, + { + "files": [ + "apps/web/**/*.html", + "apps/browser/**/*.html", + "bitwarden_license/bit-web/**/*.html", + "libs/**/*.html" + ], + "rules": { + "tailwindcss/no-custom-classname": [ + "error", + { + "whitelist": [ + "((bwi)\\-?).*", + "logo", + "logo-themed", + "file-selector", + "mfaType.*", + "filter.*", + "tw-app-region*", + "tw-@container" + ] + } + ] + }, + "jsPlugins": ["eslint-plugin-tailwindcss"] + }, + { + "files": ["libs/common/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/angular", + "@bitwarden/auth", + "@bitwarden/billing", + "@bitwarden/components", + "@bitwarden/importer", + "@bitwarden/key-management", + "@bitwarden/key-management-ui", + "@bitwarden/node", + "@bitwarden/platform", + "@bitwarden/tools", + "@bitwarden/ui", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/shared/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/angular", + "@bitwarden/auth", + "@bitwarden/billing", + "@bitwarden/common", + "@bitwarden/components", + "@bitwarden/importer", + "@bitwarden/key-management", + "@bitwarden/key-management-ui", + "@bitwarden/node", + "@bitwarden/platform", + "@bitwarden/tools", + "@bitwarden/ui", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/auth/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/billing", + "@bitwarden/components", + "@bitwarden/importer", + "@bitwarden/key-management-ui", + "@bitwarden/tools", + "@bitwarden/ui", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/key-management/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/auth", + "@bitwarden/admin-console", + "@bitwarden/billing", + "@bitwarden/importer", + "@bitwarden/key-management-ui", + "@bitwarden/tools", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/billing/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/importer", + "@bitwarden/key-management-ui", + "@bitwarden/tools", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/components/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/auth", + "@bitwarden/billing", + "@bitwarden/eslint", + "@bitwarden/importer", + "@bitwarden/key-management-ui", + "@bitwarden/node", + "@bitwarden/tools", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/ui/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/billing", + "@bitwarden/importer", + "@bitwarden/key-management-ui", + "@bitwarden/node", + "@bitwarden/platform", + "@bitwarden/tools", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/key-management-ui/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/billing", + "@bitwarden/importer", + "@bitwarden/node", + "@bitwarden/platform", + "@bitwarden/tools", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/angular/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/auth", + "@bitwarden/billing", + "@bitwarden/importer", + "@bitwarden/key-management-ui", + "@bitwarden/node", + "@bitwarden/platform", + "@bitwarden/tools", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/vault/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/importer", + "@bitwarden/tools" + ] + } + ] + } + }, + { + "files": ["libs/admin-console/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": ["**/platform/**/internal", "**/platform/messaging/**", "**/src/**/*"] + } + ] + } + }, + { + "files": ["libs/tools/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console" + ] + } + ] + } + }, + { + "files": ["libs/platform/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/auth", + "@bitwarden/billing", + "@bitwarden/importer", + "@bitwarden/key-management", + "@bitwarden/key-management-ui", + "@bitwarden/tools", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/importer/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/tools" + ] + } + ] + } + }, + { + "files": ["libs/eslint/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/angular", + "@bitwarden/auth", + "@bitwarden/billing", + "@bitwarden/components", + "@bitwarden/importer", + "@bitwarden/key-management", + "@bitwarden/key-management-ui", + "@bitwarden/node", + "@bitwarden/platform", + "@bitwarden/tools", + "@bitwarden/ui", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": ["libs/node/src/**/*.ts"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ], + "patterns": [ + "**/platform/**/internal", + "**/platform/messaging/**", + "**/src/**/*", + "@bitwarden/admin-console", + "@bitwarden/angular", + "@bitwarden/components", + "@bitwarden/importer", + "@bitwarden/key-management-ui", + "@bitwarden/platform", + "@bitwarden/tools", + "@bitwarden/ui", + "@bitwarden/vault" + ] + } + ] + } + }, + { + "files": [ + "apps/cli/src/admin-console/**/*.ts", + "apps/web/src/app/admin-console/**/*.ts", + "bitwarden_license/bit-cli/src/admin-console/**/*.ts", + "bitwarden_license/bit-web/src/app/admin-console/**/*.ts", + "libs/admin-console/src/**/*.ts" + ], + "rules": { + "@angular-eslint/component-class-suffix": "error", + "@angular-eslint/contextual-lifecycle": "error", + "@angular-eslint/directive-class-suffix": "error", + "@angular-eslint/no-empty-lifecycle-method": "error", + "@angular-eslint/no-input-rename": "error", + "@angular-eslint/no-inputs-metadata-property": "error", + "@angular-eslint/no-output-native": "error", + "@angular-eslint/no-output-on-prefix": "error", + "@angular-eslint/no-output-rename": "error", + "@angular-eslint/no-outputs-metadata-property": "error", + "@angular-eslint/use-lifecycle-interface": "error", + "@angular-eslint/use-pipe-transform-interface": "error" + }, + "jsPlugins": ["@angular-eslint/eslint-plugin"] + } ] } diff --git a/.oxlintrc.json.bak b/.oxlintrc.json.bak new file mode 100644 index 00000000000..89b0604b4c6 --- /dev/null +++ b/.oxlintrc.json.bak @@ -0,0 +1,76 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["eslint", "typescript", "import"], + "jsPlugins": [ + "eslint-plugin-storybook", + "eslint-plugin-rxjs", + "eslint-plugin-rxjs-angular", + "eslint-plugin-tailwindcss", + "@angular-eslint/eslint-plugin", + "@angular-eslint/eslint-plugin-template", + "./libs/eslint/platform/index.mjs", + "./libs/eslint/components/index.mjs" + ], + "categories": { + "correctness": "error" + }, + "rules": { + "curly": ["error", "all"], + "no-console": "error", + // Disabled: false positives on test variables assigned in beforeEach + "no-unassigned-vars": "allow", + // Disabled: ESLint uses allowTernary option which oxlint doesn't support + "no-unused-expressions": "allow", + // Disabled: use typescript/no-unused-vars for .ts files instead + "no-unused-vars": "allow", + // Disabled: not enabled in ESLint config + "no-useless-rename": "allow", + // Disabled: not enabled in ESLint config + "no-useless-catch": "allow", + // Disabled: not enabled in ESLint config + "no-unnecessary-parameter-property-assignment": "allow", + // Disabled: BOM characters slip through ESLint + "no-irregular-whitespace": "allow", + // Disabled: matches ESLint config (rule is off) + "typescript/no-explicit-any": "allow", + // Disabled: oxlint doesn't support allowedNames option, ESLint allows "self" + "typescript/no-this-alias": "allow", + // Disabled: oxlint's args:"none" doesn't work for rest parameters (...args) + // See: https://github.com/oxc-project/oxc/issues/11147 + // Let ESLint's @typescript-eslint/no-unused-vars handle this instead + "typescript/no-unused-vars": "allow", + // Requires --type-aware flag to work + "typescript/no-misused-promises": "error", + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ] + } + ] + }, + "ignorePatterns": [ + "**/build/", + "**/dist/", + "**/coverage/", + ".angular/", + "storybook-static/", + "**/node_modules/", + "**/webpack.*.js", + "**/jest.config.js", + "**/config/*.js", + "apps/*/config.js", + "apps/desktop/desktop_native", + "apps/desktop/src/auth/scripts/*.js", + "scripts/**", + "jest.preset.js", + "tailwind.config.js", + "libs/components/tailwind.config.*.js", + "libs/nx-plugin/**", + "**/*.mjs" + ] +} diff --git a/.pre-migrate-oxlintrc.json b/.pre-migrate-oxlintrc.json new file mode 100644 index 00000000000..89b0604b4c6 --- /dev/null +++ b/.pre-migrate-oxlintrc.json @@ -0,0 +1,76 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["eslint", "typescript", "import"], + "jsPlugins": [ + "eslint-plugin-storybook", + "eslint-plugin-rxjs", + "eslint-plugin-rxjs-angular", + "eslint-plugin-tailwindcss", + "@angular-eslint/eslint-plugin", + "@angular-eslint/eslint-plugin-template", + "./libs/eslint/platform/index.mjs", + "./libs/eslint/components/index.mjs" + ], + "categories": { + "correctness": "error" + }, + "rules": { + "curly": ["error", "all"], + "no-console": "error", + // Disabled: false positives on test variables assigned in beforeEach + "no-unassigned-vars": "allow", + // Disabled: ESLint uses allowTernary option which oxlint doesn't support + "no-unused-expressions": "allow", + // Disabled: use typescript/no-unused-vars for .ts files instead + "no-unused-vars": "allow", + // Disabled: not enabled in ESLint config + "no-useless-rename": "allow", + // Disabled: not enabled in ESLint config + "no-useless-catch": "allow", + // Disabled: not enabled in ESLint config + "no-unnecessary-parameter-property-assignment": "allow", + // Disabled: BOM characters slip through ESLint + "no-irregular-whitespace": "allow", + // Disabled: matches ESLint config (rule is off) + "typescript/no-explicit-any": "allow", + // Disabled: oxlint doesn't support allowedNames option, ESLint allows "self" + "typescript/no-this-alias": "allow", + // Disabled: oxlint's args:"none" doesn't work for rest parameters (...args) + // See: https://github.com/oxc-project/oxc/issues/11147 + // Let ESLint's @typescript-eslint/no-unused-vars handle this instead + "typescript/no-unused-vars": "allow", + // Requires --type-aware flag to work + "typescript/no-misused-promises": "error", + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@bitwarden/commercial-sdk-internal", + "message": "Use @bitwarden/sdk-internal instead." + } + ] + } + ] + }, + "ignorePatterns": [ + "**/build/", + "**/dist/", + "**/coverage/", + ".angular/", + "storybook-static/", + "**/node_modules/", + "**/webpack.*.js", + "**/jest.config.js", + "**/config/*.js", + "apps/*/config.js", + "apps/desktop/desktop_native", + "apps/desktop/src/auth/scripts/*.js", + "scripts/**", + "jest.preset.js", + "tailwind.config.js", + "libs/components/tailwind.config.*.js", + "libs/nx-plugin/**", + "**/*.mjs" + ] +} diff --git a/libs/eslint/components/index.mjs b/libs/eslint/components/index.mjs index 273c29890fe..58aef41d122 100644 --- a/libs/eslint/components/index.mjs +++ b/libs/eslint/components/index.mjs @@ -2,6 +2,9 @@ import requireLabelOnBiticonbutton from "./require-label-on-biticonbutton.mjs"; import requireThemeColorsInSvg from "./require-theme-colors-in-svg.mjs"; export default { + meta: { + name: "bitwarden-components", + }, rules: { "require-label-on-biticonbutton": requireLabelOnBiticonbutton, "require-theme-colors-in-svg": requireThemeColorsInSvg, diff --git a/libs/eslint/platform/index.mjs b/libs/eslint/platform/index.mjs index be78df43e3f..571f3a47a12 100644 --- a/libs/eslint/platform/index.mjs +++ b/libs/eslint/platform/index.mjs @@ -3,6 +3,9 @@ import noEnums from "./no-enums.mjs"; import noPageScriptUrlLeakage from "./no-page-script-url-leakage.mjs"; export default { + meta: { + name: "bitwarden-platform", + }, rules: { "required-using": requiredUsing, "no-enums": noEnums, From 4fa5c4e41661db97b9e9464bd4f046180d04f713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 15 Dec 2025 10:47:48 +0100 Subject: [PATCH 2/2] Removed baseUrl, prefixed some paths with . and matched type rules with eslint --- .github/workflows/lint.yml | 2 +- .oxlintrc.json | 16 ++++++++- .../tsconfig.json | 3 +- tsconfig.base.json | 34 +++++++++---------- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 07f4b927c30..956a45ae656 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -74,7 +74,7 @@ jobs: run: npm ci - name: Run oxlint - run: npm oxlint:types + run: npm run oxlint:types - name: Lint unowned dependencies run: npm run lint:dep-ownership diff --git a/.oxlintrc.json b/.oxlintrc.json index 64c6d6ed06f..f877141a86c 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -237,7 +237,21 @@ } ], "no-unused-vars": "off", - "no-unassigned-vars": "off" // False positives in test files where vars are assigned in beforeEach + "no-unassigned-vars": "off", // False positives in test files where vars are assigned in beforeEach + + // Type-aware rules not enabled in ESLint - disable to match ESLint behavior + "@typescript-eslint/no-redundant-type-constituents": "off", + "@typescript-eslint/unbound-method": "off", + "@typescript-eslint/no-duplicate-type-constituents": "off", + "@typescript-eslint/restrict-template-expressions": "off", + "@typescript-eslint/await-thenable": "off", + "@typescript-eslint/no-misused-spread": "off", + "@typescript-eslint/no-meaningless-void-operator": "off", + "@typescript-eslint/no-base-to-string": "off", + "@typescript-eslint/no-for-in-array": "off", + "@typescript-eslint/require-array-sort-compare": "off", + "@typescript-eslint/no-array-delete": "off", + "@typescript-eslint/no-implied-eval": "off" }, "jsPlugins": [ "@angular-eslint/eslint-plugin", diff --git a/apps/desktop/native-messaging-test-runner/tsconfig.json b/apps/desktop/native-messaging-test-runner/tsconfig.json index dcdf992f986..7736f2173ed 100644 --- a/apps/desktop/native-messaging-test-runner/tsconfig.json +++ b/apps/desktop/native-messaging-test-runner/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "baseUrl": "./", "outDir": "dist", "target": "es6", "module": "CommonJS", @@ -10,7 +9,7 @@ "sourceMap": false, "declaration": false, "paths": { - "@src/*": ["src/*"], + "@src/*": ["./src/*"], "@bitwarden/user-core": ["../../../libs/user-core/src/index.ts"], "@bitwarden/storage-core": ["../../../libs/storage-core/src/index.ts"], "@bitwarden/logging": ["../../../libs/logging/src/index.ts"], diff --git a/tsconfig.base.json b/tsconfig.base.json index 2d105d4263d..237884d45a9 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -12,54 +12,54 @@ "emitDecoratorMetadata": true, "declaration": false, "outDir": "dist", - "baseUrl": ".", "resolveJsonModule": true, "allowJs": true, "sourceMap": true, "skipLibCheck": true, "paths": { + ".storybook/*": ["./.storybook/*"], "@bitwarden/admin-console/common": ["./libs/admin-console/src/common"], "@bitwarden/angular/*": ["./libs/angular/src/*"], - "@bitwarden/assets": ["libs/assets/src/index.ts"], - "@bitwarden/assets/svg": ["libs/assets/src/svg/index.ts"], + "@bitwarden/assets": ["./libs/assets/src/index.ts"], + "@bitwarden/assets/svg": ["./libs/assets/src/svg/index.ts"], "@bitwarden/auth/angular": ["./libs/auth/src/angular"], "@bitwarden/auth/common": ["./libs/auth/src/common"], "@bitwarden/billing": ["./libs/billing/src"], "@bitwarden/bit-common/*": ["./bitwarden_license/bit-common/src/*"], "@bitwarden/browser/*": ["./apps/browser/src/*"], "@bitwarden/cli/*": ["./apps/cli/src/*"], - "@bitwarden/client-type": ["libs/client-type/src/index.ts"], + "@bitwarden/client-type": ["./libs/client-type/src/index.ts"], "@bitwarden/common/*": ["./libs/common/src/*"], "@bitwarden/components": ["./libs/components/src"], - "@bitwarden/core-test-utils": ["libs/core-test-utils/src/index.ts"], + "@bitwarden/core-test-utils": ["./libs/core-test-utils/src/index.ts"], "@bitwarden/dirt-card": ["./libs/dirt/card/src"], "@bitwarden/generator-components": ["./libs/tools/generator/components/src"], "@bitwarden/generator-core": ["./libs/tools/generator/core/src"], "@bitwarden/generator-history": ["./libs/tools/generator/extensions/history/src"], "@bitwarden/generator-legacy": ["./libs/tools/generator/extensions/legacy/src"], "@bitwarden/generator-navigation": ["./libs/tools/generator/extensions/navigation/src"], - "@bitwarden/guid": ["libs/guid/src/index.ts"], + "@bitwarden/guid": ["./libs/guid/src/index.ts"], "@bitwarden/importer-core": ["./libs/importer/src"], "@bitwarden/importer-ui": ["./libs/importer/src/components"], "@bitwarden/key-management": ["./libs/key-management/src"], "@bitwarden/key-management-ui": ["./libs/key-management-ui/src"], - "@bitwarden/logging": ["libs/logging/src"], - "@bitwarden/messaging": ["libs/messaging/src/index.ts"], + "@bitwarden/logging": ["./libs/logging/src"], + "@bitwarden/messaging": ["./libs/messaging/src/index.ts"], "@bitwarden/node/*": ["./libs/node/src/*"], - "@bitwarden/nx-plugin": ["libs/nx-plugin/src/index.ts"], + "@bitwarden/nx-plugin": ["./libs/nx-plugin/src/index.ts"], "@bitwarden/platform": ["./libs/platform/src"], "@bitwarden/platform/*": ["./libs/platform/src/*"], - "@bitwarden/pricing": ["libs/pricing/src/index.ts"], + "@bitwarden/pricing": ["./libs/pricing/src/index.ts"], "@bitwarden/send-ui": ["./libs/tools/send/send-ui/src"], - "@bitwarden/serialization": ["libs/serialization/src/index.ts"], - "@bitwarden/state": ["libs/state/src/index.ts"], - "@bitwarden/state-internal": ["libs/state-internal/src/index.ts"], - "@bitwarden/state-test-utils": ["libs/state-test-utils/src/index.ts"], - "@bitwarden/storage-core": ["libs/storage-core/src/index.ts"], - "@bitwarden/storage-test-utils": ["libs/storage-test-utils/src/index.ts"], + "@bitwarden/serialization": ["./libs/serialization/src/index.ts"], + "@bitwarden/state": ["./libs/state/src/index.ts"], + "@bitwarden/state-internal": ["./libs/state-internal/src/index.ts"], + "@bitwarden/state-test-utils": ["./libs/state-test-utils/src/index.ts"], + "@bitwarden/storage-core": ["./libs/storage-core/src/index.ts"], + "@bitwarden/storage-test-utils": ["./libs/storage-test-utils/src/index.ts"], "@bitwarden/ui-common": ["./libs/ui/common/src"], "@bitwarden/ui-common/setup-jest": ["./libs/ui/common/src/setup-jest"], - "@bitwarden/user-core": ["libs/user-core/src/index.ts"], + "@bitwarden/user-core": ["./libs/user-core/src/index.ts"], "@bitwarden/vault": ["./libs/vault/src"], "@bitwarden/vault-export-core": ["./libs/tools/export/vault-export/vault-export-core/src"], "@bitwarden/vault-export-ui": ["./libs/tools/export/vault-export/vault-export-ui/src"],