diff --git a/.eslintrc.json b/.eslintrc.json index 79d34dd06..758dbe6e1 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -142,8 +142,7 @@ // 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-indexed-object-style": "warn" + "@typescript-eslint/prefer-nullish-coalescing": "warn" // TODO: Requires strictNullChecks: true } } ], diff --git a/CHANGELOG.md b/CHANGELOG.md index ebe6c2f16..7e8325fdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Switched the `consistent-type-assertions` rule from `warn` to `error` in the `eslint` configuration - Switched the `prefer-optional-chain` rule from `warn` to `error` in the `eslint` configuration - Switched the `consistent-generic-constructors` rule from `warn` to `error` in the `eslint` configuration +- Switched the `consistent-indexed-object-style` rule from `warn` to `error` in the `eslint` configuration ### Fixed 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 34d98d266..1a4fb66f7 100644 --- a/apps/api/src/app/account-balance/account-balance.service.ts +++ b/apps/api/src/app/account-balance/account-balance.service.ts @@ -110,9 +110,8 @@ export class AccountBalanceService { userId, withExcludedAccounts: false // TODO }); - const accumulatedBalancesByDate: { [date: string]: HistoricalDataItem } = - {}; - const lastBalancesByAccount: { [accountId: string]: Big } = {}; + const accumulatedBalancesByDate: Record = {}; + const lastBalancesByAccount: Record = {}; for (const { accountId, date, valueInBaseCurrency } of balances) { const formattedDate = format(date, DATE_FORMAT); diff --git a/apps/api/src/app/admin/update-asset-profile.dto.ts b/apps/api/src/app/admin/update-asset-profile.dto.ts index 8c9ae220b..3c4cf3025 100644 --- a/apps/api/src/app/admin/update-asset-profile.dto.ts +++ b/apps/api/src/app/admin/update-asset-profile.dto.ts @@ -45,9 +45,7 @@ export class UpdateAssetProfileDto { @IsObject() @IsOptional() - symbolMapping?: { - [dataProvider: string]: string; - }; + symbolMapping?: Record; @IsOptional() @IsUrl({ diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 30415970d..fef37ca3d 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -158,7 +158,7 @@ export class ImportService { maxActivitiesToImport: number; user: UserWithSettings; }): Promise { - const accountIdMapping: { [oldAccountId: string]: string } = {}; + const accountIdMapping: Record = {}; const userCurrency = user.Settings.settings.baseCurrency; if (!isDryRun && accountsDto?.length) { @@ -579,9 +579,7 @@ export class ImportService { throw new Error(`Too many activities (${maxActivitiesToImport} at most)`); } - const assetProfiles: { - [assetProfileIdentifier: string]: Partial; - } = {}; + const assetProfiles: Record> = {}; for (const [ index, diff --git a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts index e54f63422..b57fda86c 100644 --- a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts @@ -12,10 +12,8 @@ export class MWRPortfolioCalculator extends PortfolioCalculator { protected getSymbolMetrics({}: { end: Date; - exchangeRates: { [dateString: string]: number }; - marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - }; + exchangeRates: Record; + marketSymbolMap: Record>; start: Date; step?: number; } & AssetProfileIdentifier): SymbolMetrics { diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index dec0e6387..c772a5f95 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -1,16 +1,3 @@ -import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; -import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; -import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; -import { PortfolioSnapshotValue } from '@ghostfolio/api/app/portfolio/interfaces/snapshot-value.interface'; -import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; -import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; -import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; -import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; -import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; -import { PortfolioSnapshotService } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.service'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; import { PORTFOLIO_SNAPSHOT_PROCESS_JOB_NAME, @@ -51,6 +38,20 @@ import { } from 'date-fns'; import { first, isNumber, last, sortBy, sum, uniq, uniqBy } from 'lodash'; +import { getFactor } from '../../../helper/portfolio.helper'; +import { LogPerformance } from '../../../interceptors/performance-logging/performance-logging.interceptor'; +import { ConfigurationService } from '../../../services/configuration/configuration.service'; +import { ExchangeRateDataService } from '../../../services/exchange-rate-data/exchange-rate-data.service'; +import { IDataGatheringItem } from '../../../services/interfaces/interfaces'; +import { PortfolioSnapshotService } from '../../../services/queues/portfolio-snapshot/portfolio-snapshot.service'; +import { Activity } from '../../order/interfaces/activities.interface'; +import { RedisCacheService } from '../../redis-cache/redis-cache.service'; +import { CurrentRateService } from '../current-rate.service'; +import { PortfolioOrder } from '../interfaces/portfolio-order.interface'; +import { PortfolioSnapshotValue } from '../interfaces/snapshot-value.interface'; +import { TransactionPointSymbol } from '../interfaces/transaction-point-symbol.interface'; +import { TransactionPoint } from '../interfaces/transaction-point.interface'; + export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -188,7 +189,7 @@ export abstract class PortfolioCalculator { }; } - const currencies: { [symbol: string]: string } = {}; + const currencies: Record = {}; const dataGatheringItems: IDataGatheringItem[] = []; let firstIndex = transactionPoints.length; let firstTransactionPoint: TransactionPoint = null; @@ -239,9 +240,7 @@ export abstract class PortfolioCalculator { this.dataProviderInfos = dataProviderInfos; - const marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - } = {}; + const marketSymbolMap: Record> = {}; for (const marketSymbol of marketSymbols) { const date = format(marketSymbol.date, DATE_FORMAT); @@ -290,8 +289,9 @@ export abstract class PortfolioCalculator { const errors: ResponseError['errors'] = []; - const accumulatedValuesByDate: { - [date: string]: { + const accumulatedValuesByDate: Record< + string, + { investmentValueWithCurrencyEffect: Big; totalAccountBalanceWithCurrencyEffect: Big; totalCurrentValue: Big; @@ -302,22 +302,23 @@ export abstract class PortfolioCalculator { totalNetPerformanceValueWithCurrencyEffect: Big; totalTimeWeightedInvestmentValue: Big; totalTimeWeightedInvestmentValueWithCurrencyEffect: Big; - }; - } = {}; - - const valuesBySymbol: { - [symbol: string]: { - currentValues: { [date: string]: Big }; - currentValuesWithCurrencyEffect: { [date: string]: Big }; - investmentValuesAccumulated: { [date: string]: Big }; - investmentValuesAccumulatedWithCurrencyEffect: { [date: string]: Big }; - investmentValuesWithCurrencyEffect: { [date: string]: Big }; - netPerformanceValues: { [date: string]: Big }; - netPerformanceValuesWithCurrencyEffect: { [date: string]: Big }; - timeWeightedInvestmentValues: { [date: string]: Big }; - timeWeightedInvestmentValuesWithCurrencyEffect: { [date: string]: Big }; - }; - } = {}; + } + > = {}; + + const valuesBySymbol: Record< + string, + { + currentValues: Record; + currentValuesWithCurrencyEffect: Record; + investmentValuesAccumulated: Record; + investmentValuesAccumulatedWithCurrencyEffect: Record; + investmentValuesWithCurrencyEffect: Record; + netPerformanceValues: Record; + netPerformanceValuesWithCurrencyEffect: Record; + timeWeightedInvestmentValues: Record; + timeWeightedInvestmentValuesWithCurrencyEffect: Record; + } + > = {}; for (const item of lastTransactionPoint.items) { const feeInBaseCurrency = item.fee.mul( @@ -461,10 +462,10 @@ export abstract class PortfolioCalculator { return map; }, - {} as { [date: string]: Big } + {} as Record ); - const accountBalanceMap: { [date: string]: Big } = {}; + const accountBalanceMap: Record = {}; let lastKnownBalance = new Big(0); @@ -670,7 +671,7 @@ export abstract class PortfolioCalculator { data: HistoricalDataItem[]; groupBy: GroupBy; }): InvestmentItem[] { - const groupedData: { [dateGroup: string]: Big } = {}; + const groupedData: Record = {}; for (const { date, investmentValueWithCurrencyEffect } of data) { const dateGroup = @@ -802,12 +803,10 @@ export abstract class PortfolioCalculator { start, symbol }: { - chartDateMap: { [date: string]: boolean }; + chartDateMap: Record; end: Date; - exchangeRates: { [dateString: string]: number }; - marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - }; + exchangeRates: Record; + marketSymbolMap: Record>; start: Date; } & AssetProfileIdentifier): SymbolMetrics; @@ -829,7 +828,7 @@ export abstract class PortfolioCalculator { endDate: Date; startDate: Date; step: number; - }): { [date: string]: true } { + }): Record { // Create a map of all relevant chart dates: // 1. Add transaction point dates const chartDateMap = this.transactionPoints.reduce((result, { date }) => { @@ -892,7 +891,7 @@ export abstract class PortfolioCalculator { @LogPerformance private computeTransactionPoints() { this.transactionPoints = []; - const symbols: { [symbol: string]: TransactionPointSymbol } = {}; + const symbols: Record = {}; let lastDate: string = null; let lastTransactionPoint: TransactionPoint = null; 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 6c0d230b0..66d4cdfac 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -1,6 +1,3 @@ -import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; -import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order-item.interface'; -import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { @@ -15,6 +12,10 @@ import { Big } from 'big.js'; import { addMilliseconds, differenceInDays, format, isBefore } from 'date-fns'; import { cloneDeep, first, last, sortBy } from 'lodash'; +import { getFactor } from '../../../../helper/portfolio.helper'; +import { PortfolioOrderItem } from '../../interfaces/portfolio-order-item.interface'; +import { PortfolioCalculator } from '../portfolio-calculator'; + export class TWRPortfolioCalculator extends PortfolioCalculator { private chartDates: string[]; @@ -116,17 +117,15 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { start, symbol }: { - chartDateMap?: { [date: string]: boolean }; + chartDateMap?: Record; end: Date; - exchangeRates: { [dateString: string]: number }; - marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - }; + exchangeRates: Record; + marketSymbolMap: Record>; start: Date; } & AssetProfileIdentifier): SymbolMetrics { const currentExchangeRate = exchangeRates[format(new Date(), DATE_FORMAT)]; - const currentValues: { [date: string]: Big } = {}; - const currentValuesWithCurrencyEffect: { [date: string]: Big } = {}; + const currentValues: Record = {}; + const currentValuesWithCurrencyEffect: Record = {}; let fees = new Big(0); let feesAtStartDate = new Big(0); let feesAtStartDateWithCurrencyEffect = new Big(0); @@ -141,20 +140,18 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let initialValueWithCurrencyEffect: Big; let investmentAtStartDate: Big; let investmentAtStartDateWithCurrencyEffect: Big; - const investmentValuesAccumulated: { [date: string]: Big } = {}; - const investmentValuesAccumulatedWithCurrencyEffect: { - [date: string]: Big; - } = {}; - const investmentValuesWithCurrencyEffect: { [date: string]: Big } = {}; + const investmentValuesAccumulated: Record = {}; + const investmentValuesAccumulatedWithCurrencyEffect: Record = + {}; + const investmentValuesWithCurrencyEffect: Record = {}; let lastAveragePrice = new Big(0); let lastAveragePriceWithCurrencyEffect = new Big(0); - const netPerformanceValues: { [date: string]: Big } = {}; - const netPerformanceValuesWithCurrencyEffect: { [date: string]: Big } = {}; - const timeWeightedInvestmentValues: { [date: string]: Big } = {}; + const netPerformanceValues: Record = {}; + const netPerformanceValuesWithCurrencyEffect: Record = {}; + const timeWeightedInvestmentValues: Record = {}; - const timeWeightedInvestmentValuesWithCurrencyEffect: { - [date: string]: Big; - } = {}; + const timeWeightedInvestmentValuesWithCurrencyEffect: Record = + {}; const totalAccountBalanceInBaseCurrency = new Big(0); let totalDividend = new Big(0); @@ -301,7 +298,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let lastUnitPrice: Big; - const ordersByDate: { [date: string]: PortfolioOrderItem[] } = {}; + const ordersByDate: Record = {}; for (const order of orders) { ordersByDate[order.date] = ordersByDate[order.date] ?? []; @@ -788,13 +785,12 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { ) : new Big(0); - const netPerformancePercentageWithCurrencyEffectMap: { - [key: DateRange]: Big; - } = {}; + const netPerformancePercentageWithCurrencyEffectMap: Record< + DateRange, + Big + > = {}; - const netPerformanceWithCurrencyEffectMap: { - [key: DateRange]: Big; - } = {}; + const netPerformanceWithCurrencyEffectMap: Record = {}; for (const dateRange of [ '1d', diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index b93ad172b..24ffdcb57 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -423,12 +423,12 @@ export class PortfolioService { const symbolProfiles = await this.symbolProfileService.getSymbolProfiles(dataGatheringItems); - const symbolProfileMap: { [symbol: string]: EnhancedSymbolProfile } = {}; + const symbolProfileMap: Record = {}; for (const symbolProfile of symbolProfiles) { symbolProfileMap[symbolProfile.symbol] = symbolProfile; } - const portfolioItemsNow: { [symbol: string]: TimelinePosition } = {}; + const portfolioItemsNow: Record = {}; for (const position of positions) { portfolioItemsNow[position.symbol] = position; } @@ -969,7 +969,7 @@ export class PortfolioService { ) ]); - const symbolProfileMap: { [symbol: string]: EnhancedSymbolProfile } = {}; + const symbolProfileMap: Record = {}; for (const symbolProfile of symbolProfiles) { symbolProfileMap[symbolProfile.symbol] = symbolProfile; diff --git a/apps/api/src/app/symbol/symbol.service.ts b/apps/api/src/app/symbol/symbol.service.ts index 2baca18dd..46ea90c70 100644 --- a/apps/api/src/app/symbol/symbol.service.ts +++ b/apps/api/src/app/symbol/symbol.service.ts @@ -74,11 +74,10 @@ export class SymbolService { date = new Date(), symbol }: IDataGatheringItem): Promise { - let historicalData: { - [symbol: string]: { - [date: string]: IDataProviderHistoricalResponse; - }; - } = { + let historicalData: Record< + string, + Record + > = { [symbol]: {} }; diff --git a/apps/api/src/helper/object.helper.ts b/apps/api/src/helper/object.helper.ts index a5854e9d9..27ae29f88 100644 --- a/apps/api/src/helper/object.helper.ts +++ b/apps/api/src/helper/object.helper.ts @@ -38,7 +38,7 @@ export function redactAttributes({ }: { isFirstRun?: boolean; object: any; - options: { attribute: string; valueMap: { [key: string]: any } }[]; + options: { attribute: string; valueMap: Record }[]; }): any { if (!object || !options?.length) { return object; diff --git a/apps/api/src/middlewares/html-template.middleware.ts b/apps/api/src/middlewares/html-template.middleware.ts index 7b7cb09f2..5df90d56c 100644 --- a/apps/api/src/middlewares/html-template.middleware.ts +++ b/apps/api/src/middlewares/html-template.middleware.ts @@ -14,7 +14,7 @@ import { join } from 'path'; const i18nService = new I18nService(); -let indexHtmlMap: { [languageCode: string]: string } = {}; +let indexHtmlMap: Record = {}; const title = 'Ghostfolio'; diff --git a/apps/api/src/models/interfaces/portfolio.interface.ts b/apps/api/src/models/interfaces/portfolio.interface.ts index b369202cd..b94e334c2 100644 --- a/apps/api/src/models/interfaces/portfolio.interface.ts +++ b/apps/api/src/models/interfaces/portfolio.interface.ts @@ -7,9 +7,7 @@ export interface PortfolioInterface { getFees(): number; - getPositions(aDate: Date): { - [symbol: string]: Position; - }; + getPositions(aDate: Date): Record; getSymbols(aDate?: Date): string[]; diff --git a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts index 564af935d..d451831f5 100644 --- a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts @@ -23,11 +23,12 @@ export class AccountClusterRiskCurrentInvestment extends Rule { } public evaluate(ruleSettings: Settings) { - const accounts: { - [symbol: string]: Pick & { + const accounts: Record< + string, + Pick & { investment: number; - }; - } = {}; + } + > = {}; for (const [accountId, account] of Object.entries(this.accounts)) { accounts[accountId] = { diff --git a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts index 016584949..ce3e6c76a 100644 --- a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts +++ b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts @@ -64,20 +64,20 @@ export class AlphaVantageService implements DataProviderInterface { from, symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { try { - const historicalData: { - [symbol: string]: IAlphaVantageHistoricalResponse[]; - } = await this.alphaVantage.crypto.daily( - symbol.substring(0, symbol.length - 3).toLowerCase(), - 'usd' - ); + const historicalData: Record = + await this.alphaVantage.crypto.daily( + symbol.substring(0, symbol.length - 3).toLowerCase(), + 'usd' + ); - const response: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - } = {}; + const response: Record< + string, + Record + > = {}; response[symbol] = {}; @@ -109,9 +109,9 @@ export class AlphaVantageService implements DataProviderInterface { return DataSource.ALPHA_VANTAGE; } - public async getQuotes({}: GetQuotesParams): Promise<{ - [symbol: string]: IDataProviderResponse; - }> { + public async getQuotes({}: GetQuotesParams): Promise< + Record + > { return {}; } diff --git a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts index d420c51fd..f1d4cbaea 100644 --- a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts +++ b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts @@ -1,16 +1,3 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { - DataProviderInterface, - GetDividendsParams, - GetHistoricalParams, - GetQuotesParams, - GetSearchParams -} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DataProviderInfo } from '@ghostfolio/common/interfaces'; @@ -25,6 +12,20 @@ import { import { format, fromUnixTime, getUnixTime } from 'date-fns'; import got, { Headers } from 'got'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { ConfigurationService } from '../../configuration/configuration.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; +import { + DataProviderInterface, + GetDividendsParams, + GetHistoricalParams, + GetQuotesParams, + GetSearchParams +} from '../interfaces/data-provider.interface'; + @Injectable() export class CoinGeckoService implements DataProviderInterface { private readonly apiUrl: string; @@ -111,9 +112,9 @@ export class CoinGeckoService implements DataProviderInterface { requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { try { const abortController = new AbortController(); @@ -134,9 +135,10 @@ export class CoinGeckoService implements DataProviderInterface { } ).json(); - const result: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - } = { + const result: Record< + string, + Record + > = { [symbol]: {} }; @@ -168,8 +170,8 @@ export class CoinGeckoService implements DataProviderInterface { public async getQuotes({ requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> { - const response: { [symbol: string]: IDataProviderResponse } = {}; + }: GetQuotesParams): Promise> { + const response: Record = {}; if (symbols.length <= 0) { return response; diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 385c7b078..b0448f639 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -1,14 +1,3 @@ -import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; -import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; -import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; -import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { DEFAULT_CURRENCY, DERIVED_CURRENCIES, @@ -30,9 +19,21 @@ import { eachDayOfInterval, format, isValid } from 'date-fns'; import { groupBy, isEmpty, isNumber, uniqWith } from 'lodash'; import ms from 'ms'; +import { RedisCacheService } from '../../app/redis-cache/redis-cache.service'; +import { LookupItem } from '../../app/symbol/interfaces/lookup-item.interface'; +import { ConfigurationService } from '../configuration/configuration.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../interfaces/interfaces'; +import { MarketDataService } from '../market-data/market-data.service'; +import { PrismaService } from '../prisma/prisma.service'; +import { PropertyService } from '../property/property.service'; +import { DataProviderInterface } from './interfaces/data-provider.interface'; + @Injectable() export class DataProviderService { - private dataProviderMapping: { [dataProviderName: string]: string }; + private dataProviderMapping: Record; public constructor( private readonly configurationService: ConfigurationService, @@ -48,9 +49,9 @@ export class DataProviderService { public async initialize() { this.dataProviderMapping = - ((await this.propertyService.getByKey(PROPERTY_DATA_SOURCE_MAPPING)) as { - [dataProviderName: string]: string; - }) ?? {}; + ((await this.propertyService.getByKey( + PROPERTY_DATA_SOURCE_MAPPING + )) as Record) ?? {}; } public async checkQuote(dataSource: DataSource) { @@ -75,12 +76,10 @@ export class DataProviderService { return false; } - public async getAssetProfiles(items: AssetProfileIdentifier[]): Promise<{ - [symbol: string]: Partial; - }> { - const response: { - [symbol: string]: Partial; - } = {}; + public async getAssetProfiles( + items: AssetProfileIdentifier[] + ): Promise>> { + const response: Record> = {}; const itemsGroupedByDataSource = groupBy(items, ({ dataSource }) => { return dataSource; @@ -177,12 +176,11 @@ export class DataProviderService { aGranularity: Granularity = 'month', from: Date, to: Date - ): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { - let response: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - } = {}; + ): Promise>> { + let response: Record< + string, + Record + > = {}; if (isEmpty(aItems) || !isValid(from) || !isValid(to)) { return response; @@ -246,9 +244,7 @@ export class DataProviderService { dataGatheringItems: AssetProfileIdentifier[]; from: Date; to: Date; - }): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }): Promise>> { for (const { currency, rootCurrency } of DERIVED_CURRENCIES) { if ( this.hasCurrency({ @@ -272,21 +268,20 @@ export class DataProviderService { return obj1.dataSource === obj2.dataSource && obj1.symbol === obj2.symbol; }); - const result: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - } = {}; + const result: Record< + string, + Record + > = {}; const promises: Promise<{ - data: { [date: string]: IDataProviderHistoricalResponse }; + data: Record; symbol: string; }>[] = []; for (const { dataSource, symbol } of dataGatheringItems) { const dataProvider = this.getDataProvider(dataSource); if (dataProvider.canHandle(symbol)) { if (symbol === `${DEFAULT_CURRENCY}USX`) { - const data: { - [date: string]: IDataProviderHistoricalResponse; - } = {}; + const data: Record = {}; for (const date of eachDayOfInterval({ end: to, start: from })) { data[format(date, DATE_FORMAT)] = { marketPrice: 100 }; @@ -354,12 +349,8 @@ export class DataProviderService { requestTimeout?: number; useCache?: boolean; user?: UserWithSettings; - }): Promise<{ - [symbol: string]: IDataProviderResponse; - }> { - const response: { - [symbol: string]: IDataProviderResponse; - } = {}; + }): Promise> { + const response: Record = {}; const startTimeTotal = performance.now(); if ( @@ -651,9 +642,7 @@ export class DataProviderService { factor }: { allData: { - data: { - [date: string]: IDataProviderHistoricalResponse; - }; + data: Record; symbol: string; }[]; currency: string; @@ -663,9 +652,7 @@ export class DataProviderService { return symbol === currency; })?.data; - const data: { - [date: string]: IDataProviderHistoricalResponse; - } = {}; + const data: Record = {}; for (const date in rootData) { if (isNumber(rootData[date].marketPrice)) { diff --git a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts index c3c948b47..99af685e6 100644 --- a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts +++ b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts @@ -1,17 +1,3 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { - DataProviderInterface, - GetDividendsParams, - GetHistoricalParams, - GetQuotesParams, - GetSearchParams -} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; -import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DEFAULT_CURRENCY, REPLACE_NAME_PARTS @@ -31,6 +17,21 @@ import { addDays, format, isSameDay, isToday } from 'date-fns'; import got from 'got'; import { isNumber } from 'lodash'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { ConfigurationService } from '../../configuration/configuration.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; +import { SymbolProfileService } from '../../symbol-profile/symbol-profile.service'; +import { + DataProviderInterface, + GetDividendsParams, + GetHistoricalParams, + GetQuotesParams, + GetSearchParams +} from '../interfaces/data-provider.interface'; + @Injectable() export class EodHistoricalDataService implements DataProviderInterface { private apiKey: string; @@ -78,9 +79,9 @@ export class EodHistoricalDataService implements DataProviderInterface { requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), symbol, to - }: GetDividendsParams): Promise<{ - [date: string]: IDataProviderHistoricalResponse; - }> { + }: GetDividendsParams): Promise< + Record + > { symbol = this.convertToEodSymbol(symbol); if (isSameDay(from, to)) { @@ -90,9 +91,7 @@ export class EodHistoricalDataService implements DataProviderInterface { try { const abortController = new AbortController(); - const response: { - [date: string]: IDataProviderHistoricalResponse; - } = {}; + const response: Record = {}; setTimeout(() => { abortController.abort(); @@ -137,9 +136,9 @@ export class EodHistoricalDataService implements DataProviderInterface { requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { symbol = this.convertToEodSymbol(symbol); try { @@ -202,8 +201,8 @@ export class EodHistoricalDataService implements DataProviderInterface { public async getQuotes({ requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> { - const response: { [symbol: string]: IDataProviderResponse } = {}; + }: GetQuotesParams): Promise> { + const response: Record = {}; if (symbols.length <= 0) { return response; diff --git a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts index 7d5b38479..e3a098b88 100644 --- a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts +++ b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts @@ -1,16 +1,3 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { - DataProviderInterface, - GetDividendsParams, - GetHistoricalParams, - GetQuotesParams, - GetSearchParams -} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; import { DataProviderInfo } from '@ghostfolio/common/interfaces'; @@ -20,6 +7,20 @@ import { DataSource, SymbolProfile } from '@prisma/client'; import { format, isAfter, isBefore, isSameDay } from 'date-fns'; import got from 'got'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { ConfigurationService } from '../../configuration/configuration.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; +import { + DataProviderInterface, + GetDividendsParams, + GetHistoricalParams, + GetQuotesParams, + GetSearchParams +} from '../interfaces/data-provider.interface'; + @Injectable() export class FinancialModelingPrepService implements DataProviderInterface { private apiKey: string; @@ -65,9 +66,9 @@ export class FinancialModelingPrepService implements DataProviderInterface { requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { try { const abortController = new AbortController(); @@ -83,9 +84,10 @@ export class FinancialModelingPrepService implements DataProviderInterface { } ).json(); - const result: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - } = { + const result: Record< + string, + Record + > = { [symbol]: {} }; @@ -119,8 +121,8 @@ export class FinancialModelingPrepService implements DataProviderInterface { public async getQuotes({ requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> { - const response: { [symbol: string]: IDataProviderResponse } = {}; + }: GetQuotesParams): Promise> { + const response: Record = {}; if (symbols.length <= 0) { return response; diff --git a/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts b/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts index 9f2344233..1db5f3b36 100644 --- a/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts +++ b/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts @@ -1,18 +1,3 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { - DataProviderInterface, - GetDividendsParams, - GetHistoricalParams, - GetQuotesParams, - GetSearchParams -} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; -import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; -import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DATE_FORMAT, parseDate } from '@ghostfolio/common/helper'; import { DataProviderInfo } from '@ghostfolio/common/interfaces'; @@ -21,6 +6,22 @@ import { DataSource, SymbolProfile } from '@prisma/client'; import { format } from 'date-fns'; import { GoogleSpreadsheet } from 'google-spreadsheet'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { ConfigurationService } from '../../configuration/configuration.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; +import { PrismaService } from '../../prisma/prisma.service'; +import { SymbolProfileService } from '../../symbol-profile/symbol-profile.service'; +import { + DataProviderInterface, + GetDividendsParams, + GetHistoricalParams, + GetQuotesParams, + GetSearchParams +} from '../interfaces/data-provider.interface'; + @Injectable() export class GoogleSheetsService implements DataProviderInterface { public constructor( @@ -60,9 +61,9 @@ export class GoogleSheetsService implements DataProviderInterface { from, symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { try { const sheet = await this.getSheet({ symbol, @@ -71,9 +72,8 @@ export class GoogleSheetsService implements DataProviderInterface { const rows = await sheet.getRows(); - const historicalData: { - [date: string]: IDataProviderHistoricalResponse; - } = {}; + const historicalData: Record = + {}; rows .filter((_row, index) => { @@ -105,8 +105,8 @@ export class GoogleSheetsService implements DataProviderInterface { public async getQuotes({ symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> { - const response: { [symbol: string]: IDataProviderResponse } = {}; + }: GetQuotesParams): Promise> { + const response: Record = {}; if (symbols.length <= 0) { return response; diff --git a/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts b/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts index 3b3644473..ca37e8ed9 100644 --- a/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts +++ b/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts @@ -1,13 +1,14 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; import { DataProviderInfo } from '@ghostfolio/common/interfaces'; import { Granularity } from '@ghostfolio/common/types'; import { DataSource, SymbolProfile } from '@prisma/client'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; + export interface DataProviderInterface { canHandle(symbol: string): boolean; @@ -19,9 +20,14 @@ export interface DataProviderInterface { getDataProviderInfo(): DataProviderInfo; - getDividends({ from, granularity, symbol, to }: GetDividendsParams): Promise<{ - [date: string]: IDataProviderHistoricalResponse; - }>; + getDividends({ + from, + granularity, + symbol, + to + }: GetDividendsParams): Promise< + Record + >; getHistorical({ from, @@ -29,9 +35,9 @@ export interface DataProviderInterface { requestTimeout, symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }>; // TODO: Return only one symbol + }: GetHistoricalParams): Promise< + Record> + >; // TODO: Return only one symbol getMaxNumberOfSymbolsPerRequest?(): number; @@ -40,7 +46,7 @@ export interface DataProviderInterface { getQuotes({ requestTimeout, symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }>; + }: GetQuotesParams): Promise>; getTestSymbol(): string; diff --git a/apps/api/src/services/data-provider/manual/manual.service.ts b/apps/api/src/services/data-provider/manual/manual.service.ts index 030ab8ea2..eeea75f61 100644 --- a/apps/api/src/services/data-provider/manual/manual.service.ts +++ b/apps/api/src/services/data-provider/manual/manual.service.ts @@ -1,18 +1,3 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { - DataProviderInterface, - GetDividendsParams, - GetHistoricalParams, - GetQuotesParams, - GetSearchParams -} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; -import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; -import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DATE_FORMAT, extractNumberFromString, @@ -31,6 +16,22 @@ import { addDays, format, isBefore } from 'date-fns'; import got, { Headers } from 'got'; import jsonpath from 'jsonpath'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { ConfigurationService } from '../../configuration/configuration.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; +import { PrismaService } from '../../prisma/prisma.service'; +import { SymbolProfileService } from '../../symbol-profile/symbol-profile.service'; +import { + DataProviderInterface, + GetDividendsParams, + GetHistoricalParams, + GetQuotesParams, + GetSearchParams +} from '../interfaces/data-provider.interface'; + @Injectable() export class ManualService implements DataProviderInterface { public constructor( @@ -79,9 +80,9 @@ export class ManualService implements DataProviderInterface { from, symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { try { const [symbolProfile] = await this.symbolProfileService.getSymbolProfiles( [{ symbol, dataSource: this.getName() }] @@ -90,9 +91,10 @@ export class ManualService implements DataProviderInterface { symbolProfile?.scraperConfiguration ?? {}; if (defaultMarketPrice) { - const historical: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - } = { + const historical: Record< + string, + Record + > = { [symbol]: {} }; let date = from; @@ -135,8 +137,8 @@ export class ManualService implements DataProviderInterface { public async getQuotes({ symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> { - const response: { [symbol: string]: IDataProviderResponse } = {}; + }: GetQuotesParams): Promise> { + const response: Record = {}; if (symbols.length <= 0) { return response; diff --git a/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts b/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts index e47e96d88..bb929a68a 100644 --- a/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts +++ b/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts @@ -1,16 +1,3 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { - DataProviderInterface, - GetDividendsParams, - GetHistoricalParams, - GetQuotesParams, - GetSearchParams -} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; import { ghostfolioFearAndGreedIndexSymbol } from '@ghostfolio/common/config'; import { DATE_FORMAT, getYesterday } from '@ghostfolio/common/helper'; import { DataProviderInfo } from '@ghostfolio/common/interfaces'; @@ -20,6 +7,20 @@ import { DataSource, SymbolProfile } from '@prisma/client'; import { format } from 'date-fns'; import got from 'got'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { ConfigurationService } from '../../configuration/configuration.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; +import { + DataProviderInterface, + GetDividendsParams, + GetHistoricalParams, + GetQuotesParams, + GetSearchParams +} from '../interfaces/data-provider.interface'; + @Injectable() export class RapidApiService implements DataProviderInterface { public constructor( @@ -57,9 +58,9 @@ export class RapidApiService implements DataProviderInterface { from, symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { try { if (symbol === ghostfolioFearAndGreedIndexSymbol) { const fgi = await this.getFearAndGreedIndex(); @@ -90,7 +91,7 @@ export class RapidApiService implements DataProviderInterface { public async getQuotes({ symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> { + }: GetQuotesParams): Promise> { if (symbols.length <= 0) { return {}; } diff --git a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts index 2d67c646c..855721932 100644 --- a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts @@ -1,17 +1,3 @@ -import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; -import { CryptocurrencyService } from '@ghostfolio/api/services/cryptocurrency/cryptocurrency.service'; -import { YahooFinanceDataEnhancerService } from '@ghostfolio/api/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service'; -import { - DataProviderInterface, - GetDividendsParams, - GetHistoricalParams, - GetQuotesParams, - GetSearchParams -} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; -import { - IDataProviderHistoricalResponse, - IDataProviderResponse -} from '@ghostfolio/api/services/interfaces/interfaces'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { DataProviderInfo } from '@ghostfolio/common/interfaces'; @@ -27,6 +13,21 @@ import { } from 'yahoo-finance2/dist/esm/src/modules/historical'; import { Quote } from 'yahoo-finance2/dist/esm/src/modules/quote'; +import { LookupItem } from '../../../app/symbol/interfaces/lookup-item.interface'; +import { CryptocurrencyService } from '../../cryptocurrency/cryptocurrency.service'; +import { + IDataProviderHistoricalResponse, + IDataProviderResponse +} from '../../interfaces/interfaces'; +import { YahooFinanceDataEnhancerService } from '../data-enhancer/yahoo-finance/yahoo-finance.service'; +import { + DataProviderInterface, + GetDividendsParams, + GetHistoricalParams, + GetQuotesParams, + GetSearchParams +} from '../interfaces/data-provider.interface'; + @Injectable() export class YahooFinanceService implements DataProviderInterface { public constructor( @@ -78,9 +79,7 @@ export class YahooFinanceService implements DataProviderInterface { } ) ); - const response: { - [date: string]: IDataProviderHistoricalResponse; - } = {}; + const response: Record = {}; for (const historicalItem of historicalResult) { response[format(historicalItem.date, DATE_FORMAT)] = { @@ -106,9 +105,9 @@ export class YahooFinanceService implements DataProviderInterface { from, symbol, to - }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { + }: GetHistoricalParams): Promise< + Record> + > { if (isSameDay(from, to)) { to = addDays(to, 1); } @@ -127,9 +126,10 @@ export class YahooFinanceService implements DataProviderInterface { ) ); - const response: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - } = {}; + const response: Record< + string, + Record + > = {}; response[symbol] = {}; @@ -160,8 +160,8 @@ export class YahooFinanceService implements DataProviderInterface { public async getQuotes({ symbols - }: GetQuotesParams): Promise<{ [symbol: string]: IDataProviderResponse }> { - const response: { [symbol: string]: IDataProviderResponse } = {}; + }: GetQuotesParams): Promise> { + const response: Record = {}; if (symbols.length <= 0) { return response; diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts index db95a3487..10c163711 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts @@ -1,9 +1,3 @@ -import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor'; -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 { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; -import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { DEFAULT_CURRENCY, DERIVED_CURRENCIES, @@ -26,11 +20,18 @@ import { import { isNumber, uniq } from 'lodash'; import ms from 'ms'; +import { LogPerformance } from '../../interceptors/performance-logging/performance-logging.interceptor'; +import { DataProviderService } from '../data-provider/data-provider.service'; +import { IDataGatheringItem } from '../interfaces/interfaces'; +import { MarketDataService } from '../market-data/market-data.service'; +import { PrismaService } from '../prisma/prisma.service'; +import { PropertyService } from '../property/property.service'; + @Injectable() export class ExchangeRateDataService { private currencies: string[] = []; private currencyPairs: IDataGatheringItem[] = []; - private exchangeRates: { [currencyPair: string]: number } = {}; + private exchangeRates: Record = {}; public constructor( private readonly dataProviderService: DataProviderService, @@ -63,9 +64,7 @@ export class ExchangeRateDataService { return {}; } - const exchangeRatesByCurrency: { - [currency: string]: { [dateString: string]: number }; - } = {}; + const exchangeRatesByCurrency: Record> = {}; for (const currency of currencies) { exchangeRatesByCurrency[`${currency}${targetCurrency}`] = @@ -351,7 +350,7 @@ export class ExchangeRateDataService { startDate: Date; }) { const dates = eachDayOfInterval({ end: endDate, start: startDate }); - const factors: { [dateString: string]: number } = {}; + const factors: Record = {}; if (currencyFrom === currencyTo) { for (const date of dates) { @@ -379,12 +378,8 @@ export class ExchangeRateDataService { } else { // Calculate indirectly via base currency - const marketPriceBaseCurrencyFromCurrency: { - [dateString: string]: number; - } = {}; - const marketPriceBaseCurrencyToCurrency: { - [dateString: string]: number; - } = {}; + const marketPriceBaseCurrencyFromCurrency: Record = {}; + const marketPriceBaseCurrencyToCurrency: Record = {}; try { if (currencyFrom === DEFAULT_CURRENCY) { diff --git a/apps/api/src/services/i18n/i18n.service.ts b/apps/api/src/services/i18n/i18n.service.ts index 13193fc6a..a37b45684 100644 --- a/apps/api/src/services/i18n/i18n.service.ts +++ b/apps/api/src/services/i18n/i18n.service.ts @@ -7,7 +7,7 @@ import { join } from 'path'; export class I18nService { private localesPath = join(__dirname, 'assets', 'locales'); - private translations: { [locale: string]: cheerio.CheerioAPI } = {}; + private translations: Record = {}; public constructor() { this.loadFiles(); diff --git a/apps/api/src/services/property/property.service.ts b/apps/api/src/services/property/property.service.ts index 34ce5713b..d75713f4b 100644 --- a/apps/api/src/services/property/property.service.ts +++ b/apps/api/src/services/property/property.service.ts @@ -17,9 +17,7 @@ export class PropertyService { } public async get() { - const response: { - [key: string]: boolean | object | string | string[]; - } = { + const response: Record = { [PROPERTY_CURRENCIES]: [] }; diff --git a/apps/api/src/services/queues/data-gathering/data-gathering.service.ts b/apps/api/src/services/queues/data-gathering/data-gathering.service.ts index 72b8ac716..1bfaabdef 100644 --- a/apps/api/src/services/queues/data-gathering/data-gathering.service.ts +++ b/apps/api/src/services/queues/data-gathering/data-gathering.service.ts @@ -395,7 +395,7 @@ export class DataGatheringService { } private async getSymbolsMax(): Promise { - const benchmarkAssetProfileIdMap: { [key: string]: boolean } = {}; + const benchmarkAssetProfileIdMap: Record = {}; ( ((await this.propertyService.getByKey( PROPERTY_BENCHMARKS 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 eb8778c34..d7199440e 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -299,10 +299,6 @@ export class SymbolProfileService { } private getSymbolMapping(symbolProfile: SymbolProfile) { - return ( - (symbolProfile['symbolMapping'] as { - [key: string]: string; - }) ?? {} - ); + return (symbolProfile['symbolMapping'] as Record) ?? {}; } } 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 1742d8307..b8def9694 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 @@ -1,4 +1,3 @@ -import { UserService } from '@ghostfolio/client/services/user/user.service'; import { DATE_FORMAT, getDateFormatString, @@ -32,6 +31,7 @@ import { first, last } from 'lodash'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject, takeUntil } from 'rxjs'; +import { UserService } from '../../services/user/user.service'; import { MarketDataDetailDialogParams } from './market-data-detail-dialog/interfaces/interfaces'; import { MarketDataDetailDialog } from './market-data-detail-dialog/market-data-detail-dialog.component'; @@ -55,11 +55,10 @@ export class AdminMarketDataDetailComponent implements OnChanges { public defaultDateFormat: string; public deviceType: string; public historicalDataItems: LineChartItem[]; - public marketDataByMonth: { - [yearMonth: string]: { - [day: string]: Pick & { day: number }; - }; - } = {}; + public marketDataByMonth: Record< + string, + Record & { day: number }> + > = {}; public user: User; private unsubscribeSubject = new Subject(); 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 aacf387e7..c5f930451 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 @@ -70,16 +70,12 @@ export class AssetProfileDialog implements OnDestroy, OnInit { }); public assetProfileSubClass: string; public benchmarks: Partial[]; - public countries: { - [code: string]: { name: string; value: number }; - }; + public countries: Record; public currencies: string[] = []; public ghostfolioScraperApiSymbolPrefix = ghostfolioScraperApiSymbolPrefix; public isBenchmark = false; public marketDataDetails: MarketData[] = []; - public sectors: { - [name: string]: { name: string; value: number }; - }; + public sectors: Record; private static readonly HISTORICAL_DATA_TEMPLATE = `date;marketPrice\n${format( new Date(), 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 b430f36ec..bec99a602 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 @@ -94,9 +94,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { public assetSubClass: string; public averagePrice: number; public benchmarkDataItems: LineChartItem[]; - public countries: { - [code: string]: { name: string; value: number }; - }; + public countries: Record; public dataProviderInfo: DataProviderInfo; public dataSource: MatTableDataSource; public dividendInBaseCurrency: number; @@ -120,9 +118,7 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { public quantity: number; public quantityPrecision = 2; public reportDataGlitchMail: string; - public sectors: { - [name: string]: { name: string; value: number }; - }; + public sectors: Record; public separatorKeysCodes: number[] = [COMMA, ENTER]; public sortColumn = 'date'; public sortDirection: SortDirection = 'desc'; diff --git a/apps/client/src/app/components/world-map-chart/world-map-chart.component.ts b/apps/client/src/app/components/world-map-chart/world-map-chart.component.ts index 969bd61e1..44e7b2c84 100644 --- a/apps/client/src/app/components/world-map-chart/world-map-chart.component.ts +++ b/apps/client/src/app/components/world-map-chart/world-map-chart.component.ts @@ -17,7 +17,7 @@ import svgMap from 'svgmap'; styleUrls: ['./world-map-chart.component.scss'] }) export class WorldMapChartComponent implements OnChanges, OnDestroy { - @Input() countries: { [code: string]: { name?: string; value: number } }; + @Input() countries: Record; @Input() format: string; @Input() isInPercent = false; @Input() locale = getLocale(); diff --git a/apps/client/src/app/pages/landing/landing-page.component.ts b/apps/client/src/app/pages/landing/landing-page.component.ts index 3f9e45b94..539cdacb7 100644 --- a/apps/client/src/app/pages/landing/landing-page.component.ts +++ b/apps/client/src/app/pages/landing/landing-page.component.ts @@ -14,9 +14,7 @@ import { Subject } from 'rxjs'; templateUrl: './landing-page.html' }) export class LandingPageComponent implements OnDestroy, OnInit { - public countriesOfSubscribersMap: { - [code: string]: { value: number }; - } = {}; + public countriesOfSubscribersMap: Record = {}; public currentYear = format(new Date(), 'yyyy'); public deviceType: string; public hasPermissionForDemo: boolean; 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 e647c54fb..4b62f7756 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 @@ -1,8 +1,3 @@ -import { AccountDetailDialog } from '@ghostfolio/client/components/account-detail-dialog/account-detail-dialog.component'; -import { AccountDetailDialogParams } from '@ghostfolio/client/components/account-detail-dialog/interfaces/interfaces'; -import { DataService } from '@ghostfolio/client/services/data.service'; -import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; -import { UserService } from '@ghostfolio/client/services/user/user.service'; import { MAX_TOP_HOLDINGS, UNKNOWN_KEY } from '@ghostfolio/common/config'; import { prettifySymbol } from '@ghostfolio/common/helper'; import { @@ -25,24 +20,27 @@ import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; +import { AccountDetailDialog } from '../../../components/account-detail-dialog/account-detail-dialog.component'; +import { AccountDetailDialogParams } from '../../../components/account-detail-dialog/interfaces/interfaces'; +import { DataService } from '../../../services/data.service'; +import { ImpersonationStorageService } from '../../../services/impersonation-storage.service'; +import { UserService } from '../../../services/user/user.service'; + @Component({ selector: 'gf-allocations-page', styleUrls: ['./allocations-page.scss'], templateUrl: './allocations-page.html' }) export class AllocationsPageComponent implements OnDestroy, OnInit { - public accounts: { - [id: string]: Pick & { + public accounts: Record< + string, + Pick & { id: string; value: number; - }; - }; - public continents: { - [code: string]: { name: string; value: number }; - }; - public countries: { - [code: string]: { name: string; value: number }; - }; + } + >; + public continents: Record; + public countries: Record; public deviceType: string; public hasImpersonationId: boolean; public isLoading = false; @@ -56,15 +54,17 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { value: number; }; }; - public platforms: { - [id: string]: Pick & { + public platforms: Record< + string, + Pick & { id: string; value: number; - }; - }; + } + >; public portfolioDetails: PortfolioDetails; - public positions: { - [symbol: string]: Pick< + public positions: Record< + string, + Pick< PortfolioPosition, | 'assetClass' | 'assetClassLabel' @@ -73,23 +73,20 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { | 'currency' | 'exchange' | 'name' - > & { etfProvider: string; value: number }; - }; - public sectors: { - [name: string]: { name: string; value: number }; - }; - public symbols: { - [name: string]: { + > & { etfProvider: string; value: number } + >; + public sectors: Record; + public symbols: Record< + string, + { dataSource?: DataSource; name: string; symbol: string; value: number; - }; - }; + } + >; public topHoldings: Holding[]; - public topHoldingsMap: { - [name: string]: { name: string; value: number }; - }; + public topHoldingsMap: Record; public totalValueInEtf = 0; public UNKNOWN_KEY = UNKNOWN_KEY; public user: User; diff --git a/apps/client/src/app/pages/public/public-page.component.ts b/apps/client/src/app/pages/public/public-page.component.ts index 3dbce23ec..1c678d0c1 100644 --- a/apps/client/src/app/pages/public/public-page.component.ts +++ b/apps/client/src/app/pages/public/public-page.component.ts @@ -1,4 +1,3 @@ -import { DataService } from '@ghostfolio/client/services/data.service'; import { UNKNOWN_KEY } from '@ghostfolio/common/config'; import { prettifySymbol } from '@ghostfolio/common/helper'; import { @@ -16,6 +15,8 @@ import { DeviceDetectorService } from 'ngx-device-detector'; import { EMPTY, Subject } from 'rxjs'; import { catchError, takeUntil } from 'rxjs/operators'; +import { DataService } from '../../services/data.service'; + @Component({ host: { class: 'page' }, selector: 'gf-public-page', @@ -23,29 +24,25 @@ import { catchError, takeUntil } from 'rxjs/operators'; templateUrl: './public-page.html' }) export class PublicPageComponent implements OnInit { - public continents: { - [code: string]: { name: string; value: number }; - }; - public countries: { - [code: string]: { name: string; value: number }; - }; + public continents: Record; + public countries: Record; public deviceType: string; public holdings: PublicPortfolioResponse['holdings'][string][]; public markets: { [key in Market]: { id: Market; valueInPercentage: number }; }; - public positions: { - [symbol: string]: Pick & { + public positions: Record< + string, + Pick & { value: number; - }; - }; + } + >; public publicPortfolioDetails: PublicPortfolioResponse; - public sectors: { - [name: string]: { name: string; value: number }; - }; - public symbols: { - [name: string]: { name: string; symbol: string; value: number }; - }; + public sectors: Record; + public symbols: Record< + string, + { name: string; symbol: string; value: number } + >; public UNKNOWN_KEY = UNKNOWN_KEY; private accessId: string; diff --git a/libs/common/src/lib/class-transformer.ts b/libs/common/src/lib/class-transformer.ts index 328e2bf9e..d2c63d545 100644 --- a/libs/common/src/lib/class-transformer.ts +++ b/libs/common/src/lib/class-transformer.ts @@ -3,11 +3,9 @@ import { Big } from 'big.js'; export function transformToMapOfBig({ value }: { - value: { [key: string]: string }; -}): { - [key: string]: Big; -} { - const mapOfBig: { [key: string]: Big } = {}; + value: Record; +}): Record { + const mapOfBig: Record = {}; for (const key in value) { mapOfBig[key] = new Big(value[key]); diff --git a/libs/common/src/lib/interfaces/admin-data.interface.ts b/libs/common/src/lib/interfaces/admin-data.interface.ts index 3dc476df8..62cbebfcb 100644 --- a/libs/common/src/lib/interfaces/admin-data.interface.ts +++ b/libs/common/src/lib/interfaces/admin-data.interface.ts @@ -6,7 +6,7 @@ export interface AdminData { label2: string; value: number; } & AssetProfileIdentifier)[]; - settings: { [key: string]: boolean | object | string | string[] }; + settings: Record; transactionCount: number; userCount: number; version: string; diff --git a/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts b/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts index e7fc4c5b5..63edd697c 100644 --- a/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts +++ b/libs/common/src/lib/interfaces/enhanced-symbol-profile.interface.ts @@ -27,7 +27,7 @@ export interface EnhancedSymbolProfile { scraperConfiguration?: ScraperConfiguration; sectors: Sector[]; symbol: string; - symbolMapping?: { [key: string]: string }; + symbolMapping?: Record; updatedAt: Date; url?: string; } diff --git a/libs/common/src/lib/interfaces/portfolio-details.interface.ts b/libs/common/src/lib/interfaces/portfolio-details.interface.ts index e455f73ca..eb91f8047 100644 --- a/libs/common/src/lib/interfaces/portfolio-details.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-details.interface.ts @@ -5,16 +5,17 @@ import { import { Market, MarketAdvanced } from '@ghostfolio/common/types'; export interface PortfolioDetails { - accounts: { - [id: string]: { + accounts: Record< + string, + { balance: number; currency: string; name: string; valueInBaseCurrency: number; valueInPercentage?: number; - }; - }; - holdings: { [symbol: string]: PortfolioPosition }; + } + >; + holdings: Record; markets?: { [key in Market]: { id: Market; @@ -29,14 +30,15 @@ export interface PortfolioDetails { valueInPercentage: number; }; }; - platforms: { - [id: string]: { + platforms: Record< + string, + { balance: number; currency: string; name: string; valueInBaseCurrency: number; valueInPercentage?: number; - }; - }; + } + >; summary?: PortfolioSummary; } diff --git a/libs/common/src/lib/interfaces/portfolio-item.interface.ts b/libs/common/src/lib/interfaces/portfolio-item.interface.ts index a3e42a05f..ece0eba82 100644 --- a/libs/common/src/lib/interfaces/portfolio-item.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-item.interface.ts @@ -4,6 +4,6 @@ export interface PortfolioItem { date: string; grossPerformancePercent: number; investment: number; - positions: { [symbol: string]: Position }; + positions: Record; value: number; } diff --git a/libs/common/src/lib/interfaces/portfolio-report.interface.ts b/libs/common/src/lib/interfaces/portfolio-report.interface.ts index a33a0aae6..6a38fd44b 100644 --- a/libs/common/src/lib/interfaces/portfolio-report.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-report.interface.ts @@ -1,5 +1,5 @@ import { PortfolioReportRule } from './portfolio-report-rule.interface'; export interface PortfolioReport { - rules: { [group: string]: PortfolioReportRule[] }; + rules: Record; } diff --git a/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts b/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts index dc6e57587..6f228417f 100644 --- a/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts +++ b/libs/common/src/lib/interfaces/responses/public-portfolio-response.interface.ts @@ -4,8 +4,9 @@ import { Market } from '../../types'; export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 { alias?: string; hasDetails: boolean; - holdings: { - [symbol: string]: Pick< + holdings: Record< + string, + Pick< PortfolioPosition, | 'allocationInPercentage' | 'assetClass' @@ -21,8 +22,8 @@ export interface PublicPortfolioResponse extends PublicPortfolioResponseV1 { | 'url' | 'valueInBaseCurrency' | 'valueInPercentage' - >; - }; + > + >; markets: { [key in Market]: Pick< PortfolioDetails['markets'][key], diff --git a/libs/common/src/lib/interfaces/scraper-configuration.interface.ts b/libs/common/src/lib/interfaces/scraper-configuration.interface.ts index 70fcd939d..2c5e033e6 100644 --- a/libs/common/src/lib/interfaces/scraper-configuration.interface.ts +++ b/libs/common/src/lib/interfaces/scraper-configuration.interface.ts @@ -1,6 +1,6 @@ export interface ScraperConfiguration { defaultMarketPrice?: number; - headers?: { [key: string]: string }; + headers?: Record; locale?: string; mode?: 'instant' | 'lazy'; selector: string; diff --git a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts index 24c1e1db4..4fbb6c14b 100644 --- a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts +++ b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts @@ -3,12 +3,8 @@ import { DateRange } from '@ghostfolio/common/types'; import { Big } from 'big.js'; export interface SymbolMetrics { - currentValues: { - [date: string]: Big; - }; - currentValuesWithCurrencyEffect: { - [date: string]: Big; - }; + currentValues: Record; + currentValuesWithCurrencyEffect: Record; feesWithCurrencyEffect: Big; grossPerformance: Big; grossPerformancePercentage: Big; @@ -17,30 +13,18 @@ export interface SymbolMetrics { hasErrors: boolean; initialValue: Big; initialValueWithCurrencyEffect: Big; - investmentValuesAccumulated: { - [date: string]: Big; - }; - investmentValuesAccumulatedWithCurrencyEffect: { - [date: string]: Big; - }; - investmentValuesWithCurrencyEffect: { - [date: string]: Big; - }; + investmentValuesAccumulated: Record; + investmentValuesAccumulatedWithCurrencyEffect: Record; + investmentValuesWithCurrencyEffect: Record; netPerformance: Big; netPerformancePercentage: Big; - netPerformancePercentageWithCurrencyEffectMap: { [key: DateRange]: Big }; - netPerformanceValues: { - [date: string]: Big; - }; - netPerformanceValuesWithCurrencyEffect: { [date: string]: Big }; - netPerformanceWithCurrencyEffectMap: { [key: DateRange]: Big }; + netPerformancePercentageWithCurrencyEffectMap: Record; + netPerformanceValues: Record; + netPerformanceValuesWithCurrencyEffect: Record; + netPerformanceWithCurrencyEffectMap: Record; timeWeightedInvestment: Big; - timeWeightedInvestmentValues: { - [date: string]: Big; - }; - timeWeightedInvestmentValuesWithCurrencyEffect: { - [date: string]: Big; - }; + timeWeightedInvestmentValues: Record; + timeWeightedInvestmentValuesWithCurrencyEffect: Record; timeWeightedInvestmentWithCurrencyEffect: Big; totalAccountBalanceInBaseCurrency: Big; totalDividend: Big; diff --git a/libs/common/src/lib/models/timeline-position.ts b/libs/common/src/lib/models/timeline-position.ts index f683c0951..6877336e6 100644 --- a/libs/common/src/lib/models/timeline-position.ts +++ b/libs/common/src/lib/models/timeline-position.ts @@ -70,10 +70,10 @@ export class TimelinePosition { netPerformancePercentage: Big; @Transform(transformToMapOfBig, { toClassOnly: true }) - netPerformancePercentageWithCurrencyEffectMap: { [key: DateRange]: Big }; + netPerformancePercentageWithCurrencyEffectMap: Record; @Transform(transformToMapOfBig, { toClassOnly: true }) - netPerformanceWithCurrencyEffectMap: { [key: DateRange]: Big }; + netPerformanceWithCurrencyEffectMap: Record; @Transform(transformToBig, { toClassOnly: true }) @Type(() => Big) diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index d73cdb416..95f304f80 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -292,7 +292,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { } } - public hasFilter(aFormValue: { [key: string]: string }) { + public hasFilter(aFormValue: Record) { return Object.values(aFormValue).some((value) => { return !!value; }); 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 0eef25fa5..1167ab23b 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 @@ -66,13 +66,14 @@ export class GfPortfolioProportionChartComponent @Input() locale = getLocale(); @Input() maxItems?: number; @Input() showLabels = false; - @Input() positions: { - [symbol: string]: Pick & { + @Input() positions: Record< + string, + Pick & { dataSource?: DataSource; name: string; value: number; - }; - } = {}; + } + > = {}; @Output() proportionChartClicked = new EventEmitter(); @@ -83,9 +84,7 @@ export class GfPortfolioProportionChartComponent private readonly OTHER_KEY = 'OTHER'; - private colorMap: { - [symbol: string]: string; - } = {}; + private colorMap: Record = {}; public constructor() { Chart.register(ArcElement, DoughnutController, LinearScale, Tooltip); @@ -109,14 +108,15 @@ export class GfPortfolioProportionChartComponent private initialize() { this.isLoading = true; - const chartData: { - [symbol: string]: { + const chartData: Record< + string, + { color?: string; name: string; - subCategory?: { [symbol: string]: { value: Big } }; + subCategory?: Record; value: Big; - }; - } = {}; + } + > = {}; this.colorMap = { [this.OTHER_KEY]: `rgba(${getTextColor(this.colorScheme)}, 0.24)`, [UNKNOWN_KEY]: `rgba(${getTextColor(this.colorScheme)}, 0.12)`