From b3b344866e8276a50a0ba5b2be07939f3b60716e Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Thu, 28 Mar 2024 08:28:51 +1000 Subject: [PATCH] [AC-2278] [AC-2296] Use SafeProvider in browser services module (#8418) --- .../popup/services/unauth-guard.service.ts | 3 - .../popup/services/popup-search.service.ts | 6 +- .../src/popup/services/services.module.ts | 661 +++++++++--------- .../src/platform/utils/safe-provider.ts | 67 +- .../src/services/jslib-services.module.ts | 5 +- 5 files changed, 381 insertions(+), 361 deletions(-) diff --git a/apps/browser/src/auth/popup/services/unauth-guard.service.ts b/apps/browser/src/auth/popup/services/unauth-guard.service.ts index 062239a7d3..0fbb4ac9ba 100644 --- a/apps/browser/src/auth/popup/services/unauth-guard.service.ts +++ b/apps/browser/src/auth/popup/services/unauth-guard.service.ts @@ -1,8 +1,5 @@ -import { Injectable } from "@angular/core"; - import { UnauthGuard as BaseUnauthGuardService } from "@bitwarden/angular/auth/guards"; -@Injectable() export class UnauthGuardService extends BaseUnauthGuardService { protected homepage = "tabs/current"; } diff --git a/apps/browser/src/popup/services/popup-search.service.ts b/apps/browser/src/popup/services/popup-search.service.ts index 7eea1265a2..bc5e565e6c 100644 --- a/apps/browser/src/popup/services/popup-search.service.ts +++ b/apps/browser/src/popup/services/popup-search.service.ts @@ -1,14 +1,14 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { SearchService } from "@bitwarden/common/services/search.service"; export class PopupSearchService extends SearchService { constructor( private mainSearchService: SearchService, - consoleLogService: ConsoleLogService, + logService: LogService, i18nService: I18nService, ) { - super(consoleLogService, i18nService); + super(logService, i18nService); } clearIndex() { diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 7ab04603e4..33593b56dd 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -1,15 +1,18 @@ import { APP_INITIALIZER, NgModule, NgZone } from "@angular/core"; import { DomSanitizer } from "@angular/platform-browser"; +import { Router } from "@angular/router"; import { ToastrService } from "ngx-toastr"; import { UnauthGuard as BaseUnauthGuardService } from "@bitwarden/angular/auth/guards"; import { AngularThemingService } from "@bitwarden/angular/platform/services/theming/angular-theming.service"; +import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; import { MEMORY_STORAGE, SECURE_STORAGE, OBSERVABLE_DISK_STORAGE, OBSERVABLE_MEMORY_STORAGE, SYSTEM_THEME_OBSERVABLE, + SafeInjectionToken, } from "@bitwarden/angular/services/injection-tokens"; import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module"; import { @@ -129,323 +132,351 @@ function getBgService(service: keyof MainBackground) { }; } +/** + * Provider definitions used in the ngModule. + * Add your provider definition here using the safeProvider function as a wrapper. This will give you type safety. + * If you need help please ask for it, do NOT change the type of this array. + */ +const safeProviders: SafeProvider[] = [ + safeProvider(InitService), + safeProvider(DebounceNavigationService), + safeProvider(DialogService), + safeProvider(PopupCloseWarningService), + safeProvider({ + provide: APP_INITIALIZER as SafeInjectionToken<() => Promise>, + useFactory: (initService: InitService) => initService.init(), + deps: [InitService], + multi: true, + }), + safeProvider({ + provide: BaseUnauthGuardService, + useClass: UnauthGuardService, + deps: [AuthServiceAbstraction, Router], + }), + safeProvider({ + provide: MessagingService, + useFactory: () => { + return needsBackgroundInit + ? new BrowserMessagingPrivateModePopupService() + : new BrowserMessagingService(); + }, + deps: [], + }), + safeProvider({ + provide: TwoFactorService, + useFactory: getBgService("twoFactorService"), + deps: [], + }), + safeProvider({ + provide: AuthServiceAbstraction, + useFactory: getBgService("authService"), + deps: [], + }), + safeProvider({ + provide: LoginStrategyServiceAbstraction, + useFactory: getBgService("loginStrategyService"), + deps: [], + }), + safeProvider({ + provide: SsoLoginServiceAbstraction, + useFactory: getBgService("ssoLoginService"), + deps: [], + }), + safeProvider({ + provide: SearchServiceAbstraction, + useFactory: (logService: LogService, i18nService: I18nServiceAbstraction) => { + return new PopupSearchService( + getBgService("searchService")(), + logService, + i18nService, + ); + }, + deps: [LogService, I18nServiceAbstraction], + }), + safeProvider({ + provide: CipherFileUploadService, + useFactory: getBgService("cipherFileUploadService"), + deps: [], + }), + safeProvider({ + provide: CipherService, + useFactory: getBgService("cipherService"), + deps: [], + }), + safeProvider({ + provide: CryptoFunctionService, + useFactory: () => new WebCryptoFunctionService(window), + deps: [], + }), + safeProvider({ + provide: CollectionService, + useFactory: getBgService("collectionService"), + deps: [], + }), + safeProvider({ + provide: LogService, + useFactory: (platformUtilsService: PlatformUtilsService) => + new ConsoleLogService(platformUtilsService.isDev()), + deps: [PlatformUtilsService], + }), + safeProvider({ + provide: EnvironmentService, + useExisting: BrowserEnvironmentService, + }), + safeProvider({ + provide: BrowserEnvironmentService, + useClass: BrowserEnvironmentService, + deps: [LogService, StateProvider, AccountServiceAbstraction], + }), + safeProvider({ + provide: TotpService, + useFactory: getBgService("totpService"), + deps: [], + }), + safeProvider({ + provide: I18nServiceAbstraction, + useFactory: (globalStateProvider: GlobalStateProvider) => { + return new I18nService(BrowserApi.getUILanguage(), globalStateProvider); + }, + deps: [GlobalStateProvider], + }), + safeProvider({ + provide: CryptoService, + useFactory: (encryptService: EncryptService) => { + const cryptoService = getBgService("cryptoService")(); + new ContainerService(cryptoService, encryptService).attachToGlobal(self); + return cryptoService; + }, + deps: [EncryptService], + }), + safeProvider({ + provide: AuthRequestServiceAbstraction, + useFactory: getBgService("authRequestService"), + deps: [], + }), + safeProvider({ + provide: DeviceTrustCryptoServiceAbstraction, + useFactory: getBgService("deviceTrustCryptoService"), + deps: [], + }), + safeProvider({ + provide: DevicesServiceAbstraction, + useFactory: getBgService("devicesService"), + deps: [], + }), + safeProvider({ + provide: PlatformUtilsService, + useExisting: ForegroundPlatformUtilsService, + }), + safeProvider({ + provide: ForegroundPlatformUtilsService, + useClass: ForegroundPlatformUtilsService, + useFactory: (sanitizer: DomSanitizer, toastrService: ToastrService) => { + return new ForegroundPlatformUtilsService( + sanitizer, + toastrService, + (clipboardValue: string, clearMs: number) => { + void BrowserApi.sendMessage("clearClipboard", { clipboardValue, clearMs }); + }, + async () => { + const response = await BrowserApi.sendMessageWithResponse<{ + result: boolean; + error: string; + }>("biometricUnlock"); + if (!response.result) { + throw response.error; + } + return response.result; + }, + window, + ); + }, + deps: [DomSanitizer, ToastrService], + }), + safeProvider({ + provide: PasswordGenerationServiceAbstraction, + useFactory: getBgService("passwordGenerationService"), + deps: [], + }), + safeProvider({ + provide: SyncService, + useFactory: getBgService("syncService"), + deps: [], + }), + safeProvider({ + provide: DomainSettingsService, + useClass: DefaultDomainSettingsService, + deps: [StateProvider], + }), + safeProvider({ + provide: AbstractStorageService, + useClass: BrowserLocalStorageService, + deps: [], + }), + safeProvider({ + provide: AutofillService, + useFactory: getBgService("autofillService"), + deps: [], + }), + safeProvider({ + provide: VaultExportServiceAbstraction, + useFactory: getBgService("exportService"), + deps: [], + }), + safeProvider({ + provide: KeyConnectorService, + useFactory: getBgService("keyConnectorService"), + deps: [], + }), + safeProvider({ + provide: UserVerificationService, + useFactory: getBgService("userVerificationService"), + deps: [], + }), + safeProvider({ + provide: VaultTimeoutSettingsService, + useFactory: getBgService("vaultTimeoutSettingsService"), + deps: [], + }), + safeProvider({ + provide: VaultTimeoutService, + useFactory: getBgService("vaultTimeoutService"), + deps: [], + }), + safeProvider({ + provide: NotificationsService, + useFactory: getBgService("notificationsService"), + deps: [], + }), + safeProvider({ + provide: VaultFilterService, + useClass: VaultFilterService, + deps: [ + OrganizationService, + FolderServiceAbstraction, + CipherService, + CollectionService, + PolicyService, + StateProvider, + AccountServiceAbstraction, + ], + }), + safeProvider({ + provide: SECURE_STORAGE, + useExisting: AbstractStorageService, // Secure storage is not available in the browser, so we use normal storage instead and warn users when it is used. + }), + safeProvider({ + provide: MEMORY_STORAGE, + useFactory: getBgService("memoryStorageService"), + deps: [], + }), + safeProvider({ + provide: OBSERVABLE_MEMORY_STORAGE, + useClass: ForegroundMemoryStorageService, + deps: [], + }), + safeProvider({ + provide: OBSERVABLE_DISK_STORAGE, + useExisting: AbstractStorageService, + }), + safeProvider({ + provide: StateServiceAbstraction, + useFactory: ( + storageService: AbstractStorageService, + secureStorageService: AbstractStorageService, + memoryStorageService: AbstractMemoryStorageService, + logService: LogService, + accountService: AccountServiceAbstraction, + environmentService: EnvironmentService, + tokenService: TokenService, + migrationRunner: MigrationRunner, + ) => { + return new BrowserStateService( + storageService, + secureStorageService, + memoryStorageService, + logService, + new StateFactory(GlobalState, Account), + accountService, + environmentService, + tokenService, + migrationRunner, + ); + }, + deps: [ + AbstractStorageService, + SECURE_STORAGE, + MEMORY_STORAGE, + LogService, + AccountServiceAbstraction, + EnvironmentService, + TokenService, + MigrationRunner, + ], + }), + safeProvider({ + provide: UsernameGenerationServiceAbstraction, + useFactory: getBgService("usernameGenerationService"), + deps: [], + }), + safeProvider({ + provide: BaseStateServiceAbstraction, + useExisting: StateServiceAbstraction, + deps: [], + }), + safeProvider({ + provide: FileDownloadService, + useClass: BrowserFileDownloadService, + deps: [], + }), + safeProvider({ + provide: LoginServiceAbstraction, + useClass: LoginService, + deps: [StateServiceAbstraction], + }), + safeProvider({ + provide: SYSTEM_THEME_OBSERVABLE, + useFactory: (platformUtilsService: PlatformUtilsService) => { + // Safari doesn't properly handle the (prefers-color-scheme) media query in the popup window, it always returns light. + // In Safari, we have to use the background page instead, which comes with limitations like not dynamically changing the extension theme when the system theme is changed. + let windowContext = window; + const backgroundWindow = BrowserApi.getBackgroundPage(); + if (platformUtilsService.isSafari() && backgroundWindow) { + windowContext = backgroundWindow; + } + + return AngularThemingService.createSystemThemeFromWindow(windowContext); + }, + deps: [PlatformUtilsService], + }), + safeProvider({ + provide: FilePopoutUtilsService, + useFactory: (platformUtilsService: PlatformUtilsService) => { + return new FilePopoutUtilsService(platformUtilsService); + }, + deps: [PlatformUtilsService], + }), + safeProvider({ + provide: DerivedStateProvider, + useClass: ForegroundDerivedStateProvider, + deps: [OBSERVABLE_MEMORY_STORAGE, NgZone], + }), + safeProvider({ + provide: AutofillSettingsServiceAbstraction, + useClass: AutofillSettingsService, + deps: [StateProvider, PolicyService], + }), + safeProvider({ + provide: UserNotificationSettingsServiceAbstraction, + useClass: UserNotificationSettingsService, + deps: [StateProvider], + }), +]; + @NgModule({ imports: [JslibServicesModule], declarations: [], - providers: [ - InitService, - DebounceNavigationService, - DialogService, - PopupCloseWarningService, - { - provide: APP_INITIALIZER, - useFactory: (initService: InitService) => initService.init(), - deps: [InitService], - multi: true, - }, - { provide: BaseUnauthGuardService, useClass: UnauthGuardService }, - { - provide: MessagingService, - useFactory: () => { - return needsBackgroundInit - ? new BrowserMessagingPrivateModePopupService() - : new BrowserMessagingService(); - }, - }, - { - provide: TwoFactorService, - useFactory: getBgService("twoFactorService"), - deps: [], - }, - { - provide: AuthServiceAbstraction, - useFactory: getBgService("authService"), - deps: [], - }, - { - provide: LoginStrategyServiceAbstraction, - useFactory: getBgService("loginStrategyService"), - }, - { - provide: SsoLoginServiceAbstraction, - useFactory: getBgService("ssoLoginService"), - deps: [], - }, - { - provide: SearchServiceAbstraction, - useFactory: (logService: ConsoleLogService, i18nService: I18nServiceAbstraction) => { - return new PopupSearchService( - getBgService("searchService")(), - logService, - i18nService, - ); - }, - deps: [LogService, I18nServiceAbstraction], - }, - { - provide: CipherFileUploadService, - useFactory: getBgService("cipherFileUploadService"), - deps: [], - }, - { provide: CipherService, useFactory: getBgService("cipherService"), deps: [] }, - { - provide: CryptoFunctionService, - useFactory: () => new WebCryptoFunctionService(window), - deps: [], - }, - { - provide: CollectionService, - useFactory: getBgService("collectionService"), - deps: [], - }, - { - provide: LogService, - useFactory: (platformUtilsService: PlatformUtilsService) => - new ConsoleLogService(platformUtilsService.isDev()), - deps: [PlatformUtilsService], - }, - { - provide: BrowserEnvironmentService, - useClass: BrowserEnvironmentService, - deps: [LogService, StateProvider, AccountServiceAbstraction], - }, - { - provide: EnvironmentService, - useExisting: BrowserEnvironmentService, - }, - { provide: TotpService, useFactory: getBgService("totpService"), deps: [] }, - { - provide: I18nServiceAbstraction, - useFactory: (globalStateProvider: GlobalStateProvider) => { - return new I18nService(BrowserApi.getUILanguage(), globalStateProvider); - }, - deps: [GlobalStateProvider], - }, - { - provide: CryptoService, - useFactory: (encryptService: EncryptService) => { - const cryptoService = getBgService("cryptoService")(); - new ContainerService(cryptoService, encryptService).attachToGlobal(self); - return cryptoService; - }, - deps: [EncryptService], - }, - { - provide: AuthRequestServiceAbstraction, - useFactory: getBgService("authRequestService"), - deps: [], - }, - { - provide: DeviceTrustCryptoServiceAbstraction, - useFactory: getBgService("deviceTrustCryptoService"), - deps: [], - }, - { - provide: DevicesServiceAbstraction, - useFactory: getBgService("devicesService"), - deps: [], - }, - { - provide: PlatformUtilsService, - useExisting: ForegroundPlatformUtilsService, - }, - { - provide: ForegroundPlatformUtilsService, - useClass: ForegroundPlatformUtilsService, - useFactory: (sanitizer: DomSanitizer, toastrService: ToastrService) => { - return new ForegroundPlatformUtilsService( - sanitizer, - toastrService, - (clipboardValue: string, clearMs: number) => { - void BrowserApi.sendMessage("clearClipboard", { clipboardValue, clearMs }); - }, - async () => { - const response = await BrowserApi.sendMessageWithResponse<{ - result: boolean; - error: string; - }>("biometricUnlock"); - if (!response.result) { - throw response.error; - } - return response.result; - }, - window, - ); - }, - deps: [DomSanitizer, ToastrService], - }, - { - provide: PasswordGenerationServiceAbstraction, - useFactory: getBgService("passwordGenerationService"), - deps: [], - }, - { provide: SyncService, useFactory: getBgService("syncService"), deps: [] }, - { - provide: DomainSettingsService, - useClass: DefaultDomainSettingsService, - deps: [StateProvider], - }, - { - provide: AbstractStorageService, - useClass: BrowserLocalStorageService, - deps: [], - }, - { - provide: AutofillService, - useFactory: getBgService("autofillService"), - deps: [], - }, - { - provide: VaultExportServiceAbstraction, - useFactory: getBgService("exportService"), - deps: [], - }, - { - provide: KeyConnectorService, - useFactory: getBgService("keyConnectorService"), - deps: [], - }, - { - provide: UserVerificationService, - useFactory: getBgService("userVerificationService"), - deps: [], - }, - { - provide: VaultTimeoutSettingsService, - useFactory: getBgService("vaultTimeoutSettingsService"), - deps: [], - }, - { - provide: VaultTimeoutService, - useFactory: getBgService("vaultTimeoutService"), - deps: [], - }, - { - provide: NotificationsService, - useFactory: getBgService("notificationsService"), - deps: [], - }, - { - provide: VaultFilterService, - useClass: VaultFilterService, - deps: [ - OrganizationService, - FolderServiceAbstraction, - CipherService, - CollectionService, - PolicyService, - StateProvider, - AccountServiceAbstraction, - ], - }, - { - provide: SECURE_STORAGE, - useExisting: AbstractStorageService, // Secure storage is not available in the browser, so we use normal storage instead and warn users when it is used. - }, - { - provide: MEMORY_STORAGE, - useFactory: getBgService("memoryStorageService"), - }, - { - provide: OBSERVABLE_MEMORY_STORAGE, - useClass: ForegroundMemoryStorageService, - deps: [], - }, - { - provide: OBSERVABLE_DISK_STORAGE, - useExisting: AbstractStorageService, - }, - { - provide: StateServiceAbstraction, - useFactory: ( - storageService: AbstractStorageService, - secureStorageService: AbstractStorageService, - memoryStorageService: AbstractMemoryStorageService, - logService: LogService, - accountService: AccountServiceAbstraction, - environmentService: EnvironmentService, - tokenService: TokenService, - migrationRunner: MigrationRunner, - ) => { - return new BrowserStateService( - storageService, - secureStorageService, - memoryStorageService, - logService, - new StateFactory(GlobalState, Account), - accountService, - environmentService, - tokenService, - migrationRunner, - ); - }, - deps: [ - AbstractStorageService, - SECURE_STORAGE, - MEMORY_STORAGE, - LogService, - AccountServiceAbstraction, - EnvironmentService, - TokenService, - MigrationRunner, - ], - }, - { - provide: UsernameGenerationServiceAbstraction, - useFactory: getBgService("usernameGenerationService"), - deps: [], - }, - { - provide: BaseStateServiceAbstraction, - useExisting: StateServiceAbstraction, - deps: [], - }, - { - provide: FileDownloadService, - useClass: BrowserFileDownloadService, - }, - { - provide: LoginServiceAbstraction, - useClass: LoginService, - deps: [StateServiceAbstraction], - }, - { - provide: SYSTEM_THEME_OBSERVABLE, - useFactory: (platformUtilsService: PlatformUtilsService) => { - // Safari doesn't properly handle the (prefers-color-scheme) media query in the popup window, it always returns light. - // In Safari, we have to use the background page instead, which comes with limitations like not dynamically changing the extension theme when the system theme is changed. - let windowContext = window; - const backgroundWindow = BrowserApi.getBackgroundPage(); - if (platformUtilsService.isSafari() && backgroundWindow) { - windowContext = backgroundWindow; - } - - return AngularThemingService.createSystemThemeFromWindow(windowContext); - }, - deps: [PlatformUtilsService], - }, - { - provide: FilePopoutUtilsService, - useFactory: (platformUtilsService: PlatformUtilsService) => { - return new FilePopoutUtilsService(platformUtilsService); - }, - deps: [PlatformUtilsService], - }, - { - provide: DerivedStateProvider, - useClass: ForegroundDerivedStateProvider, - deps: [OBSERVABLE_MEMORY_STORAGE, NgZone], - }, - { - provide: AutofillSettingsServiceAbstraction, - useClass: AutofillSettingsService, - deps: [StateProvider, PolicyService], - }, - { - provide: UserNotificationSettingsServiceAbstraction, - useClass: UserNotificationSettingsService, - deps: [StateProvider], - }, - ], + // Do not register your dependency here! Add it to the typesafeProviders array using the helper function + providers: safeProviders, }) export class ServicesModule {} diff --git a/libs/angular/src/platform/utils/safe-provider.ts b/libs/angular/src/platform/utils/safe-provider.ts index 65ce49cda9..4ab1d2ae2a 100644 --- a/libs/angular/src/platform/utils/safe-provider.ts +++ b/libs/angular/src/platform/utils/safe-provider.ts @@ -4,7 +4,7 @@ import { Constructor, Opaque } from "type-fest"; import { SafeInjectionToken } from "../../services/injection-tokens"; /** - * The return type of our dependency helper functions. + * The return type of the {@link safeProvider} helper function. * Used to distinguish a type safe provider definition from a non-type safe provider definition. */ export type SafeProvider = Opaque; @@ -18,12 +18,22 @@ type MapParametersToDeps = { type SafeInjectionTokenType = T extends SafeInjectionToken ? J : never; +/** + * Gets the instance type from a constructor, abstract constructor, or SafeInjectionToken + */ +type ProviderInstanceType = + T extends SafeInjectionToken + ? InstanceType> + : T extends Constructor | AbstractConstructor + ? InstanceType + : never; + /** * Represents a dependency provided with the useClass option. */ type SafeClassProvider< - A extends AbstractConstructor, - I extends Constructor>, + A extends AbstractConstructor | SafeInjectionToken, + I extends Constructor>, D extends MapParametersToDeps>, > = { provide: A; @@ -40,37 +50,25 @@ type SafeValueProvider, V extends SafeInjectio }; /** - * Represents a dependency provided with the useFactory option where a SafeInjectionToken is used as the token. + * Represents a dependency provided with the useFactory option. */ -type SafeFactoryProviderWithToken< - A extends SafeInjectionToken, - I extends (...args: any) => InstanceType>, - D extends MapParametersToDeps>, -> = { - provide: A; - useFactory: I; - deps: D; -}; - -/** - * Represents a dependency provided with the useFactory option where an abstract class is used as the token. - */ -type SafeFactoryProviderWithClass< - A extends AbstractConstructor, - I extends (...args: any) => InstanceType, +type SafeFactoryProvider< + A extends AbstractConstructor | SafeInjectionToken, + I extends (...args: any) => ProviderInstanceType, D extends MapParametersToDeps>, > = { provide: A; useFactory: I; deps: D; + multi?: boolean; }; /** * Represents a dependency provided with the useExisting option. */ type SafeExistingProvider< - A extends Constructor | AbstractConstructor, - I extends Constructor> | AbstractConstructor>, + A extends Constructor | AbstractConstructor | SafeInjectionToken, + I extends Constructor> | AbstractConstructor>, > = { provide: A; useExisting: I; @@ -84,31 +82,26 @@ type SafeExistingProvider< */ export const safeProvider = < // types for useClass - AClass extends AbstractConstructor, - IClass extends Constructor>, + AClass extends AbstractConstructor | SafeInjectionToken, + IClass extends Constructor>, DClass extends MapParametersToDeps>, // types for useValue AValue extends SafeInjectionToken, VValue extends SafeInjectionTokenType, - // types for useFactoryWithToken - AFactoryToken extends SafeInjectionToken, - IFactoryToken extends (...args: any) => InstanceType>, - DFactoryToken extends MapParametersToDeps>, - // types for useFactoryWithClass - AFactoryClass extends AbstractConstructor, - IFactoryClass extends (...args: any) => InstanceType, - DFactoryClass extends MapParametersToDeps>, + // types for useFactory + AFactory extends AbstractConstructor | SafeInjectionToken, + IFactory extends (...args: any) => ProviderInstanceType, + DFactory extends MapParametersToDeps>, // types for useExisting - AExisting extends Constructor | AbstractConstructor, + AExisting extends Constructor | AbstractConstructor | SafeInjectionToken, IExisting extends - | Constructor> - | AbstractConstructor>, + | Constructor> + | AbstractConstructor>, >( provider: | SafeClassProvider | SafeValueProvider - | SafeFactoryProviderWithToken - | SafeFactoryProviderWithClass + | SafeFactoryProvider | SafeExistingProvider | Constructor, ): SafeProvider => provider as SafeProvider; diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 67d38d33de..521387181b 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1,5 +1,4 @@ import { LOCALE_ID, NgModule } from "@angular/core"; -import { UnwrapOpaque } from "type-fest"; import { AuthRequestServiceAbstraction, @@ -267,7 +266,7 @@ import { ModalService } from "./modal.service"; * Add your provider definition here using the safeProvider function as a wrapper. This will give you type safety. * If you need help please ask for it, do NOT change the type of this array. */ -const typesafeProviders: Array = [ +const safeProviders: SafeProvider[] = [ safeProvider(AuthGuard), safeProvider(UnauthGuard), safeProvider(ModalService), @@ -1085,6 +1084,6 @@ function encryptServiceFactory( @NgModule({ declarations: [], // Do not register your dependency here! Add it to the typesafeProviders array using the helper function - providers: typesafeProviders as UnwrapOpaque[], + providers: safeProviders, }) export class JslibServicesModule {}