diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index c9a25670a9..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,29 +0,0 @@ -**/build -**/dist -**/coverage -.angular -storybook-static - -**/node_modules - -**/webpack.*.js -**/jest.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/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/*.js diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 3fd6dec3d7..0000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,258 +0,0 @@ -{ - "root": true, - "env": { - "browser": true, - "webextensions": true - }, - "overrides": [ - { - "files": ["*.ts", "*.js"], - "plugins": ["@typescript-eslint", "rxjs", "rxjs-angular", "import"], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": ["./tsconfig.eslint.json"], - "sourceType": "module", - "ecmaVersion": 2020 - }, - "extends": [ - "eslint:recommended", - "plugin:@angular-eslint/recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "plugin:rxjs/recommended", - "prettier", - "plugin:storybook/recommended" - ], - "settings": { - "import/parsers": { - "@typescript-eslint/parser": [".ts"] - }, - "import/resolver": { - "typescript": { - "alwaysTryTypes": true - } - } - }, - "rules": { - "@angular-eslint/component-class-suffix": 0, - "@angular-eslint/contextual-lifecycle": 0, - "@angular-eslint/directive-class-suffix": 0, - "@angular-eslint/no-empty-lifecycle-method": 0, - "@angular-eslint/no-host-metadata-property": 0, - "@angular-eslint/no-input-rename": 0, - "@angular-eslint/no-inputs-metadata-property": 0, - "@angular-eslint/no-output-native": 0, - "@angular-eslint/no-output-on-prefix": 0, - "@angular-eslint/no-output-rename": 0, - "@angular-eslint/no-outputs-metadata-property": 0, - "@angular-eslint/use-lifecycle-interface": "error", - "@angular-eslint/use-pipe-transform-interface": 0, - "@typescript-eslint/explicit-member-accessibility": [ - "error", - { "accessibility": "no-public" } - ], - "@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled - "@typescript-eslint/no-floating-promises": "error", - "@typescript-eslint/no-misused-promises": ["error", { "checksVoidReturn": false }], - "@typescript-eslint/no-this-alias": ["error", { "allowedNames": ["self"] }], - "@typescript-eslint/no-unused-expressions": ["error", { "allowTernary": true }], - "@typescript-eslint/no-unused-vars": ["error", { "args": "none" }], - "no-console": "error", - "import/no-unresolved": "off", // TODO: Look into turning off once each package is an actual package. - "import/order": [ - "error", - { - "alphabetize": { - "order": "asc" - }, - "newlines-between": "always", - "pathGroups": [ - { - "pattern": "@bitwarden/**", - "group": "external", - "position": "after" - }, - { - "pattern": "src/**/*", - "group": "parent", - "position": "before" - } - ], - "pathGroupsExcludedImportTypes": ["builtin"] - } - ], - "rxjs-angular/prefer-takeuntil": ["error", { "alias": ["takeUntilDestroyed"] }], - "rxjs/no-exposed-subjects": ["error", { "allowProtected": true }], - "no-restricted-syntax": [ - "error", - { - "message": "Calling `svgIcon` directly is not allowed", - "selector": "CallExpression[callee.name='svgIcon']" - }, - { - "message": "Accessing FormGroup using `get` is not allowed, use `.value` instead", - "selector": "ChainExpression[expression.object.callee.property.name='get'][expression.property.name='value']" - } - ], - "curly": ["error", "all"], - "import/namespace": ["off"], // This doesn't resolve namespace imports correctly, but TS will throw for this anyway - "import/no-restricted-paths": [ - "error", - { - "zones": [ - { - "target": ["libs/**/*"], - "from": ["apps/**/*"], - "message": "Libs should not import app-specific code." - }, - { - // avoid specific frameworks or large dependencies in common - "target": "./libs/common/**/*", - "from": [ - // Angular - "./libs/angular/**/*", - "./node_modules/@angular*/**/*", - - // Node - "./libs/node/**/*", - - //Generator - "./libs/tools/generator/components/**/*", - "./libs/tools/generator/core/**/*", - "./libs/tools/generator/extensions/**/*", - - // Import/export - "./libs/importer/**/*", - "./libs/tools/export/vault-export/vault-export-core/**/*" - ] - }, - { - // avoid import of unexported state objects - "target": [ - "!(libs)/**/*", - "libs/!(common)/**/*", - "libs/common/!(src)/**/*", - "libs/common/src/!(platform)/**/*", - "libs/common/src/platform/!(state)/**/*" - ], - "from": ["./libs/common/src/platform/state/**/*"], - // allow module index import - "except": ["**/state/index.ts"] - } - ] - } - ] - } - }, - { - "files": ["*.html"], - "parser": "@angular-eslint/template-parser", - "plugins": ["@angular-eslint/template", "tailwindcss"], - "rules": { - "@angular-eslint/template/button-has-type": "error", - "tailwindcss/no-custom-classname": [ - "error", - { - // uses negative lookahead to whitelist any class that doesn't start with "tw-" - // in other words: classnames that start with tw- must be valid TailwindCSS classes - "whitelist": ["(?!(tw)\\-).*"] - } - ], - "tailwindcss/enforces-negative-arbitrary-values": "error", - "tailwindcss/enforces-shorthand": "error", - "tailwindcss/no-contradicting-classname": "error" - } - }, - { - "files": ["apps/browser/src/**/*.ts", "libs/**/*.ts"], - "excludedFiles": [ - "apps/browser/src/autofill/{content,notification}/**/*.ts", - "apps/browser/src/**/background/**/*.ts", // It's okay to have long lived listeners in the background - "apps/browser/src/platform/background.ts" - ], - "rules": { - "no-restricted-syntax": [ - "error", - { - "message": "Using addListener in the browser popup produces a memory leak in Safari, use `BrowserApi.addListener` instead", - // This selector covers events like chrome.storage.onChange & chrome.runtime.onMessage - "selector": "CallExpression > [object.object.object.name='chrome'][property.name='addListener']" - }, - { - "message": "Using addListener in the browser popup produces a memory leak in Safari, use `BrowserApi.addListener` instead", - // This selector covers events like chrome.storage.local.onChange - "selector": "CallExpression > [object.object.object.object.name='chrome'][property.name='addListener']" - } - ] - } - }, - { - "files": ["**/*.ts"], - "excludedFiles": ["**/platform/**/*.ts"], - "rules": { - "no-restricted-imports": [ - "error", - { - "patterns": [ - "**/platform/**/internal", // General internal pattern - // All features that have been converted to barrel files - "**/platform/messaging/**" - ] - } - ] - } - }, - { - "files": ["**/src/**/*.ts"], - "excludedFiles": ["**/platform/**/*.ts"], - "rules": { - "no-restricted-imports": [ - "error", - { - "patterns": [ - "**/platform/**/internal", // General internal pattern - // All features that have been converted to barrel files - "**/platform/messaging/**", - "**/src/**/*" // Prevent relative imports across libs. - ] - } - ] - } - }, - { - "files": ["bitwarden_license/bit-common/src/**/*.ts"], - "rules": { - "no-restricted-imports": [ - "error", - { "patterns": ["@bitwarden/bit-common/*", "**/src/**/*"] } - ] - } - }, - { - "files": ["apps/**/*.ts"], - "rules": { - // Catches static imports - "no-restricted-imports": [ - "error", - { - "patterns": [ - "biwarden_license/**", - "@bitwarden/bit-common/*", - "@bitwarden/bit-web/*", - "**/src/**/*" - ] - } - ], - // Catches dynamic imports, e.g. in routing modules where modules are lazy-loaded - "no-restricted-syntax": [ - "error", - { - "message": "Don't import Bitwarden licensed code into OSS code.", - "selector": "ImportExpression > Literal.source[value=/.*(bitwarden_license|bit-common|bit-web).*/]" - } - ] - } - } - ] -} diff --git a/.github/renovate.json b/.github/renovate.json index b5c43cc1d3..64b81cd9ee 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -69,6 +69,26 @@ "commitMessagePrefix": "[deps] Auth:", "reviewers": ["team:team-auth-dev"] }, + { + "matchPackageNames": [ + "@angular-eslint/schematics", + "angular-eslint", + "eslint-config-prettier", + "eslint-import-resolver-typescript", + "eslint-plugin-import", + "eslint-plugin-rxjs-angular", + "eslint-plugin-rxjs", + "eslint-plugin-storybook", + "eslint-plugin-tailwindcss", + "eslint", + "husky", + "lint-staged", + "typescript-eslint" + ], + "description": "Architecture owned dependencies", + "commitMessagePrefix": "[deps] Architecture:", + "reviewers": ["team:dept-architecture"] + }, { "matchPackageNames": [ "@angular-eslint/eslint-plugin-template", @@ -88,9 +108,8 @@ "husky", "lint-staged" ], - "description": "Architecture owned dependencies", - "commitMessagePrefix": "[deps] Architecture:", - "reviewers": ["team:dept-architecture"] + "groupName": "Linting minor-patch", + "matchUpdateTypes": ["minor", "patch"] }, { "matchPackageNames": [ diff --git a/.storybook/main.ts b/.storybook/main.ts index b48a86ba2b..d98ca06ead 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,7 +1,8 @@ import { dirname, join } from "path"; + import { StorybookConfig } from "@storybook/angular"; -import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin"; import remarkGfm from "remark-gfm"; +import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin"; const config: StorybookConfig = { stories: [ @@ -29,6 +30,8 @@ const config: StorybookConfig = { getAbsolutePath("@storybook/addon-designs"), getAbsolutePath("@storybook/addon-interactions"), { + // @storybook/addon-docs is part of @storybook/addon-essentials + // eslint-disable-next-line storybook/no-uninstalled-addons name: "@storybook/addon-docs", options: { mdxPluginOptions: { diff --git a/.storybook/manager.js b/.storybook/manager.js index 409f93ec50..e0ec04fd37 100644 --- a/.storybook/manager.js +++ b/.storybook/manager.js @@ -50,10 +50,14 @@ const darkTheme = create({ }); export const getPreferredColorScheme = () => { - if (!globalThis || !globalThis.matchMedia) return "light"; + if (!globalThis || !globalThis.matchMedia) { + return "light"; + } const isDarkThemePreferred = globalThis.matchMedia("(prefers-color-scheme: dark)").matches; - if (isDarkThemePreferred) return "dark"; + if (isDarkThemePreferred) { + return "dark"; + } return "light"; }; diff --git a/.vscode/settings.json b/.vscode/settings.json index 6b31121e17..295c290a37 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,5 +7,6 @@ "**/_locales/*[^n]/messages.json": true }, "rust-analyzer.linkedProjects": ["apps/desktop/desktop_native/Cargo.toml"], - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "eslint.useFlatConfig": true } diff --git a/apps/browser/.eslintrc.json b/apps/browser/.eslintrc.json deleted file mode 100644 index ba96051183..0000000000 --- a/apps/browser/.eslintrc.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "env": { - "browser": true, - "webextensions": true - }, - "overrides": [ - { - "files": ["src/**/*.ts"], - "excludedFiles": [ - "src/**/{content,popup,spec}/**/*.ts", - "src/**/autofill/{notification,overlay}/**/*.ts", - "src/**/autofill/**/{autofill-overlay-content,collect-autofill-content,dom-element-visibility,insert-autofill-content}.service.ts", - "src/**/*.spec.ts" - ], - "rules": { - "no-restricted-globals": [ - "error", - { - "name": "window", - "message": "The `window` object is not available in service workers and may not be available within the background script. Consider using `self`, `globalThis`, or another global property instead." - } - ] - } - } - ] -} diff --git a/apps/browser/src/auth/popup/register.component.ts b/apps/browser/src/auth/popup/register.component.ts index f8a332f0fd..50475b2204 100644 --- a/apps/browser/src/auth/popup/register.component.ts +++ b/apps/browser/src/auth/popup/register.component.ts @@ -13,9 +13,7 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { DialogService, ToastService } from "@bitwarden/components"; -import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { KeyService } from "@bitwarden/key-management"; @Component({ @@ -34,9 +32,7 @@ export class RegisterComponent extends BaseRegisterComponent { i18nService: I18nService, keyService: KeyService, apiService: ApiService, - stateService: StateService, platformUtilsService: PlatformUtilsService, - passwordGenerationService: PasswordGenerationServiceAbstraction, environmentService: EnvironmentService, logService: LogService, auditService: AuditService, @@ -51,9 +47,7 @@ export class RegisterComponent extends BaseRegisterComponent { i18nService, keyService, apiService, - stateService, platformUtilsService, - passwordGenerationService, environmentService, logService, auditService, diff --git a/apps/browser/src/autofill/content/components/.lit-storybook/main.ts b/apps/browser/src/autofill/content/components/.lit-storybook/main.ts index 9e2da59d99..157682160e 100644 --- a/apps/browser/src/autofill/content/components/.lit-storybook/main.ts +++ b/apps/browser/src/autofill/content/components/.lit-storybook/main.ts @@ -1,8 +1,8 @@ -import { dirname, join } from "path"; -import path from "path"; +import path, { dirname, join } from "path"; + import type { StorybookConfig } from "@storybook/web-components-webpack5"; -import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin"; import remarkGfm from "remark-gfm"; +import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin"; const getAbsolutePath = (value: string): string => dirname(require.resolve(join(value, "package.json"))); diff --git a/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.html b/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.html index 9f6c0aca50..45c0612af4 100644 --- a/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.html +++ b/apps/browser/src/autofill/popup/fido2/fido2-use-browser-link.component.html @@ -47,6 +47,6 @@
diff --git a/apps/browser/src/services/families-policy.service.spec.ts b/apps/browser/src/billing/services/families-policy.service.spec.ts similarity index 100% rename from apps/browser/src/services/families-policy.service.spec.ts rename to apps/browser/src/billing/services/families-policy.service.spec.ts diff --git a/apps/browser/src/services/families-policy.service.ts b/apps/browser/src/billing/services/families-policy.service.ts similarity index 100% rename from apps/browser/src/services/families-policy.service.ts rename to apps/browser/src/billing/services/families-policy.service.ts diff --git a/apps/browser/src/platform/popup/layout/popup-page.component.html b/apps/browser/src/platform/popup/layout/popup-page.component.html index ba9a108a50..94f0846a85 100644 --- a/apps/browser/src/platform/popup/layout/popup-page.component.html +++ b/apps/browser/src/platform/popup/layout/popup-page.component.html @@ -13,13 +13,13 @@