1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-21 11:35:34 +01:00

[PS-182] Upgrade Angular to V14 (#2948)

This commit is contained in:
Oscar Hinton 2022-07-26 14:48:11 +02:00 committed by GitHub
parent c90eb42ead
commit 2011131bb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 13362 additions and 18644 deletions

1
.gitignore vendored
View File

@ -26,6 +26,7 @@ npm-debug.log
# Build directories
dist
build
.angular/cache
# Testing
coverage

View File

@ -4,7 +4,10 @@
"types": ["node"],
"allowSyntheticDefaultImports": true
},
"exclude": ["../src/test.setup.ts", "../src/**/*.spec.ts", "../projects/**/*.spec.ts"],
"include": ["../src/**/*", "../projects/**/*"],
"files": ["./typings.d.ts"]
"exclude": ["../src/test.setup.ts", "../apps/src/**/*.spec.ts", "../libs/**/*.spec.ts"],
"files": [
"./typings.d.ts",
"../libs/components/src/main.ts",
"../libs/components/src/polyfills.ts"
]
}

View File

@ -3,6 +3,83 @@
"version": 1,
"newProjectRoot": "apps",
"projects": {
"web": {
"projectType": "application",
"schematics": {
"@schematics/angular:application": {
"strict": true
}
},
"root": "apps/web",
"sourceRoot": "apps/web/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/web",
"index": "apps/web/src/index.html",
"main": "apps/web/src/app/main.ts",
"polyfills": "apps/web/src/app/polyfills.ts",
"tsConfig": "apps/web/tsconfig.json",
"assets": ["apps/web/src/favicon.ico"],
"styles": [],
"scripts": []
}
}
}
},
"browser": {
"projectType": "application",
"schematics": {
"@schematics/angular:application": {
"strict": true
}
},
"root": "apps/browser",
"sourceRoot": "apps/browser/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/browser",
"index": "apps/browser/src/popup/index.html",
"main": "apps/browser/src/popup/main.ts",
"polyfills": "apps/browser/src/popup/polyfills.ts",
"tsConfig": "apps/browser/tsconfig.json",
"assets": [],
"styles": [],
"scripts": []
}
}
}
},
"desktop": {
"projectType": "application",
"schematics": {
"@schematics/angular:application": {
"strict": true
}
},
"root": "apps/desktop",
"sourceRoot": "apps/desktop/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/desktop",
"index": "apps/desktop/src/index.html",
"main": "apps/desktop/src/app/main.ts",
"tsConfig": "apps/desktop/tsconfig.json",
"assets": [],
"styles": [],
"scripts": []
}
}
}
},
"components": {
"projectType": "application",
"schematics": {
@ -10,9 +87,9 @@
"strict": true
}
},
"root": "./libs/components",
"root": "libs/components",
"sourceRoot": "libs/components/src",
"prefix": "components",
"prefix": "bit",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
@ -31,18 +108,6 @@
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"outputHashing": "all"
},
"development": {
@ -60,22 +125,42 @@
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "components:build:production"
"browserTarget": "test-storybook:build:production"
},
"development": {
"browserTarget": "components:build:development"
"browserTarget": "test-storybook:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
}
}
},
"storybook": {
"projectType": "application",
"root": "libs/components",
"sourceRoot": "libs/components/src",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"browserTarget": "components:build"
"tsConfig": ".storybook/tsconfig.json",
"styles": ["libs/components/src/styles.scss", "libs/components/src/styles.css"],
"scripts": []
}
}
}
},
"angular": {
"projectType": "library",
"root": "libs/angular",
"sourceRoot": "libs/angular/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"defaultConfiguration": "production"
}
}
}
},
"defaultProject": "components"
}
}

View File

@ -156,7 +156,7 @@ export class BrowserApi {
static reloadExtension(win: Window) {
if (win != null) {
return win.location.reload(true);
return (win.location as any).reload(true);
} else {
return chrome.runtime.reload();
}

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { Router } from "@angular/router";
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
@ -21,7 +21,7 @@ import { StateService } from "@bitwarden/common/abstractions/state.service";
export class RegisterComponent extends BaseRegisterComponent {
constructor(
formValidationErrorService: FormValidationErrorsService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
authService: AuthService,
router: Router,
i18nService: I18nService,

View File

@ -239,7 +239,6 @@ registerLocaleData(localeZhTw, "zh-TW");
RemovePasswordComponent,
VaultSelectComponent,
],
entryComponents: [],
providers: [CurrencyPipe, DatePipe],
bootstrap: [AppComponent],
})

View File

@ -1,4 +1,3 @@
import "core-js/stable";
import "date-input-polyfill";
import "web-animations-js";
import "zone.js/dist/zone";

View File

@ -11,4 +11,4 @@
@import "plugins.scss";
@import "environment.scss";
@import "pages.scss";
@import "~@angular/cdk/overlay-prebuilt.css";
@import "@angular/cdk/overlay-prebuilt.css";

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { Router } from "@angular/router";
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/components/export.component";
@ -28,7 +28,7 @@ export class ExportComponent extends BaseExportComponent {
private router: Router,
logService: LogService,
userVerificationService: UserVerificationService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
fileDownloadService: FileDownloadService
) {
super(

View File

@ -1,5 +1,5 @@
import { Component, ElementRef, OnInit, ViewChild } from "@angular/core";
import { FormControl } from "@angular/forms";
import { UntypedFormControl } from "@angular/forms";
import { Router } from "@angular/router";
import Swal from "sweetalert2";
@ -50,7 +50,7 @@ export class SettingsComponent implements OnInit {
previousVaultTimeout: number = null;
showChangeMasterPass = true;
vaultTimeout: FormControl = new FormControl(null);
vaultTimeout: UntypedFormControl = new UntypedFormControl(null);
constructor(
private platformUtilsService: PlatformUtilsService,

View File

@ -29,8 +29,8 @@ export class BrowserFileDownloadService implements FileDownloadService {
true
);
} else {
if (navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(builder.blob, request.fileName);
if ((navigator as any).msSaveOrOpenBlob) {
(navigator as any).msSaveBlob(builder.blob, request.fileName);
} else {
const a = window.document.createElement("a");
a.href = URL.createObjectURL(builder.blob);

View File

@ -46,13 +46,20 @@ const moduleRules = [
"sass-loader",
],
},
// Hide System.import warnings. ref: https://github.com/angular/angular/issues/21560
{
test: /[\/\\]@angular[\/\\].+\.js$/,
parser: { system: true },
test: /\.[cm]?js$/,
use: [
{
loader: "babel-loader",
options: {
configFile: false,
plugins: ["@angular/compiler-cli/linker/babel"],
},
},
],
},
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
test: /\.[jt]sx?$/,
loader: "@ngtools/webpack",
},
];
@ -102,7 +109,7 @@ const plugins = [
cleanAfterEveryBuildPatterns: ["!popup/fonts/**/*"],
}),
new webpack.ProvidePlugin({
process: "process/browser",
process: "process/browser.js",
}),
new webpack.SourceMapDevToolPlugin({
exclude: [/content\/.*/, /notification\/.*/],

View File

@ -1,5 +1,5 @@
import { Component, NgZone } from "@angular/core";
import { FormControl, FormGroup, Validators } from "@angular/forms";
import { UntypedFormControl, UntypedFormGroup, Validators } from "@angular/forms";
import { Router } from "@angular/router";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
@ -19,8 +19,8 @@ export class AccessibilityCookieComponent {
listenForCookie = false;
hCaptchaWindow: Window;
accessibilityForm = new FormGroup({
link: new FormControl("", Validators.required),
accessibilityForm = new UntypedFormGroup({
link: new UntypedFormControl("", Validators.required),
});
constructor(

View File

@ -1,5 +1,5 @@
import { Component, NgZone, OnDestroy, OnInit } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { Router } from "@angular/router";
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
@ -24,7 +24,7 @@ const BroadcasterSubscriptionId = "RegisterComponent";
export class RegisterComponent extends BaseRegisterComponent implements OnInit, OnDestroy {
constructor(
formValidationErrorService: FormValidationErrorsService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
authService: AuthService,
router: Router,
i18nService: I18nService,

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from "@angular/core";
import { FormControl } from "@angular/forms";
import { UntypedFormControl } from "@angular/forms";
import { debounceTime } from "rxjs/operators";
import { ModalService } from "@bitwarden/angular/services/modal.service";
@ -60,7 +60,7 @@ export class SettingsComponent implements OnInit {
startToTrayText: string;
startToTrayDescText: string;
vaultTimeout: FormControl = new FormControl(null);
vaultTimeout: UntypedFormControl = new UntypedFormControl(null);
showSecurity = true;
showAccountPreferences = true;

View File

@ -195,7 +195,7 @@ export class AppComponent implements OnInit {
await this.reloadProcess();
break;
case "reloadProcess":
window.location.reload(true);
(window.location as any).reload(true);
break;
case "syncStarted":
break;

View File

@ -1,5 +1,5 @@
import { Component, OnDestroy, OnInit } from "@angular/core";
import { FormControl } from "@angular/forms";
import { UntypedFormControl } from "@angular/forms";
import { StateService } from "@bitwarden/common/abstractions/state.service";
@ -11,7 +11,7 @@ import { SearchBarService, SearchBarState } from "./search-bar.service";
})
export class SearchComponent implements OnInit, OnDestroy {
state: SearchBarState;
searchText: FormControl = new FormControl(null);
searchText: UntypedFormControl = new UntypedFormControl(null);
constructor(private searchBarService: SearchBarService, private stateService: StateService) {
this.searchBarService.state.subscribe((state) => {

View File

@ -1,7 +1,7 @@
import * as os from "os";
import { Component, OnInit } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/components/export.component";
import { BroadcasterService } from "@bitwarden/common/abstractions/broadcaster.service";
@ -30,7 +30,7 @@ export class ExportComponent extends BaseExportComponent implements OnInit {
eventService: EventService,
policyService: PolicyService,
userVerificationService: UserVerificationService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
private broadcasterService: BroadcasterService,
logService: LogService,
fileDownloadService: FileDownloadService

View File

@ -1,6 +1,6 @@
@import "../../../../libs/angular/src/scss/webfonts.css";
@import "../../../../libs/angular/src/scss/bwicons/styles/style.scss";
@import "~@angular/cdk/overlay-prebuilt.css";
@import "@angular/cdk/overlay-prebuilt.css";
@import "variables.scss";
@import "base.scss";
@import "grid.scss";

View File

@ -12,7 +12,19 @@ const common = {
module: {
rules: [
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
test: /\.[cm]?js$/,
use: [
{
loader: "babel-loader",
options: {
configFile: false,
plugins: ["@angular/compiler-cli/linker/babel"],
},
},
],
},
{
test: /\.[jt]sx?$/,
loader: "@ngtools/webpack",
},
{

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { first } from "rxjs/operators";
@ -36,7 +36,7 @@ export class RegisterComponent extends BaseRegisterComponent {
constructor(
formValidationErrorService: FormValidationErrorsService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
authService: AuthService,
router: Router,
i18nService: I18nService,

View File

@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { FormGroup } from "@angular/forms";
import { UntypedFormGroup } from "@angular/forms";
@Component({
selector: "app-org-info",
@ -10,6 +10,6 @@ export class OrganizationInformationComponent {
@Input() createOrganization = true;
@Input() isProvider = false;
@Input() acceptingSponsorship = false;
@Input() formGroup: FormGroup;
@Input() formGroup: UntypedFormGroup;
@Output() changedBusinessOwned = new EventEmitter<void>();
}

View File

@ -1,5 +1,5 @@
import { Component, Input } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { Router } from "@angular/router";
import { RegisterComponent as BaseRegisterComponent } from "@bitwarden/angular/components/register.component";
@ -28,7 +28,7 @@ export class RegisterFormComponent extends BaseRegisterComponent {
constructor(
formValidationErrorService: FormValidationErrorsService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
authService: AuthService,
router: Router,
i18nService: I18nService,

View File

@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { UntypedFormBuilder, FormGroup } from "@angular/forms";
import { Router } from "@angular/router";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@ -34,7 +34,7 @@ export class BillingComponent extends OrganizationPlansComponent {
organizationService: OrganizationService,
logService: LogService,
messagingService: MessagingService,
formBuilder: FormBuilder
formBuilder: UntypedFormBuilder
) {
super(
apiService,

View File

@ -1,7 +1,7 @@
import { StepperSelectionEvent } from "@angular/cdk/stepper";
import { TitleCasePipe } from "@angular/common";
import { Component, OnInit, ViewChild } from "@angular/core";
import { FormBuilder, Validators } from "@angular/forms";
import { UntypedFormBuilder, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { first } from "rxjs";
@ -45,7 +45,7 @@ export class TrialInitiationComponent implements OnInit {
constructor(
private route: ActivatedRoute,
protected router: Router,
private formBuilder: FormBuilder,
private formBuilder: UntypedFormBuilder,
private titleCasePipe: TitleCasePipe,
private stateService: StateService,
private apiService: ApiService,

View File

@ -1,5 +1,5 @@
import { Directive, Input, OnInit } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { UntypedFormControl, UntypedFormGroup } from "@angular/forms";
import { PolicyType } from "@bitwarden/common/enums/policyType";
import { Organization } from "@bitwarden/common/models/domain/organization";
@ -22,8 +22,8 @@ export abstract class BasePolicyComponent implements OnInit {
@Input() policyResponse: PolicyResponse;
@Input() policy: BasePolicy;
enabled = new FormControl(false);
data: FormGroup = null;
enabled = new UntypedFormControl(false);
data: UntypedFormGroup = null;
ngOnInit(): void {
this.enabled.setValue(this.policyResponse.enabled);

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
@ -32,7 +32,7 @@ export class MasterPasswordPolicyComponent extends BasePolicyComponent {
showKeyConnectorInfo = false;
constructor(
private formBuilder: FormBuilder,
private formBuilder: UntypedFormBuilder,
i18nService: I18nService,
private organizationService: OrganizationService
) {

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PolicyType } from "@bitwarden/common/enums/policyType";
@ -34,7 +34,7 @@ export class PasswordGeneratorPolicyComponent extends BasePolicyComponent {
defaultTypes: { name: string; value: string }[];
constructor(private formBuilder: FormBuilder, i18nService: I18nService) {
constructor(private formBuilder: UntypedFormBuilder, i18nService: I18nService) {
super();
this.defaultTypes = [

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
import { PolicyType } from "@bitwarden/common/enums/policyType";
@ -30,7 +30,10 @@ export class ResetPasswordPolicyComponent extends BasePolicyComponent {
defaultTypes: { name: string; value: string }[];
showKeyConnectorInfo = false;
constructor(private formBuilder: FormBuilder, private organizationService: OrganizationService) {
constructor(
private formBuilder: UntypedFormBuilder,
private organizationService: OrganizationService
) {
super();
}

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { PolicyType } from "@bitwarden/common/enums/policyType";
@ -21,7 +21,7 @@ export class SendOptionsPolicyComponent extends BasePolicyComponent {
disableHideEmail: false,
});
constructor(private formBuilder: FormBuilder) {
constructor(private formBuilder: UntypedFormBuilder) {
super();
}
}

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { ActivatedRoute } from "@angular/router";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
@ -30,7 +30,7 @@ export class OrganizationExportComponent extends ExportComponent {
policyService: PolicyService,
logService: LogService,
userVerificationService: UserVerificationService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
fileDownloadService: FileDownloadService
) {
super(

View File

@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core";
import { FormBuilder, Validators } from "@angular/forms";
import { UntypedFormBuilder, Validators } from "@angular/forms";
import { Router } from "@angular/router";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@ -79,7 +79,7 @@ export class OrganizationPlansComponent implements OnInit {
private organizationService: OrganizationService,
private logService: LogService,
private messagingService: MessagingService,
private formBuilder: FormBuilder
private formBuilder: UntypedFormBuilder
) {
this.selfHosted = platformUtilsService.isSelfHost();
}

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from "@angular/core";
import { FormControl } from "@angular/forms";
import { UntypedFormControl } from "@angular/forms";
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
@ -25,7 +25,7 @@ export class PreferencesComponent implements OnInit {
localeOptions: any[];
themeOptions: any[];
vaultTimeout: FormControl = new FormControl(null);
vaultTimeout: UntypedFormControl = new UntypedFormControl(null);
private startingLocale: string;
private startingTheme: ThemeType;

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { notAllowedValueAsync } from "@bitwarden/angular/validators/notAllowedValueAsync.validator";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@ -24,7 +24,7 @@ export class SponsoredFamiliesComponent implements OnInit {
// Conditional display properties
formPromise: Promise<any>;
sponsorshipForm: FormGroup;
sponsorshipForm: UntypedFormGroup;
constructor(
private apiService: ApiService,
@ -32,7 +32,7 @@ export class SponsoredFamiliesComponent implements OnInit {
private platformUtilsService: PlatformUtilsService,
private syncService: SyncService,
private organizationService: OrganizationService,
private formBuilder: FormBuilder,
private formBuilder: UntypedFormBuilder,
private stateService: StateService
) {
this.sponsorshipForm = this.formBuilder.group({

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { ExportComponent as BaseExportComponent } from "@bitwarden/angular/components/export.component";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
@ -28,7 +28,7 @@ export class ExportComponent extends BaseExportComponent {
policyService: PolicyService,
logService: LogService,
userVerificationService: UserVerificationService,
formBuilder: FormBuilder,
formBuilder: UntypedFormBuilder,
fileDownloadService: FileDownloadService
) {
super(

View File

@ -64,18 +64,25 @@ const moduleRules = [
],
},
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
test: /\.[cm]?js$/,
use: [
{
loader: "babel-loader",
options: {
configFile: false,
plugins: ["@angular/compiler-cli/linker/babel"],
},
},
],
},
{
test: /\.[jt]sx?$/,
loader: "@ngtools/webpack",
},
];
const plugins = [
new CleanWebpackPlugin(),
// ref: https://github.com/angular/angular/issues/20357
new webpack.ContextReplacementPlugin(
/\@angular(\\|\/)core(\\|\/)fesm5/,
path.resolve(__dirname, "./src")
),
new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "index.html",
@ -142,6 +149,9 @@ const plugins = [
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
new webpack.ProvidePlugin({
process: "process/browser.js",
}),
new webpack.EnvironmentPlugin({
ENV: ENV,
NODE_ENV: NODE_ENV === "production" ? "production" : "development",
@ -153,9 +163,6 @@ const plugins = [
PAYPAL_CONFIG: envConfig["paypal"] ?? {},
FLAGS: envConfig["flags"] ?? {},
}),
new webpack.ProvidePlugin({
process: "process/browser",
}),
new AngularWebpackPlugin({
tsConfigPath: "tsconfig.json",
entryModule: "src/app/app.module#AppModule",

View File

@ -1,5 +1,5 @@
import { Directive, Input, OnInit, Self } from "@angular/core";
import { ControlValueAccessor, FormControl, NgControl, Validators } from "@angular/forms";
import { ControlValueAccessor, UntypedFormControl, NgControl, Validators } from "@angular/forms";
import { dirtyRequired } from "@bitwarden/angular/validators/dirty.validator";
@ -25,7 +25,7 @@ export abstract class BaseCvaComponent implements ControlValueAccessor, OnInit {
@Input() controlId: string;
@Input() helperText: string;
internalControl = new FormControl("");
internalControl = new UntypedFormControl("");
protected onChange: any;
protected onTouched: any;

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormControl } from "@angular/forms";
import { UntypedFormBuilder, FormControl } from "@angular/forms";
import { ActivatedRoute } from "@angular/router";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
@ -33,7 +33,7 @@ export class ScimComponent implements OnInit {
});
constructor(
private formBuilder: FormBuilder,
private formBuilder: UntypedFormBuilder,
private route: ActivatedRoute,
private apiService: ApiService,
private platformUtilsService: PlatformUtilsService,

View File

@ -1,5 +1,5 @@
import { Component, OnInit } from "@angular/core";
import { AbstractControl, FormBuilder, FormGroup } from "@angular/forms";
import { AbstractControl, UntypedFormBuilder, UntypedFormGroup } from "@angular/forms";
import { ActivatedRoute } from "@angular/router";
import { SelectOptions } from "@bitwarden/angular/interfaces/selectOptions";
@ -142,7 +142,7 @@ export class SsoComponent implements OnInit {
});
constructor(
private formBuilder: FormBuilder,
private formBuilder: UntypedFormBuilder,
private route: ActivatedRoute,
private apiService: ApiService,
private platformUtilsService: PlatformUtilsService,
@ -242,9 +242,9 @@ export class SsoComponent implements OnInit {
this.showOpenIdCustomizations = !this.showOpenIdCustomizations;
}
getErrorCount(form: FormGroup): number {
getErrorCount(form: UntypedFormGroup): number {
return Object.values(form.controls).reduce((acc: number, control: AbstractControl) => {
if (control instanceof FormGroup) {
if (control instanceof UntypedFormGroup) {
return acc + this.getErrorCount(control);
}
@ -270,13 +270,13 @@ export class SsoComponent implements OnInit {
return this.samlSigningAlgorithms.map((algorithm) => ({ name: algorithm, value: algorithm }));
}
private validateForm(form: FormGroup) {
private validateForm(form: UntypedFormGroup) {
Object.values(form.controls).forEach((control: AbstractControl) => {
if (control.disabled) {
return;
}
if (control instanceof FormGroup) {
if (control instanceof UntypedFormGroup) {
this.validateForm(control);
} else {
control.markAsDirty();

View File

@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PolicyType } from "@bitwarden/common/enums/policyType";
@ -27,7 +27,7 @@ export class MaximumVaultTimeoutPolicyComponent extends BasePolicyComponent {
minutes: [null],
});
constructor(private formBuilder: FormBuilder, private i18nService: I18nService) {
constructor(private formBuilder: UntypedFormBuilder, private i18nService: I18nService) {
super();
}

View File

@ -3,7 +3,6 @@ const { pathsToModuleNameMapper } = require("ts-jest");
const { compilerOptions } = require("../shared/tsconfig.libs");
module.exports = {
name: "angular",
displayName: "libs/angular tests",
preset: "jest-preset-angular",
testMatch: ["**/+(*.)+(spec).+(ts)"],

View File

@ -1,5 +1,5 @@
import { Directive, EventEmitter, OnInit, Output } from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { UntypedFormBuilder } from "@angular/forms";
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { EventService } from "@bitwarden/common/abstractions/event.service";
@ -41,7 +41,7 @@ export class ExportComponent implements OnInit {
protected win: Window,
private logService: LogService,
private userVerificationService: UserVerificationService,
private formBuilder: FormBuilder,
private formBuilder: UntypedFormBuilder,
protected fileDownloadService: FileDownloadService
) {}

View File

@ -1,5 +1,5 @@
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { AbstractControl, FormBuilder, ValidatorFn, Validators } from "@angular/forms";
import { AbstractControl, UntypedFormBuilder, ValidatorFn, Validators } from "@angular/forms";
import { Router } from "@angular/router";
import { InputsFieldMatch } from "@bitwarden/angular/validators/inputsFieldMatch.validator";
@ -67,7 +67,7 @@ export class RegisterComponent extends CaptchaProtectedComponent implements OnIn
constructor(
protected formValidationErrorService: FormValidationErrorsService,
protected formBuilder: FormBuilder,
protected formBuilder: UntypedFormBuilder,
protected authService: AuthService,
protected router: Router,
i18nService: I18nService,

View File

@ -1,6 +1,6 @@
import { DatePipe } from "@angular/common";
import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
import { UntypedFormControl, UntypedFormGroup } from "@angular/forms";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
@ -62,15 +62,15 @@ export class EffluxDatesComponent implements OnInit {
return BrowserPath.Default;
}
datesForm = new FormGroup({
selectedDeletionDatePreset: new FormControl(),
selectedExpirationDatePreset: new FormControl(),
defaultDeletionDateTime: new FormControl(),
defaultExpirationDateTime: new FormControl(),
fallbackDeletionDate: new FormControl(),
fallbackDeletionTime: new FormControl(),
fallbackExpirationDate: new FormControl(),
fallbackExpirationTime: new FormControl(),
datesForm = new UntypedFormGroup({
selectedDeletionDatePreset: new UntypedFormControl(),
selectedExpirationDatePreset: new UntypedFormControl(),
defaultDeletionDateTime: new UntypedFormControl(),
defaultExpirationDateTime: new UntypedFormControl(),
fallbackDeletionDate: new UntypedFormControl(),
fallbackDeletionTime: new UntypedFormControl(),
fallbackExpirationDate: new UntypedFormControl(),
fallbackExpirationTime: new UntypedFormControl(),
});
deletionDatePresets: any[] = [
@ -87,36 +87,36 @@ export class EffluxDatesComponent implements OnInit {
{ name: this.i18nService.t("never"), value: DatePreset.Never },
].concat([...this.deletionDatePresets]);
get selectedDeletionDatePreset(): FormControl {
return this.datesForm.get("selectedDeletionDatePreset") as FormControl;
get selectedDeletionDatePreset(): UntypedFormControl {
return this.datesForm.get("selectedDeletionDatePreset") as UntypedFormControl;
}
get selectedExpirationDatePreset(): FormControl {
return this.datesForm.get("selectedExpirationDatePreset") as FormControl;
get selectedExpirationDatePreset(): UntypedFormControl {
return this.datesForm.get("selectedExpirationDatePreset") as UntypedFormControl;
}
get defaultDeletionDateTime(): FormControl {
return this.datesForm.get("defaultDeletionDateTime") as FormControl;
get defaultDeletionDateTime(): UntypedFormControl {
return this.datesForm.get("defaultDeletionDateTime") as UntypedFormControl;
}
get defaultExpirationDateTime(): FormControl {
return this.datesForm.get("defaultExpirationDateTime") as FormControl;
get defaultExpirationDateTime(): UntypedFormControl {
return this.datesForm.get("defaultExpirationDateTime") as UntypedFormControl;
}
get fallbackDeletionDate(): FormControl {
return this.datesForm.get("fallbackDeletionDate") as FormControl;
get fallbackDeletionDate(): UntypedFormControl {
return this.datesForm.get("fallbackDeletionDate") as UntypedFormControl;
}
get fallbackDeletionTime(): FormControl {
return this.datesForm.get("fallbackDeletionTime") as FormControl;
get fallbackDeletionTime(): UntypedFormControl {
return this.datesForm.get("fallbackDeletionTime") as UntypedFormControl;
}
get fallbackExpirationDate(): FormControl {
return this.datesForm.get("fallbackExpirationDate") as FormControl;
get fallbackExpirationDate(): UntypedFormControl {
return this.datesForm.get("fallbackExpirationDate") as UntypedFormControl;
}
get fallbackExpirationTime(): FormControl {
return this.datesForm.get("fallbackExpirationTime") as FormControl;
get fallbackExpirationTime(): UntypedFormControl {
return this.datesForm.get("fallbackExpirationTime") as UntypedFormControl;
}
// Should be able to call these at any time and compute a submitable value

View File

@ -2,7 +2,7 @@ import { Directive, Input, OnInit } from "@angular/core";
import {
AbstractControl,
ControlValueAccessor,
FormBuilder,
UntypedFormBuilder,
ValidationErrors,
Validator,
} from "@angular/forms";
@ -44,7 +44,7 @@ export class VaultTimeoutInputComponent implements ControlValueAccessor, Validat
private validatorChange: () => void;
constructor(
private formBuilder: FormBuilder,
private formBuilder: UntypedFormBuilder,
private policyService: PolicyService,
private i18nService: I18nService
) {}

View File

@ -1,6 +1,6 @@
import { animate, style, transition, trigger } from "@angular/animations";
import { Component, OnInit } from "@angular/core";
import { ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR } from "@angular/forms";
import { ControlValueAccessor, UntypedFormControl, NG_VALUE_ACCESSOR } from "@angular/forms";
import { KeyConnectorService } from "@bitwarden/common/abstractions/keyConnector.service";
import { UserVerificationService } from "@bitwarden/common/abstractions/userVerification.service";
@ -34,7 +34,7 @@ export class UserVerificationComponent implements ControlValueAccessor, OnInit {
disableRequestOTP = false;
sentCode = false;
secret = new FormControl("");
secret = new UntypedFormControl("");
private onChange: (value: Verification) => void;

View File

@ -1,4 +1,4 @@
import { AbstractControl, FormGroup, ValidatorFn } from "@angular/forms";
import { AbstractControl, UntypedFormGroup, ValidatorFn } from "@angular/forms";
import { FormGroupControls } from "@bitwarden/common/abstractions/formValidationErrors.service";
@ -39,7 +39,7 @@ export class InputsFieldMatch {
//checks the formGroup if two fields have the same value and validation is controlled from either field
static validateFormInputsMatch(field: string, fieldMatchTo: string, errorMessage: string) {
return (formGroup: FormGroup) => {
return (formGroup: UntypedFormGroup) => {
const fieldCtrl = formGroup.controls[field];
const fieldMatchToCtrl = formGroup.controls[fieldMatchTo];

View File

@ -3,7 +3,6 @@ const { pathsToModuleNameMapper } = require("ts-jest");
const { compilerOptions } = require("../shared/tsconfig.libs");
module.exports = {
name: "common",
displayName: "libs/common tests",
preset: "ts-jest",
testEnvironment: "jsdom",

View File

@ -1,4 +1,4 @@
import { mockReset, mock, MockProxy } from "jest-mock-extended";
import { mockReset, mock } from "jest-mock-extended";
import { CryptoFunctionService } from "@bitwarden/common/abstractions/cryptoFunction.service";
import { LogService } from "@bitwarden/common/abstractions/log.service";

View File

@ -1,4 +1,4 @@
import { FormGroup, ValidationErrors } from "@angular/forms";
import { UntypedFormGroup, ValidationErrors } from "@angular/forms";
import {
FormGroupControls,
@ -11,7 +11,7 @@ export class FormValidationErrorsService implements FormValidationErrorsAbstract
let errors: AllValidationErrors[] = [];
Object.keys(controls).forEach((key) => {
const control = controls[key];
if (control instanceof FormGroup) {
if (control instanceof UntypedFormGroup) {
errors = errors.concat(this.getFormValidationErrors(control.controls));
}

View File

@ -3,7 +3,6 @@ const { pathsToModuleNameMapper } = require("ts-jest");
const { compilerOptions } = require("./tsconfig");
module.exports = {
name: "angular",
displayName: "libs/components tests",
preset: "jest-preset-angular",
testMatch: ["**/+(*.)+(spec).+(ts)"],

View File

@ -1,5 +1,5 @@
import { Component, Input } from "@angular/core";
import { AbstractControl, FormGroup } from "@angular/forms";
import { AbstractControl, UntypedFormGroup } from "@angular/forms";
@Component({
selector: "bit-error-summary",
@ -13,7 +13,7 @@ import { AbstractControl, FormGroup } from "@angular/forms";
})
export class BitErrorSummary {
@Input()
formGroup: FormGroup;
formGroup: UntypedFormGroup;
get errorCount(): number {
return this.getErrorCount(this.formGroup);
@ -23,9 +23,9 @@ export class BitErrorSummary {
return this.errorCount.toString();
}
private getErrorCount(form: FormGroup): number {
private getErrorCount(form: UntypedFormGroup): number {
return Object.values(form.controls).reduce((acc: number, control: AbstractControl) => {
if (control instanceof FormGroup) {
if (control instanceof UntypedFormGroup) {
return acc + this.getErrorCount(control);
}

View File

@ -1,4 +1,4 @@
import { FormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms";
import { UntypedFormBuilder, FormsModule, ReactiveFormsModule, Validators } from "@angular/forms";
import { Meta, moduleMetadata, Story } from "@storybook/angular";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
@ -39,7 +39,7 @@ export default {
},
} as Meta;
const fb = new FormBuilder();
const fb = new UntypedFormBuilder();
const formObj = fb.group({
name: ["", [Validators.required]],

View File

@ -1,6 +1,6 @@
import {
AbstractControl,
FormBuilder,
UntypedFormBuilder,
FormsModule,
ReactiveFormsModule,
ValidationErrors,
@ -46,7 +46,7 @@ export default {
},
} as Meta;
const fb = new FormBuilder();
const fb = new UntypedFormBuilder();
const formObj = fb.group({
test: [""],
required: ["", [Validators.required]],

31502
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -31,13 +31,13 @@
"libs/*"
],
"devDependencies": {
"@angular-devkit/build-angular": "^12.2.13",
"@angular/cli": "^12.2.13",
"@angular/compiler-cli": "^12.2.13",
"@angular/elements": "^12.2.13",
"@angular-devkit/build-angular": "^14.0.6",
"@angular/cli": "^14.0.6",
"@angular/compiler-cli": "^14.0.6",
"@angular/elements": "^14.0.6",
"@compodoc/compodoc": "^1.1.19",
"@fluffy-spoon/substitute": "^1.208.0",
"@ngtools/webpack": "^12.2.13",
"@ngtools/webpack": "^14.0.6",
"@storybook/addon-a11y": "^6.5.7",
"@storybook/addon-actions": "^6.5.7",
"@storybook/addon-essentials": "^6.5.7",
@ -78,7 +78,7 @@
"chromatic": "^6.5.6",
"clean-webpack-plugin": "^4.0.0",
"concurrently": "^7.2.1",
"copy-webpack-plugin": "^10.0.0",
"copy-webpack-plugin": "^11.0.0",
"cross-env": "^7.0.3",
"css-loader": "^6.5.1",
"del": "^6.0.0",
@ -100,55 +100,56 @@
"gulp-json-editor": "^2.5.5",
"gulp-replace": "^1.1.0",
"gulp-zip": "^5.1.0",
"html-loader": "^3.0.1",
"html-loader": "^4.1.0",
"html-webpack-injector": "^1.1.4",
"html-webpack-plugin": "^5.5.0",
"husky": "^7.0.4",
"husky": "^8.0.1",
"jasmine-core": "^3.7.1",
"jasmine-spec-reporter": "^7.0.0",
"jest-mock-extended": "^2.0.6",
"jest-preset-angular": "^10.1.0",
"lint-staged": "^12.4.1",
"jest-preset-angular": "^12.1.0",
"lint-staged": "^13.0.3",
"mini-css-extract-plugin": "^2.4.5",
"node-ipc": "^9.2.1",
"pkg": "5.7.0",
"postcss": "^8.4.14",
"postcss-loader": "^6.2.1",
"postcss-loader": "^7.0.1",
"prettier": "^2.6.2",
"process": "^0.11.10",
"regedit": "^3.0.3",
"rimraf": "^3.0.2",
"sass": "^1.34.1",
"sass-loader": "^12.4.0",
"sass-loader": "^13.0.2",
"storybook-addon-designs": "^6.2.1",
"style-loader": "^3.3.1",
"tailwindcss": "^3.0.24",
"tapable": "^1.1.3",
"ts-jest": "^28.0.6",
"ts-loader": "^9.2.5",
"tsconfig-paths-webpack-plugin": "^3.5.2",
"typescript": "4.3.5",
"typescript": "4.6.4",
"url": "^0.11.0",
"util": "^0.12.4",
"webcrypto-shim": "^0.1.7",
"webpack": "^5.64.4",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "4.6",
"webpack-dev-server": "^4.9.3",
"webpack-node-externals": "^3.0.0"
},
"dependencies": {
"@angular/animations": "^12.2.13",
"@angular/cdk": "^12.2.13",
"@angular/common": "^12.2.13",
"@angular/compiler": "^12.2.13",
"@angular/core": "^12.2.13",
"@angular/forms": "^12.2.13",
"@angular/platform-browser": "^12.2.13",
"@angular/platform-browser-dynamic": "^12.2.13",
"@angular/router": "^12.2.13",
"@angular/animations": "^14.0.6",
"@angular/cdk": "^14.0.4",
"@angular/common": "^14.0.6",
"@angular/compiler": "^14.0.6",
"@angular/core": "^14.0.6",
"@angular/forms": "^14.0.6",
"@angular/platform-browser": "^14.0.6",
"@angular/platform-browser-dynamic": "^14.0.6",
"@angular/router": "^14.0.6",
"@koa/multer": "^3.0.0",
"@koa/router": "^10.1.1",
"@microsoft/signalr": "^5.0.17",
"@microsoft/signalr-protocol-msgpack": "^5.0.17",
"@microsoft/signalr": "^6.0.7",
"@microsoft/signalr-protocol-msgpack": "^6.0.7",
"big-integer": "^1.6.51",
"bootstrap": "4.6.0",
"braintree-web-drop-in": "^1.33.1",
@ -172,8 +173,8 @@
"lunr": "^2.3.9",
"mousetrap": "^1.6.5",
"multer": "^1.4.5-lts.1",
"ngx-infinite-scroll": "^10.0.1",
"ngx-toastr": "14.1.4",
"ngx-infinite-scroll": "^14.0.0",
"ngx-toastr": "^15.0.0",
"node-fetch": "^2.6.7",
"node-forge": "^1.3.1",
"nord": "^0.2.1",
@ -186,7 +187,6 @@
"sweetalert2": "^10.16.6",
"tldjs": "^2.3.1",
"utf-8-validate": "^5.0.9",
"web-animations-js": "^2.3.2",
"whatwg-fetch": "^3.6.2",
"zone.js": "^0.11.4",
"zxcvbn": "^4.4.2"

11
tailwind.config.js Normal file
View File

@ -0,0 +1,11 @@
/* eslint-disable */
const config = require("./libs/components/tailwind.config.base");
config.content = ["./libs/components/src/**/*.{html,ts,mdx}", "./.storybook/preview.js"];
config.safelist = [
{
pattern: /tw-bg-(.*)/,
},
];
module.exports = config;

View File

@ -7,11 +7,10 @@
"module": "commonjs",
"lib": ["es5", "es6", "es7", "dom"],
"sourceMap": true,
"declaration": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declarationDir": "dist/types",
"declaration": false,
"outDir": "dist",
"baseUrl": ".",
"paths": {
@ -27,5 +26,6 @@
}
]
},
"include": ["apps/*/src/*", "libs/*/src/**/*"]
"include": ["apps/*/src/**/*.stories.ts", "libs/*/src/**/*"],
"exclude": ["apps/*/src/**/*.spec.ts", "libs/*/src/**/*.spec.ts"]
}