Merge branch 'main' of gitea.suda.codes:giteauser/ghostfolio-mirror
This commit is contained in:
commit
3fa32b2ae9
@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 2.106.0-beta.3 - 2024-08-28
|
||||
## 2.106.0-beta.5 - 2024-08-31
|
||||
|
||||
### Added
|
||||
|
||||
@ -14,9 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
|
||||
- Reworked the portfolio calculator
|
||||
- Improved the caching of the portfolio snapshot in the portfolio calculator by returning cached data and recalculating in the background when it expires
|
||||
- Exposed the log levels as an environment variable (`LOG_LEVELS`)
|
||||
- Exposed the maximum of chart data items as an environment variable (`MAX_CHART_ITEMS`)
|
||||
- Changed the data format of the environment variable `CACHE_QUOTES_TTL` from seconds to milliseconds
|
||||
- Changed the data format of the environment variable `CACHE_TTL` from seconds to milliseconds
|
||||
- Removed the environment variable `MAX_ITEM_IN_CACHE`
|
||||
- Improved the language localization for Polish (`pl`)
|
||||
- Migrated from `cache-manager-redis-store` to `cache-manager-redis-yet`
|
||||
- Upgraded `cache-manager` from version `3.4.3` to `5.7.6`
|
||||
- Upgraded `prisma` from version `5.18.0` to `5.19.0`
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -443,7 +443,7 @@ export class BenchmarkService {
|
||||
benchmarks,
|
||||
expiration: expiration.getTime()
|
||||
}),
|
||||
ms('12 hours') / 1000
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
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';
|
||||
@ -32,6 +33,7 @@ import { Logger } from '@nestjs/common';
|
||||
import { Big } from 'big.js';
|
||||
import { plainToClass } from 'class-transformer';
|
||||
import {
|
||||
addMilliseconds,
|
||||
differenceInDays,
|
||||
eachDayOfInterval,
|
||||
endOfDay,
|
||||
@ -863,6 +865,29 @@ export abstract class PortfolioCalculator {
|
||||
return chartDateMap;
|
||||
}
|
||||
|
||||
private async computeAndCacheSnapshot() {
|
||||
const snapshot = await this.computeSnapshot();
|
||||
|
||||
const expiration = addMilliseconds(
|
||||
new Date(),
|
||||
this.configurationService.get('CACHE_QUOTES_TTL')
|
||||
);
|
||||
|
||||
this.redisCacheService.set(
|
||||
this.redisCacheService.getPortfolioSnapshotKey({
|
||||
filters: this.filters,
|
||||
userId: this.userId
|
||||
}),
|
||||
JSON.stringify(<PortfolioSnapshotValue>(<unknown>{
|
||||
expiration: expiration.getTime(),
|
||||
portfolioSnapshot: snapshot
|
||||
})),
|
||||
0
|
||||
);
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
@LogPerformance
|
||||
private computeTransactionPoints() {
|
||||
this.transactionPoints = [];
|
||||
@ -1006,19 +1031,33 @@ export abstract class PortfolioCalculator {
|
||||
private async initialize() {
|
||||
const startTimeTotal = performance.now();
|
||||
|
||||
const cachedSnapshot = await this.redisCacheService.get(
|
||||
this.redisCacheService.getPortfolioSnapshotKey({
|
||||
filters: this.filters,
|
||||
userId: this.userId
|
||||
})
|
||||
);
|
||||
let cachedPortfolioSnapshot: PortfolioSnapshot;
|
||||
let isCachedPortfolioSnapshotExpired = false;
|
||||
|
||||
if (cachedSnapshot) {
|
||||
this.snapshot = plainToClass(
|
||||
PortfolioSnapshot,
|
||||
JSON.parse(cachedSnapshot)
|
||||
try {
|
||||
const cachedPortfolioSnapshotValue = await this.redisCacheService.get(
|
||||
this.redisCacheService.getPortfolioSnapshotKey({
|
||||
filters: this.filters,
|
||||
userId: this.userId
|
||||
})
|
||||
);
|
||||
|
||||
const { expiration, portfolioSnapshot }: PortfolioSnapshotValue =
|
||||
JSON.parse(cachedPortfolioSnapshotValue);
|
||||
|
||||
cachedPortfolioSnapshot = plainToClass(
|
||||
PortfolioSnapshot,
|
||||
portfolioSnapshot
|
||||
);
|
||||
|
||||
if (isAfter(new Date(), new Date(expiration))) {
|
||||
isCachedPortfolioSnapshotExpired = true;
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (cachedPortfolioSnapshot) {
|
||||
this.snapshot = cachedPortfolioSnapshot;
|
||||
|
||||
Logger.debug(
|
||||
`Fetched portfolio snapshot from cache in ${(
|
||||
(performance.now() - startTimeTotal) /
|
||||
@ -1026,17 +1065,14 @@ export abstract class PortfolioCalculator {
|
||||
).toFixed(3)} seconds`,
|
||||
'PortfolioCalculator'
|
||||
);
|
||||
} else {
|
||||
this.snapshot = await this.computeSnapshot();
|
||||
|
||||
this.redisCacheService.set(
|
||||
this.redisCacheService.getPortfolioSnapshotKey({
|
||||
filters: this.filters,
|
||||
userId: this.userId
|
||||
}),
|
||||
JSON.stringify(this.snapshot),
|
||||
this.configurationService.get('CACHE_QUOTES_TTL')
|
||||
);
|
||||
if (isCachedPortfolioSnapshotExpired) {
|
||||
// Compute in the background
|
||||
this.computeAndCacheSnapshot();
|
||||
}
|
||||
} else {
|
||||
// Wait for computation
|
||||
this.snapshot = await this.computeAndCacheSnapshot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
export interface PortfolioSnapshotValue {
|
||||
expiration: number;
|
||||
portfolioSnapshot: string;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { Cache } from 'cache-manager';
|
||||
|
||||
import type { RedisStore } from './redis-store.interface';
|
||||
|
||||
export interface RedisCache extends Cache {
|
||||
store: RedisStore;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Store } from 'cache-manager';
|
||||
import { createClient } from 'redis';
|
||||
|
||||
export interface RedisStore extends Store {
|
||||
getClient: () => ReturnType<typeof createClient>;
|
||||
isCacheableValue: (value: any) => boolean;
|
||||
name: 'redis';
|
||||
}
|
@ -3,31 +3,31 @@ import { ConfigurationService } from '@ghostfolio/api/services/configuration/con
|
||||
|
||||
import { CacheModule } from '@nestjs/cache-manager';
|
||||
import { Module } from '@nestjs/common';
|
||||
import * as redisStore from 'cache-manager-redis-store';
|
||||
import { redisStore } from 'cache-manager-redis-yet';
|
||||
import type { RedisClientOptions } from 'redis';
|
||||
|
||||
import { RedisCacheService } from './redis-cache.service';
|
||||
|
||||
@Module({
|
||||
exports: [RedisCacheService],
|
||||
imports: [
|
||||
CacheModule.registerAsync({
|
||||
CacheModule.registerAsync<RedisClientOptions>({
|
||||
imports: [ConfigurationModule],
|
||||
inject: [ConfigurationService],
|
||||
useFactory: async (configurationService: ConfigurationService) => {
|
||||
const redisPassword = encodeURIComponent(
|
||||
configurationService.get('REDIS_PASSWORD')
|
||||
);
|
||||
|
||||
return <RedisClientOptions>{
|
||||
db: configurationService.get('REDIS_DB'),
|
||||
host: configurationService.get('REDIS_HOST'),
|
||||
max: configurationService.get('MAX_ITEM_IN_CACHE'),
|
||||
password: configurationService.get('REDIS_PASSWORD'),
|
||||
port: configurationService.get('REDIS_PORT'),
|
||||
store: redisStore,
|
||||
ttl: configurationService.get('CACHE_TTL')
|
||||
ttl: configurationService.get('CACHE_TTL'),
|
||||
url: `redis://${redisPassword ? `:${redisPassword}` : ''}@${configurationService.get('REDIS_HOST')}:${configurationService.get('REDIS_PORT')}/${configurationService.get('REDIS_DB')}`
|
||||
};
|
||||
}
|
||||
}),
|
||||
ConfigurationModule
|
||||
],
|
||||
providers: [RedisCacheService],
|
||||
exports: [RedisCacheService]
|
||||
providers: [RedisCacheService]
|
||||
})
|
||||
export class RedisCacheModule {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { RedisCacheService } from './redis-cache.service';
|
||||
import { Milliseconds } from 'cache-manager';
|
||||
|
||||
export const RedisCacheServiceMock = {
|
||||
get: (key: string): Promise<string> => {
|
||||
@ -7,7 +7,7 @@ export const RedisCacheServiceMock = {
|
||||
getPortfolioSnapshotKey: (userId: string): string => {
|
||||
return `portfolio-snapshot-${userId}`;
|
||||
},
|
||||
set: (key: string, value: string, ttlInSeconds?: number): Promise<string> => {
|
||||
set: (key: string, value: string, ttl?: Milliseconds): Promise<string> => {
|
||||
return Promise.resolve(value);
|
||||
}
|
||||
};
|
||||
|
@ -4,17 +4,17 @@ import { AssetProfileIdentifier, Filter } from '@ghostfolio/common/interfaces';
|
||||
|
||||
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { Milliseconds } from 'cache-manager';
|
||||
import { RedisCache } from 'cache-manager-redis-yet';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
import type { RedisCache } from './interfaces/redis-cache.interface';
|
||||
|
||||
@Injectable()
|
||||
export class RedisCacheService {
|
||||
public constructor(
|
||||
@Inject(CACHE_MANAGER) private readonly cache: RedisCache,
|
||||
private readonly configurationService: ConfigurationService
|
||||
) {
|
||||
const client = cache.store.getClient();
|
||||
const client = cache.store.client;
|
||||
|
||||
client.on('error', (error) => {
|
||||
Logger.error(error, 'RedisCacheService');
|
||||
@ -81,11 +81,11 @@ export class RedisCacheService {
|
||||
return this.cache.reset();
|
||||
}
|
||||
|
||||
public async set(key: string, value: string, ttlInSeconds?: number) {
|
||||
public async set(key: string, value: string, ttl?: Milliseconds) {
|
||||
return this.cache.set(
|
||||
key,
|
||||
value,
|
||||
ttlInSeconds ?? this.configurationService.get('CACHE_TTL')
|
||||
ttl ?? this.configurationService.get('CACHE_TTL')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ export class ConfigurationService {
|
||||
API_KEY_FINANCIAL_MODELING_PREP: str({ default: '' }),
|
||||
API_KEY_OPEN_FIGI: str({ default: '' }),
|
||||
API_KEY_RAPID_API: str({ default: '' }),
|
||||
CACHE_QUOTES_TTL: num({ default: ms('1 minute') / 1000 }),
|
||||
CACHE_QUOTES_TTL: num({ default: ms('1 minute') }),
|
||||
CACHE_TTL: num({ default: 1 }),
|
||||
DATA_SOURCE_EXCHANGE_RATES: str({ default: DataSource.YAHOO }),
|
||||
DATA_SOURCE_IMPORT: str({ default: DataSource.YAHOO }),
|
||||
@ -43,7 +43,6 @@ export class ConfigurationService {
|
||||
JWT_SECRET_KEY: str({}),
|
||||
MAX_ACTIVITIES_TO_IMPORT: num({ default: Number.MAX_SAFE_INTEGER }),
|
||||
MAX_CHART_ITEMS: num({ default: 365 }),
|
||||
MAX_ITEM_IN_CACHE: num({ default: 9999 }),
|
||||
PORT: port({ default: 3333 }),
|
||||
REDIS_DB: num({ default: 0 }),
|
||||
REDIS_HOST: str({ default: 'localhost' }),
|
||||
|
@ -29,7 +29,6 @@ export interface Environment extends CleanedEnvAccessors {
|
||||
JWT_SECRET_KEY: string;
|
||||
MAX_ACTIVITIES_TO_IMPORT: number;
|
||||
MAX_CHART_ITEMS: number;
|
||||
MAX_ITEM_IN_CACHE: number;
|
||||
PORT: number;
|
||||
REDIS_DB: number;
|
||||
REDIS_HOST: string;
|
||||
|
File diff suppressed because it is too large
Load Diff
295
package-lock.json
generated
295
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ghostfolio",
|
||||
"version": "2.103.0",
|
||||
"version": "2.106.0-beta.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ghostfolio",
|
||||
"version": "2.103.0",
|
||||
"version": "2.106.0-beta.3",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
@ -30,7 +30,7 @@
|
||||
"@dinero.js/currencies": "2.0.0-alpha.8",
|
||||
"@internationalized/number": "3.5.2",
|
||||
"@nestjs/bull": "10.0.1",
|
||||
"@nestjs/cache-manager": "2.1.0",
|
||||
"@nestjs/cache-manager": "2.2.2",
|
||||
"@nestjs/common": "10.1.3",
|
||||
"@nestjs/config": "3.0.0",
|
||||
"@nestjs/core": "10.1.3",
|
||||
@ -40,7 +40,7 @@
|
||||
"@nestjs/platform-express": "10.1.3",
|
||||
"@nestjs/schedule": "3.0.2",
|
||||
"@nestjs/serve-static": "4.0.0",
|
||||
"@prisma/client": "5.18.0",
|
||||
"@prisma/client": "5.19.0",
|
||||
"@simplewebauthn/browser": "9.0.1",
|
||||
"@simplewebauthn/server": "9.0.3",
|
||||
"@stripe/stripe-js": "3.5.0",
|
||||
@ -49,8 +49,8 @@
|
||||
"body-parser": "1.20.2",
|
||||
"bootstrap": "4.6.0",
|
||||
"bull": "4.10.4",
|
||||
"cache-manager": "3.4.3",
|
||||
"cache-manager-redis-store": "2.0.0",
|
||||
"cache-manager": "5.7.6",
|
||||
"cache-manager-redis-yet": "5.1.4",
|
||||
"chart.js": "4.2.0",
|
||||
"chartjs-adapter-date-fns": "3.0.0",
|
||||
"chartjs-chart-treemap": "2.3.1",
|
||||
@ -84,7 +84,7 @@
|
||||
"passport": "0.7.0",
|
||||
"passport-google-oauth20": "2.0.0",
|
||||
"passport-jwt": "4.0.1",
|
||||
"prisma": "5.18.0",
|
||||
"prisma": "5.19.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rxjs": "7.5.6",
|
||||
"stripe": "15.11.0",
|
||||
@ -126,7 +126,7 @@
|
||||
"@trivago/prettier-plugin-sort-imports": "4.3.0",
|
||||
"@types/big.js": "6.2.2",
|
||||
"@types/body-parser": "1.19.5",
|
||||
"@types/cache-manager": "3.4.2",
|
||||
"@types/cache-manager": "4.0.6",
|
||||
"@types/color": "3.0.6",
|
||||
"@types/google-spreadsheet": "3.1.5",
|
||||
"@types/jest": "29.4.4",
|
||||
@ -6800,14 +6800,14 @@
|
||||
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
||||
},
|
||||
"node_modules/@nestjs/cache-manager": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-2.1.0.tgz",
|
||||
"integrity": "sha512-9kep3a8Mq5cMuXN/anGhSYc0P48CRBXk5wyJJRBFxhNkCH8AIzZF4CASGVDIEMmm3OjVcEUHojjyJwCODS17Qw==",
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-2.2.2.tgz",
|
||||
"integrity": "sha512-+n7rpU1QABeW2WV17Dl1vZCG3vWjJU1MaamWgZvbGxYE9EeCM0lVLfw3z7acgDTNwOy+K68xuQPoIMxD0bhjlA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^9.0.0 || ^10.0.0",
|
||||
"@nestjs/core": "^9.0.0 || ^10.0.0",
|
||||
"cache-manager": "<=5",
|
||||
"reflect-metadata": "^0.1.12",
|
||||
"rxjs": "^7.0.0"
|
||||
}
|
||||
},
|
||||
@ -9646,9 +9646,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@prisma/client": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.18.0.tgz",
|
||||
"integrity": "sha512-BWivkLh+af1kqC89zCJYkHsRcyWsM8/JHpsDMM76DjP3ZdEquJhXa4IeX+HkWPnwJ5FanxEJFZZDTWiDs/Kvyw==",
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.19.0.tgz",
|
||||
"integrity": "sha512-CzOpau+q1kEWQyoQMvlnXIHqPvwmWbh48xZ4n8KWbAql0p8PC0BIgSTYW5ncxXa4JSEff0tcoxSZB874wDstdg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
@ -9664,48 +9664,113 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/debug": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.18.0.tgz",
|
||||
"integrity": "sha512-f+ZvpTLidSo3LMJxQPVgAxdAjzv5OpzAo/eF8qZqbwvgi2F5cTOI9XCpdRzJYA0iGfajjwjOKKrVq64vkxEfUw==",
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.19.0.tgz",
|
||||
"integrity": "sha512-+b/G0ubAZlrS+JSiDhXnYV5DF/aTJ3pinktkiV/L4TtLRLZO6SVGyFELgxBsicCTWJ2ZMu5vEV/jTtYCdjFTRA==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/engines": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.18.0.tgz",
|
||||
"integrity": "sha512-ofmpGLeJ2q2P0wa/XaEgTnX/IsLnvSp/gZts0zjgLNdBhfuj2lowOOPmDcfKljLQUXMvAek3lw5T01kHmCG8rg==",
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.19.0.tgz",
|
||||
"integrity": "sha512-UtW+0m4HYoRSSR3LoDGKF3Ud4BSMWYlLEt4slTnuP1mI+vrV3zaDoiAPmejdAT76vCN5UqnWURbkXxf66nSylQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "5.18.0",
|
||||
"@prisma/engines-version": "5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169",
|
||||
"@prisma/fetch-engine": "5.18.0",
|
||||
"@prisma/get-platform": "5.18.0"
|
||||
"@prisma/debug": "5.19.0",
|
||||
"@prisma/engines-version": "5.19.0-31.5fe21811a6ba0b952a3bc71400666511fe3b902f",
|
||||
"@prisma/fetch-engine": "5.19.0",
|
||||
"@prisma/get-platform": "5.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/engines-version": {
|
||||
"version": "5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169.tgz",
|
||||
"integrity": "sha512-a/+LpJj8vYU3nmtkg+N3X51ddbt35yYrRe8wqHTJtYQt7l1f8kjIBcCs6sHJvodW/EK5XGvboOiwm47fmNrbgg==",
|
||||
"version": "5.19.0-31.5fe21811a6ba0b952a3bc71400666511fe3b902f",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.19.0-31.5fe21811a6ba0b952a3bc71400666511fe3b902f.tgz",
|
||||
"integrity": "sha512-GimI9aZIFy/yvvR11KfXRn3pliFn1QAkdebVlsXlnoh5uk0YhLblVmeYiHfsu+wDA7BeKqYT4sFfzg8mutzuWw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@prisma/fetch-engine": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.18.0.tgz",
|
||||
"integrity": "sha512-I/3u0x2n31rGaAuBRx2YK4eB7R/1zCuayo2DGwSpGyrJWsZesrV7QVw7ND0/Suxeo/vLkJ5OwuBqHoCxvTHpOg==",
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.19.0.tgz",
|
||||
"integrity": "sha512-oOiPNtmJX0cP/ebu7BBEouJvCw8T84/MFD/Hf2zlqjxkK4ojl38bB9i9J5LAxotL6WlYVThKdxc7HqoWnPOhqQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "5.18.0",
|
||||
"@prisma/engines-version": "5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169",
|
||||
"@prisma/get-platform": "5.18.0"
|
||||
"@prisma/debug": "5.19.0",
|
||||
"@prisma/engines-version": "5.19.0-31.5fe21811a6ba0b952a3bc71400666511fe3b902f",
|
||||
"@prisma/get-platform": "5.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/get-platform": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.18.0.tgz",
|
||||
"integrity": "sha512-Tk+m7+uhqcKDgnMnFN0lRiH7Ewea0OEsZZs9pqXa7i3+7svS3FSCqDBCaM9x5fmhhkufiG0BtunJVDka+46DlA==",
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.19.0.tgz",
|
||||
"integrity": "sha512-s9DWkZKnuP4Y8uy6yZfvqQ/9X3/+2KYf3IZUVZz5OstJdGBJrBlbmIuMl81917wp5TuK/1k2TpHNCEdpYLPKmg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/debug": "5.18.0"
|
||||
"@prisma/debug": "5.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/bloom": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
|
||||
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/client": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz",
|
||||
"integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cluster-key-slot": "1.1.2",
|
||||
"generic-pool": "3.9.0",
|
||||
"yallist": "4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/client/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@redis/graph": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
|
||||
"integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/json": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
|
||||
"integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/search": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
|
||||
"integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@redis/time-series": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
|
||||
"integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@redis/client": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
@ -11468,10 +11533,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cache-manager": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/cache-manager/-/cache-manager-3.4.2.tgz",
|
||||
"integrity": "sha512-1IwA74t5ID4KWo0Kndal16MhiPSZgMe1fGc+MLT6j5r+Ab7jku36PFTl4PP6MiWw0BJscM9QpZEo00qixNQoRg==",
|
||||
"dev": true
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/cache-manager/-/cache-manager-4.0.6.tgz",
|
||||
"integrity": "sha512-8qL93MF05/xrzFm/LSPtzNEOE1eQF3VwGHAcQEylgp5hDSTe41jtFwbSYAPfyYcVa28y1vYSjIt0c1fLLUiC/Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/cacheable-request": {
|
||||
"version": "6.0.3",
|
||||
@ -13255,7 +13321,8 @@
|
||||
"node_modules/async": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
|
||||
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw=="
|
||||
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
@ -14243,41 +14310,50 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cache-manager": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-3.4.3.tgz",
|
||||
"integrity": "sha512-6+Hfzy1SNs/thUwo+07pV0ozgxc4sadrAN0eFVGvXl/X9nz3J0BqEnnEoyxEn8jnF+UkEo0MKpyk9BO80hMeiQ==",
|
||||
"version": "5.7.6",
|
||||
"resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.7.6.tgz",
|
||||
"integrity": "sha512-wBxnBHjDxF1RXpHCBD6HGvKER003Ts7IIm0CHpggliHzN1RZditb7rXoduE1rplc2DEFYKxhLKgFuchXMJje9w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"async": "3.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lru-cache": "6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cache-manager-redis-store": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cache-manager-redis-store/-/cache-manager-redis-store-2.0.0.tgz",
|
||||
"integrity": "sha512-bWLWlUg6nCYHiJLCCYxY2MgvwvKnvlWwrbuynrzpjEIhfArD2GC9LtutIHFEPeyGVQN6C+WEw+P3r+BFBwhswg==",
|
||||
"dependencies": {
|
||||
"redis": "^3.0.2"
|
||||
"eventemitter3": "^5.0.1",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"lru-cache": "^10.2.2",
|
||||
"promise-coalesce": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.3"
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/cache-manager-redis-yet": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cache-manager-redis-yet/-/cache-manager-redis-yet-5.1.4.tgz",
|
||||
"integrity": "sha512-2mXZjo+txfH2m+mSTHTITNq8c5SssU2nP7NutzrocO3Mw/SbjHcDo+mriI3ZuR63ov/oUUIaF9iF+MzDqVzMoQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@redis/bloom": "^1.2.0",
|
||||
"@redis/client": "^1.6.0",
|
||||
"@redis/graph": "^1.1.1",
|
||||
"@redis/json": "^1.0.7",
|
||||
"@redis/search": "^1.2.0",
|
||||
"@redis/time-series": "^1.1.0",
|
||||
"cache-manager": "^5.7.6",
|
||||
"redis": "^4.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/cache-manager/node_modules/eventemitter3": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cache-manager/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/cache-manager/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/cacheable-lookup": {
|
||||
"version": "5.0.4",
|
||||
@ -19466,6 +19542,15 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/generic-pool": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
|
||||
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
@ -24555,6 +24640,12 @@
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/lodash.clonedeep": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
||||
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.clonedeepwith": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz",
|
||||
@ -28738,19 +28829,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prisma": {
|
||||
"version": "5.18.0",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.18.0.tgz",
|
||||
"integrity": "sha512-+TrSIxZsh64OPOmaSgVPH7ALL9dfU0jceYaMJXsNrTkFHO7/3RANi5K2ZiPB1De9+KDxCWn7jvRq8y8pvk+o9g==",
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.19.0.tgz",
|
||||
"integrity": "sha512-Pu7lUKpVyTx8cVwM26dYh8NdvMOkMnJXzE8L6cikFuR4JwyMU5NKofQkWyxJKlTT4fNjmcnibTvklV8oVMrn+g==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@prisma/engines": "5.18.0"
|
||||
"@prisma/engines": "5.19.0"
|
||||
},
|
||||
"bin": {
|
||||
"prisma": "build/index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.13"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/prismjs": {
|
||||
@ -28785,6 +28879,15 @@
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"node_modules/promise-coalesce": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/promise-coalesce/-/promise-coalesce-1.1.2.tgz",
|
||||
"integrity": "sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/promise-inflight": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
|
||||
@ -29125,28 +29228,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/redis": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
|
||||
"integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
|
||||
"version": "4.7.0",
|
||||
"resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz",
|
||||
"integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"./packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"denque": "^1.5.0",
|
||||
"redis-commands": "^1.7.0",
|
||||
"redis-errors": "^1.2.0",
|
||||
"redis-parser": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/node-redis"
|
||||
"@redis/bloom": "1.2.0",
|
||||
"@redis/client": "1.6.0",
|
||||
"@redis/graph": "1.1.1",
|
||||
"@redis/json": "1.0.7",
|
||||
"@redis/search": "1.2.0",
|
||||
"@redis/time-series": "1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/redis-commands": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
|
||||
"integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
|
||||
},
|
||||
"node_modules/redis-errors": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
|
||||
@ -29166,14 +29263,6 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/redis/node_modules/denque": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
|
||||
"integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect-metadata": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
|
||||
|
14
package.json
14
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ghostfolio",
|
||||
"version": "2.106.0-beta.3",
|
||||
"version": "2.106.0-beta.5",
|
||||
"homepage": "https://ghostfol.io",
|
||||
"license": "AGPL-3.0",
|
||||
"repository": "https://github.com/ghostfolio/ghostfolio",
|
||||
@ -74,7 +74,7 @@
|
||||
"@dinero.js/currencies": "2.0.0-alpha.8",
|
||||
"@internationalized/number": "3.5.2",
|
||||
"@nestjs/bull": "10.0.1",
|
||||
"@nestjs/cache-manager": "2.1.0",
|
||||
"@nestjs/cache-manager": "2.2.2",
|
||||
"@nestjs/common": "10.1.3",
|
||||
"@nestjs/config": "3.0.0",
|
||||
"@nestjs/core": "10.1.3",
|
||||
@ -84,7 +84,7 @@
|
||||
"@nestjs/platform-express": "10.1.3",
|
||||
"@nestjs/schedule": "3.0.2",
|
||||
"@nestjs/serve-static": "4.0.0",
|
||||
"@prisma/client": "5.18.0",
|
||||
"@prisma/client": "5.19.0",
|
||||
"@simplewebauthn/browser": "9.0.1",
|
||||
"@simplewebauthn/server": "9.0.3",
|
||||
"@stripe/stripe-js": "3.5.0",
|
||||
@ -93,8 +93,8 @@
|
||||
"body-parser": "1.20.2",
|
||||
"bootstrap": "4.6.0",
|
||||
"bull": "4.10.4",
|
||||
"cache-manager": "3.4.3",
|
||||
"cache-manager-redis-store": "2.0.0",
|
||||
"cache-manager": "5.7.6",
|
||||
"cache-manager-redis-yet": "5.1.4",
|
||||
"chart.js": "4.2.0",
|
||||
"chartjs-adapter-date-fns": "3.0.0",
|
||||
"chartjs-chart-treemap": "2.3.1",
|
||||
@ -128,7 +128,7 @@
|
||||
"passport": "0.7.0",
|
||||
"passport-google-oauth20": "2.0.0",
|
||||
"passport-jwt": "4.0.1",
|
||||
"prisma": "5.18.0",
|
||||
"prisma": "5.19.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
"rxjs": "7.5.6",
|
||||
"stripe": "15.11.0",
|
||||
@ -170,7 +170,7 @@
|
||||
"@trivago/prettier-plugin-sort-imports": "4.3.0",
|
||||
"@types/big.js": "6.2.2",
|
||||
"@types/body-parser": "1.19.5",
|
||||
"@types/cache-manager": "3.4.2",
|
||||
"@types/cache-manager": "4.0.6",
|
||||
"@types/color": "3.0.6",
|
||||
"@types/google-spreadsheet": "3.1.5",
|
||||
"@types/jest": "29.4.4",
|
||||
|
Loading…
x
Reference in New Issue
Block a user