refactor data-provider.service.ts to have dynamic list of services (#429)
* Refactor data-provider.service.ts to have dynamic list of services * Update changelog Co-authored-by: Valentin Zickner <ghostfolio@zickner.ch> Co-authored-by: Thomas <4159106+dtslvr@users.noreply.github.com>
This commit is contained in:
parent
e3cd99f5d2
commit
099ad18aaf
@ -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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Changed the data provider service to handle a dynamic list of services
|
||||||
|
|
||||||
## 1.63.0 - 19.10.2021
|
## 1.63.0 - 19.10.2021
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -72,15 +72,7 @@ describe('CurrentRateService', () => {
|
|||||||
let marketDataService: MarketDataService;
|
let marketDataService: MarketDataService;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
dataProviderService = new DataProviderService(
|
dataProviderService = new DataProviderService(null, [], [], null);
|
||||||
null,
|
|
||||||
null,
|
|
||||||
[],
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
exchangeRateDataService = new ExchangeRateDataService(null, null);
|
exchangeRateDataService = new ExchangeRateDataService(null, null);
|
||||||
marketDataService = new MarketDataService(null);
|
marketDataService = new MarketDataService(null);
|
||||||
|
|
||||||
|
@ -84,6 +84,10 @@ export class AlphaVantageService implements DataProviderInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getName(): DataSource {
|
||||||
|
return DataSource.ALPHA_VANTAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
||||||
const result = await this.alphaVantage.data.search(aSymbol);
|
const result = await this.alphaVantage.data.search(aSymbol);
|
||||||
|
|
||||||
|
@ -22,6 +22,26 @@ import { DataProviderService } from './data-provider.service';
|
|||||||
inject: [TrackinsightDataEnhancerService],
|
inject: [TrackinsightDataEnhancerService],
|
||||||
provide: 'DataEnhancers',
|
provide: 'DataEnhancers',
|
||||||
useFactory: (trackinsight) => [trackinsight]
|
useFactory: (trackinsight) => [trackinsight]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
inject: [
|
||||||
|
AlphaVantageService,
|
||||||
|
GhostfolioScraperApiService,
|
||||||
|
RakutenRapidApiService,
|
||||||
|
YahooFinanceService
|
||||||
|
],
|
||||||
|
provide: 'DataProviderInterfaces',
|
||||||
|
useFactory: (
|
||||||
|
alphaVantageService,
|
||||||
|
ghostfolioScraperApiService,
|
||||||
|
rakutenRapidApiService,
|
||||||
|
yahooFinanceService
|
||||||
|
) => [
|
||||||
|
alphaVantageService,
|
||||||
|
ghostfolioScraperApiService,
|
||||||
|
rakutenRapidApiService,
|
||||||
|
yahooFinanceService
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
exports: [DataProviderService, GhostfolioScraperApiService]
|
exports: [DataProviderService, GhostfolioScraperApiService]
|
||||||
|
@ -13,26 +13,18 @@ import { Inject, Injectable } from '@nestjs/common';
|
|||||||
import { DataSource, MarketData } from '@prisma/client';
|
import { DataSource, MarketData } from '@prisma/client';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
import { DataProviderInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface';
|
||||||
import { AlphaVantageService } from './alpha-vantage/alpha-vantage.service';
|
|
||||||
import { GhostfolioScraperApiService } from './ghostfolio-scraper-api/ghostfolio-scraper-api.service';
|
|
||||||
import { RakutenRapidApiService } from './rakuten-rapid-api/rakuten-rapid-api.service';
|
|
||||||
import { YahooFinanceService } from './yahoo-finance/yahoo-finance.service';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DataProviderService {
|
export class DataProviderService {
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly alphaVantageService: AlphaVantageService,
|
|
||||||
private readonly configurationService: ConfigurationService,
|
private readonly configurationService: ConfigurationService,
|
||||||
@Inject('DataEnhancers')
|
@Inject('DataEnhancers')
|
||||||
private readonly dataEnhancers: DataEnhancerInterface[],
|
private readonly dataEnhancers: DataEnhancerInterface[],
|
||||||
private readonly ghostfolioScraperApiService: GhostfolioScraperApiService,
|
@Inject('DataProviderInterfaces')
|
||||||
private readonly prismaService: PrismaService,
|
private readonly dataProviderInterfaces: DataProviderInterface[],
|
||||||
private readonly rakutenRapidApiService: RakutenRapidApiService,
|
private readonly prismaService: PrismaService
|
||||||
private readonly yahooFinanceService: YahooFinanceService
|
) {}
|
||||||
) {
|
|
||||||
this.rakutenRapidApiService?.setPrisma(this.prismaService);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async get(items: IDataGatheringItem[]): Promise<{
|
public async get(items: IDataGatheringItem[]): Promise<{
|
||||||
[symbol: string]: IDataProviderResponse;
|
[symbol: string]: IDataProviderResponse;
|
||||||
@ -204,17 +196,11 @@ export class DataProviderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getDataProvider(providerName: DataSource) {
|
private getDataProvider(providerName: DataSource) {
|
||||||
switch (providerName) {
|
for (const dataProviderInterface of this.dataProviderInterfaces) {
|
||||||
case DataSource.ALPHA_VANTAGE:
|
if (dataProviderInterface.getName() === providerName) {
|
||||||
return this.alphaVantageService;
|
return dataProviderInterface;
|
||||||
case DataSource.GHOSTFOLIO:
|
}
|
||||||
return this.ghostfolioScraperApiService;
|
|
||||||
case DataSource.RAKUTEN:
|
|
||||||
return this.rakutenRapidApiService;
|
|
||||||
case DataSource.YAHOO:
|
|
||||||
return this.yahooFinanceService;
|
|
||||||
default:
|
|
||||||
throw new Error('No data provider has been found.');
|
|
||||||
}
|
}
|
||||||
|
throw new Error('No data provider has been found.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,10 @@ export class GhostfolioScraperApiService implements DataProviderInterface {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getName(): DataSource {
|
||||||
|
return DataSource.GHOSTFOLIO;
|
||||||
|
}
|
||||||
|
|
||||||
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
||||||
return { items: [] };
|
return { items: [] };
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
IDataProviderHistoricalResponse,
|
IDataProviderHistoricalResponse,
|
||||||
IDataProviderResponse
|
IDataProviderResponse
|
||||||
} from '../../interfaces/interfaces';
|
} from '../../interfaces/interfaces';
|
||||||
|
import { DataSource } from '@prisma/client';
|
||||||
|
|
||||||
export interface DataProviderInterface {
|
export interface DataProviderInterface {
|
||||||
canHandle(symbol: string): boolean;
|
canHandle(symbol: string): boolean;
|
||||||
@ -20,5 +21,7 @@ export interface DataProviderInterface {
|
|||||||
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
|
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
getName(): DataSource;
|
||||||
|
|
||||||
search(aSymbol: string): Promise<{ items: LookupItem[] }>;
|
search(aSymbol: string): Promise<{ items: LookupItem[] }>;
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,9 @@ import { DataProviderInterface } from '../interfaces/data-provider.interface';
|
|||||||
export class RakutenRapidApiService implements DataProviderInterface {
|
export class RakutenRapidApiService implements DataProviderInterface {
|
||||||
public static FEAR_AND_GREED_INDEX_NAME = 'Fear & Greed Index';
|
public static FEAR_AND_GREED_INDEX_NAME = 'Fear & Greed Index';
|
||||||
|
|
||||||
private prismaService: PrismaService;
|
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly configurationService: ConfigurationService
|
private readonly configurationService: ConfigurationService,
|
||||||
|
private readonly prismaService: PrismaService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public canHandle(symbol: string) {
|
public canHandle(symbol: string) {
|
||||||
@ -134,12 +133,12 @@ export class RakutenRapidApiService implements DataProviderInterface {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
public getName(): DataSource {
|
||||||
return { items: [] };
|
return DataSource.RAKUTEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setPrisma(aPrismaService: PrismaService) {
|
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
||||||
this.prismaService = aPrismaService;
|
return { items: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getFearAndGreedIndex(): Promise<{
|
private async getFearAndGreedIndex(): Promise<{
|
||||||
|
@ -171,6 +171,10 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getName(): DataSource {
|
||||||
|
return DataSource.YAHOO;
|
||||||
|
}
|
||||||
|
|
||||||
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
public async search(aSymbol: string): Promise<{ items: LookupItem[] }> {
|
||||||
const items: LookupItem[] = [];
|
const items: LookupItem[] = [];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user