[SM-468] Add eslint rule for forcing type to buttons (#4576)

* Add eslint rule for forcing type to buttons

* Fix eslint js errors
This commit is contained in:
Oscar Hinton 2023-01-31 18:39:10 +01:00 committed by GitHub
parent 8ac8cc0274
commit 4d6e333d8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 1200 additions and 132 deletions

View File

@ -4,106 +4,118 @@
"browser": true,
"webextensions": true
},
"plugins": ["@typescript-eslint", "rxjs", "rxjs-angular", "import"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["./tsconfig.eslint.json"],
"sourceType": "module"
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"prettier",
"plugin:rxjs/recommended"
],
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [".ts"]
},
"import/resolver": {
"typescript": {
"alwaysTryTypes": true
}
}
},
"rules": {
"@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
"accessibility": "no-public"
}
],
"@typescript-eslint/no-this-alias": [
"error",
{
"allowedNames": ["self"]
}
],
"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"
"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:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"prettier",
"plugin:rxjs/recommended"
],
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [".ts"]
},
"newlines-between": "always",
"pathGroups": [
"import/resolver": {
"typescript": {
"alwaysTryTypes": true
}
}
},
"rules": {
"@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
"pattern": "@bitwarden/**",
"group": "external",
"position": "after"
},
{
"pattern": "src/**/*",
"group": "parent",
"position": "before"
"accessibility": "no-public"
}
],
"pathGroupsExcludedImportTypes": ["builtin"]
}
],
"rxjs-angular/prefer-takeuntil": "error",
"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": [
// Do not allow angular/node code to be imported into common
"@typescript-eslint/no-this-alias": [
"error",
{
"target": "./libs/common/**/*",
"from": "./libs/angular/**/*"
"allowedNames": ["self"]
}
],
"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",
"rxjs/no-exposed-subjects": ["error", { "allowProtected": true }],
"no-restricted-syntax": [
"error",
{
"message": "Calling `svgIcon` directly is not allowed",
"selector": "CallExpression[callee.name='svgIcon']"
},
{
"target": "./libs/common/**/*",
"from": "./libs/node/**/*"
"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": [
// Do not allow angular/node code to be imported into common
{
"target": "./libs/common/**/*",
"from": "./libs/angular/**/*"
},
{
"target": "./libs/common/**/*",
"from": "./libs/node/**/*"
}
]
}
],
"no-restricted-imports": [
"error",
{ "patterns": ["src/**/*"], "paths": ["@fluffy-spoon/substitute"] }
]
}
],
"no-restricted-imports": [
"error",
{ "patterns": ["src/**/*"], "paths": ["@fluffy-spoon/substitute"] }
]
},
"overrides": [
},
{
"files": ["*.html"],
"parser": "@angular-eslint/template-parser",
"plugins": ["@angular-eslint/template"],
"rules": {
"@angular-eslint/template/button-has-type": "error"
}
},
{
"files": ["libs/common/src/**/*.ts"],
"rules": {

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="loaded && organizations$ | async as organizations">
<div class="content org-filter-content" *ngIf="loaded && shouldShow(organizations)">
<ng-container *ngIf="selectedVault$ | async as vaultFilterDisplay">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<header>
<div class="left">
<button type="button" (click)="close()">{{ "close" | i18n }}</button>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<button
class="account-switcher"
(click)="toggle()"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div id="sends" class="vault">
<div class="left-nav">
<div class="vault-filters">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="show">
<div class="filter-heading">
<h2>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="!hide">
<div class="filter-heading">
<h2>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="show">
<ng-container [ngSwitch]="displayMode">
<ng-container *ngSwitchCase="'personalOwnershipPolicy'">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="show">
<h2 class="sr-only">{{ "filters" | i18n }}</h2>
<ul class="filter-options">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="filter-heading">
<h2>
<button

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="container loading-spinner" *ngIf="!loaded">
<i class="bwi bwi-spinner bwi-spin bwi-3x" aria-hidden="true"></i>
</div>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="content">
<div class="inner-content" *ngIf="cipher">
<div class="box">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div *ngIf="accountCreateOnly" class="">
<h1 class="tw-mt-12 tw-text-center tw-text-xl">{{ "createAccount" | i18n }}</h1>
<div

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="tw-m-2.5 tw-h-16 tw-text-center">
<button
(click)="selectStep()"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="confirmUserTitle">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<form class="modal-content" #form (ngSubmit)="submit()">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<nav class="navbar navbar-expand navbar-dark" [ngClass]="{ 'nav-background-alt': selfHosted }">
<div class="container">
<a class="navbar-brand" routerLink="/" appA11yTitle="{{ 'pageTitle' | i18n: 'Bitwarden' }}">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-template [ngIf]="isEnabled">
<button
bitIconButton="bwi bwi-fw bwi-filter"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="d-flex page-header">
<h1>
{{ "billingHistory" | i18n }}

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="container page-content">
<div class="tw-mb-4 tw-flex">
<h1>{{ "groups" | i18n }}</h1>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="container page-content">
<div class="tw-mb-4 tw-flex tw-flex-col tw-space-y-4">
<h1>{{ "members" | i18n }}</h1>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="container page-content">
<div class="row">
<div class="col-3">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="sendAddEditTitle">
<div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
<form

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="container page-content">
<app-callout type="warning" title="{{ 'sendDisabled' | i18n }}" *ngIf="disableSend">
<span>{{ "sendDisabledWarning" | i18n }}</span>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="page-header">
<h1>{{ "myAccount" | i18n }}</h1>
</div>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="d-flex tabbed-header">
<h1>
{{ "billingHistory" | i18n }}

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="page-header">
<h1>{{ "emergencyAccess" | i18n }}</h1>
</div>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="d-flex" [ngClass]="headerClass">
<h1>
{{ "paymentMethod" | i18n }}

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<app-change-kdf *ngIf="showChangeKdf"></app-change-kdf>
<div
[ngClass]="{ 'tabbed-header': !showChangeKdf, 'secondary-header': showChangeKdf }"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<td>
{{ sponsoringOrg.familySponsorshipFriendlyName }}
</td>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="tabbed-header">
<h1 *ngIf="!organizationId">{{ "twoStepLogin" | i18n }}</h1>
<h1 *ngIf="organizationId">{{ "twoStepLoginEnforcement" | i18n }}</h1>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="passHistoryTitle">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<div class="modal-content">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<button
bitBadge
[style.color]="textColor"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin text-muted tw-m-2"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="filters && filters.length">
<div *ngIf="headerInfo.showHeader" class="filter-heading">
<button

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container>
<bit-table
*ngIf="filteredCiphers.length || filteredCollections.length"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<!DOCTYPE html>
<html class="theme_light">
<head>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<!DOCTYPE html>
<html>
<head>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<!DOCTYPE html>
<html>
<head>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="addTitle">
<div class="modal-dialog modal-dialog-scrollable" role="document">
<div class="modal-content">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="page-header d-flex">
<h1>{{ "clients" | i18n }}</h1>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div class="page-header d-flex">
<h1>{{ "people" | i18n }}</h1>
<div class="ml-auto d-flex">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<header
*ngIf="routeData$ | async as routeData"
class="-tw-m-6 tw-mb-3 tw-flex tw-flex-col tw-p-6"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<button bitButton class="tw-min-w-max" buttonType="primary" [bitMenuTriggerFor]="newMenu">
{{ "new" | i18n }} <i class="bwi bwi-angle-down" aria-hidden="true"></i>
</button>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<bit-nav-group
*ngIf="activeOrganization$ | async as activeOrganization"
[text]="activeOrganization.name"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngIf="secrets$ | async as secrets; else spinner">
<div *ngIf="secrets.length > 0" class="float-right tw-mt-3 tw-items-center">
<button bitButton buttonType="secondary" (click)="openNewSecretDialog()">

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div *ngIf="!projects" class="tw-items-center tw-justify-center tw-pt-64 tw-text-center">
<i class="bwi bwi-spinner bwi-spin bwi-3x"></i>
</div>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<form [formGroup]="formGroup" [bitSubmit]="submit">
<bit-dialog dialogSize="default" disablePadding>
<ng-container bitDialogTitle>{{ title | i18n }}</ng-container>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div *ngIf="!tokens" class="tw-items-center tw-justify-center tw-pt-64 tw-text-center">
<i class="bwi bwi-spinner bwi-spin bwi-3x"></i>
</div>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<bit-dialog dialogSize="default">
<ng-container bitDialogTitle>
<span>{{ "createAccessToken" | i18n }}</span>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div *ngIf="!serviceAccounts" class="tw-items-center tw-justify-center tw-pt-64 tw-text-center">
<i class="bwi bwi-spinner bwi-spin bwi-3x"></i>
</div>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div *ngIf="!secrets" class="tw-items-center tw-justify-center tw-pt-64 tw-text-center">
<i class="bwi bwi-spinner bwi-spin bwi-3x"></i>
</div>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div
class="tw-flex tw-items-center tw-gap-2 tw-p-2 tw-pl-4 tw-text-contrast"
[ngClass]="bannerClass"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<ng-container *ngFor="let breadcrumb of beforeOverflow; let last = last">
<ng-container *ngIf="breadcrumb.route">
<a

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<bit-simple-dialog>
<i bit-dialog-icon class="bwi tw-text-3xl" [class]="iconClasses" aria-hidden="true"></i>

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<!-- This a higher order component that composes `NavItemComponent` -->
<bit-nav-item
[text]="text"

View File

@ -1,3 +1,5 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable @angular-eslint/template/button-has-type -->
<div
class="tw-relative"
[ngClass]="[

1027
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,9 @@
],
"devDependencies": {
"@angular-devkit/build-angular": "^14.0.6",
"@angular-eslint/eslint-plugin": "^14.1.2",
"@angular-eslint/eslint-plugin-template": "^14.1.2",
"@angular-eslint/template-parser": "^14.1.2",
"@angular/cli": "^14.0.6",
"@angular/compiler-cli": "^14.0.6",
"@angular/elements": "^14.0.6",