Transform data source (#658)
* Transform data source * Update changelog
This commit is contained in:
parent
b8ad6d6662
commit
155c08d665
@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- Added support for the (optional) `accountId` in the import functionality for activities
|
- Added support for the (optional) `accountId` in the import functionality for activities
|
||||||
- Added support for the (optional) `dataSource` in the import functionality for activities
|
- Added support for the (optional) `dataSource` in the import functionality for activities
|
||||||
|
- Added support for the data source transformation
|
||||||
- Added support for the cryptocurrency _Mina Protocol_ (`MINA-USD`)
|
- Added support for the cryptocurrency _Mina Protocol_ (`MINA-USD`)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
@ -18,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Improved the consistent use of `symbol` in combination with `dataSource`
|
- Improved the consistent use of `symbol` in combination with `dataSource`
|
||||||
- Removed the primary data source from the client
|
- Removed the primary data source from the client
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Removed the unused endpoint `GET api/order/:id`
|
||||||
|
|
||||||
## 1.108.0 - 27.01.2022
|
## 1.108.0 - 27.01.2022
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { UserService } from '@ghostfolio/api/app/user/user.service';
|
import { UserService } from '@ghostfolio/api/app/user/user.service';
|
||||||
import { nullifyValuesInObjects } from '@ghostfolio/api/helper/object.helper';
|
import { nullifyValuesInObjects } from '@ghostfolio/api/helper/object.helper';
|
||||||
|
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor';
|
||||||
|
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor';
|
||||||
import { ImpersonationService } from '@ghostfolio/api/services/impersonation.service';
|
import { ImpersonationService } from '@ghostfolio/api/services/impersonation.service';
|
||||||
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
|
||||||
import type { RequestWithUser } from '@ghostfolio/common/types';
|
import type { RequestWithUser } from '@ghostfolio/common/types';
|
||||||
@ -14,7 +16,8 @@ import {
|
|||||||
Param,
|
Param,
|
||||||
Post,
|
Post,
|
||||||
Put,
|
Put,
|
||||||
UseGuards
|
UseGuards,
|
||||||
|
UseInterceptors
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { REQUEST } from '@nestjs/core';
|
import { REQUEST } from '@nestjs/core';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
@ -58,6 +61,7 @@ export class OrderController {
|
|||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
||||||
public async getAllOrders(
|
public async getAllOrders(
|
||||||
@Headers('impersonation-id') impersonationId
|
@Headers('impersonation-id') impersonationId
|
||||||
): Promise<Activities> {
|
): Promise<Activities> {
|
||||||
@ -91,19 +95,9 @@ export class OrderController {
|
|||||||
return { activities };
|
return { activities };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':id')
|
|
||||||
@UseGuards(AuthGuard('jwt'))
|
|
||||||
public async getOrderById(@Param('id') id: string): Promise<OrderModel> {
|
|
||||||
return this.orderService.order({
|
|
||||||
id_userId: {
|
|
||||||
id,
|
|
||||||
userId: this.request.user.id
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
@UseInterceptors(TransformDataSourceInRequestInterceptor)
|
||||||
public async createOrder(@Body() data: CreateOrderDto): Promise<OrderModel> {
|
public async createOrder(@Body() data: CreateOrderDto): Promise<OrderModel> {
|
||||||
if (
|
if (
|
||||||
!hasPermission(this.request.user.permissions, permissions.createOrder)
|
!hasPermission(this.request.user.permissions, permissions.createOrder)
|
||||||
@ -138,6 +132,7 @@ export class OrderController {
|
|||||||
|
|
||||||
@Put(':id')
|
@Put(':id')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
@UseInterceptors(TransformDataSourceInRequestInterceptor)
|
||||||
public async update(@Param('id') id: string, @Body() data: UpdateOrderDto) {
|
public async update(@Param('id') id: string, @Body() data: UpdateOrderDto) {
|
||||||
if (
|
if (
|
||||||
!hasPermission(this.request.user.permissions, permissions.updateOrder)
|
!hasPermission(this.request.user.permissions, permissions.updateOrder)
|
||||||
|
@ -4,9 +4,12 @@ import {
|
|||||||
hasNotDefinedValuesInObject,
|
hasNotDefinedValuesInObject,
|
||||||
nullifyValuesInObject
|
nullifyValuesInObject
|
||||||
} from '@ghostfolio/api/helper/object.helper';
|
} from '@ghostfolio/api/helper/object.helper';
|
||||||
|
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor';
|
||||||
|
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor';
|
||||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
|
import { ConfigurationService } from '@ghostfolio/api/services/configuration.service';
|
||||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
||||||
import { baseCurrency } from '@ghostfolio/common/config';
|
import { baseCurrency } from '@ghostfolio/common/config';
|
||||||
|
import { parseDate } from '@ghostfolio/common/helper';
|
||||||
import {
|
import {
|
||||||
PortfolioChart,
|
PortfolioChart,
|
||||||
PortfolioDetails,
|
PortfolioDetails,
|
||||||
@ -25,13 +28,11 @@ import {
|
|||||||
Inject,
|
Inject,
|
||||||
Param,
|
Param,
|
||||||
Query,
|
Query,
|
||||||
Res,
|
UseGuards,
|
||||||
UseGuards
|
UseInterceptors
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { REQUEST } from '@nestjs/core';
|
import { REQUEST } from '@nestjs/core';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
import { DataSource } from '@prisma/client';
|
|
||||||
import { Response } from 'express';
|
|
||||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||||
|
|
||||||
import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface';
|
import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface';
|
||||||
@ -53,8 +54,7 @@ export class PortfolioController {
|
|||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async getChart(
|
public async getChart(
|
||||||
@Headers('impersonation-id') impersonationId: string,
|
@Headers('impersonation-id') impersonationId: string,
|
||||||
@Query('range') range,
|
@Query('range') range
|
||||||
@Res() res: Response
|
|
||||||
): Promise<PortfolioChart> {
|
): Promise<PortfolioChart> {
|
||||||
const historicalDataContainer = await this.portfolioServiceStrategy
|
const historicalDataContainer = await this.portfolioServiceStrategy
|
||||||
.get()
|
.get()
|
||||||
@ -90,27 +90,29 @@ export class PortfolioController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return <any>res.json({
|
return {
|
||||||
hasError,
|
hasError,
|
||||||
chart: chartData,
|
chart: chartData,
|
||||||
isAllTimeHigh: historicalDataContainer.isAllTimeHigh,
|
isAllTimeHigh: historicalDataContainer.isAllTimeHigh,
|
||||||
isAllTimeLow: historicalDataContainer.isAllTimeLow
|
isAllTimeLow: historicalDataContainer.isAllTimeLow
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('details')
|
@Get('details')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
||||||
public async getDetails(
|
public async getDetails(
|
||||||
@Headers('impersonation-id') impersonationId: string,
|
@Headers('impersonation-id') impersonationId: string,
|
||||||
@Query('range') range,
|
@Query('range') range
|
||||||
@Res() res: Response
|
): Promise<PortfolioDetails & { hasError: boolean }> {
|
||||||
): Promise<PortfolioDetails> {
|
|
||||||
if (
|
if (
|
||||||
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
|
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
|
||||||
this.request.user.subscription.type === 'Basic'
|
this.request.user.subscription.type === 'Basic'
|
||||||
) {
|
) {
|
||||||
res.status(StatusCodes.FORBIDDEN);
|
throw new HttpException(
|
||||||
return <any>res.json({ accounts: {}, holdings: {} });
|
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||||
|
StatusCodes.FORBIDDEN
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasError = false;
|
let hasError = false;
|
||||||
@ -159,21 +161,22 @@ export class PortfolioController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <any>res.json({ accounts, hasError, holdings });
|
return { accounts, hasError, holdings };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('investments')
|
@Get('investments')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async getInvestments(
|
public async getInvestments(
|
||||||
@Headers('impersonation-id') impersonationId: string,
|
@Headers('impersonation-id') impersonationId: string
|
||||||
@Res() res: Response
|
|
||||||
): Promise<PortfolioInvestments> {
|
): Promise<PortfolioInvestments> {
|
||||||
if (
|
if (
|
||||||
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
|
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
|
||||||
this.request.user.subscription.type === 'Basic'
|
this.request.user.subscription.type === 'Basic'
|
||||||
) {
|
) {
|
||||||
res.status(StatusCodes.FORBIDDEN);
|
throw new HttpException(
|
||||||
return <any>res.json({});
|
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||||
|
StatusCodes.FORBIDDEN
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let investments = await this.portfolioServiceStrategy
|
let investments = await this.portfolioServiceStrategy
|
||||||
@ -195,15 +198,14 @@ export class PortfolioController {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return <any>res.json({ firstOrderDate: investments[0]?.date, investments });
|
return { firstOrderDate: parseDate(investments[0]?.date), investments };
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('performance')
|
@Get('performance')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async getPerformance(
|
public async getPerformance(
|
||||||
@Headers('impersonation-id') impersonationId: string,
|
@Headers('impersonation-id') impersonationId: string,
|
||||||
@Query('range') range,
|
@Query('range') range
|
||||||
@Res() res: Response
|
|
||||||
): Promise<{ hasErrors: boolean; performance: PortfolioPerformance }> {
|
): Promise<{ hasErrors: boolean; performance: PortfolioPerformance }> {
|
||||||
const performanceInformation = await this.portfolioServiceStrategy
|
const performanceInformation = await this.portfolioServiceStrategy
|
||||||
.get()
|
.get()
|
||||||
@ -219,15 +221,15 @@ export class PortfolioController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <any>res.json(performanceInformation);
|
return performanceInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('positions')
|
@Get('positions')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
||||||
public async getPositions(
|
public async getPositions(
|
||||||
@Headers('impersonation-id') impersonationId: string,
|
@Headers('impersonation-id') impersonationId: string,
|
||||||
@Query('range') range,
|
@Query('range') range
|
||||||
@Res() res: Response
|
|
||||||
): Promise<PortfolioPositions> {
|
): Promise<PortfolioPositions> {
|
||||||
const result = await this.portfolioServiceStrategy
|
const result = await this.portfolioServiceStrategy
|
||||||
.get()
|
.get()
|
||||||
@ -247,13 +249,12 @@ export class PortfolioController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return <any>res.json(result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('public/:accessId')
|
@Get('public/:accessId')
|
||||||
public async getPublic(
|
public async getPublic(
|
||||||
@Param('accessId') accessId,
|
@Param('accessId') accessId
|
||||||
@Res() res: Response
|
|
||||||
): Promise<PortfolioPublicDetails> {
|
): Promise<PortfolioPublicDetails> {
|
||||||
const access = await this.accessService.access({ id: accessId });
|
const access = await this.accessService.access({ id: accessId });
|
||||||
const user = await this.userService.user({
|
const user = await this.userService.user({
|
||||||
@ -261,8 +262,10 @@ export class PortfolioController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!access) {
|
if (!access) {
|
||||||
res.status(StatusCodes.NOT_FOUND);
|
throw new HttpException(
|
||||||
return <any>res.json({ accounts: {}, holdings: {} });
|
getReasonPhrase(StatusCodes.NOT_FOUND),
|
||||||
|
StatusCodes.NOT_FOUND
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasDetails = true;
|
let hasDetails = true;
|
||||||
@ -305,7 +308,7 @@ export class PortfolioController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <any>res.json(portfolioPublicDetails);
|
return portfolioPublicDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('summary')
|
@Get('summary')
|
||||||
@ -339,6 +342,7 @@ export class PortfolioController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Get('position/:dataSource/:symbol')
|
@Get('position/:dataSource/:symbol')
|
||||||
|
@UseInterceptors(TransformDataSourceInRequestInterceptor)
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async getPosition(
|
public async getPosition(
|
||||||
@Headers('impersonation-id') impersonationId: string,
|
@Headers('impersonation-id') impersonationId: string,
|
||||||
@ -376,21 +380,18 @@ export class PortfolioController {
|
|||||||
@Get('report')
|
@Get('report')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async getReport(
|
public async getReport(
|
||||||
@Headers('impersonation-id') impersonationId: string,
|
@Headers('impersonation-id') impersonationId: string
|
||||||
@Res() res: Response
|
|
||||||
): Promise<PortfolioReport> {
|
): Promise<PortfolioReport> {
|
||||||
if (
|
if (
|
||||||
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
|
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
|
||||||
this.request.user.subscription.type === 'Basic'
|
this.request.user.subscription.type === 'Basic'
|
||||||
) {
|
) {
|
||||||
res.status(StatusCodes.FORBIDDEN);
|
throw new HttpException(
|
||||||
return <any>res.json({ rules: [] });
|
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||||
|
StatusCodes.FORBIDDEN
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <any>(
|
return await this.portfolioServiceStrategy.get().getReport(impersonationId);
|
||||||
res.json(
|
|
||||||
await this.portfolioServiceStrategy.get().getReport(impersonationId)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
Body,
|
Body,
|
||||||
Controller,
|
Controller,
|
||||||
Get,
|
Get,
|
||||||
|
HttpCode,
|
||||||
HttpException,
|
HttpException,
|
||||||
Inject,
|
Inject,
|
||||||
Logger,
|
Logger,
|
||||||
@ -17,7 +18,6 @@ import {
|
|||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { REQUEST } from '@nestjs/core';
|
import { REQUEST } from '@nestjs/core';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
import { Response } from 'express';
|
|
||||||
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
|
||||||
|
|
||||||
import { SubscriptionService } from './subscription.service';
|
import { SubscriptionService } from './subscription.service';
|
||||||
@ -32,11 +32,9 @@ export class SubscriptionController {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Post('redeem-coupon')
|
@Post('redeem-coupon')
|
||||||
|
@HttpCode(StatusCodes.OK)
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
public async redeemCoupon(
|
public async redeemCoupon(@Body() { couponCode }: { couponCode: string }) {
|
||||||
@Body() { couponCode }: { couponCode: string },
|
|
||||||
@Res() res: Response
|
|
||||||
) {
|
|
||||||
if (!this.request.user) {
|
if (!this.request.user) {
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
getReasonPhrase(StatusCodes.FORBIDDEN),
|
getReasonPhrase(StatusCodes.FORBIDDEN),
|
||||||
@ -74,12 +72,10 @@ export class SubscriptionController {
|
|||||||
`Subscription for user '${this.request.user.id}' has been created with coupon`
|
`Subscription for user '${this.request.user.id}' has been created with coupon`
|
||||||
);
|
);
|
||||||
|
|
||||||
res.status(StatusCodes.OK);
|
return {
|
||||||
|
|
||||||
return <any>res.json({
|
|
||||||
message: getReasonPhrase(StatusCodes.OK),
|
message: getReasonPhrase(StatusCodes.OK),
|
||||||
statusCode: StatusCodes.OK
|
statusCode: StatusCodes.OK
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get('stripe/callback')
|
@Get('stripe/callback')
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor';
|
||||||
|
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor';
|
||||||
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
|
import { IDataProviderHistoricalResponse } from '@ghostfolio/api/services/interfaces/interfaces';
|
||||||
import {
|
import {
|
||||||
Controller,
|
Controller,
|
||||||
@ -5,7 +7,8 @@ import {
|
|||||||
HttpException,
|
HttpException,
|
||||||
Param,
|
Param,
|
||||||
Query,
|
Query,
|
||||||
UseGuards
|
UseGuards,
|
||||||
|
UseInterceptors
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { AuthGuard } from '@nestjs/passport';
|
import { AuthGuard } from '@nestjs/passport';
|
||||||
import { DataSource } from '@prisma/client';
|
import { DataSource } from '@prisma/client';
|
||||||
@ -25,6 +28,7 @@ export class SymbolController {
|
|||||||
*/
|
*/
|
||||||
@Get('lookup')
|
@Get('lookup')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
||||||
public async lookupSymbol(
|
public async lookupSymbol(
|
||||||
@Query() { query = '' }
|
@Query() { query = '' }
|
||||||
): Promise<{ items: LookupItem[] }> {
|
): Promise<{ items: LookupItem[] }> {
|
||||||
@ -43,6 +47,8 @@ export class SymbolController {
|
|||||||
*/
|
*/
|
||||||
@Get(':dataSource/:symbol')
|
@Get(':dataSource/:symbol')
|
||||||
@UseGuards(AuthGuard('jwt'))
|
@UseGuards(AuthGuard('jwt'))
|
||||||
|
@UseInterceptors(TransformDataSourceInRequestInterceptor)
|
||||||
|
@UseInterceptors(TransformDataSourceInResponseInterceptor)
|
||||||
public async getSymbolData(
|
public async getSymbolData(
|
||||||
@Param('dataSource') dataSource: DataSource,
|
@Param('dataSource') dataSource: DataSource,
|
||||||
@Param('symbol') symbol: string,
|
@Param('symbol') symbol: string,
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
import {
|
||||||
|
CallHandler,
|
||||||
|
ExecutionContext,
|
||||||
|
Injectable,
|
||||||
|
NestInterceptor
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ConfigurationService } from '../services/configuration.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TransformDataSourceInRequestInterceptor<T>
|
||||||
|
implements NestInterceptor<T, any>
|
||||||
|
{
|
||||||
|
public constructor(
|
||||||
|
private readonly configurationService: ConfigurationService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public intercept(
|
||||||
|
context: ExecutionContext,
|
||||||
|
next: CallHandler<T>
|
||||||
|
): Observable<any> {
|
||||||
|
const http = context.switchToHttp();
|
||||||
|
const request = http.getRequest();
|
||||||
|
|
||||||
|
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') === true) {
|
||||||
|
if (request.body.dataSource) {
|
||||||
|
request.body.dataSource = this.decodeDataSource(
|
||||||
|
request.body.dataSource
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.params.dataSource) {
|
||||||
|
request.params.dataSource = this.decodeDataSource(
|
||||||
|
request.params.dataSource
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next.handle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private decodeDataSource(encodeDataSource: string) {
|
||||||
|
return Buffer.from(encodeDataSource, 'hex').toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
import {
|
||||||
|
CallHandler,
|
||||||
|
ExecutionContext,
|
||||||
|
Injectable,
|
||||||
|
NestInterceptor
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { DataSource } from '@prisma/client';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { ConfigurationService } from '../services/configuration.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TransformDataSourceInResponseInterceptor<T>
|
||||||
|
implements NestInterceptor<T, any>
|
||||||
|
{
|
||||||
|
public constructor(
|
||||||
|
private readonly configurationService: ConfigurationService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public intercept(
|
||||||
|
context: ExecutionContext,
|
||||||
|
next: CallHandler<T>
|
||||||
|
): Observable<any> {
|
||||||
|
return next.handle().pipe(
|
||||||
|
map((data: any) => {
|
||||||
|
if (
|
||||||
|
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') === true
|
||||||
|
) {
|
||||||
|
if (data.activities) {
|
||||||
|
data.activities.map((activity) => {
|
||||||
|
activity.SymbolProfile.dataSource = this.encodeDataSource(
|
||||||
|
activity.SymbolProfile.dataSource
|
||||||
|
);
|
||||||
|
activity.dataSource = this.encodeDataSource(activity.dataSource);
|
||||||
|
return activity;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.dataSource) {
|
||||||
|
data.dataSource = this.encodeDataSource(data.dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.holdings) {
|
||||||
|
for (const symbol of Object.keys(data.holdings)) {
|
||||||
|
if (data.holdings[symbol].dataSource) {
|
||||||
|
data.holdings[symbol].dataSource = this.encodeDataSource(
|
||||||
|
data.holdings[symbol].dataSource
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.items) {
|
||||||
|
data.items.map((item) => {
|
||||||
|
item.dataSource = this.encodeDataSource(item.dataSource);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.positions) {
|
||||||
|
data.positions.map((position) => {
|
||||||
|
position.dataSource = this.encodeDataSource(position.dataSource);
|
||||||
|
return position;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private encodeDataSource(aDataSource: DataSource) {
|
||||||
|
return Buffer.from(aDataSource, 'utf-8').toString('hex');
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user