From a7efd2158ebd2032eea0dce8a1f5bc47c43e2165 Mon Sep 17 00:00:00 2001
From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com>
Date: Fri, 9 May 2025 08:52:54 -0700
Subject: [PATCH 01/35] [PM-18802] - Autofill Settings Nudges and Settings
Badge (#14439)
* autofill nudge
* remove undismiss logic
* revert change to popup view cache service
* move browser autofill logic to platform. cleanup
* fix test
* adjustments to autofill nudges
* add missing provider
* updates to autofill nudges
* fix date logic
* change autofillBrowserSettingsService isBrowserAutofillSettingOverridden to function
* fix up browser autofill overridden settings logic
* remove check for privacy in isBrowserAutofillSettingOverridden
---
apps/browser/src/_locales/en/messages.json | 18 ++++
.../popup/settings/autofill.component.html | 10 +++
.../popup/settings/autofill.component.ts | 84 +++++++++++--------
.../autofill-browser-settings.service.ts | 31 +++++++
.../src/platform/browser/browser-api.ts | 23 +++++
.../view-cache/popup-view-cache.service.ts | 2 +-
.../popup/settings/settings-v2.component.html | 10 ++-
.../popup/settings/settings-v2.component.ts | 39 ++++++++-
.../spotlight/spotlight.component.html | 5 +-
.../spotlight/spotlight.component.ts | 8 +-
.../components/spotlight/spotlight.stories.ts | 20 ++---
.../autofill-nudge.service.ts | 47 +++++++++++
.../services/custom-nudges-services/index.ts | 1 +
.../src/services/vault-nudges.service.spec.ts | 1 +
.../src/services/vault-nudges.service.ts | 3 +
15 files changed, 240 insertions(+), 62 deletions(-)
create mode 100644 apps/browser/src/autofill/services/autofill-browser-settings.service.ts
create mode 100644 libs/vault/src/services/custom-nudges-services/autofill-nudge.service.ts
diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json
index 1df0bf96616..1c3214a6ef7 100644
--- a/apps/browser/src/_locales/en/messages.json
+++ b/apps/browser/src/_locales/en/messages.json
@@ -1589,6 +1589,24 @@
"autofillSuggestionsSectionTitle": {
"message": "Autofill suggestions"
},
+ "autofillSpotlightTitle": {
+ "message": "Easily find autofill suggestions"
+ },
+ "autofillSpotlightDesc": {
+ "message": "Turn off your browser's autofill settings, so they don't conflict with Bitwarden."
+ },
+ "turnOffBrowserAutofill": {
+ "message": "Turn off $BROWSER$ autofill",
+ "placeholders": {
+ "browser": {
+ "content": "$1",
+ "example": "Chrome"
+ }
+ }
+ },
+ "turnOffAutofill": {
+ "message": "Turn off autofill"
+ },
"showInlineMenuLabel": {
"message": "Show autofill suggestions on form fields"
},
diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html
index 4fd85ddce33..264b04b039b 100644
--- a/apps/browser/src/autofill/popup/settings/autofill.component.html
+++ b/apps/browser/src/autofill/popup/settings/autofill.component.html
@@ -6,6 +6,16 @@
+
+
+
{{ "autofillSuggestionsSectionTitle" | i18n }}
diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.ts b/apps/browser/src/autofill/popup/settings/autofill.component.ts
index c30f150e71d..d63f9a4589d 100644
--- a/apps/browser/src/autofill/popup/settings/autofill.component.ts
+++ b/apps/browser/src/autofill/popup/settings/autofill.component.ts
@@ -11,9 +11,11 @@ import {
FormControl,
} from "@angular/forms";
import { RouterModule } from "@angular/router";
-import { firstValueFrom } from "rxjs";
+import { Observable, filter, firstValueFrom, map, switchMap } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
+import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
+import { getUserId } from "@bitwarden/common/auth/services/account.service";
import {
AutofillOverlayVisibility,
BrowserClientVendors,
@@ -53,7 +55,9 @@ import {
SelectModule,
TypographyModule,
} from "@bitwarden/components";
+import { SpotlightComponent, VaultNudgesService, VaultNudgeType } from "@bitwarden/vault";
+import { AutofillBrowserSettingsService } from "../../../autofill/services/autofill-browser-settings.service";
import { BrowserApi } from "../../../platform/browser/browser-api";
import { PopOutComponent } from "../../../platform/popup/components/pop-out.component";
import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component";
@@ -81,6 +85,7 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co
SelectModule,
TypographyModule,
ReactiveFormsModule,
+ SpotlightComponent,
],
})
export class AutofillComponent implements OnInit {
@@ -100,6 +105,14 @@ export class AutofillComponent implements OnInit {
protected browserClientIsUnknown: boolean;
protected autofillOnPageLoadFromPolicy$ =
this.autofillSettingsService.activateAutofillOnPageLoadFromPolicy$;
+ protected showSpotlightNudge$: Observable = this.accountService.activeAccount$.pipe(
+ filter((account): account is Account => account !== null),
+ switchMap((account) =>
+ this.vaultNudgesService
+ .showNudge$(VaultNudgeType.AutofillNudge, account.id)
+ .pipe(map((nudgeStatus) => !nudgeStatus.hasSpotlightDismissed)),
+ ),
+ );
protected autofillOnPageLoadForm = new FormGroup({
autofillOnPageLoad: new FormControl(),
@@ -142,6 +155,9 @@ export class AutofillComponent implements OnInit {
private configService: ConfigService,
private formBuilder: FormBuilder,
private destroyRef: DestroyRef,
+ private vaultNudgesService: VaultNudgesService,
+ private accountService: AccountService,
+ private autofillBrowserSettingsService: AutofillBrowserSettingsService,
) {
this.autofillOnPageLoadOptions = [
{ name: this.i18nService.t("autoFillOnPageLoadYes"), value: true },
@@ -165,7 +181,7 @@ export class AutofillComponent implements OnInit {
{ name: i18nService.t("never"), value: UriMatchStrategy.Never },
];
- this.browserClientVendor = this.getBrowserClientVendor();
+ this.browserClientVendor = BrowserApi.getBrowserClientVendor(window);
this.disablePasswordManagerURI = DisablePasswordManagerUris[this.browserClientVendor];
this.browserShortcutsURI = BrowserShortcutsUris[this.browserClientVendor];
this.browserClientIsUnknown = this.browserClientVendor === BrowserClientVendors.Unknown;
@@ -173,7 +189,11 @@ export class AutofillComponent implements OnInit {
async ngOnInit() {
this.canOverrideBrowserAutofillSetting = !this.browserClientIsUnknown;
- this.defaultBrowserAutofillDisabled = await this.browserAutofillSettingCurrentlyOverridden();
+
+ this.defaultBrowserAutofillDisabled =
+ await this.autofillBrowserSettingsService.isBrowserAutofillSettingOverridden(
+ this.browserClientVendor,
+ );
this.inlineMenuVisibility = await firstValueFrom(
this.autofillSettingsService.inlineMenuVisibility$,
@@ -308,6 +328,27 @@ export class AutofillComponent implements OnInit {
);
}
+ get spotlightButtonIcon() {
+ if (this.browserClientVendor === BrowserClientVendors.Unknown) {
+ return "bwi-external-link";
+ }
+ return null;
+ }
+
+ get spotlightButtonText() {
+ if (this.browserClientVendor === BrowserClientVendors.Unknown) {
+ return this.i18nService.t("turnOffAutofill");
+ }
+ return this.i18nService.t("turnOffBrowserAutofill", this.browserClientVendor);
+ }
+
+ async dismissSpotlight() {
+ await this.vaultNudgesService.dismissNudge(
+ VaultNudgeType.AutofillNudge,
+ await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)),
+ );
+ }
+
async updateInlineMenuVisibility() {
if (!this.enableInlineMenu) {
this.enableInlineMenuOnIconSelect = false;
@@ -346,26 +387,6 @@ export class AutofillComponent implements OnInit {
}
}
- private getBrowserClientVendor(): BrowserClientVendor {
- if (this.platformUtilsService.isChrome()) {
- return BrowserClientVendors.Chrome;
- }
-
- if (this.platformUtilsService.isOpera()) {
- return BrowserClientVendors.Opera;
- }
-
- if (this.platformUtilsService.isEdge()) {
- return BrowserClientVendors.Edge;
- }
-
- if (this.platformUtilsService.isVivaldi()) {
- return BrowserClientVendors.Vivaldi;
- }
-
- return BrowserClientVendors.Unknown;
- }
-
protected async openURI(event: Event, uri: BrowserShortcutsUri | DisablePasswordManagerUri) {
event.preventDefault();
@@ -422,7 +443,7 @@ export class AutofillComponent implements OnInit {
if (
this.inlineMenuVisibility === AutofillOverlayVisibility.Off ||
!this.canOverrideBrowserAutofillSetting ||
- (await this.browserAutofillSettingCurrentlyOverridden())
+ this.defaultBrowserAutofillDisabled
) {
return;
}
@@ -460,6 +481,9 @@ export class AutofillComponent implements OnInit {
}
await BrowserApi.updateDefaultBrowserAutofillSettings(!this.defaultBrowserAutofillDisabled);
+ this.autofillBrowserSettingsService.setDefaultBrowserAutofillDisabled(
+ this.defaultBrowserAutofillDisabled,
+ );
}
private handleOverrideDialogAccept = async () => {
@@ -467,18 +491,6 @@ export class AutofillComponent implements OnInit {
await this.updateDefaultBrowserAutofillDisabled();
};
- async browserAutofillSettingCurrentlyOverridden() {
- if (!this.canOverrideBrowserAutofillSetting) {
- return false;
- }
-
- if (!(await this.privacyPermissionGranted())) {
- return false;
- }
-
- return await BrowserApi.browserAutofillSettingsOverridden();
- }
-
async privacyPermissionGranted(): Promise {
return await BrowserApi.permissionsGranted(["privacy"]);
}
diff --git a/apps/browser/src/autofill/services/autofill-browser-settings.service.ts b/apps/browser/src/autofill/services/autofill-browser-settings.service.ts
new file mode 100644
index 00000000000..ba59a655b77
--- /dev/null
+++ b/apps/browser/src/autofill/services/autofill-browser-settings.service.ts
@@ -0,0 +1,31 @@
+import { Injectable } from "@angular/core";
+import { BehaviorSubject, Observable } from "rxjs";
+
+import { BrowserClientVendors } from "@bitwarden/common/autofill/constants";
+import { BrowserClientVendor } from "@bitwarden/common/autofill/types";
+
+import { BrowserApi } from "../../platform/browser/browser-api";
+
+/**
+ * Service class for various Autofill-related browser API operations.
+ */
+@Injectable({
+ providedIn: "root",
+})
+export class AutofillBrowserSettingsService {
+ async isBrowserAutofillSettingOverridden(browserClient: BrowserClientVendor) {
+ return (
+ browserClient !== BrowserClientVendors.Unknown &&
+ (await BrowserApi.browserAutofillSettingsOverridden())
+ );
+ }
+
+ private _defaultBrowserAutofillDisabled$ = new BehaviorSubject(false);
+
+ defaultBrowserAutofillDisabled$: Observable =
+ this._defaultBrowserAutofillDisabled$.asObservable();
+
+ setDefaultBrowserAutofillDisabled(value: boolean) {
+ this._defaultBrowserAutofillDisabled$.next(value);
+ }
+}
diff --git a/apps/browser/src/platform/browser/browser-api.ts b/apps/browser/src/platform/browser/browser-api.ts
index 4b4cec7e7da..b27e8ca7c96 100644
--- a/apps/browser/src/platform/browser/browser-api.ts
+++ b/apps/browser/src/platform/browser/browser-api.ts
@@ -2,6 +2,8 @@
// @ts-strict-ignore
import { Observable } from "rxjs";
+import { BrowserClientVendors } from "@bitwarden/common/autofill/constants";
+import { BrowserClientVendor } from "@bitwarden/common/autofill/types";
import { DeviceType } from "@bitwarden/common/enums";
import { isBrowserSafariApi } from "@bitwarden/platform";
@@ -131,6 +133,27 @@ export class BrowserApi {
});
}
+ static getBrowserClientVendor(clientWindow: Window): BrowserClientVendor {
+ const device = BrowserPlatformUtilsService.getDevice(clientWindow);
+
+ switch (device) {
+ case DeviceType.ChromeExtension:
+ case DeviceType.ChromeBrowser:
+ return BrowserClientVendors.Chrome;
+ case DeviceType.OperaExtension:
+ case DeviceType.OperaBrowser:
+ return BrowserClientVendors.Opera;
+ case DeviceType.EdgeExtension:
+ case DeviceType.EdgeBrowser:
+ return BrowserClientVendors.Edge;
+ case DeviceType.VivaldiExtension:
+ case DeviceType.VivaldiBrowser:
+ return BrowserClientVendors.Vivaldi;
+ default:
+ return BrowserClientVendors.Unknown;
+ }
+ }
+
/**
* Gets the tab with the given id.
*
diff --git a/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts b/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts
index 6fc3e11493c..ff63b52ab3f 100644
--- a/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts
+++ b/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts
@@ -82,7 +82,7 @@ export class PopupViewCacheService implements ViewCacheService {
initialValue,
persistNavigation,
} = options;
- const cachedValue = this.cache[key]
+ const cachedValue = this.cache[key]?.value
? deserializer(JSON.parse(this.cache[key].value))
: initialValue;
const _signal = signal(cachedValue);
diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.html b/apps/browser/src/tools/popup/settings/settings-v2.component.html
index b9f4176b927..22e2d9a28d0 100644
--- a/apps/browser/src/tools/popup/settings/settings-v2.component.html
+++ b/apps/browser/src/tools/popup/settings/settings-v2.component.html
@@ -17,7 +17,15 @@
- {{ "autofill" | i18n }}
+
+
{{ "autofill" | i18n }}
+
1
+
diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.ts b/apps/browser/src/tools/popup/settings/settings-v2.component.ts
index 9301b8622c5..be05452529a 100644
--- a/apps/browser/src/tools/popup/settings/settings-v2.component.ts
+++ b/apps/browser/src/tools/popup/settings/settings-v2.component.ts
@@ -1,7 +1,15 @@
import { CommonModule } from "@angular/common";
-import { Component } from "@angular/core";
+import { Component, OnInit } from "@angular/core";
import { RouterModule } from "@angular/router";
-import { filter, firstValueFrom, Observable, shareReplay, switchMap } from "rxjs";
+import {
+ combineLatest,
+ filter,
+ firstValueFrom,
+ map,
+ Observable,
+ shareReplay,
+ switchMap,
+} from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
@@ -12,6 +20,8 @@ import { BadgeComponent, ItemModule } from "@bitwarden/components";
import { NudgeStatus, VaultNudgesService, VaultNudgeType } from "@bitwarden/vault";
import { CurrentAccountComponent } from "../../../auth/popup/account-switching/current-account.component";
+import { AutofillBrowserSettingsService } from "../../../autofill/services/autofill-browser-settings.service";
+import { BrowserApi } from "../../../platform/browser/browser-api";
import { PopOutComponent } from "../../../platform/popup/components/pop-out.component";
import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component";
import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component";
@@ -31,8 +41,10 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co
BadgeComponent,
],
})
-export class SettingsV2Component {
+export class SettingsV2Component implements OnInit {
VaultNudgeType = VaultNudgeType;
+ activeUserId: UserId | null = null;
+ protected isBrowserAutofillSettingOverridden = false;
private authenticatedAccount$: Observable = this.accountService.activeAccount$.pipe(
filter((account): account is Account => account !== null),
@@ -51,6 +63,19 @@ export class SettingsV2Component {
),
);
+ showAutofillBadge$: Observable = combineLatest([
+ this.autofillBrowserSettingsService.defaultBrowserAutofillDisabled$,
+ this.authenticatedAccount$,
+ ]).pipe(
+ switchMap(([defaultBrowserAutofillDisabled, account]) =>
+ this.vaultNudgesService.showNudge$(VaultNudgeType.AutofillNudge, account.id).pipe(
+ map((nudgeStatus) => {
+ return !defaultBrowserAutofillDisabled && nudgeStatus.hasBadgeDismissed === false;
+ }),
+ ),
+ ),
+ );
+
protected isNudgeFeatureEnabled$ = this.configService.getFeatureFlag$(
FeatureFlag.PM8851_BrowserOnboardingNudge,
);
@@ -58,9 +83,17 @@ export class SettingsV2Component {
constructor(
private readonly vaultNudgesService: VaultNudgesService,
private readonly accountService: AccountService,
+ private readonly autofillBrowserSettingsService: AutofillBrowserSettingsService,
private readonly configService: ConfigService,
) {}
+ async ngOnInit() {
+ this.isBrowserAutofillSettingOverridden =
+ await this.autofillBrowserSettingsService.isBrowserAutofillSettingOverridden(
+ BrowserApi.getBrowserClientVendor(window),
+ );
+ }
+
async dismissBadge(type: VaultNudgeType) {
if (!(await firstValueFrom(this.showVaultBadge$)).hasBadgeDismissed) {
const account = await firstValueFrom(this.authenticatedAccount$);
diff --git a/libs/vault/src/components/spotlight/spotlight.component.html b/libs/vault/src/components/spotlight/spotlight.component.html
index e949ca4d912..0c6a37914d8 100644
--- a/libs/vault/src/components/spotlight/spotlight.component.html
+++ b/libs/vault/src/components/spotlight/spotlight.component.html
@@ -23,10 +23,9 @@
type="button"
buttonType="primary"
*ngIf="buttonText"
- (click)="handleButtonClick()"
+ (click)="handleButtonClick($event)"
>
{{ buttonText }}
+
-
-
diff --git a/libs/vault/src/components/spotlight/spotlight.component.ts b/libs/vault/src/components/spotlight/spotlight.component.ts
index e52669cc404..8639fe7947f 100644
--- a/libs/vault/src/components/spotlight/spotlight.component.ts
+++ b/libs/vault/src/components/spotlight/spotlight.component.ts
@@ -19,11 +19,13 @@ export class SpotlightComponent {
@Input() buttonText?: string;
// Wheter the component can be dismissed, if true, the component will not show a close button
@Input() persistent = false;
+ // Optional icon to display on the button
+ @Input() buttonIcon: string | null = null;
@Output() onDismiss = new EventEmitter();
- @Output() onButtonClick = new EventEmitter();
+ @Output() onButtonClick = new EventEmitter();
- handleButtonClick(): void {
- this.onButtonClick.emit();
+ handleButtonClick(event: MouseEvent): void {
+ this.onButtonClick.emit(event);
}
handleDismiss(): void {
diff --git a/libs/vault/src/components/spotlight/spotlight.stories.ts b/libs/vault/src/components/spotlight/spotlight.stories.ts
index 9f7757e4528..8e660aacbad 100644
--- a/libs/vault/src/components/spotlight/spotlight.stories.ts
+++ b/libs/vault/src/components/spotlight/spotlight.stories.ts
@@ -52,9 +52,9 @@ export const Persistent: Story = {
},
};
-export const WithCustomButton: Story = {
+export const WithButtonIcon: Story = {
args: {
- buttonText: "Custom Button",
+ buttonIcon: "bwi bwi-external-link",
},
render: (args) => ({
props: args,
@@ -62,19 +62,9 @@ export const WithCustomButton: Story = {
-
-
+ buttonText="External Link"
+ buttonIcon="bwi-external-link"
+ >
`,
}),
};
diff --git a/libs/vault/src/services/custom-nudges-services/autofill-nudge.service.ts b/libs/vault/src/services/custom-nudges-services/autofill-nudge.service.ts
new file mode 100644
index 00000000000..b5595e590c9
--- /dev/null
+++ b/libs/vault/src/services/custom-nudges-services/autofill-nudge.service.ts
@@ -0,0 +1,47 @@
+import { Injectable, inject } from "@angular/core";
+import { Observable, combineLatest, from, map, of } from "rxjs";
+import { catchError } from "rxjs/operators";
+
+import { VaultProfileService } from "@bitwarden/angular/vault/services/vault-profile.service";
+import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
+import { UserId } from "@bitwarden/common/types/guid";
+
+import { DefaultSingleNudgeService } from "../default-single-nudge.service";
+import { NudgeStatus, VaultNudgeType } from "../vault-nudges.service";
+
+const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;
+
+/**
+ * Custom Nudge Service to use for the Autofill Nudge in the Vault
+ */
+@Injectable({
+ providedIn: "root",
+})
+export class AutofillNudgeService extends DefaultSingleNudgeService {
+ vaultProfileService = inject(VaultProfileService);
+ logService = inject(LogService);
+
+ nudgeStatus$(_: VaultNudgeType, userId: UserId): Observable {
+ const profileDate$ = from(this.vaultProfileService.getProfileCreationDate(userId)).pipe(
+ catchError(() => {
+ this.logService.error("Error getting profile creation date");
+ // Default to today to ensure we show the nudge
+ return of(new Date());
+ }),
+ );
+
+ return combineLatest([
+ profileDate$,
+ this.getNudgeStatus$(VaultNudgeType.AutofillNudge, userId),
+ of(Date.now() - THIRTY_DAYS_MS),
+ ]).pipe(
+ map(([profileCreationDate, status, profileCutoff]) => {
+ const profileOlderThanCutoff = profileCreationDate.getTime() < profileCutoff;
+ return {
+ hasBadgeDismissed: status.hasBadgeDismissed || profileOlderThanCutoff,
+ hasSpotlightDismissed: status.hasSpotlightDismissed || profileOlderThanCutoff,
+ };
+ }),
+ );
+ }
+}
diff --git a/libs/vault/src/services/custom-nudges-services/index.ts b/libs/vault/src/services/custom-nudges-services/index.ts
index 68427a8dc4d..2e9ade985cc 100644
--- a/libs/vault/src/services/custom-nudges-services/index.ts
+++ b/libs/vault/src/services/custom-nudges-services/index.ts
@@ -1,3 +1,4 @@
+export * from "./autofill-nudge.service";
export * from "./has-items-nudge.service";
export * from "./download-bitwarden-nudge.service";
export * from "./empty-vault-nudge.service";
diff --git a/libs/vault/src/services/vault-nudges.service.spec.ts b/libs/vault/src/services/vault-nudges.service.spec.ts
index a7469410711..89465fc5382 100644
--- a/libs/vault/src/services/vault-nudges.service.spec.ts
+++ b/libs/vault/src/services/vault-nudges.service.spec.ts
@@ -55,6 +55,7 @@ describe("Vault Nudges Service", () => {
useValue: mock(),
},
{ provide: CipherService, useValue: mock() },
+ { provide: LogService, useValue: mock() },
{
provide: AccountService,
useValue: mock(),
diff --git a/libs/vault/src/services/vault-nudges.service.ts b/libs/vault/src/services/vault-nudges.service.ts
index 171fe85252f..e04cb609d7f 100644
--- a/libs/vault/src/services/vault-nudges.service.ts
+++ b/libs/vault/src/services/vault-nudges.service.ts
@@ -9,6 +9,7 @@ import { UserId } from "@bitwarden/common/types/guid";
import {
HasItemsNudgeService,
EmptyVaultNudgeService,
+ AutofillNudgeService,
DownloadBitwardenNudgeService,
NewItemNudgeService,
} from "./custom-nudges-services";
@@ -28,6 +29,7 @@ export enum VaultNudgeType {
*/
EmptyVaultNudge = "empty-vault-nudge",
HasVaultItems = "has-vault-items",
+ AutofillNudge = "autofill-nudge",
DownloadBitwarden = "download-bitwarden",
newLoginItemStatus = "new-login-item-status",
newCardItemStatus = "new-card-item-status",
@@ -57,6 +59,7 @@ export class VaultNudgesService {
private customNudgeServices: Partial> = {
[VaultNudgeType.HasVaultItems]: inject(HasItemsNudgeService),
[VaultNudgeType.EmptyVaultNudge]: inject(EmptyVaultNudgeService),
+ [VaultNudgeType.AutofillNudge]: inject(AutofillNudgeService),
[VaultNudgeType.DownloadBitwarden]: inject(DownloadBitwardenNudgeService),
[VaultNudgeType.newLoginItemStatus]: this.newItemNudgeService,
[VaultNudgeType.newCardItemStatus]: this.newItemNudgeService,
From 903b1bf0bade6587d8d4ffa895c0570bac7dd53a Mon Sep 17 00:00:00 2001
From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com>
Date: Fri, 9 May 2025 08:56:56 -0700
Subject: [PATCH 02/35] re-add missing i18n keys (#14690)
---
apps/desktop/src/locales/en/messages.json | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json
index 681a0e3147c..ea198086f8d 100644
--- a/apps/desktop/src/locales/en/messages.json
+++ b/apps/desktop/src/locales/en/messages.json
@@ -3616,6 +3616,27 @@
"biometricsStatusHelptextUnavailableReasonUnknown": {
"message": "Biometric unlock is currently unavailable for an unknown reason."
},
+ "itemDetails": {
+ "message": "Item details"
+ },
+ "itemName": {
+ "message": "Item name"
+ },
+ "loginCredentials": {
+ "message": "Login credentials"
+ },
+ "additionalOptions": {
+ "message": "Additional options"
+ },
+ "itemHistory": {
+ "message": "Item history"
+ },
+ "lastEdited": {
+ "message": "Last edited"
+ },
+ "upload": {
+ "message": "Upload"
+ },
"authorize": {
"message": "Authorize"
},
From 47d41f928956599bd367974cec9d0516d18059d7 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 9 May 2025 18:12:02 +0200
Subject: [PATCH 03/35] [deps]: Update codecov/test-results-action action to
v1.1.0 (#14501)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel García
---
.github/workflows/test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 78a735e4870..f76b349ccd4 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -70,7 +70,7 @@ jobs:
uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2
- name: Upload results to codecov.io
- uses: codecov/test-results-action@4e79e65778be1cecd5df25e14af1eafb6df80ea9 # v1.0.2
+ uses: codecov/test-results-action@f2dba722c67b86c6caa034178c6e4d35335f6706 # v1.1.0
rust:
name: Run Rust tests on ${{ matrix.os }}
From 89be04a45ef1ec20728148198291bc9ed0baed0a Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 9 May 2025 19:01:50 +0200
Subject: [PATCH 04/35] [deps]: Update dorny/test-reporter action to v2
(#14518)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Daniel García
---
.github/workflows/test.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index f76b349ccd4..50f04ebaeb1 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -58,7 +58,7 @@ jobs:
run: npm test -- --coverage --maxWorkers=3
- name: Report test results
- uses: dorny/test-reporter@31a54ee7ebcacc03a09ea97a7e5465a47b84aea5 # v1.9.1
+ uses: dorny/test-reporter@6e6a65b7a0bd2c9197df7d0ae36ac5cee784230c # v2.0.0
if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !cancelled() }}
with:
name: Test Results
From 0d2c890da11b23948d229070c89050f911fe8852 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 9 May 2025 13:29:48 -0400
Subject: [PATCH 05/35] [deps] UI Foundation: Update @types/react to v18.3.20
(#14464)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
package-lock.json | 6 +++---
package.json | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 0db144090b9..bdf9c3a9d26 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11820,9 +11820,9 @@
"license": "MIT"
},
"node_modules/@types/react": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz",
- "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==",
+ "version": "18.3.20",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.20.tgz",
+ "integrity": "sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==",
"dev": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index 7c1873090c1..6fe463ac387 100644
--- a/package.json
+++ b/package.json
@@ -212,7 +212,7 @@
},
"react": "18.3.1",
"react-dom": "18.3.1",
- "@types/react": "18.3.1",
+ "@types/react": "18.3.20",
"replacestream": "4.0.3"
},
"lint-staged": {
From 624dafa431f9bf783529e11f35cd665f276eb664 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 9 May 2025 13:51:15 -0400
Subject: [PATCH 06/35] [deps] UI Foundation: Update angular-cli monorepo to
v18.2.19 (#14465)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
package-lock.json | 718 +++++++++++++++++++++-------------------------
package.json | 6 +-
2 files changed, 333 insertions(+), 391 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index bdf9c3a9d26..1e7e0741cd8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -74,9 +74,9 @@
"zxcvbn": "4.4.2"
},
"devDependencies": {
- "@angular-devkit/build-angular": "18.2.12",
+ "@angular-devkit/build-angular": "18.2.19",
"@angular-eslint/schematics": "18.4.3",
- "@angular/cli": "18.2.12",
+ "@angular/cli": "18.2.19",
"@angular/compiler-cli": "18.2.13",
"@babel/core": "7.24.9",
"@babel/preset-env": "7.24.8",
@@ -84,7 +84,7 @@
"@electron/notarize": "2.5.0",
"@electron/rebuild": "3.7.2",
"@lit-labs/signals": "0.1.2",
- "@ngtools/webpack": "18.2.12",
+ "@ngtools/webpack": "18.2.19",
"@storybook/addon-a11y": "8.6.12",
"@storybook/addon-actions": "8.6.12",
"@storybook/addon-designs": "8.2.1",
@@ -414,29 +414,28 @@
}
},
"node_modules/@angular-devkit/build-angular": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.12.tgz",
- "integrity": "sha512-quVUi7eqTq9OHumQFNl9Y8t2opm8miu4rlYnuF6rbujmmBDvdUvR6trFChueRczl2p5HWqTOr6NPoDGQm8AyNw==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.19.tgz",
+ "integrity": "sha512-xwY7v+nGE7TXOc4pgY6u57bLzIPSHuecosYr3TiWHAl9iEcKHzkCCFKsLZyunohHmq/i1uA6g3cC6iwp2xNYyg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "2.3.0",
- "@angular-devkit/architect": "0.1802.12",
- "@angular-devkit/build-webpack": "0.1802.12",
- "@angular-devkit/core": "18.2.12",
- "@angular/build": "18.2.12",
- "@babel/core": "7.25.2",
- "@babel/generator": "7.25.0",
- "@babel/helper-annotate-as-pure": "7.24.7",
+ "@angular-devkit/architect": "0.1802.19",
+ "@angular-devkit/build-webpack": "0.1802.19",
+ "@angular-devkit/core": "18.2.19",
+ "@angular/build": "18.2.19",
+ "@babel/core": "7.26.10",
+ "@babel/generator": "7.26.10",
+ "@babel/helper-annotate-as-pure": "7.25.9",
"@babel/helper-split-export-declaration": "7.24.7",
- "@babel/plugin-transform-async-generator-functions": "7.25.0",
- "@babel/plugin-transform-async-to-generator": "7.24.7",
- "@babel/plugin-transform-runtime": "7.24.7",
- "@babel/preset-env": "7.25.3",
- "@babel/runtime": "7.25.0",
+ "@babel/plugin-transform-async-generator-functions": "7.26.8",
+ "@babel/plugin-transform-async-to-generator": "7.25.9",
+ "@babel/plugin-transform-runtime": "7.26.10",
+ "@babel/preset-env": "7.26.9",
+ "@babel/runtime": "7.26.10",
"@discoveryjs/json-ext": "0.6.1",
- "@ngtools/webpack": "18.2.12",
- "@vitejs/plugin-basic-ssl": "1.1.0",
+ "@ngtools/webpack": "18.2.19",
"ansi-colors": "4.1.3",
"autoprefixer": "10.4.20",
"babel-loader": "9.1.3",
@@ -446,7 +445,7 @@
"css-loader": "7.1.2",
"esbuild-wasm": "0.23.0",
"fast-glob": "3.3.2",
- "http-proxy-middleware": "3.0.3",
+ "http-proxy-middleware": "3.0.5",
"https-proxy-agent": "7.0.5",
"istanbul-lib-instrument": "6.0.3",
"jsonc-parser": "3.3.1",
@@ -475,7 +474,6 @@
"terser": "5.31.6",
"tree-kill": "1.2.2",
"tslib": "2.6.3",
- "vite": "5.4.6",
"watchpack": "2.4.1",
"webpack": "5.94.0",
"webpack-dev-middleware": "7.4.2",
@@ -543,13 +541,13 @@
}
},
"node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": {
- "version": "0.1802.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz",
- "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==",
+ "version": "0.1802.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.19.tgz",
+ "integrity": "sha512-M4B1tzxGX1nWCZr9GMM8OO0yBJO2HFSdK8M8P74vEFQfKIeq3y16IQ5zlEveJrkCOFVtmlIy2C9foMCdNyBRMA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.12",
+ "@angular-devkit/core": "18.2.19",
"rxjs": "7.8.1"
},
"engines": {
@@ -559,9 +557,9 @@
}
},
"node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz",
- "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.19.tgz",
+ "integrity": "sha512-Ptf92Zomc6FCr7GWmHKdgOUbA1GpctZwH/hRcpYpU3tM56MG2t5FOFpufnE595GgolOCktabkFEoODMG8PBVDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -587,22 +585,22 @@
}
},
"node_modules/@angular-devkit/build-angular/node_modules/@babel/core": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
- "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
+ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.0",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-module-transforms": "^7.25.2",
- "@babel/helpers": "^7.25.0",
- "@babel/parser": "^7.25.0",
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.2",
- "@babel/types": "^7.25.2",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.10",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.10",
+ "@babel/parser": "^7.26.10",
+ "@babel/template": "^7.26.9",
+ "@babel/traverse": "^7.26.10",
+ "@babel/types": "^7.26.10",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -627,95 +625,110 @@
"semver": "bin/semver.js"
}
},
- "node_modules/@angular-devkit/build-angular/node_modules/@babel/preset-env": {
- "version": "7.25.3",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz",
- "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==",
+ "node_modules/@angular-devkit/build-angular/node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+ "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/compat-data": "^7.25.2",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-validator-option": "^7.24.8",
- "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3",
- "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0",
- "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7",
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@angular-devkit/build-angular/node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz",
+ "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@angular-devkit/build-angular/node_modules/@babel/preset-env": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz",
+ "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.26.8",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-validator-option": "^7.25.9",
+ "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
+ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
"@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.14.5",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
- "@babel/plugin-syntax-import-assertions": "^7.24.7",
- "@babel/plugin-syntax-import-attributes": "^7.24.7",
- "@babel/plugin-syntax-import-meta": "^7.10.4",
- "@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.10.4",
- "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
- "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-syntax-import-assertions": "^7.26.0",
+ "@babel/plugin-syntax-import-attributes": "^7.26.0",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
- "@babel/plugin-transform-arrow-functions": "^7.24.7",
- "@babel/plugin-transform-async-generator-functions": "^7.25.0",
- "@babel/plugin-transform-async-to-generator": "^7.24.7",
- "@babel/plugin-transform-block-scoped-functions": "^7.24.7",
- "@babel/plugin-transform-block-scoping": "^7.25.0",
- "@babel/plugin-transform-class-properties": "^7.24.7",
- "@babel/plugin-transform-class-static-block": "^7.24.7",
- "@babel/plugin-transform-classes": "^7.25.0",
- "@babel/plugin-transform-computed-properties": "^7.24.7",
- "@babel/plugin-transform-destructuring": "^7.24.8",
- "@babel/plugin-transform-dotall-regex": "^7.24.7",
- "@babel/plugin-transform-duplicate-keys": "^7.24.7",
- "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0",
- "@babel/plugin-transform-dynamic-import": "^7.24.7",
- "@babel/plugin-transform-exponentiation-operator": "^7.24.7",
- "@babel/plugin-transform-export-namespace-from": "^7.24.7",
- "@babel/plugin-transform-for-of": "^7.24.7",
- "@babel/plugin-transform-function-name": "^7.25.1",
- "@babel/plugin-transform-json-strings": "^7.24.7",
- "@babel/plugin-transform-literals": "^7.25.2",
- "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
- "@babel/plugin-transform-member-expression-literals": "^7.24.7",
- "@babel/plugin-transform-modules-amd": "^7.24.7",
- "@babel/plugin-transform-modules-commonjs": "^7.24.8",
- "@babel/plugin-transform-modules-systemjs": "^7.25.0",
- "@babel/plugin-transform-modules-umd": "^7.24.7",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
- "@babel/plugin-transform-new-target": "^7.24.7",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
- "@babel/plugin-transform-numeric-separator": "^7.24.7",
- "@babel/plugin-transform-object-rest-spread": "^7.24.7",
- "@babel/plugin-transform-object-super": "^7.24.7",
- "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
- "@babel/plugin-transform-optional-chaining": "^7.24.8",
- "@babel/plugin-transform-parameters": "^7.24.7",
- "@babel/plugin-transform-private-methods": "^7.24.7",
- "@babel/plugin-transform-private-property-in-object": "^7.24.7",
- "@babel/plugin-transform-property-literals": "^7.24.7",
- "@babel/plugin-transform-regenerator": "^7.24.7",
- "@babel/plugin-transform-reserved-words": "^7.24.7",
- "@babel/plugin-transform-shorthand-properties": "^7.24.7",
- "@babel/plugin-transform-spread": "^7.24.7",
- "@babel/plugin-transform-sticky-regex": "^7.24.7",
- "@babel/plugin-transform-template-literals": "^7.24.7",
- "@babel/plugin-transform-typeof-symbol": "^7.24.8",
- "@babel/plugin-transform-unicode-escapes": "^7.24.7",
- "@babel/plugin-transform-unicode-property-regex": "^7.24.7",
- "@babel/plugin-transform-unicode-regex": "^7.24.7",
- "@babel/plugin-transform-unicode-sets-regex": "^7.24.7",
+ "@babel/plugin-transform-arrow-functions": "^7.25.9",
+ "@babel/plugin-transform-async-generator-functions": "^7.26.8",
+ "@babel/plugin-transform-async-to-generator": "^7.25.9",
+ "@babel/plugin-transform-block-scoped-functions": "^7.26.5",
+ "@babel/plugin-transform-block-scoping": "^7.25.9",
+ "@babel/plugin-transform-class-properties": "^7.25.9",
+ "@babel/plugin-transform-class-static-block": "^7.26.0",
+ "@babel/plugin-transform-classes": "^7.25.9",
+ "@babel/plugin-transform-computed-properties": "^7.25.9",
+ "@babel/plugin-transform-destructuring": "^7.25.9",
+ "@babel/plugin-transform-dotall-regex": "^7.25.9",
+ "@babel/plugin-transform-duplicate-keys": "^7.25.9",
+ "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-dynamic-import": "^7.25.9",
+ "@babel/plugin-transform-exponentiation-operator": "^7.26.3",
+ "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+ "@babel/plugin-transform-for-of": "^7.26.9",
+ "@babel/plugin-transform-function-name": "^7.25.9",
+ "@babel/plugin-transform-json-strings": "^7.25.9",
+ "@babel/plugin-transform-literals": "^7.25.9",
+ "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
+ "@babel/plugin-transform-member-expression-literals": "^7.25.9",
+ "@babel/plugin-transform-modules-amd": "^7.25.9",
+ "@babel/plugin-transform-modules-commonjs": "^7.26.3",
+ "@babel/plugin-transform-modules-systemjs": "^7.25.9",
+ "@babel/plugin-transform-modules-umd": "^7.25.9",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
+ "@babel/plugin-transform-new-target": "^7.25.9",
+ "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6",
+ "@babel/plugin-transform-numeric-separator": "^7.25.9",
+ "@babel/plugin-transform-object-rest-spread": "^7.25.9",
+ "@babel/plugin-transform-object-super": "^7.25.9",
+ "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
+ "@babel/plugin-transform-optional-chaining": "^7.25.9",
+ "@babel/plugin-transform-parameters": "^7.25.9",
+ "@babel/plugin-transform-private-methods": "^7.25.9",
+ "@babel/plugin-transform-private-property-in-object": "^7.25.9",
+ "@babel/plugin-transform-property-literals": "^7.25.9",
+ "@babel/plugin-transform-regenerator": "^7.25.9",
+ "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
+ "@babel/plugin-transform-reserved-words": "^7.25.9",
+ "@babel/plugin-transform-shorthand-properties": "^7.25.9",
+ "@babel/plugin-transform-spread": "^7.25.9",
+ "@babel/plugin-transform-sticky-regex": "^7.25.9",
+ "@babel/plugin-transform-template-literals": "^7.26.8",
+ "@babel/plugin-transform-typeof-symbol": "^7.26.7",
+ "@babel/plugin-transform-unicode-escapes": "^7.25.9",
+ "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-regex": "^7.25.9",
+ "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
"@babel/preset-modules": "0.1.6-no-external-plugins",
"babel-plugin-polyfill-corejs2": "^0.4.10",
- "babel-plugin-polyfill-corejs3": "^0.10.4",
+ "babel-plugin-polyfill-corejs3": "^0.11.0",
"babel-plugin-polyfill-regenerator": "^0.6.1",
- "core-js-compat": "^3.37.1",
+ "core-js-compat": "^3.40.0",
"semver": "^6.3.1"
},
"engines": {
@@ -827,6 +840,20 @@
"webpack": ">=5"
}
},
+ "node_modules/@angular-devkit/build-angular/node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+ "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
+ "core-js-compat": "^3.40.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
"node_modules/@angular-devkit/build-angular/node_modules/browserslist": {
"version": "4.24.5",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz",
@@ -1345,9 +1372,9 @@
}
},
"node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-server/node_modules/http-proxy-middleware": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
- "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz",
+ "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1416,13 +1443,13 @@
}
},
"node_modules/@angular-devkit/build-webpack": {
- "version": "0.1802.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.12.tgz",
- "integrity": "sha512-0Z3fdbZVRnjYWE2/VYyfy+uieY+6YZyEp4ylzklVkc+fmLNsnz4Zw6cK1LzzcBqAwKIyh1IdW20Cg7o8b0sONA==",
+ "version": "0.1802.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.19.tgz",
+ "integrity": "sha512-axz1Sasn+c+GJpJexBL+B3Rh1w3wJrQq8k8gkniodjJ594p4ti2qGk7i9Tj8A4cXx5fGY+EpuZvKfI/9Tr7QwA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/architect": "0.1802.12",
+ "@angular-devkit/architect": "0.1802.19",
"rxjs": "7.8.1"
},
"engines": {
@@ -1436,13 +1463,13 @@
}
},
"node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": {
- "version": "0.1802.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz",
- "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==",
+ "version": "0.1802.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.19.tgz",
+ "integrity": "sha512-M4B1tzxGX1nWCZr9GMM8OO0yBJO2HFSdK8M8P74vEFQfKIeq3y16IQ5zlEveJrkCOFVtmlIy2C9foMCdNyBRMA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.12",
+ "@angular-devkit/core": "18.2.19",
"rxjs": "7.8.1"
},
"engines": {
@@ -1452,9 +1479,9 @@
}
},
"node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz",
- "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.19.tgz",
+ "integrity": "sha512-Ptf92Zomc6FCr7GWmHKdgOUbA1GpctZwH/hRcpYpU3tM56MG2t5FOFpufnE595GgolOCktabkFEoODMG8PBVDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1581,13 +1608,13 @@
}
},
"node_modules/@angular-devkit/schematics": {
- "version": "18.2.14",
- "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.14.tgz",
- "integrity": "sha512-mukjZIHHB7gWratq8fZwUq5WZ+1bF4feG/idXr1wgQ+/FqWjs2PP7HDesHVcPymmRulpTyCpB7TNB1O1fgnCpA==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.19.tgz",
+ "integrity": "sha512-P/0KjkzOf2ZShuShx3cBbjLI7XlcS6B/yCRBo1MQfCC4cZfmzPQoUEOSQeYZgy5pnC24f+dKh/+TWc5uYL/Lvg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.14",
+ "@angular-devkit/core": "18.2.19",
"jsonc-parser": "3.3.1",
"magic-string": "0.30.11",
"ora": "5.4.1",
@@ -1600,9 +1627,9 @@
}
},
"node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": {
- "version": "18.2.14",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.14.tgz",
- "integrity": "sha512-UGIGOjXuOyCW+5S4tINu7e6LOu738CmTw3h7Ui1I8OzdTIYJcYJrei8sgrwDwOYADRal+p0MeMlnykH3TM5XBA==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.19.tgz",
+ "integrity": "sha512-Ptf92Zomc6FCr7GWmHKdgOUbA1GpctZwH/hRcpYpU3tM56MG2t5FOFpufnE595GgolOCktabkFEoODMG8PBVDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2034,14 +2061,14 @@
}
},
"node_modules/@angular/build": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.12.tgz",
- "integrity": "sha512-4Ohz+OSILoL+cCAQ4UTiCT5v6pctu3fXNoNpTEUK46OmxELk9jDITO5rNyNS7TxBn9wY69kjX5VcDf7MenquFQ==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.19.tgz",
+ "integrity": "sha512-dTqR+mhcZWtCRyOafvzHNVpYxMQnt8HHHqNM0kyEMzcztXL2L9zDlKr0H9d+AgGGq/v4qwCh+1gFDxsHByZwMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "2.3.0",
- "@angular-devkit/architect": "0.1802.12",
+ "@angular-devkit/architect": "0.1802.19",
"@babel/core": "7.25.2",
"@babel/helper-annotate-as-pure": "7.24.7",
"@babel/helper-split-export-declaration": "7.24.7",
@@ -2063,7 +2090,7 @@
"rollup": "4.22.4",
"sass": "1.77.6",
"semver": "7.6.3",
- "vite": "5.4.6",
+ "vite": "~5.4.17",
"watchpack": "2.4.1"
},
"engines": {
@@ -2103,13 +2130,13 @@
}
},
"node_modules/@angular/build/node_modules/@angular-devkit/architect": {
- "version": "0.1802.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz",
- "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==",
+ "version": "0.1802.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.19.tgz",
+ "integrity": "sha512-M4B1tzxGX1nWCZr9GMM8OO0yBJO2HFSdK8M8P74vEFQfKIeq3y16IQ5zlEveJrkCOFVtmlIy2C9foMCdNyBRMA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.12",
+ "@angular-devkit/core": "18.2.19",
"rxjs": "7.8.1"
},
"engines": {
@@ -2119,9 +2146,9 @@
}
},
"node_modules/@angular/build/node_modules/@angular-devkit/core": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz",
- "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.19.tgz",
+ "integrity": "sha512-Ptf92Zomc6FCr7GWmHKdgOUbA1GpctZwH/hRcpYpU3tM56MG2t5FOFpufnE595GgolOCktabkFEoODMG8PBVDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2325,18 +2352,18 @@
}
},
"node_modules/@angular/cli": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.12.tgz",
- "integrity": "sha512-xhuZ/b7IhqNw1MgXf+arWf4x+GfUSt/IwbdWU4+CO8A7h0Y46zQywouP/KUK3cMQZfVdHdciTBvlpF3vFacA6Q==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.19.tgz",
+ "integrity": "sha512-LGVMTc36JQuw8QX8Sclxyei306EQW3KslopXbf7cfqt6D5/fHS+FqqA0O7V8ob/vOGMca+l6hQD27nW5Y3W6pA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/architect": "0.1802.12",
- "@angular-devkit/core": "18.2.12",
- "@angular-devkit/schematics": "18.2.12",
+ "@angular-devkit/architect": "0.1802.19",
+ "@angular-devkit/core": "18.2.19",
+ "@angular-devkit/schematics": "18.2.19",
"@inquirer/prompts": "5.3.8",
"@listr2/prompt-adapter-inquirer": "2.0.15",
- "@schematics/angular": "18.2.12",
+ "@schematics/angular": "18.2.19",
"@yarnpkg/lockfile": "1.1.0",
"ini": "4.1.3",
"jsonc-parser": "3.3.1",
@@ -2359,13 +2386,13 @@
}
},
"node_modules/@angular/cli/node_modules/@angular-devkit/architect": {
- "version": "0.1802.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz",
- "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==",
+ "version": "0.1802.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.19.tgz",
+ "integrity": "sha512-M4B1tzxGX1nWCZr9GMM8OO0yBJO2HFSdK8M8P74vEFQfKIeq3y16IQ5zlEveJrkCOFVtmlIy2C9foMCdNyBRMA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.12",
+ "@angular-devkit/core": "18.2.19",
"rxjs": "7.8.1"
},
"engines": {
@@ -2375,9 +2402,9 @@
}
},
"node_modules/@angular/cli/node_modules/@angular-devkit/core": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz",
- "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.19.tgz",
+ "integrity": "sha512-Ptf92Zomc6FCr7GWmHKdgOUbA1GpctZwH/hRcpYpU3tM56MG2t5FOFpufnE595GgolOCktabkFEoODMG8PBVDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2402,25 +2429,6 @@
}
}
},
- "node_modules/@angular/cli/node_modules/@angular-devkit/schematics": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.12.tgz",
- "integrity": "sha512-mMea9txHbnCX5lXLHlo0RAgfhFHDio45/jMsREM2PA8UtVf2S8ltXz7ZwUrUyMQRv8vaSfn4ijDstF4hDMnRgQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@angular-devkit/core": "18.2.12",
- "jsonc-parser": "3.3.1",
- "magic-string": "0.30.11",
- "ora": "5.4.1",
- "rxjs": "7.8.1"
- },
- "engines": {
- "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
- "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
- "yarn": ">= 1.13.0"
- }
- },
"node_modules/@angular/cli/node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@@ -2718,14 +2726,14 @@
"license": "ISC"
},
"node_modules/@babel/code-frame": {
- "version": "7.26.2",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
- "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.27.1",
"js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "picocolors": "^1.1.1"
},
"engines": {
"node": ">=6.9.0"
@@ -2786,15 +2794,16 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz",
- "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz",
+ "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.25.0",
+ "@babel/parser": "^7.26.10",
+ "@babel/types": "^7.26.10",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^2.5.1"
+ "jsesc": "^3.0.2"
},
"engines": {
"node": ">=6.9.0"
@@ -2916,13 +2925,13 @@
}
},
"node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.26.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz",
- "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz",
+ "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.25.9",
+ "@babel/helper-annotate-as-pure": "^7.27.1",
"regexpu-core": "^6.2.0",
"semver": "^6.3.1"
},
@@ -2934,13 +2943,13 @@
}
},
"node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
- "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.1.tgz",
+ "integrity": "sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.25.9"
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -3031,9 +3040,9 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.26.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz",
- "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -3116,18 +3125,18 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
- "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
- "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -3158,25 +3167,25 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz",
- "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz",
+ "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==",
"license": "MIT",
"dependencies": {
- "@babel/template": "^7.26.9",
- "@babel/types": "^7.26.9"
+ "@babel/template": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
- "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
+ "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.26.9"
+ "@babel/types": "^7.27.1"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -3616,16 +3625,15 @@
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz",
- "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==",
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
+ "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.8",
- "@babel/helper-remap-async-to-generator": "^7.25.0",
- "@babel/plugin-syntax-async-generators": "^7.8.4",
- "@babel/traverse": "^7.25.0"
+ "@babel/helper-plugin-utils": "^7.26.5",
+ "@babel/helper-remap-async-to-generator": "^7.25.9",
+ "@babel/traverse": "^7.26.8"
},
"engines": {
"node": ">=6.9.0"
@@ -3635,15 +3643,15 @@
}
},
"node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz",
- "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==",
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
+ "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/helper-remap-async-to-generator": "^7.24.7"
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.25.9",
+ "@babel/helper-remap-async-to-generator": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
@@ -4281,6 +4289,23 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-regexp-modifiers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz",
+ "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
"node_modules/@babel/plugin-transform-reserved-words": {
"version": "7.25.9",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
@@ -4298,16 +4323,16 @@
}
},
"node_modules/@babel/plugin-transform-runtime": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz",
- "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz",
+ "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-plugin-utils": "^7.26.5",
"babel-plugin-polyfill-corejs2": "^0.4.10",
- "babel-plugin-polyfill-corejs3": "^0.10.1",
+ "babel-plugin-polyfill-corejs3": "^0.11.0",
"babel-plugin-polyfill-regenerator": "^0.6.1",
"semver": "^6.3.1"
},
@@ -4318,6 +4343,20 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-runtime/node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz",
+ "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.6.3",
+ "core-js-compat": "^3.40.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+ }
+ },
"node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -4598,9 +4637,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
- "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
+ "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==",
"license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
@@ -4610,30 +4649,30 @@
}
},
"node_modules/@babel/template": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
- "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.26.2",
- "@babel/parser": "^7.26.9",
- "@babel/types": "^7.26.9"
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz",
- "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz",
+ "integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==",
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.9",
- "@babel/parser": "^7.26.9",
- "@babel/template": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/code-frame": "^7.27.1",
+ "@babel/generator": "^7.27.1",
+ "@babel/parser": "^7.27.1",
+ "@babel/template": "^7.27.1",
+ "@babel/types": "^7.27.1",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -4642,13 +4681,13 @@
}
},
"node_modules/@babel/traverse/node_modules/@babel/generator": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz",
- "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz",
+ "integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==",
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/parser": "^7.27.1",
+ "@babel/types": "^7.27.1",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -4657,26 +4696,14 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/traverse/node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/@babel/types": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
- "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
+ "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.25.9",
- "@babel/helper-validator-identifier": "^7.25.9"
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -5022,23 +5049,6 @@
"semver": "bin/semver.js"
}
},
- "node_modules/@compodoc/compodoc/node_modules/@babel/generator": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz",
- "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.26.9",
- "@babel/types": "^7.26.9",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@compodoc/compodoc/node_modules/@babel/plugin-syntax-import-attributes": {
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
@@ -5055,42 +5065,6 @@
"@babel/core": "^7.0.0-0"
}
},
- "node_modules/@compodoc/compodoc/node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.26.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz",
- "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.26.5",
- "@babel/helper-remap-async-to-generator": "^7.25.9",
- "@babel/traverse": "^7.26.8"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@compodoc/compodoc/node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.25.9",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
- "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.25.9",
- "@babel/helper-plugin-utils": "^7.25.9",
- "@babel/helper-remap-async-to-generator": "^7.25.9"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
"node_modules/@compodoc/compodoc/node_modules/@babel/plugin-transform-private-methods": {
"version": "7.25.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz",
@@ -5233,19 +5207,6 @@
"node": ">= 6"
}
},
- "node_modules/@compodoc/compodoc/node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/@compodoc/compodoc/node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -8353,9 +8314,9 @@
}
},
"node_modules/@ngtools/webpack": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.12.tgz",
- "integrity": "sha512-FFJAwtWbtpncMOVNuULPBwFJB7GSjiUwO93eGTzRp8O4EPQ8lCQeFbezQm/NP34+T0+GBLGzPSuQT+muob8YKw==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.19.tgz",
+ "integrity": "sha512-bExj5JrByKPibsqBbn5Pjn8lo91AUOTsyP2hgKpnOnmSr62rhWSiRwXltgz2MCiZRmuUznpt93WiOLixgYfYvQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -9633,14 +9594,14 @@
"license": "MIT"
},
"node_modules/@schematics/angular": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.12.tgz",
- "integrity": "sha512-sIoeipsisK5eTLW3XuNZYcal83AfslBbgI7LnV+3VrXwpasKPGHwo2ZdwhCd2IXAkuJ02Iyu7MyV0aQRM9i/3g==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.19.tgz",
+ "integrity": "sha512-s9aynH/fwB/LT94miVfsaL2C4Qd5BLgjMzWFx7iJ8Hyv7FjOBGYO6eGVovjCt2c6/abG+GQAk4EBOCfg3AUtCA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@angular-devkit/core": "18.2.12",
- "@angular-devkit/schematics": "18.2.12",
+ "@angular-devkit/core": "18.2.19",
+ "@angular-devkit/schematics": "18.2.19",
"jsonc-parser": "3.3.1"
},
"engines": {
@@ -9650,9 +9611,9 @@
}
},
"node_modules/@schematics/angular/node_modules/@angular-devkit/core": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz",
- "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==",
+ "version": "18.2.19",
+ "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.19.tgz",
+ "integrity": "sha512-Ptf92Zomc6FCr7GWmHKdgOUbA1GpctZwH/hRcpYpU3tM56MG2t5FOFpufnE595GgolOCktabkFEoODMG8PBVDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9677,25 +9638,6 @@
}
}
},
- "node_modules/@schematics/angular/node_modules/@angular-devkit/schematics": {
- "version": "18.2.12",
- "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.12.tgz",
- "integrity": "sha512-mMea9txHbnCX5lXLHlo0RAgfhFHDio45/jMsREM2PA8UtVf2S8ltXz7ZwUrUyMQRv8vaSfn4ijDstF4hDMnRgQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@angular-devkit/core": "18.2.12",
- "jsonc-parser": "3.3.1",
- "magic-string": "0.30.11",
- "ora": "5.4.1",
- "rxjs": "7.8.1"
- },
- "engines": {
- "node": "^18.19.1 || ^20.11.1 || >=22.0.0",
- "npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
- "yarn": ">= 1.13.0"
- }
- },
"node_modules/@schematics/angular/node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@@ -21441,9 +21383,9 @@
}
},
"node_modules/http-proxy-middleware": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz",
- "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz",
+ "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -24398,15 +24340,15 @@
}
},
"node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
},
"engines": {
- "node": ">=4"
+ "node": ">=6"
}
},
"node_modules/json-buffer": {
@@ -35658,9 +35600,9 @@
}
},
"node_modules/vite": {
- "version": "5.4.6",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz",
- "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==",
+ "version": "5.4.19",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz",
+ "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==",
"dev": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index 6fe463ac387..81f1c92d5a5 100644
--- a/package.json
+++ b/package.json
@@ -36,9 +36,9 @@
"libs/**/*"
],
"devDependencies": {
- "@angular-devkit/build-angular": "18.2.12",
+ "@angular-devkit/build-angular": "18.2.19",
"@angular-eslint/schematics": "18.4.3",
- "@angular/cli": "18.2.12",
+ "@angular/cli": "18.2.19",
"@angular/compiler-cli": "18.2.13",
"@babel/core": "7.24.9",
"@babel/preset-env": "7.24.8",
@@ -46,7 +46,7 @@
"@electron/notarize": "2.5.0",
"@electron/rebuild": "3.7.2",
"@lit-labs/signals": "0.1.2",
- "@ngtools/webpack": "18.2.12",
+ "@ngtools/webpack": "18.2.19",
"@storybook/addon-a11y": "8.6.12",
"@storybook/addon-actions": "8.6.12",
"@storybook/addon-designs": "8.2.1",
From e538425e7a5ce635b1fbe88835a4f392d31413ee Mon Sep 17 00:00:00 2001
From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com>
Date: Fri, 9 May 2025 12:07:14 -0700
Subject: [PATCH 07/35] [PM-21343] - add download bitwarden to list of nudges
for settings badge (#14682)
* add download bitwarden to list of nudges for settings badge
* update tests
---
.../src/services/vault-nudges.service.spec.ts | 33 ++++++++++++++-----
.../src/services/vault-nudges.service.ts | 2 +-
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/libs/vault/src/services/vault-nudges.service.spec.ts b/libs/vault/src/services/vault-nudges.service.spec.ts
index 89465fc5382..40c58644309 100644
--- a/libs/vault/src/services/vault-nudges.service.spec.ts
+++ b/libs/vault/src/services/vault-nudges.service.spec.ts
@@ -12,7 +12,11 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi
import { FakeStateProvider, mockAccountServiceWith } from "../../../common/spec";
-import { HasItemsNudgeService, EmptyVaultNudgeService } from "./custom-nudges-services";
+import {
+ HasItemsNudgeService,
+ EmptyVaultNudgeService,
+ DownloadBitwardenNudgeService,
+} from "./custom-nudges-services";
import { DefaultSingleNudgeService } from "./default-single-nudge.service";
import { VaultNudgesService, VaultNudgeType } from "./vault-nudges.service";
@@ -25,6 +29,8 @@ describe("Vault Nudges Service", () => {
getFeatureFlag: jest.fn().mockReturnValue(true),
};
+ const vaultNudgeServices = [EmptyVaultNudgeService, DownloadBitwardenNudgeService];
+
beforeEach(async () => {
fakeStateProvider = new FakeStateProvider(mockAccountServiceWith("user-id" as UserId));
@@ -46,6 +52,10 @@ describe("Vault Nudges Service", () => {
provide: HasItemsNudgeService,
useValue: mock(),
},
+ {
+ provide: DownloadBitwardenNudgeService,
+ useValue: mock(),
+ },
{
provide: EmptyVaultNudgeService,
useValue: mock(),
@@ -130,11 +140,14 @@ describe("Vault Nudges Service", () => {
describe("HasActiveBadges", () => {
it("should return true if a nudgeType with hasBadgeDismissed === false", async () => {
- TestBed.overrideProvider(EmptyVaultNudgeService, {
- useValue: {
- nudgeStatus$: () => of({ hasBadgeDismissed: false, hasSpotlightDismissed: false }),
- },
+ vaultNudgeServices.forEach((service) => {
+ TestBed.overrideProvider(service, {
+ useValue: {
+ nudgeStatus$: () => of({ hasBadgeDismissed: false, hasSpotlightDismissed: false }),
+ },
+ });
});
+
const service = testBed.inject(VaultNudgesService);
const result = await firstValueFrom(service.hasActiveBadges$("user-id" as UserId));
@@ -142,10 +155,12 @@ describe("Vault Nudges Service", () => {
expect(result).toBe(true);
});
it("should return false if all nudgeTypes have hasBadgeDismissed === true", async () => {
- TestBed.overrideProvider(EmptyVaultNudgeService, {
- useValue: {
- nudgeStatus$: () => of({ hasBadgeDismissed: true, hasSpotlightDismissed: true }),
- },
+ vaultNudgeServices.forEach((service) => {
+ TestBed.overrideProvider(service, {
+ useValue: {
+ nudgeStatus$: () => of({ hasBadgeDismissed: true, hasSpotlightDismissed: false }),
+ },
+ });
});
const service = testBed.inject(VaultNudgesService);
diff --git a/libs/vault/src/services/vault-nudges.service.ts b/libs/vault/src/services/vault-nudges.service.ts
index e04cb609d7f..be6e978eaa0 100644
--- a/libs/vault/src/services/vault-nudges.service.ts
+++ b/libs/vault/src/services/vault-nudges.service.ts
@@ -114,7 +114,7 @@ export class VaultNudgesService {
*/
hasActiveBadges$(userId: UserId): Observable {
// Add more nudge types here if they have the settings badge feature
- const nudgeTypes = [VaultNudgeType.EmptyVaultNudge];
+ const nudgeTypes = [VaultNudgeType.EmptyVaultNudge, VaultNudgeType.DownloadBitwarden];
const nudgeTypesWithBadge$ = nudgeTypes.map((nudge) => {
return this.getNudgeService(nudge)
From 6b6f9577f4344daa32767824e9d209e640b5f72e Mon Sep 17 00:00:00 2001
From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com>
Date: Fri, 9 May 2025 12:08:12 -0700
Subject: [PATCH 08/35] multiple fixes for bitwarden component (#14685)
---
apps/browser/src/_locales/en/messages.json | 6 ++++
.../download-bitwarden.component.html | 36 +++++++++++++------
.../settings/download-bitwarden.component.ts | 3 +-
3 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json
index 1c3214a6ef7..57a0e78fd1b 100644
--- a/apps/browser/src/_locales/en/messages.json
+++ b/apps/browser/src/_locales/en/messages.json
@@ -4551,6 +4551,12 @@
"downloadFromBitwardenNow": {
"message": "Download from bitwarden.com now"
},
+ "getItOnGooglePlay": {
+ "message": "Get it on Google Play"
+ },
+ "downloadOnTheAppStore": {
+ "message": "Download on the App Store"
+ },
"permanentlyDeleteAttachmentConfirmation": {
"message": "Are you sure you want to permanently delete this attachment?"
},
diff --git a/apps/browser/src/vault/popup/settings/download-bitwarden.component.html b/apps/browser/src/vault/popup/settings/download-bitwarden.component.html
index ad063691e76..20896a3c782 100644
--- a/apps/browser/src/vault/popup/settings/download-bitwarden.component.html
+++ b/apps/browser/src/vault/popup/settings/download-bitwarden.component.html
@@ -2,7 +2,6 @@
-