From 76ff34b0c488864e30c384124460fbc62315aace Mon Sep 17 00:00:00 2001 From: dw-0 Date: Fri, 25 Oct 2024 18:49:31 +0200 Subject: [PATCH 1/9] Feature/switch no-empty-function rule in eslint configuration from warn to error (#3979) * Switch no-empty-function rule in eslint configuration from warn to error * Update changelog --------- Signed-off-by: Dominik Willner --- .eslintrc.json | 1 - CHANGELOG.md | 4 ++++ README.md | 6 ++++++ apps/api/src/app/health/health.controller.ts | 7 ++++++- .../admin-market-data/admin-market-data.component.ts | 6 +++--- .../admin-market-data/admin-market-data.service.ts | 3 +-- .../asset-profile-dialog/asset-profile-dialog.component.ts | 4 ++-- apps/client/src/app/services/user/user.service.ts | 2 +- 8 files changed, 23 insertions(+), 10 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index d3f7edea9..cdda2a982 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -144,7 +144,6 @@ // and can be remove once solved "@typescript-eslint/consistent-type-definitions": "warn", "@typescript-eslint/prefer-function-type": "warn", - "@typescript-eslint/no-empty-function": "warn", "@typescript-eslint/prefer-nullish-coalescing": "warn", // TODO: Requires strictNullChecks: true "@typescript-eslint/consistent-type-assertions": "warn", "@typescript-eslint/prefer-optional-chain": "warn", diff --git a/CHANGELOG.md b/CHANGELOG.md index 9800f9251..9e80f3b05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Switched the `no-empty-function` rule from `warn` to `error` in the `eslint` configuration + ### Fixed - Fixed an issue with the X-axis scale of the dividend timeline on the analysis page diff --git a/README.md b/README.md index 989cc37ea..dca360c39 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,12 @@ Deprecated: `GET http://localhost:3333/api/v1/auth/anonymous/ {}); + .subscribe(); } public onGatherProfileDataBySymbol({ @@ -274,14 +274,14 @@ export class AdminMarketDataComponent this.adminService .gatherProfileDataBySymbol({ dataSource, symbol }) .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => {}); + .subscribe(); } public onGatherSymbol({ dataSource, symbol }: AssetProfileIdentifier) { this.adminService .gatherSymbol({ dataSource, symbol }) .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => {}); + .subscribe(); } public onOpenAssetProfileDialog({ diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts index 9695dc2a2..86965cd8a 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts @@ -59,10 +59,9 @@ export class AdminMarketDataService { }), finalize(() => { window.location.reload(); - setTimeout(() => {}, 300); }) ) - .subscribe(() => {}); + .subscribe(); }, confirmType: ConfirmationDialogType.Warn, title: $localize`Do you really want to delete these profiles?` diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index 7cb3aac08..aacf387e7 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -190,14 +190,14 @@ export class AssetProfileDialog implements OnDestroy, OnInit { this.adminService .gatherProfileDataBySymbol({ dataSource, symbol }) .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => {}); + .subscribe(); } public onGatherSymbol({ dataSource, symbol }: AssetProfileIdentifier) { this.adminService .gatherSymbol({ dataSource, symbol }) .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => {}); + .subscribe(); } public onImportHistoricalData() { diff --git a/apps/client/src/app/services/user/user.service.ts b/apps/client/src/app/services/user/user.service.ts index eef0b2f41..a36f2a850 100644 --- a/apps/client/src/app/services/user/user.service.ts +++ b/apps/client/src/app/services/user/user.service.ts @@ -114,7 +114,7 @@ export class UserService extends ObservableStore { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => {}); + .subscribe(); } return user; From 405ec0d2b29a30715884a5c6af0e670d55b53f12 Mon Sep 17 00:00:00 2001 From: dw-0 Date: Sat, 26 Oct 2024 09:41:37 +0200 Subject: [PATCH 2/9] Feature/switch the consistent-type-definitions eslint rule from warn to error (#3980) * Switch the consistent-type-definitions eslint rule from warn to error * Update changelog --------- Signed-off-by: Dominik Willner --- .eslintrc.json | 1 - CHANGELOG.md | 1 + apps/api/src/app/auth/interfaces/simplewebauthn.ts | 4 ++-- apps/api/src/app/user/update-user-setting.dto.ts | 4 ++-- .../components/home-holdings/home-holdings.component.ts | 7 ++----- .../rule/rule-settings-dialog/interfaces/interfaces.ts | 6 ++++-- .../rule-settings-dialog/rule-settings-dialog.component.ts | 2 +- apps/client/src/app/components/rule/rule.component.ts | 6 ++++-- apps/client/src/app/components/rules/rules.component.ts | 6 ++++-- apps/client/src/app/components/toggle/toggle.component.ts | 2 +- .../pages/portfolio/analysis/analysis-page.component.ts | 5 +++-- libs/common/src/lib/interfaces/index.ts | 6 +++++- .../toggle-option.interface.ts} | 4 ++-- libs/common/src/lib/interfaces/user-settings.interface.ts | 4 ++-- .../x-ray-rules-settings.interface.ts} | 4 ++-- libs/common/src/lib/types/index.ts | 6 +----- 16 files changed, 36 insertions(+), 32 deletions(-) rename libs/common/src/lib/{types/toggle-option.type.ts => interfaces/toggle-option.interface.ts} (50%) rename libs/common/src/lib/{types/x-ray-rules-settings.type.ts => interfaces/x-ray-rules-settings.interface.ts} (92%) diff --git a/.eslintrc.json b/.eslintrc.json index cdda2a982..a66ee6f02 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -142,7 +142,6 @@ // The following rules are part of @typescript-eslint/stylistic-type-checked // and can be remove once solved - "@typescript-eslint/consistent-type-definitions": "warn", "@typescript-eslint/prefer-function-type": "warn", "@typescript-eslint/prefer-nullish-coalescing": "warn", // TODO: Requires strictNullChecks: true "@typescript-eslint/consistent-type-assertions": "warn", diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e80f3b05..8bc021cf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Switched the `consistent-type-definitions` rule from `warn` to `error` in the `eslint` configuration - Switched the `no-empty-function` rule from `warn` to `error` in the `eslint` configuration ### Fixed diff --git a/apps/api/src/app/auth/interfaces/simplewebauthn.ts b/apps/api/src/app/auth/interfaces/simplewebauthn.ts index 4b9058e2f..ef0a14ffa 100644 --- a/apps/api/src/app/auth/interfaces/simplewebauthn.ts +++ b/apps/api/src/app/auth/interfaces/simplewebauthn.ts @@ -198,12 +198,12 @@ export interface AuthenticatorAssertionResponseJSON /** * A WebAuthn-compatible device and the information needed to verify assertions by it */ -export declare type AuthenticatorDevice = { +export declare interface AuthenticatorDevice { credentialPublicKey: Buffer; credentialID: Buffer; counter: number; transports?: AuthenticatorTransport[]; -}; +} /** * An attempt to communicate that this isn't just any string, but a Base64URL-encoded string */ diff --git a/apps/api/src/app/user/update-user-setting.dto.ts b/apps/api/src/app/user/update-user-setting.dto.ts index 6ea6d7427..a4441af92 100644 --- a/apps/api/src/app/user/update-user-setting.dto.ts +++ b/apps/api/src/app/user/update-user-setting.dto.ts @@ -1,10 +1,10 @@ import { IsCurrencyCode } from '@ghostfolio/api/validators/is-currency-code'; +import { XRayRulesSettings } from '@ghostfolio/common/interfaces'; import type { ColorScheme, DateRange, HoldingsViewMode, - ViewMode, - XRayRulesSettings + ViewMode } from '@ghostfolio/common/types'; import { diff --git a/apps/client/src/app/components/home-holdings/home-holdings.component.ts b/apps/client/src/app/components/home-holdings/home-holdings.component.ts index c76638d33..d2b23d037 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.component.ts +++ b/apps/client/src/app/components/home-holdings/home-holdings.component.ts @@ -4,14 +4,11 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { AssetProfileIdentifier, PortfolioPosition, + ToggleOption, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { - HoldingType, - HoldingsViewMode, - ToggleOption -} from '@ghostfolio/common/types'; +import { HoldingType, HoldingsViewMode } from '@ghostfolio/common/types'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; diff --git a/apps/client/src/app/components/rule/rule-settings-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/rule/rule-settings-dialog/interfaces/interfaces.ts index 7eee7e52d..6fcbd2d38 100644 --- a/apps/client/src/app/components/rule/rule-settings-dialog/interfaces/interfaces.ts +++ b/apps/client/src/app/components/rule/rule-settings-dialog/interfaces/interfaces.ts @@ -1,5 +1,7 @@ -import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; -import { XRayRulesSettings } from '@ghostfolio/common/types'; +import { + PortfolioReportRule, + XRayRulesSettings +} from '@ghostfolio/common/interfaces'; export interface IRuleSettingsDialogParams { rule: PortfolioReportRule; diff --git a/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts b/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts index 7aa228776..8b3dfed31 100644 --- a/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts +++ b/apps/client/src/app/components/rule/rule-settings-dialog/rule-settings-dialog.component.ts @@ -1,4 +1,4 @@ -import { XRayRulesSettings } from '@ghostfolio/common/types'; +import { XRayRulesSettings } from '@ghostfolio/common/interfaces'; import { CommonModule } from '@angular/common'; import { Component, Inject } from '@angular/core'; diff --git a/apps/client/src/app/components/rule/rule.component.ts b/apps/client/src/app/components/rule/rule.component.ts index f51ce805f..04e6de666 100644 --- a/apps/client/src/app/components/rule/rule.component.ts +++ b/apps/client/src/app/components/rule/rule.component.ts @@ -1,7 +1,9 @@ import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto'; import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; -import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; -import { XRayRulesSettings } from '@ghostfolio/common/types'; +import { + PortfolioReportRule, + XRayRulesSettings +} from '@ghostfolio/common/interfaces'; import { ChangeDetectionStrategy, diff --git a/apps/client/src/app/components/rules/rules.component.ts b/apps/client/src/app/components/rules/rules.component.ts index fb2ef1cdb..bec0b642f 100644 --- a/apps/client/src/app/components/rules/rules.component.ts +++ b/apps/client/src/app/components/rules/rules.component.ts @@ -1,6 +1,8 @@ import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto'; -import { PortfolioReportRule } from '@ghostfolio/common/interfaces'; -import { XRayRulesSettings } from '@ghostfolio/common/types'; +import { + PortfolioReportRule, + XRayRulesSettings +} from '@ghostfolio/common/interfaces'; import { ChangeDetectionStrategy, diff --git a/apps/client/src/app/components/toggle/toggle.component.ts b/apps/client/src/app/components/toggle/toggle.component.ts index ecc210294..4e056f1d3 100644 --- a/apps/client/src/app/components/toggle/toggle.component.ts +++ b/apps/client/src/app/components/toggle/toggle.component.ts @@ -1,4 +1,4 @@ -import { ToggleOption } from '@ghostfolio/common/types'; +import { ToggleOption } from '@ghostfolio/common/interfaces'; import { ChangeDetectionStrategy, diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index 4cd75c7ad..6eb42b68d 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -4,13 +4,14 @@ import { ImpersonationStorageService } from '@ghostfolio/client/services/imperso import { UserService } from '@ghostfolio/client/services/user/user.service'; import { HistoricalDataItem, + InvestmentItem, PortfolioInvestments, PortfolioPerformance, PortfolioPosition, + ToggleOption, User } from '@ghostfolio/common/interfaces'; -import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; -import { GroupBy, ToggleOption } from '@ghostfolio/common/types'; +import { GroupBy } from '@ghostfolio/common/types'; import { translate } from '@ghostfolio/ui/i18n'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index 51bb7c10e..0ec04594c 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -50,8 +50,10 @@ import type { Subscription } from './subscription.interface'; import type { SymbolMetrics } from './symbol-metrics.interface'; import type { SystemMessage } from './system-message.interface'; import type { TabConfiguration } from './tab-configuration.interface'; +import type { ToggleOption } from './toggle-option.interface'; import type { UserSettings } from './user-settings.interface'; import type { User } from './user.interface'; +import type { XRayRulesSettings } from './x-ray-rules-settings.interface'; export { Access, @@ -104,6 +106,8 @@ export { Subscription, SymbolMetrics, TabConfiguration, + ToggleOption, User, - UserSettings + UserSettings, + XRayRulesSettings }; diff --git a/libs/common/src/lib/types/toggle-option.type.ts b/libs/common/src/lib/interfaces/toggle-option.interface.ts similarity index 50% rename from libs/common/src/lib/types/toggle-option.type.ts rename to libs/common/src/lib/interfaces/toggle-option.interface.ts index 25ba4d7d2..ca7b16bb2 100644 --- a/libs/common/src/lib/types/toggle-option.type.ts +++ b/libs/common/src/lib/interfaces/toggle-option.interface.ts @@ -1,4 +1,4 @@ -export type ToggleOption = { +export interface ToggleOption { label: string; value: string; -}; +} diff --git a/libs/common/src/lib/interfaces/user-settings.interface.ts b/libs/common/src/lib/interfaces/user-settings.interface.ts index 106f54600..e9e90e71f 100644 --- a/libs/common/src/lib/interfaces/user-settings.interface.ts +++ b/libs/common/src/lib/interfaces/user-settings.interface.ts @@ -1,9 +1,9 @@ +import { XRayRulesSettings } from '@ghostfolio/common/interfaces/x-ray-rules-settings.interface'; import { ColorScheme, DateRange, HoldingsViewMode, - ViewMode, - XRayRulesSettings + ViewMode } from '@ghostfolio/common/types'; export interface UserSettings { diff --git a/libs/common/src/lib/types/x-ray-rules-settings.type.ts b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts similarity index 92% rename from libs/common/src/lib/types/x-ray-rules-settings.type.ts rename to libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts index 8808162f5..f38a8e6a9 100644 --- a/libs/common/src/lib/types/x-ray-rules-settings.type.ts +++ b/libs/common/src/lib/interfaces/x-ray-rules-settings.interface.ts @@ -1,4 +1,4 @@ -export type XRayRulesSettings = { +export interface XRayRulesSettings { AccountClusterRiskCurrentInvestment?: RuleSettings; AccountClusterRiskSingleAccount?: RuleSettings; AllocationClusterRiskDevelopedMarkets?: RuleSettings; @@ -7,7 +7,7 @@ export type XRayRulesSettings = { CurrencyClusterRiskCurrentInvestment?: RuleSettings; EmergencyFundSetup?: RuleSettings; FeeRatioInitialInvestment?: RuleSettings; -}; +} interface RuleSettings { isActive: boolean; diff --git a/libs/common/src/lib/types/index.ts b/libs/common/src/lib/types/index.ts index f8307152d..a66755ab1 100644 --- a/libs/common/src/lib/types/index.ts +++ b/libs/common/src/lib/types/index.ts @@ -16,10 +16,8 @@ import type { Market } from './market.type'; import type { OrderWithAccount } from './order-with-account.type'; import type { RequestWithUser } from './request-with-user.type'; import type { SubscriptionOffer } from './subscription-offer.type'; -import type { ToggleOption } from './toggle-option.type'; import type { UserWithSettings } from './user-with-settings.type'; import type { ViewMode } from './view-mode.type'; -import type { XRayRulesSettings } from './x-ray-rules-settings.type'; export type { AccessType, @@ -40,8 +38,6 @@ export type { OrderWithAccount, RequestWithUser, SubscriptionOffer, - ToggleOption, UserWithSettings, - ViewMode, - XRayRulesSettings + ViewMode }; From fccac5640dc77dab33186100b45476344466c728 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 26 Oct 2024 09:42:33 +0200 Subject: [PATCH 3/9] Bugfix/fix calculation of allocation cluster risk x ray rules (#3988) * Fix calculation of allocation cluster risk X-ray rules * Update changelog --- CHANGELOG.md | 2 ++ .../src/app/portfolio/portfolio.service.ts | 28 +++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bc021cf1..7f39882a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed an issue with the X-axis scale of the dividend timeline on the analysis page - Fixed an issue with the X-axis scale of the investment timeline on the analysis page - Fixed an issue with the X-axis scale of the portfolio evolution chart on the analysis page +- Fixed an issue in the calculation of the static portfolio analysis rule: Allocation Cluster Risk (Developed Markets) +- Fixed an issue in the calculation of the static portfolio analysis rule: Allocation Cluster Risk (Emerging Markets) ## 2.118.0 - 2024-10-23 diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index ea366304a..28df6398d 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1169,6 +1169,12 @@ export class PortfolioService { withSummary: true }); + const marketsTotalInBaseCurrency = getSum( + Object.values(markets).map(({ valueInBaseCurrency }) => { + return new Big(valueInBaseCurrency); + }) + ).toNumber(); + return { rules: { accountClusterRisk: @@ -1193,12 +1199,12 @@ export class PortfolioService { [ new AllocationClusterRiskDevelopedMarkets( this.exchangeRateDataService, - summary.currentValueInBaseCurrency, + marketsTotalInBaseCurrency, markets.developedMarkets.valueInBaseCurrency ), new AllocationClusterRiskEmergingMarkets( this.exchangeRateDataService, - summary.currentValueInBaseCurrency, + marketsTotalInBaseCurrency, markets.emergingMarkets.valueInBaseCurrency ) ], @@ -1358,20 +1364,20 @@ export class PortfolioService { } } - const marketsTotal = - markets.developedMarkets.valueInBaseCurrency + - markets.emergingMarkets.valueInBaseCurrency + - markets.otherMarkets.valueInBaseCurrency + - markets[UNKNOWN_KEY].valueInBaseCurrency; + const marketsTotalInBaseCurrency = getSum( + Object.values(markets).map(({ valueInBaseCurrency }) => { + return new Big(valueInBaseCurrency); + }) + ).toNumber(); markets.developedMarkets.valueInPercentage = - markets.developedMarkets.valueInBaseCurrency / marketsTotal; + markets.developedMarkets.valueInBaseCurrency / marketsTotalInBaseCurrency; markets.emergingMarkets.valueInPercentage = - markets.emergingMarkets.valueInBaseCurrency / marketsTotal; + markets.emergingMarkets.valueInBaseCurrency / marketsTotalInBaseCurrency; markets.otherMarkets.valueInPercentage = - markets.otherMarkets.valueInBaseCurrency / marketsTotal; + markets.otherMarkets.valueInBaseCurrency / marketsTotalInBaseCurrency; markets[UNKNOWN_KEY].valueInPercentage = - markets[UNKNOWN_KEY].valueInBaseCurrency / marketsTotal; + markets[UNKNOWN_KEY].valueInBaseCurrency / marketsTotalInBaseCurrency; const marketsAdvancedTotal = marketsAdvanced.asiaPacific.valueInBaseCurrency + From 9a885e821e8904e0c9964ae1e00c953201a06b7d Mon Sep 17 00:00:00 2001 From: dw-0 Date: Sat, 26 Oct 2024 09:58:43 +0200 Subject: [PATCH 4/9] Feature/switch prefer-function-type eslint rule from warn to error (#3981) * Switch prefer-function-type eslint rule from warn to error * Update changelog --------- Signed-off-by: Dominik Willner --- .eslintrc.json | 1 - CHANGELOG.md | 1 + apps/client/src/app/util/form.util.ts | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index a66ee6f02..445d2d477 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -142,7 +142,6 @@ // The following rules are part of @typescript-eslint/stylistic-type-checked // and can be remove once solved - "@typescript-eslint/prefer-function-type": "warn", "@typescript-eslint/prefer-nullish-coalescing": "warn", // TODO: Requires strictNullChecks: true "@typescript-eslint/consistent-type-assertions": "warn", "@typescript-eslint/prefer-optional-chain": "warn", diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f39882a2..c4953202b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Switched the `consistent-type-definitions` rule from `warn` to `error` in the `eslint` configuration - Switched the `no-empty-function` rule from `warn` to `error` in the `eslint` configuration +- Switched the `prefer-function-type` rule from `warn` to `error` in the `eslint` configuration ### Fixed diff --git a/apps/client/src/app/util/form.util.ts b/apps/client/src/app/util/form.util.ts index f629cc4a2..425aa4699 100644 --- a/apps/client/src/app/util/form.util.ts +++ b/apps/client/src/app/util/form.util.ts @@ -8,7 +8,7 @@ export async function validateObjectForForm({ ignoreFields = [], object }: { - classDto: { new (): T }; + classDto: new () => T; form: FormGroup; ignoreFields?: string[]; object: T; From 4104fb2f8f08ee7f74237b7e22a7bb3700123a6d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 26 Oct 2024 10:29:04 +0200 Subject: [PATCH 5/9] Feature/Improve subscription service (#3989) * Various improvements --- apps/api/src/app/subscription/subscription.controller.ts | 2 +- apps/api/src/app/subscription/subscription.service.ts | 4 +++- apps/client/src/app/components/header/header.component.html | 3 ++- .../user-account-membership/user-account-membership.html | 3 ++- apps/client/src/app/pages/pricing/pricing-page.html | 3 ++- libs/common/src/lib/types/subscription-offer.type.ts | 6 +++++- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/api/src/app/subscription/subscription.controller.ts b/apps/api/src/app/subscription/subscription.controller.ts index f4ca6d427..a042b2ea2 100644 --- a/apps/api/src/app/subscription/subscription.controller.ts +++ b/apps/api/src/app/subscription/subscription.controller.ts @@ -113,7 +113,7 @@ export class SubscriptionController { @Post('stripe/checkout-session') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async createCheckoutSession( - @Body() { couponId, priceId }: { couponId: string; priceId: string } + @Body() { couponId, priceId }: { couponId?: string; priceId: string } ) { try { return this.subscriptionService.createCheckoutSession({ diff --git a/apps/api/src/app/subscription/subscription.service.ts b/apps/api/src/app/subscription/subscription.service.ts index 545450669..7c1df023c 100644 --- a/apps/api/src/app/subscription/subscription.service.ts +++ b/apps/api/src/app/subscription/subscription.service.ts @@ -124,7 +124,9 @@ export class SubscriptionService { let offer: SubscriptionOffer = price ? 'renewal' : 'default'; if (isBefore(createdAt, parseDate('2023-01-01'))) { - offer = 'renewal-early-bird'; + offer = 'renewal-early-bird-2023'; + } else if (isBefore(createdAt, parseDate('2024-01-01'))) { + offer = 'renewal-early-bird-2024'; } return { diff --git a/apps/client/src/app/components/header/header.component.html b/apps/client/src/app/components/header/header.component.html index 2e9c03122..ff36c2ebe 100644 --- a/apps/client/src/app/components/header/header.component.html +++ b/apps/client/src/app/components/header/header.component.html @@ -180,7 +180,8 @@ Upgrade Plan } @else if ( user.subscription.offer === 'renewal' || - user.subscription.offer === 'renewal-early-bird' + user.subscription.offer === 'renewal-early-bird-2023' || + user.subscription.offer === 'renewal-early-bird-2024' ) { Renew Plan } diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.html b/apps/client/src/app/components/user-account-membership/user-account-membership.html index 644ec0605..d30ce7bdd 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.html +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.html @@ -16,7 +16,8 @@ Upgrade Plan } @else if ( user.subscription.offer === 'renewal' || - user.subscription.offer === 'renewal-early-bird' + user.subscription.offer === 'renewal-early-bird-2023' || + user.subscription.offer === 'renewal-early-bird-2024' ) { Renew Plan } diff --git a/apps/client/src/app/pages/pricing/pricing-page.html b/apps/client/src/app/pages/pricing/pricing-page.html index 1caa4e8a0..fe805ef62 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.html +++ b/apps/client/src/app/pages/pricing/pricing-page.html @@ -278,7 +278,8 @@ Upgrade Plan } @else if ( user.subscription.offer === 'renewal' || - user.subscription.offer === 'renewal-early-bird' + user.subscription.offer === 'renewal-early-bird-2023' || + user.subscription.offer === 'renewal-early-bird-2024' ) { Renew Plan } diff --git a/libs/common/src/lib/types/subscription-offer.type.ts b/libs/common/src/lib/types/subscription-offer.type.ts index 180088b1e..98977da45 100644 --- a/libs/common/src/lib/types/subscription-offer.type.ts +++ b/libs/common/src/lib/types/subscription-offer.type.ts @@ -1 +1,5 @@ -export type SubscriptionOffer = 'default' | 'renewal' | 'renewal-early-bird'; +export type SubscriptionOffer = + | 'default' + | 'renewal' + | 'renewal-early-bird-2023' + | 'renewal-early-bird-2024'; From ed97029e1b4255ca8e19da47b85f903bb467127d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 26 Oct 2024 10:29:24 +0200 Subject: [PATCH 6/9] Feature/upgrade prisma to version 5.21.1 (#3987) * Upgrade prisma to version 5.21.1 * Update changelog --- CHANGELOG.md | 1 + package-lock.json | 68 +++++++++++++++++++++++------------------------ package.json | 4 +-- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4953202b..fb814fba2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Switched the `consistent-type-definitions` rule from `warn` to `error` in the `eslint` configuration - Switched the `no-empty-function` rule from `warn` to `error` in the `eslint` configuration - Switched the `prefer-function-type` rule from `warn` to `error` in the `eslint` configuration +- Upgraded `prisma` from version `5.20.0` to `5.21.1` ### Fixed diff --git a/package-lock.json b/package-lock.json index 3c450b4e3..492600202 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.117.0", + "version": "2.118.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.117.0", + "version": "2.118.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { @@ -40,7 +40,7 @@ "@nestjs/platform-express": "10.1.3", "@nestjs/schedule": "3.0.2", "@nestjs/serve-static": "4.0.0", - "@prisma/client": "5.20.0", + "@prisma/client": "5.21.1", "@simplewebauthn/browser": "9.0.1", "@simplewebauthn/server": "9.0.3", "@stripe/stripe-js": "3.5.0", @@ -150,7 +150,7 @@ "nx": "20.0.3", "prettier": "3.3.3", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "5.20.0", + "prisma": "5.21.1", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "7.0.1", @@ -8753,9 +8753,9 @@ "license": "MIT" }, "node_modules/@prisma/client": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.20.0.tgz", - "integrity": "sha512-CLv55ZuMuUawMsxoqxGtLT3bEZoa2W8L3Qnp6rDIFWy+ZBrUcOFKdoeGPSnbBqxc3SkdxJrF+D1veN/WNynZYA==", + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.21.1.tgz", + "integrity": "sha512-3n+GgbAZYjaS/k0M03yQsQfR1APbr411r74foknnsGpmhNKBG49VuUkxIU6jORgvJPChoD4WC4PqoHImN1FP0w==", "hasInstallScript": true, "license": "Apache-2.0", "engines": { @@ -8771,53 +8771,53 @@ } }, "node_modules/@prisma/debug": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.20.0.tgz", - "integrity": "sha512-oCx79MJ4HSujokA8S1g0xgZUGybD4SyIOydoHMngFYiwEwYDQ5tBQkK5XoEHuwOYDKUOKRn/J0MEymckc4IgsQ==", + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.21.1.tgz", + "integrity": "sha512-uY8SAhcnORhvgtOrNdvWS98Aq/nkQ9QDUxrWAgW8XrCZaI3j2X7zb7Xe6GQSh6xSesKffFbFlkw0c2luHQviZA==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.20.0.tgz", - "integrity": "sha512-DtqkP+hcZvPEbj8t8dK5df2b7d3B8GNauKqaddRRqQBBlgkbdhJkxhoJTrOowlS3vaRt2iMCkU0+CSNn0KhqAQ==", + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.21.1.tgz", + "integrity": "sha512-hGVTldUkIkTwoV8//hmnAAiAchi4oMEKD3aW5H2RrnI50tTdwza7VQbTTAyN3OIHWlK5DVg6xV7X8N/9dtOydA==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "5.20.0", - "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284", - "@prisma/fetch-engine": "5.20.0", - "@prisma/get-platform": "5.20.0" + "@prisma/debug": "5.21.1", + "@prisma/engines-version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", + "@prisma/fetch-engine": "5.21.1", + "@prisma/get-platform": "5.21.1" } }, "node_modules/@prisma/engines-version": { - "version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284.tgz", - "integrity": "sha512-Lg8AS5lpi0auZe2Mn4gjuCg081UZf88k3cn0RCwHgR+6cyHHpttPZBElJTHf83ZGsRNAmVCZCfUGA57WB4u4JA==", + "version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36.tgz", + "integrity": "sha512-qvnEflL0//lh44S/T9NcvTMxfyowNeUxTunPcDfKPjyJNrCNf2F1zQLcUv5UHAruECpX+zz21CzsC7V2xAeM7Q==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.20.0.tgz", - "integrity": "sha512-JVcaPXC940wOGpCOwuqQRTz6I9SaBK0c1BAyC1pcz9xBi+dzFgUu3G/p9GV1FhFs9OKpfSpIhQfUJE9y00zhqw==", + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.21.1.tgz", + "integrity": "sha512-70S31vgpCGcp9J+mh/wHtLCkVezLUqe/fGWk3J3JWZIN7prdYSlr1C0niaWUyNK2VflLXYi8kMjAmSxUVq6WGQ==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "5.20.0", - "@prisma/engines-version": "5.20.0-12.06fc58a368dc7be9fbbbe894adf8d445d208c284", - "@prisma/get-platform": "5.20.0" + "@prisma/debug": "5.21.1", + "@prisma/engines-version": "5.21.1-1.bf0e5e8a04cada8225617067eaa03d041e2bba36", + "@prisma/get-platform": "5.21.1" } }, "node_modules/@prisma/get-platform": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.20.0.tgz", - "integrity": "sha512-8/+CehTZZNzJlvuryRgc77hZCWrUDYd/PmlZ7p2yNXtmf2Una4BWnTbak3us6WVdqoz5wmptk6IhsXdG2v5fmA==", + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.21.1.tgz", + "integrity": "sha512-sRxjL3Igst3ct+e8ya/x//cDXmpLbZQ5vfps2N4tWl4VGKQAmym77C/IG/psSMsQKszc8uFC/q1dgmKFLUgXZQ==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "5.20.0" + "@prisma/debug": "5.21.1" } }, "node_modules/@redis/bloom": { @@ -29794,14 +29794,14 @@ } }, "node_modules/prisma": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.20.0.tgz", - "integrity": "sha512-6obb3ucKgAnsGS9x9gLOe8qa51XxvJ3vLQtmyf52CTey1Qcez3A6W6ROH5HIz5Q5bW+0VpmZb8WBohieMFGpig==", + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.21.1.tgz", + "integrity": "sha512-PB+Iqzld/uQBPaaw2UVIk84kb0ITsLajzsxzsadxxl54eaU5Gyl2/L02ysivHxK89t7YrfQJm+Ggk37uvM70oQ==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/engines": "5.20.0" + "@prisma/engines": "5.21.1" }, "bin": { "prisma": "build/index.js" diff --git a/package.json b/package.json index 46d93209f..88248515d 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "@nestjs/platform-express": "10.1.3", "@nestjs/schedule": "3.0.2", "@nestjs/serve-static": "4.0.0", - "@prisma/client": "5.20.0", + "@prisma/client": "5.21.1", "@simplewebauthn/browser": "9.0.1", "@simplewebauthn/server": "9.0.3", "@stripe/stripe-js": "3.5.0", @@ -196,7 +196,7 @@ "nx": "20.0.3", "prettier": "3.3.3", "prettier-plugin-organize-attributes": "1.0.0", - "prisma": "5.20.0", + "prisma": "5.21.1", "react": "18.2.0", "react-dom": "18.2.0", "replace-in-file": "7.0.1", From 906e526cb9fad9c71e2696f7c8e7f2373eb556e1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 26 Oct 2024 10:31:24 +0200 Subject: [PATCH 7/9] Release 2.119.0 (#3990) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb814fba2..f42b96b10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.119.0 - 2024-10-26 ### Changed diff --git a/package.json b/package.json index 88248515d..b83ce5c59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.118.0", + "version": "2.119.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 6a10b932b010194b695672c03b96c24e6d6142c9 Mon Sep 17 00:00:00 2001 From: dw-0 Date: Sat, 26 Oct 2024 11:07:48 +0200 Subject: [PATCH 8/9] Feature/Switch consistent-type-assertions eslint rule from warn to error (#3982) * Switch consistent-type-assertions eslint rule from warn to error * Update changelog --------- Signed-off-by: Dominik Willner --- .eslintrc.json | 1 - CHANGELOG.md | 6 ++++++ .../account-balance.service.ts | 2 +- apps/api/src/app/account/account.service.ts | 4 ++-- .../src/app/admin/queue/queue.controller.ts | 4 ++-- apps/api/src/app/auth/auth.controller.ts | 2 +- .../src/app/benchmark/benchmark.service.ts | 4 ++-- apps/api/src/app/order/order.service.ts | 6 +++--- .../calculator/twr/portfolio-calculator.ts | 4 ++-- .../src/app/portfolio/portfolio.service.ts | 4 ++-- .../src/app/redis-cache/redis-cache.module.ts | 4 ++-- .../subscription/subscription.controller.ts | 2 +- .../src/app/user/update-user-setting.dto.ts | 10 ++++----- apps/api/src/app/user/user.controller.ts | 2 +- apps/api/src/app/user/user.service.ts | 4 ++-- apps/api/src/services/api/api.service.ts | 16 +++++++------- .../market-data/market-data.service.ts | 20 +++++++++--------- .../data-gathering.processor.ts | 2 +- .../portfolio-snapshot.processor.ts | 4 ++-- .../symbol-profile/symbol-profile.service.ts | 2 +- apps/client/src/app/app.component.ts | 4 ++-- .../admin-market-data-detail.component.ts | 4 ++-- .../admin-market-data.component.ts | 21 +++++++++---------- .../admin-overview.component.ts | 4 ++-- .../benchmark-comparator.component.ts | 13 ++++++------ .../holding-detail-dialog.component.ts | 2 +- .../investment-chart.component.ts | 11 +++++----- .../pages/accounts/accounts-page.component.ts | 4 ++-- .../activities/activities-page.component.ts | 8 +++---- .../allocations/allocations-page.component.ts | 4 ++-- apps/client/src/app/services/data.service.ts | 20 +++++++++--------- .../src/app/services/user/user.service.ts | 4 ++-- apps/client/src/main.ts | 6 +++--- libs/common/src/lib/config.ts | 4 ++-- libs/common/src/lib/helper.ts | 2 +- .../activities-filter.component.ts | 2 +- .../src/lib/assistant/assistant.component.ts | 4 ++-- .../src/lib/benchmark/benchmark.component.ts | 4 ++-- .../lib/line-chart/line-chart.component.ts | 19 ++++++++--------- .../portfolio-proportion-chart.component.ts | 16 +++++++------- libs/ui/src/lib/value/value.component.ts | 4 ++-- 41 files changed, 132 insertions(+), 131 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 445d2d477..41157718c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -143,7 +143,6 @@ // The following rules are part of @typescript-eslint/stylistic-type-checked // and can be remove once solved "@typescript-eslint/prefer-nullish-coalescing": "warn", // TODO: Requires strictNullChecks: true - "@typescript-eslint/consistent-type-assertions": "warn", "@typescript-eslint/prefer-optional-chain": "warn", "@typescript-eslint/consistent-indexed-object-style": "warn", "@typescript-eslint/consistent-generic-constructors": "warn" diff --git a/CHANGELOG.md b/CHANGELOG.md index f42b96b10..f049bed09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Switched the `consistent-type-assertions` rule from `warn` to `error` in the `eslint` configuration + ## 2.119.0 - 2024-10-26 ### Changed diff --git a/apps/api/src/app/account-balance/account-balance.service.ts b/apps/api/src/app/account-balance/account-balance.service.ts index f2b5f907e..34d98d266 100644 --- a/apps/api/src/app/account-balance/account-balance.service.ts +++ b/apps/api/src/app/account-balance/account-balance.service.ts @@ -88,7 +88,7 @@ export class AccountBalanceService { this.eventEmitter.emit( PortfolioChangedEvent.getName(), new PortfolioChangedEvent({ - userId: where.userId + userId: where.userId as string }) ); diff --git a/apps/api/src/app/account/account.service.ts b/apps/api/src/app/account/account.service.ts index 096caba48..df369859b 100644 --- a/apps/api/src/app/account/account.service.ts +++ b/apps/api/src/app/account/account.service.ts @@ -209,8 +209,8 @@ export class AccountService { const { data, where } = params; await this.accountBalanceService.createOrUpdateAccountBalance({ - accountId: data.id, - balance: data.balance, + accountId: data.id as string, + balance: data.balance as number, date: format(new Date(), DATE_FORMAT), userId: aUserId }); diff --git a/apps/api/src/app/admin/queue/queue.controller.ts b/apps/api/src/app/admin/queue/queue.controller.ts index 978cb9721..060abd247 100644 --- a/apps/api/src/app/admin/queue/queue.controller.ts +++ b/apps/api/src/app/admin/queue/queue.controller.ts @@ -26,7 +26,7 @@ export class QueueController { public async deleteJobs( @Query('status') filterByStatus?: string ): Promise { - const status = filterByStatus?.split(',') ?? undefined; + const status = (filterByStatus?.split(',') as JobStatus[]) ?? undefined; return this.queueService.deleteJobs({ status }); } @@ -36,7 +36,7 @@ export class QueueController { public async getJobs( @Query('status') filterByStatus?: string ): Promise { - const status = filterByStatus?.split(',') ?? undefined; + const status = (filterByStatus?.split(',') as JobStatus[]) ?? undefined; return this.queueService.getJobs({ status }); } diff --git a/apps/api/src/app/auth/auth.controller.ts b/apps/api/src/app/auth/auth.controller.ts index 5019bef21..a91525269 100644 --- a/apps/api/src/app/auth/auth.controller.ts +++ b/apps/api/src/app/auth/auth.controller.ts @@ -85,7 +85,7 @@ export class AuthController { @Res() response: Response ) { // Handles the Google OAuth2 callback - const jwt: string = (request.user).jwt; + const jwt: string = (request.user as any).jwt; if (jwt) { response.redirect( diff --git a/apps/api/src/app/benchmark/benchmark.service.ts b/apps/api/src/app/benchmark/benchmark.service.ts index 34f101a8e..36f196842 100644 --- a/apps/api/src/app/benchmark/benchmark.service.ts +++ b/apps/api/src/app/benchmark/benchmark.service.ts @@ -442,10 +442,10 @@ export class BenchmarkService { await this.redisCacheService.set( this.CACHE_KEY_BENCHMARKS, - JSON.stringify({ + JSON.stringify({ benchmarks, expiration: expiration.getTime() - }), + } as BenchmarkValue), CACHE_TTL_INFINITE ); } diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 8e69aae6f..5613adc5c 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -410,7 +410,7 @@ export class OrderService { where.SymbolProfile, { AND: [ - { dataSource: filterByDataSource }, + { dataSource: filterByDataSource as DataSource }, { symbol: filterBySymbol } ] } @@ -419,7 +419,7 @@ export class OrderService { } else { where.SymbolProfile = { AND: [ - { dataSource: filterByDataSource }, + { dataSource: filterByDataSource as DataSource }, { symbol: filterBySymbol } ] }; @@ -638,7 +638,7 @@ export class OrderService { { dataSource: data.SymbolProfile.connect.dataSource_symbol.dataSource, - date: data.date, + date: data.date as Date, symbol: data.SymbolProfile.connect.dataSource_symbol.symbol } ], diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 950d9e4d3..6c0d230b0 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -796,7 +796,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { [key: DateRange]: Big; } = {}; - for (const dateRange of [ + for (const dateRange of [ '1d', '1y', '5y', @@ -812,7 +812,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { // .map((date) => { // return format(date, 'yyyy'); // }) - ]) { + ] as DateRange[]) { const dateInterval = getIntervalFromDateRange(dateRange); const endDate = dateInterval.endDate; let startDate = dateInterval.startDate; diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 28df6398d..d88d925a4 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -138,7 +138,7 @@ export class PortfolioService { some: { SymbolProfile: { AND: [ - { dataSource: filterByDataSource }, + { dataSource: filterByDataSource as DataSource }, { symbol: filterBySymbol } ] } @@ -1160,7 +1160,7 @@ export class PortfolioService { public async getReport(impersonationId: string): Promise { const userId = await this.getUserId(impersonationId, this.request.user.id); - const userSettings = this.request.user.Settings.settings; + const userSettings = this.request.user.Settings.settings as UserSettings; const { accounts, holdings, markets, summary } = await this.getDetails({ impersonationId, diff --git a/apps/api/src/app/redis-cache/redis-cache.module.ts b/apps/api/src/app/redis-cache/redis-cache.module.ts index a507479b9..5411309bd 100644 --- a/apps/api/src/app/redis-cache/redis-cache.module.ts +++ b/apps/api/src/app/redis-cache/redis-cache.module.ts @@ -19,11 +19,11 @@ import { RedisCacheService } from './redis-cache.service'; configurationService.get('REDIS_PASSWORD') ); - return { + return { store: redisStore, ttl: configurationService.get('CACHE_TTL'), url: `redis://${redisPassword ? `:${redisPassword}` : ''}@${configurationService.get('REDIS_HOST')}:${configurationService.get('REDIS_PORT')}/${configurationService.get('REDIS_DB')}` - }; + } as RedisClientOptions; } }), ConfigurationModule diff --git a/apps/api/src/app/subscription/subscription.controller.ts b/apps/api/src/app/subscription/subscription.controller.ts index a042b2ea2..f37543fdf 100644 --- a/apps/api/src/app/subscription/subscription.controller.ts +++ b/apps/api/src/app/subscription/subscription.controller.ts @@ -95,7 +95,7 @@ export class SubscriptionController { @Res() response: Response ) { const userId = await this.subscriptionService.createSubscriptionViaStripe( - request.query.checkoutSessionId + request.query.checkoutSessionId as string ); Logger.log( diff --git a/apps/api/src/app/user/update-user-setting.dto.ts b/apps/api/src/app/user/update-user-setting.dto.ts index a4441af92..13a3a5d2c 100644 --- a/apps/api/src/app/user/update-user-setting.dto.ts +++ b/apps/api/src/app/user/update-user-setting.dto.ts @@ -31,11 +31,11 @@ export class UpdateUserSettingDto { @IsOptional() benchmark?: string; - @IsIn(['DARK', 'LIGHT']) + @IsIn(['DARK', 'LIGHT'] as ColorScheme[]) @IsOptional() colorScheme?: ColorScheme; - @IsIn([ + @IsIn([ '1d', '1y', '5y', @@ -48,7 +48,7 @@ export class UpdateUserSettingDto { return format(date, 'yyyy'); } ) - ]) + ] as DateRange[]) @IsOptional() dateRange?: DateRange; @@ -68,7 +68,7 @@ export class UpdateUserSettingDto { @IsOptional() 'filters.tags'?: string[]; - @IsIn(['CHART', 'TABLE']) + @IsIn(['CHART', 'TABLE'] as HoldingsViewMode[]) @IsOptional() holdingsViewMode?: HoldingsViewMode; @@ -100,7 +100,7 @@ export class UpdateUserSettingDto { @IsOptional() savingsRate?: number; - @IsIn(['DEFAULT', 'ZEN']) + @IsIn(['DEFAULT', 'ZEN'] as ViewMode[]) @IsOptional() viewMode?: ViewMode; diff --git a/apps/api/src/app/user/user.controller.ts b/apps/api/src/app/user/user.controller.ts index c23870437..149e06285 100644 --- a/apps/api/src/app/user/user.controller.ts +++ b/apps/api/src/app/user/user.controller.ts @@ -148,7 +148,7 @@ export class UserController { const userSettings: UserSettings = merge( {}, - this.request.user.Settings.settings, + this.request.user.Settings.settings as UserSettings, data ); diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index d0b7ab983..556d28340 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -116,8 +116,8 @@ export class UserService { accounts: Account, dateOfFirstActivity: firstActivity?.date ?? new Date(), settings: { - ...(Settings.settings), - locale: (Settings.settings)?.locale ?? aLocale + ...(Settings.settings as UserSettings), + locale: (Settings.settings as UserSettings)?.locale ?? aLocale } }; } diff --git a/apps/api/src/services/api/api.service.ts b/apps/api/src/services/api/api.service.ts index 8ff438ef1..052119246 100644 --- a/apps/api/src/services/api/api.service.ts +++ b/apps/api/src/services/api/api.service.ts @@ -34,28 +34,28 @@ export class ApiService { const filters = [ ...accountIds.map((accountId) => { - return { + return { id: accountId, type: 'ACCOUNT' - }; + } as Filter; }), ...assetClasses.map((assetClass) => { - return { + return { id: assetClass, type: 'ASSET_CLASS' - }; + } as Filter; }), ...assetSubClasses.map((assetClass) => { - return { + return { id: assetClass, type: 'ASSET_SUB_CLASS' - }; + } as Filter; }), ...tagIds.map((tagId) => { - return { + return { id: tagId, type: 'TAG' - }; + } as Filter; }) ]; diff --git a/apps/api/src/services/market-data/market-data.service.ts b/apps/api/src/services/market-data/market-data.service.ts index 09f591b9e..c0abdf04e 100644 --- a/apps/api/src/services/market-data/market-data.service.ts +++ b/apps/api/src/services/market-data/market-data.service.ts @@ -144,21 +144,21 @@ export class MarketDataService { ({ dataSource, date, marketPrice, symbol, state }) => { return this.prismaService.marketData.upsert({ create: { - dataSource: dataSource, - date: date, - marketPrice: marketPrice, - state: state, - symbol: symbol + dataSource: dataSource as DataSource, + date: date as Date, + marketPrice: marketPrice as number, + state: state as MarketDataState, + symbol: symbol as string }, update: { - marketPrice: marketPrice, - state: state + marketPrice: marketPrice as number, + state: state as MarketDataState }, where: { dataSource_date_symbol: { - dataSource: dataSource, - date: date, - symbol: symbol + dataSource: dataSource as DataSource, + date: date as Date, + symbol: symbol as string } } }); diff --git a/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts b/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts index 5d0d1e131..dc8cc5996 100644 --- a/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts +++ b/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts @@ -78,7 +78,7 @@ export class DataGatheringProcessor { public async gatherHistoricalMarketData(job: Job) { try { const { dataSource, date, symbol } = job.data; - let currentDate = parseISO((date)); + let currentDate = parseISO(date as unknown as string); Logger.log( `Historical market data gathering has been started for ${symbol} (${dataSource}) at ${format( diff --git a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts index c586a51b3..a5a9a37e0 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts @@ -94,10 +94,10 @@ export class PortfolioSnapshotProcessor { filters: job.data.filters, userId: job.data.userId }), - JSON.stringify(({ + JSON.stringify({ expiration: expiration.getTime(), portfolioSnapshot: snapshot - })), + } as unknown as PortfolioSnapshotValue), CACHE_TTL_INFINITE ); diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.ts index 283da7b52..eb8778c34 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -176,7 +176,7 @@ export class SymbolProfileService { countries: this.getCountries( symbolProfile?.countries as unknown as Prisma.JsonArray ), - dateOfFirstActivity: undefined, + dateOfFirstActivity: undefined as Date, holdings: this.getHoldings(symbolProfile), scraperConfiguration: this.getScraperConfiguration(symbolProfile), sectors: this.getSectors(symbolProfile), diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts index bc16f8080..b67165b68 100644 --- a/apps/client/src/app/app.component.ts +++ b/apps/client/src/app/app.component.ts @@ -292,7 +292,7 @@ export class AppComponent implements OnDestroy, OnInit { const dialogRef = this.dialog.open(GfHoldingDetailDialogComponent, { autoFocus: false, - data: { + data: { dataSource, symbol, baseCurrency: this.user?.settings?.baseCurrency, @@ -312,7 +312,7 @@ export class AppComponent implements OnDestroy, OnInit { hasPermission(this.user?.permissions, permissions.updateOrder) && !this.user?.settings?.isRestrictedView, locale: this.user?.settings?.locale - }, + } as HoldingDetailDialogParams, height: this.deviceType === 'mobile' ? '98vh' : '80vh', width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts index c8ba46851..1742d8307 100644 --- a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts +++ b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts @@ -178,14 +178,14 @@ export class AdminMarketDataDetailComponent implements OnChanges { const marketPrice = this.marketDataByMonth[yearMonth]?.[day]?.marketPrice; const dialogRef = this.dialog.open(MarketDataDetailDialog, { - data: { + data: { marketPrice, currency: this.currency, dataSource: this.dataSource, dateString: `${yearMonth}-${day}`, symbol: this.symbol, user: this.user - }, + } as MarketDataDetailDialogParams, height: this.deviceType === 'mobile' ? '98vh' : '80vh', width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 777a08d6c..5eb869694 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -71,36 +71,35 @@ export class AdminMarketDataComponent return { id: assetSubClass.toString(), label: translate(assetSubClass), - type: 'ASSET_SUB_CLASS' + type: 'ASSET_SUB_CLASS' as Filter['type'] }; }) .concat([ { id: 'BENCHMARKS', label: $localize`Benchmarks`, - type: 'PRESET_ID' + type: 'PRESET_ID' as Filter['type'] }, { id: 'CURRENCIES', label: $localize`Currencies`, - type: 'PRESET_ID' + type: 'PRESET_ID' as Filter['type'] }, { id: 'ETF_WITHOUT_COUNTRIES', label: $localize`ETFs without Countries`, - type: 'PRESET_ID' + type: 'PRESET_ID' as Filter['type'] }, { id: 'ETF_WITHOUT_SECTORS', label: $localize`ETFs without Sectors`, - type: 'PRESET_ID' + type: 'PRESET_ID' as Filter['type'] } ]); public benchmarks: Partial[]; public currentDataSource: DataSource; public currentSymbol: string; - public dataSource: MatTableDataSource = - new MatTableDataSource(); + public dataSource = new MatTableDataSource(); public defaultDateFormat: string; public deviceType: string; public displayedColumns: string[] = []; @@ -375,13 +374,13 @@ export class AdminMarketDataComponent const dialogRef = this.dialog.open(AssetProfileDialog, { autoFocus: false, - data: { + data: { dataSource, symbol, colorScheme: this.user?.settings.colorScheme, deviceType: this.deviceType, locale: this.user?.settings?.locale - }, + } as AssetProfileDialogParams, height: this.deviceType === 'mobile' ? '98vh' : '80vh', width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); @@ -404,10 +403,10 @@ export class AdminMarketDataComponent const dialogRef = this.dialog.open(CreateAssetProfileDialog, { autoFocus: false, - data: { + data: { deviceType: this.deviceType, locale: this.user?.settings?.locale - }, + } as CreateAssetProfileDialogParams, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/apps/client/src/app/components/admin-overview/admin-overview.component.ts b/apps/client/src/app/components/admin-overview/admin-overview.component.ts index 15547bb6d..82bb85c13 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.component.ts +++ b/apps/client/src/app/components/admin-overview/admin-overview.component.ts @@ -225,10 +225,10 @@ export class AdminOverviewComponent implements OnDestroy, OnInit { $localize`Please set your system message:`, JSON.stringify( this.systemMessage ?? - { + ({ message: '⚒️ Scheduled maintenance in progress...', targetGroups: ['Basic', 'Premium'] - } + } as SystemMessage) ) ); diff --git a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts index 2035d06a9..4ea3422ec 100644 --- a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts +++ b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -98,7 +98,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { } private initialize() { - const benchmarkDataValues: { [date: string]: number } = {}; + const benchmarkDataValues: Record = {}; for (const { date, value } of this.benchmarkDataItems) { benchmarkDataValues[date] = value; @@ -133,9 +133,8 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { if (this.chartCanvas) { if (this.chart) { this.chart.data = data; - this.chart.options.plugins.tooltip = ( - this.getTooltipPluginConfiguration() - ); + this.chart.options.plugins.tooltip = + this.getTooltipPluginConfiguration() as unknown; this.chart.update(); } else { this.chart = new Chart(this.chartCanvas.nativeElement, { @@ -154,7 +153,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { }, interaction: { intersect: false, mode: 'index' }, maintainAspectRatio: true, - plugins: { + plugins: { annotation: { annotations: { yAxis: { @@ -173,7 +172,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { verticalHoverLine: { color: `rgba(${getTextColor(this.colorScheme)}, 0.1)` } - }, + } as unknown, responsive: true, scales: { x: { @@ -238,7 +237,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { unit: '%' }), mode: 'index', - position: 'top', + position: 'top' as unknown, xAlign: 'center', yAlign: 'bottom' }; diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts index 792ec6f9c..b430f36ec 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts @@ -148,7 +148,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { public ngOnInit() { this.activityForm = this.formBuilder.group({ - tags: [] + tags: [] as string[] }); const filters: Filter[] = [ diff --git a/apps/client/src/app/components/investment-chart/investment-chart.component.ts b/apps/client/src/app/components/investment-chart/investment-chart.component.ts index 7c97ff3e2..aa0ce557a 100644 --- a/apps/client/src/app/components/investment-chart/investment-chart.component.ts +++ b/apps/client/src/app/components/investment-chart/investment-chart.component.ts @@ -154,9 +154,8 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy { if (this.chartCanvas) { if (this.chart) { this.chart.data = chartData; - this.chart.options.plugins.tooltip = ( - this.getTooltipPluginConfiguration() - ); + this.chart.options.plugins.tooltip = + this.getTooltipPluginConfiguration() as unknown; if ( this.savingsRate && @@ -186,7 +185,7 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy { }, interaction: { intersect: false, mode: 'index' }, maintainAspectRatio: true, - plugins: { + plugins: { annotation: { annotations: { savingsRate: this.savingsRate @@ -227,7 +226,7 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy { verticalHoverLine: { color: `rgba(${getTextColor(this.colorScheme)}, 0.1)` } - }, + } as unknown, responsive: true, scales: { x: { @@ -294,7 +293,7 @@ export class InvestmentChartComponent implements OnChanges, OnDestroy { unit: this.isInPercent ? '%' : undefined }), mode: 'index', - position: 'top', + position: 'top' as unknown, xAlign: 'center', yAlign: 'bottom' }; diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index 88ad3c6a0..a6aa1264c 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -222,7 +222,7 @@ export class AccountsPageComponent implements OnDestroy, OnInit { private openAccountDetailDialog(aAccountId: string) { const dialogRef = this.dialog.open(AccountDetailDialog, { autoFocus: false, - data: { + data: { accountId: aAccountId, deviceType: this.deviceType, hasImpersonationId: this.hasImpersonationId, @@ -230,7 +230,7 @@ export class AccountsPageComponent implements OnDestroy, OnInit { !this.hasImpersonationId && hasPermission(this.user?.permissions, permissions.createOrder) && !this.user?.settings?.isRestrictedView - }, + } as AccountDetailDialogParams, height: this.deviceType === 'mobile' ? '98vh' : '80vh', width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index 8cab0741d..4f70993db 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -218,10 +218,10 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { public onImport() { const dialogRef = this.dialog.open(ImportActivitiesDialog, { - data: { + data: { deviceType: this.deviceType, user: this.user - }, + } as ImportActivitiesDialogParams, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); @@ -235,11 +235,11 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { public onImportDividends() { const dialogRef = this.dialog.open(ImportActivitiesDialog, { - data: { + data: { activityTypes: ['DIVIDEND'], deviceType: this.deviceType, user: this.user - }, + } as ImportActivitiesDialogParams, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 8ff0554cb..e647c54fb 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -505,7 +505,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { private openAccountDetailDialog(aAccountId: string) { const dialogRef = this.dialog.open(AccountDetailDialog, { autoFocus: false, - data: { + data: { accountId: aAccountId, deviceType: this.deviceType, hasImpersonationId: this.hasImpersonationId, @@ -513,7 +513,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { !this.hasImpersonationId && hasPermission(this.user?.permissions, permissions.createOrder) && !this.user?.settings?.isRestrictedView - }, + } as AccountDetailDialogParams, height: this.deviceType === 'mobile' ? '98vh' : '80vh', width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index b5affeb60..abf4b21a0 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -230,8 +230,8 @@ export class DataService { public fetchActivity(aActivityId: string) { return this.http.get(`/api/v1/order/${aActivityId}`).pipe( map((activity) => { - activity.createdAt = parseISO((activity.createdAt)); - activity.date = parseISO((activity.date)); + activity.createdAt = parseISO(activity.createdAt as unknown as string); + activity.date = parseISO(activity.date as unknown as string); return activity; }) @@ -387,8 +387,8 @@ export class DataService { map((data) => { if (data.orders) { for (const order of data.orders) { - order.createdAt = parseISO((order.createdAt)); - order.date = parseISO((order.date)); + order.createdAt = parseISO(order.createdAt as unknown as string); + order.date = parseISO(order.date as unknown as string); } } @@ -399,9 +399,9 @@ export class DataService { public fetchInfo(): InfoItem { const info = cloneDeep((window as any).info); - const utmSource = <'ios' | 'trusted-web-activity'>( - window.localStorage.getItem('utm_source') - ); + const utmSource = window.localStorage.getItem('utm_source') as + | 'ios' + | 'trusted-web-activity'; info.globalPermissions = filterGlobalPermissions( info.globalPermissions, @@ -715,9 +715,9 @@ export class DataService { public updateInfo() { this.http.get('/api/v1/info').subscribe((info) => { - const utmSource = <'ios' | 'trusted-web-activity'>( - window.localStorage.getItem('utm_source') - ); + const utmSource = window.localStorage.getItem('utm_source') as + | 'ios' + | 'trusted-web-activity'; info.globalPermissions = filterGlobalPermissions( info.globalPermissions, diff --git a/apps/client/src/app/services/user/user.service.ts b/apps/client/src/app/services/user/user.service.ts index a36f2a850..3ecc58c16 100644 --- a/apps/client/src/app/services/user/user.service.ts +++ b/apps/client/src/app/services/user/user.service.ts @@ -104,9 +104,9 @@ export class UserService extends ObservableStore { ) { const dialogRef = this.dialog.open(SubscriptionInterstitialDialog, { autoFocus: false, - data: { + data: { user - }, + } as SubscriptionInterstitialDialogParams, height: this.deviceType === 'mobile' ? '98vh' : '80vh', width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/apps/client/src/main.ts b/apps/client/src/main.ts index 9f89777aa..2f656ddf2 100644 --- a/apps/client/src/main.ts +++ b/apps/client/src/main.ts @@ -12,9 +12,9 @@ import { environment } from './environments/environment'; (async () => { const response = await fetch('/api/v1/info'); const info: InfoItem = await response.json(); - const utmSource = <'ios' | 'trusted-web-activity'>( - window.localStorage.getItem('utm_source') - ); + const utmSource = window.localStorage.getItem('utm_source') as + | 'ios' + | 'trusted-web-activity'; info.globalPermissions = filterGlobalPermissions( info.globalPermissions, diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 4580ef4df..fbd416bb7 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -125,14 +125,14 @@ export const PROPERTY_SLACK_COMMUNITY_USERS = 'SLACK_COMMUNITY_USERS'; export const PROPERTY_STRIPE_CONFIG = 'STRIPE_CONFIG'; export const PROPERTY_SYSTEM_MESSAGE = 'SYSTEM_MESSAGE'; -export const QUEUE_JOB_STATUS_LIST = [ +export const QUEUE_JOB_STATUS_LIST = [ 'active', 'completed', 'delayed', 'failed', 'paused', 'waiting' -]; +] as JobStatus[]; export const REPLACE_NAME_PARTS = [ 'Amundi Index Solutions -', diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index 005d3d77e..a7cf59a10 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -108,7 +108,7 @@ export function downloadAsFile({ content = JSON.stringify(content, undefined, ' '); } - const file = new Blob([content], { + const file = new Blob([content as string], { type: contentType }); a.href = URL.createObjectURL(file); diff --git a/libs/ui/src/lib/activities-filter/activities-filter.component.ts b/libs/ui/src/lib/activities-filter/activities-filter.component.ts index 6244fa5fc..a1258fc19 100644 --- a/libs/ui/src/lib/activities-filter/activities-filter.component.ts +++ b/libs/ui/src/lib/activities-filter/activities-filter.component.ts @@ -157,7 +157,7 @@ export class GfActivitiesFilterComponent implements OnChanges, OnDestroy { for (const type of Object.keys(filterGroupsMap)) { filterGroups.push({ - name: translate(type), + name: translate(type) as Filter['type'], filters: filterGroupsMap[type] }); } diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index c93d04303..d73cdb416 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -180,10 +180,10 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { debounceTime(300), distinctUntilChanged(), mergeMap(async (searchTerm) => { - const result = { + const result = { assetProfiles: [], holdings: [] - }; + } as ISearchResults; try { if (searchTerm) { diff --git a/libs/ui/src/lib/benchmark/benchmark.component.ts b/libs/ui/src/lib/benchmark/benchmark.component.ts index f2298a64c..4afd8d053 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.ts +++ b/libs/ui/src/lib/benchmark/benchmark.component.ts @@ -109,13 +109,13 @@ export class GfBenchmarkComponent implements OnChanges, OnDestroy { symbol }: AssetProfileIdentifier) { const dialogRef = this.dialog.open(GfBenchmarkDetailDialogComponent, { - data: { + data: { dataSource, symbol, colorScheme: this.user?.settings?.colorScheme, deviceType: this.deviceType, locale: this.locale - }, + } as BenchmarkDetailDialogParams, height: this.deviceType === 'mobile' ? '98vh' : undefined, width: this.deviceType === 'mobile' ? '100vw' : '50rem' }); diff --git a/libs/ui/src/lib/line-chart/line-chart.component.ts b/libs/ui/src/lib/line-chart/line-chart.component.ts index e48ead9d9..dc2df1c73 100644 --- a/libs/ui/src/lib/line-chart/line-chart.component.ts +++ b/libs/ui/src/lib/line-chart/line-chart.component.ts @@ -172,15 +172,14 @@ export class GfLineChartComponent if (this.chartCanvas) { if (this.chart) { this.chart.data = data; - this.chart.options.plugins.tooltip = ( - this.getTooltipPluginConfiguration() - ); + this.chart.options.plugins.tooltip = + this.getTooltipPluginConfiguration() as unknown; this.chart.options.animation = this.isAnimated && - { + ({ x: this.getAnimationConfigurationForAxis({ labels, axis: 'x' }), y: this.getAnimationConfigurationForAxis({ labels, axis: 'y' }) - }; + } as unknown); this.chart.update(); } else { this.chart = new Chart(this.chartCanvas.nativeElement, { @@ -188,10 +187,10 @@ export class GfLineChartComponent options: { animation: this.isAnimated && - { + ({ x: this.getAnimationConfigurationForAxis({ labels, axis: 'x' }), y: this.getAnimationConfigurationForAxis({ labels, axis: 'y' }) - }, + } as unknown), aspectRatio: 16 / 9, elements: { point: { @@ -200,7 +199,7 @@ export class GfLineChartComponent } }, interaction: { intersect: false, mode: 'index' }, - plugins: { + plugins: { legend: { align: 'start', display: this.showLegend, @@ -210,7 +209,7 @@ export class GfLineChartComponent verticalHoverLine: { color: `rgba(${getTextColor(this.colorScheme)}, 0.1)` } - }, + } as unknown, scales: { x: { border: { @@ -325,7 +324,7 @@ export class GfLineChartComponent unit: this.unit }), mode: 'index', - position: 'top', + position: 'top' as unknown, xAlign: 'center', yAlign: 'bottom' }; diff --git a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts index d3a28dffe..0eef25fa5 100644 --- a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts +++ b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -304,14 +304,14 @@ export class GfPortfolioProportionChartComponent if (this.chartCanvas) { if (this.chart) { this.chart.data = data; - this.chart.options.plugins.tooltip = ( - this.getTooltipPluginConfiguration(data) - ); + this.chart.options.plugins.tooltip = this.getTooltipPluginConfiguration( + data + ) as unknown; this.chart.update(); } else { this.chart = new Chart(this.chartCanvas.nativeElement, { data, - options: { + options: { animation: false, cutout: '70%', layout: { @@ -358,7 +358,7 @@ export class GfPortfolioProportionChartComponent legend: { display: false }, tooltip: this.getTooltipPluginConfiguration(data) } - }, + } as unknown, plugins: [ChartDataLabels], type: 'doughnut' }); @@ -405,7 +405,7 @@ export class GfPortfolioProportionChartComponent symbol = $localize`No data available`; } - const name = translate(this.positions[symbol]?.name); + const name = translate(this.positions[symbol as string]?.name); let sum = 0; for (const item of context.dataset.data) { @@ -414,12 +414,12 @@ export class GfPortfolioProportionChartComponent const percentage = (context.parsed * 100) / sum; - if (context.raw === Number.MAX_SAFE_INTEGER) { + if ((context.raw as number) === Number.MAX_SAFE_INTEGER) { return $localize`No data available`; } else if (this.isInPercent) { return [`${name ?? symbol}`, `${percentage.toFixed(2)}%`]; } else { - const value = context.raw; + const value = context.raw as number; return [ `${name ?? symbol}`, `${value.toLocaleString(this.locale, { diff --git a/libs/ui/src/lib/value/value.component.ts b/libs/ui/src/lib/value/value.component.ts index 43415e87a..06b885ff5 100644 --- a/libs/ui/src/lib/value/value.component.ts +++ b/libs/ui/src/lib/value/value.component.ts @@ -48,7 +48,7 @@ export class GfValueComponent implements OnChanges { if (isNumber(this.value)) { this.isNumber = true; this.isString = false; - this.absoluteValue = Math.abs(this.value); + this.absoluteValue = Math.abs(this.value as number); if (this.colorizeSign) { if (this.isCurrency) { @@ -113,7 +113,7 @@ export class GfValueComponent implements OnChanges { this.isString = true; if (this.isDate) { - this.formattedValue = new Date(this.value).toLocaleDateString( + this.formattedValue = new Date(this.value).toLocaleDateString( this.locale, { day: '2-digit', From 860483a013fd2293e80624c15df94442399a2e44 Mon Sep 17 00:00:00 2001 From: dw-0 Date: Sat, 26 Oct 2024 11:26:49 +0200 Subject: [PATCH 9/9] chore: revert import changes Signed-off-by: Dominik Willner --- apps/api/src/app/user/user.service.ts | 35 +++++++++---------- .../market-data/market-data.service.ts | 9 +++-- .../data-gathering.processor.ts | 6 ++-- .../portfolio-snapshot.processor.ts | 18 +++++----- .../admin-market-data.component.ts | 6 ++-- 5 files changed, 36 insertions(+), 38 deletions(-) diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 820311b5a..556d28340 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -1,3 +1,20 @@ +import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service'; +import { environment } from '@ghostfolio/api/environments/environment'; +import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; +import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/account-cluster-risk/current-investment'; +import { AccountClusterRiskSingleAccount } from '@ghostfolio/api/models/rules/account-cluster-risk/single-account'; +import { AllocationClusterRiskDevelopedMarkets } from '@ghostfolio/api/models/rules/allocation-cluster-risk/developed-markets'; +import { AllocationClusterRiskEmergingMarkets } from '@ghostfolio/api/models/rules/allocation-cluster-risk/emerging-markets'; +import { CurrencyClusterRiskBaseCurrencyCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/base-currency-current-investment'; +import { CurrencyClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/current-investment'; +import { EmergencyFundSetup } from '@ghostfolio/api/models/rules/emergency-fund/emergency-fund-setup'; +import { FeeRatioInitialInvestment } from '@ghostfolio/api/models/rules/fees/fee-ratio-initial-investment'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; +import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; +import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; +import { PropertyService } from '@ghostfolio/api/services/property/property.service'; +import { TagService } from '@ghostfolio/api/services/tag/tag.service'; import { DEFAULT_CURRENCY, DEFAULT_LANGUAGE_CODE, @@ -23,24 +40,6 @@ import { Prisma, Role, User } from '@prisma/client'; import { differenceInDays } from 'date-fns'; import { sortBy, without } from 'lodash'; -import { environment } from '../../environments/environment'; -import { PortfolioChangedEvent } from '../../events/portfolio-changed.event'; -import { AccountClusterRiskCurrentInvestment } from '../../models/rules/account-cluster-risk/current-investment'; -import { AccountClusterRiskSingleAccount } from '../../models/rules/account-cluster-risk/single-account'; -import { AllocationClusterRiskDevelopedMarkets } from '../../models/rules/allocation-cluster-risk/developed-markets'; -import { AllocationClusterRiskEmergingMarkets } from '../../models/rules/allocation-cluster-risk/emerging-markets'; -import { CurrencyClusterRiskBaseCurrencyCurrentInvestment } from '../../models/rules/currency-cluster-risk/base-currency-current-investment'; -import { CurrencyClusterRiskCurrentInvestment } from '../../models/rules/currency-cluster-risk/current-investment'; -import { EmergencyFundSetup } from '../../models/rules/emergency-fund/emergency-fund-setup'; -import { FeeRatioInitialInvestment } from '../../models/rules/fees/fee-ratio-initial-investment'; -import { ConfigurationService } from '../../services/configuration/configuration.service'; -import { I18nService } from '../../services/i18n/i18n.service'; -import { PrismaService } from '../../services/prisma/prisma.service'; -import { PropertyService } from '../../services/property/property.service'; -import { TagService } from '../../services/tag/tag.service'; -import { OrderService } from '../order/order.service'; -import { SubscriptionService } from '../subscription/subscription.service'; - const crypto = require('crypto'); @Injectable() diff --git a/apps/api/src/services/market-data/market-data.service.ts b/apps/api/src/services/market-data/market-data.service.ts index c754055f5..c0abdf04e 100644 --- a/apps/api/src/services/market-data/market-data.service.ts +++ b/apps/api/src/services/market-data/market-data.service.ts @@ -1,3 +1,7 @@ +import { UpdateMarketDataDto } from '@ghostfolio/api/app/admin/update-market-data.dto'; +import { DateQuery } from '@ghostfolio/api/app/portfolio/interfaces/date-query.interface'; +import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; +import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { resetHours } from '@ghostfolio/common/helper'; import { AssetProfileIdentifier } from '@ghostfolio/common/interfaces'; @@ -9,11 +13,6 @@ import { Prisma } from '@prisma/client'; -import { UpdateMarketDataDto } from '../../app/admin/update-market-data.dto'; -import { DateQuery } from '../../app/portfolio/interfaces/date-query.interface'; -import { IDataGatheringItem } from '../interfaces/interfaces'; -import { PrismaService } from '../prisma/prisma.service'; - @Injectable() export class MarketDataService { public constructor(private readonly prismaService: PrismaService) {} diff --git a/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts b/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts index 28cf43df9..dc8cc5996 100644 --- a/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts +++ b/apps/api/src/services/queues/data-gathering/data-gathering.processor.ts @@ -1,3 +1,6 @@ +import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; +import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; +import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import { DATA_GATHERING_QUEUE, DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY, @@ -22,9 +25,6 @@ import { parseISO } from 'date-fns'; -import { DataProviderService } from '../../data-provider/data-provider.service'; -import { IDataGatheringItem } from '../../interfaces/interfaces'; -import { MarketDataService } from '../../market-data/market-data.service'; import { DataGatheringService } from './data-gathering.service'; @Injectable() diff --git a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts index 94220d5f5..a5a9a37e0 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.processor.ts @@ -1,3 +1,12 @@ +import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; +import { OrderService } from '@ghostfolio/api/app/order/order.service'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { CACHE_TTL_INFINITE, DEFAULT_PROCESSOR_PORTFOLIO_SNAPSHOT_COMPUTATION_CONCURRENCY, @@ -10,15 +19,6 @@ import { Injectable, Logger } from '@nestjs/common'; import { Job } from 'bull'; import { addMilliseconds } from 'date-fns'; -import { AccountBalanceService } from '../../../app/account-balance/account-balance.service'; -import { OrderService } from '../../../app/order/order.service'; -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '../../../app/portfolio/calculator/portfolio-calculator.factory'; -import { PortfolioSnapshotValue } from '../../../app/portfolio/interfaces/snapshot-value.interface'; -import { RedisCacheService } from '../../../app/redis-cache/redis-cache.service'; -import { ConfigurationService } from '../../configuration/configuration.service'; import { IPortfolioSnapshotQueueJob } from './interfaces/portfolio-snapshot-queue-job.interface'; @Injectable() diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 5483fdb07..5eb869694 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -1,3 +1,6 @@ +import { AdminService } from '@ghostfolio/client/services/admin.service'; +import { DataService } from '@ghostfolio/client/services/data.service'; +import { UserService } from '@ghostfolio/client/services/user/user.service'; import { DEFAULT_PAGE_SIZE, ghostfolioScraperApiSymbolPrefix @@ -34,9 +37,6 @@ import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject } from 'rxjs'; import { distinctUntilChanged, switchMap, takeUntil } from 'rxjs/operators'; -import { AdminService } from '../../services/admin.service'; -import { DataService } from '../../services/data.service'; -import { UserService } from '../../services/user/user.service'; import { AdminMarketDataService } from './admin-market-data.service'; import { AssetProfileDialog } from './asset-profile-dialog/asset-profile-dialog.component'; import { AssetProfileDialogParams } from './asset-profile-dialog/interfaces/interfaces';