From 7999ff973b8aab86f1f6b064ec3424fa8a34207f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 2 Jan 2026 10:43:39 +0100 Subject: [PATCH 1/4] Bugfix/jsonpath import in manual service (#6129) * Fix jsonpath import * Update changelog --- CHANGELOG.md | 6 +++++ apps/api/src/helper/object.helper.spec.ts | 22 ++++++++++++++++++- apps/api/src/helper/object.helper.ts | 11 ++++++++++ .../data-provider/manual/manual.service.ts | 11 +++++++--- package-lock.json | 8 +++++++ package.json | 1 + 6 files changed, 55 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 088dd774b..2ee1be4c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed the import of `jsonpath` to support REST APIs (`JSON`) via the scraper configuration + ## 2.226.0 - 2026-01-01 ### Added diff --git a/apps/api/src/helper/object.helper.spec.ts b/apps/api/src/helper/object.helper.spec.ts index 433490325..e1ec81b8f 100644 --- a/apps/api/src/helper/object.helper.spec.ts +++ b/apps/api/src/helper/object.helper.spec.ts @@ -1,4 +1,24 @@ -import { redactAttributes } from './object.helper'; +import { query, redactAttributes } from './object.helper'; + +describe('query', () => { + it('should get market price from stock API response', () => { + const object = { + currency: 'USD', + market: { + previousClose: 273.04, + price: 271.86 + }, + symbol: 'AAPL' + }; + + const result = query({ + object, + pathExpression: '$.market.price' + })[0]; + + expect(result).toBe(271.86); + }); +}); describe('redactAttributes', () => { it('should redact provided attributes', () => { diff --git a/apps/api/src/helper/object.helper.ts b/apps/api/src/helper/object.helper.ts index a5854e9d9..6bb6579d2 100644 --- a/apps/api/src/helper/object.helper.ts +++ b/apps/api/src/helper/object.helper.ts @@ -1,4 +1,5 @@ import { Big } from 'big.js'; +import jsonpath from 'jsonpath'; import { cloneDeep, isArray, isObject } from 'lodash'; export function hasNotDefinedValuesInObject(aObject: Object): boolean { @@ -31,6 +32,16 @@ export function nullifyValuesInObjects(aObjects: T[], keys: string[]): T[] { }); } +export function query({ + object, + pathExpression +}: { + object: object; + pathExpression: string; +}) { + return jsonpath.query(object, pathExpression); +} + export function redactAttributes({ isFirstRun = true, object, 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 f18da49ab..7392f0914 100644 --- a/apps/api/src/services/data-provider/manual/manual.service.ts +++ b/apps/api/src/services/data-provider/manual/manual.service.ts @@ -1,3 +1,4 @@ +import { query } from '@ghostfolio/api/helper/object.helper'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { DataProviderInterface, @@ -26,7 +27,6 @@ import { Injectable, Logger } from '@nestjs/common'; import { DataSource, SymbolProfile } from '@prisma/client'; import * as cheerio from 'cheerio'; import { addDays, format, isBefore } from 'date-fns'; -import * as jsonpath from 'jsonpath'; @Injectable() export class ManualService implements DataProviderInterface { @@ -286,9 +286,14 @@ export class ManualService implements DataProviderInterface { let value: string; if (response.headers.get('content-type')?.includes('application/json')) { - const data = await response.json(); + const object = await response.json(); - value = String(jsonpath.query(data, scraperConfiguration.selector)[0]); + value = String( + query({ + object, + pathExpression: scraperConfiguration.selector + })[0] + ); } else { const $ = cheerio.load(await response.text()); diff --git a/package-lock.json b/package-lock.json index 9e897adc4..6512d2162 100644 --- a/package-lock.json +++ b/package-lock.json @@ -124,6 +124,7 @@ "@types/big.js": "6.2.2", "@types/google-spreadsheet": "3.1.5", "@types/jest": "30.0.0", + "@types/jsonpath": "0.2.4", "@types/lodash": "4.17.20", "@types/node": "22.15.17", "@types/papaparse": "5.3.7", @@ -12436,6 +12437,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/jsonpath": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@types/jsonpath/-/jsonpath-0.2.4.tgz", + "integrity": "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/jsonwebtoken": { "version": "9.0.10", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", diff --git a/package.json b/package.json index 464a9a7cd..59a455ae1 100644 --- a/package.json +++ b/package.json @@ -168,6 +168,7 @@ "@types/big.js": "6.2.2", "@types/google-spreadsheet": "3.1.5", "@types/jest": "30.0.0", + "@types/jsonpath": "0.2.4", "@types/lodash": "4.17.20", "@types/node": "22.15.17", "@types/papaparse": "5.3.7", From 6d3e16a6fb931404d39c9c4919e70fcd184d77e6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 2 Jan 2026 11:15:17 +0100 Subject: [PATCH 2/4] Bugfix/initialize input properties in fire calculator (#6122) * Initialize input properties * Update changelog --- CHANGELOG.md | 4 ++++ .../fire-calculator/fire-calculator.component.stories.ts | 4 +++- .../src/lib/fire-calculator/fire-calculator.component.ts | 8 ++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ee1be4c1..d9028e21c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Initialized the input properties in the _FIRE_ calculator + ### Fixed - Fixed the import of `jsonpath` to support REST APIs (`JSON`) via the scraper configuration diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts index e4cfa18ea..0872c2aac 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.stories.ts @@ -44,8 +44,10 @@ type Story = StoryObj; export const Simple: Story = { args: { + annualInterestRate: 5, currency: 'USD', fireWealth: 50000, - locale: locale + locale: locale, + savingsRate: 1000 } }; diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts index 655798b3d..6b0bc8dcb 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -77,16 +77,16 @@ import { FireCalculatorService } from './fire-calculator.service'; templateUrl: './fire-calculator.component.html' }) export class GfFireCalculatorComponent implements OnChanges, OnDestroy { - @Input() annualInterestRate: number; + @Input() annualInterestRate = 0; @Input() colorScheme: ColorScheme; @Input() currency: string; @Input() deviceType: string; - @Input() fireWealth: number; + @Input() fireWealth = 0; @Input() hasPermissionToUpdateUserSettings: boolean; @Input() locale = getLocale(); - @Input() projectedTotalAmount: number; + @Input() projectedTotalAmount = 0; @Input() retirementDate: Date; - @Input() savingsRate: number; + @Input() savingsRate = 0; @Output() annualInterestRateChanged = new EventEmitter(); @Output() calculationCompleted = From a1fab9fdf36f415bac5fbf5a83257582f6cdac24 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 2 Jan 2026 11:28:04 +0100 Subject: [PATCH 3/4] Task/upgrade stripe to version 20.1.0 (#6132) * Upgrade stripe to version 20.1.0 * Update changelog --- CHANGELOG.md | 1 + .../api/src/app/subscription/subscription.service.ts | 2 +- package-lock.json | 12 ++++++------ package.json | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9028e21c..d438e0610 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Initialized the input properties in the _FIRE_ calculator +- Upgraded `stripe` from version `18.5.0` to `20.1.0` ### Fixed diff --git a/apps/api/src/app/subscription/subscription.service.ts b/apps/api/src/app/subscription/subscription.service.ts index 8dc7d27f1..b38b07bb4 100644 --- a/apps/api/src/app/subscription/subscription.service.ts +++ b/apps/api/src/app/subscription/subscription.service.ts @@ -35,7 +35,7 @@ export class SubscriptionService { this.stripe = new Stripe( this.configurationService.get('STRIPE_SECRET_KEY'), { - apiVersion: '2025-08-27.basil' + apiVersion: '2025-12-15.clover' } ); } diff --git a/package-lock.json b/package-lock.json index 6512d2162..d1a228ade 100644 --- a/package-lock.json +++ b/package-lock.json @@ -84,7 +84,7 @@ "passport-openidconnect": "0.1.2", "reflect-metadata": "0.2.2", "rxjs": "7.8.1", - "stripe": "18.5.0", + "stripe": "20.1.0", "svgmap": "2.14.0", "tablemark": "4.1.0", "twitter-api-v2": "1.27.0", @@ -31464,18 +31464,18 @@ } }, "node_modules/stripe": { - "version": "18.5.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-18.5.0.tgz", - "integrity": "sha512-Hp+wFiEQtCB0LlNgcFh5uVyKznpDjzyUZ+CNVEf+I3fhlYvh7rZruIg+jOwzJRCpy0ZTPMjlzm7J2/M2N6d+DA==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-20.1.0.tgz", + "integrity": "sha512-o1VNRuMkY76ZCq92U3EH3/XHm/WHp7AerpzDs4Zyo8uE5mFL4QUcv/2SudWsSnhBSp4moO2+ZoGCZ7mT8crPmQ==", "license": "MIT", "dependencies": { "qs": "^6.11.0" }, "engines": { - "node": ">=12.*" + "node": ">=16" }, "peerDependencies": { - "@types/node": ">=12.x.x" + "@types/node": ">=16" }, "peerDependenciesMeta": { "@types/node": { diff --git a/package.json b/package.json index 59a455ae1..b887010cd 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "passport-openidconnect": "0.1.2", "reflect-metadata": "0.2.2", "rxjs": "7.8.1", - "stripe": "18.5.0", + "stripe": "20.1.0", "svgmap": "2.14.0", "tablemark": "4.1.0", "twitter-api-v2": "1.27.0", From a6011f2c47532195a044abdc337b8f2adbe49e1f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 2 Jan 2026 12:16:20 +0100 Subject: [PATCH 4/4] Task/remove deprecated public Stripe key (#6124) * Remove deprecated public Stripe key * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/info/info.service.ts | 1 - apps/api/src/services/configuration/configuration.service.ts | 1 - apps/api/src/services/interfaces/environment.interface.ts | 1 - 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d438e0610..22acc4090 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Initialized the input properties in the _FIRE_ calculator +- Removed the deprecated public _Stripe_ key - Upgraded `stripe` from version `18.5.0` to `20.1.0` ### Fixed diff --git a/apps/api/src/app/info/info.service.ts b/apps/api/src/app/info/info.service.ts index 3802e3ef4..c5152c1a2 100644 --- a/apps/api/src/app/info/info.service.ts +++ b/apps/api/src/app/info/info.service.ts @@ -93,7 +93,6 @@ export class InfoService { (await this.propertyService.getByKey( PROPERTY_COUNTRIES_OF_SUBSCRIBERS )) ?? []; - info.stripePublicKey = this.configurationService.get('STRIPE_PUBLIC_KEY'); } if (this.configurationService.get('ENABLE_FEATURE_SYSTEM_MESSAGE')) { diff --git a/apps/api/src/services/configuration/configuration.service.ts b/apps/api/src/services/configuration/configuration.service.ts index a91aa6e69..5f9d1055d 100644 --- a/apps/api/src/services/configuration/configuration.service.ts +++ b/apps/api/src/services/configuration/configuration.service.ts @@ -102,7 +102,6 @@ export class ConfigurationService { ROOT_URL: url({ default: environment.rootUrl }), - STRIPE_PUBLIC_KEY: str({ default: '' }), STRIPE_SECRET_KEY: str({ default: '' }), TWITTER_ACCESS_TOKEN: str({ default: 'dummyAccessToken' }), TWITTER_ACCESS_TOKEN_SECRET: str({ default: 'dummyAccessTokenSecret' }), diff --git a/apps/api/src/services/interfaces/environment.interface.ts b/apps/api/src/services/interfaces/environment.interface.ts index 3c03744f1..57c58898e 100644 --- a/apps/api/src/services/interfaces/environment.interface.ts +++ b/apps/api/src/services/interfaces/environment.interface.ts @@ -52,7 +52,6 @@ export interface Environment extends CleanedEnvAccessors { REDIS_PORT: number; REQUEST_TIMEOUT: number; ROOT_URL: string; - STRIPE_PUBLIC_KEY: string; STRIPE_SECRET_KEY: string; TWITTER_ACCESS_TOKEN: string; TWITTER_ACCESS_TOKEN_SECRET: string;