Browse Source

Merge branch 'main' into Task/remove-deprecated-public-stripe-key

pull/6124/head
Thomas Kaul 1 month ago
committed by GitHub
parent
commit
6fdac0f218
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      CHANGELOG.md
  2. 6
      README.md
  3. 22
      apps/api/src/helper/object.helper.spec.ts
  4. 11
      apps/api/src/helper/object.helper.ts
  5. 11
      apps/api/src/services/data-provider/manual/manual.service.ts
  6. 17
      apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html
  7. 38
      package-lock.json
  8. 7
      package.json

15
CHANGELOG.md

@ -11,6 +11,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed the deprecated public _Stripe_ key - Removed the deprecated public _Stripe_ key
### Fixed
- Fixed the import of `jsonpath` to support REST APIs (`JSON`) via the scraper configuration
## 2.226.0 - 2026-01-01
### Added
- Extended the content of the _Self-Hosting_ section by information about additional data providers on the Frequently Asked Questions (FAQ) page
### Changed
- Upgraded `class-validator` from version `0.14.2` to `0.14.3`
- Upgraded `yahoo-finance2` from version `3.10.2` to `3.11.2`
## 2.225.0 - 2025-12-31 ## 2.225.0 - 2025-12-31
### Added ### Added

6
README.md

@ -241,7 +241,7 @@ Deprecated: `GET http://localhost:3333/api/v1/auth/anonymous/<INSERT_SECURITY_TO
| `accountId` | `string` (optional) | Id of the account | | `accountId` | `string` (optional) | Id of the account |
| `comment` | `string` (optional) | Comment of the activity | | `comment` | `string` (optional) | Comment of the activity |
| `currency` | `string` | `CHF` \| `EUR` \| `USD` etc. | | `currency` | `string` | `CHF` \| `EUR` \| `USD` etc. |
| `dataSource` | `string` | `COINGECKO` \| `MANUAL` \| `YAHOO` | | `dataSource` | `string` | `COINGECKO` \| `GHOSTFOLIO` [^1] \| `MANUAL` \| `YAHOO` |
| `date` | `string` | Date in the format `ISO-8601` | | `date` | `string` | Date in the format `ISO-8601` |
| `fee` | `number` | Fee of the activity | | `fee` | `number` | Fee of the activity |
| `quantity` | `number` | Quantity of the activity | | `quantity` | `number` | Quantity of the activity |
@ -331,6 +331,8 @@ If you like to support this project, become a [**Sponsor**](https://github.com/s
## License ## License
© 2021 - 2025 [Ghostfolio](https://ghostfol.io) © 2021 - 2026 [Ghostfolio](https://ghostfol.io)
Licensed under the [AGPLv3 License](https://www.gnu.org/licenses/agpl-3.0.html). Licensed under the [AGPLv3 License](https://www.gnu.org/licenses/agpl-3.0.html).
[^1]: Available with [**Ghostfolio Premium**](https://ghostfol.io/en/pricing).

22
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', () => { describe('redactAttributes', () => {
it('should redact provided attributes', () => { it('should redact provided attributes', () => {

11
apps/api/src/helper/object.helper.ts

@ -1,4 +1,5 @@
import { Big } from 'big.js'; import { Big } from 'big.js';
import jsonpath from 'jsonpath';
import { cloneDeep, isArray, isObject } from 'lodash'; import { cloneDeep, isArray, isObject } from 'lodash';
export function hasNotDefinedValuesInObject(aObject: Object): boolean { export function hasNotDefinedValuesInObject(aObject: Object): boolean {
@ -31,6 +32,16 @@ export function nullifyValuesInObjects<T>(aObjects: T[], keys: string[]): T[] {
}); });
} }
export function query({
object,
pathExpression
}: {
object: object;
pathExpression: string;
}) {
return jsonpath.query(object, pathExpression);
}
export function redactAttributes({ export function redactAttributes({
isFirstRun = true, isFirstRun = true,
object, object,

11
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 { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { import {
DataProviderInterface, DataProviderInterface,
@ -26,7 +27,6 @@ import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client'; import { DataSource, SymbolProfile } from '@prisma/client';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
import { addDays, format, isBefore } from 'date-fns'; import { addDays, format, isBefore } from 'date-fns';
import * as jsonpath from 'jsonpath';
@Injectable() @Injectable()
export class ManualService implements DataProviderInterface { export class ManualService implements DataProviderInterface {
@ -286,9 +286,14 @@ export class ManualService implements DataProviderInterface {
let value: string; let value: string;
if (response.headers.get('content-type')?.includes('application/json')) { 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 { } else {
const $ = cheerio.load(await response.text()); const $ = cheerio.load(await response.text());

17
apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html

@ -135,9 +135,17 @@
<mat-card-title>Which data providers are supported?</mat-card-title> <mat-card-title>Which data providers are supported?</mat-card-title>
</mat-card-header> </mat-card-header>
<mat-card-content <mat-card-content
><code>COINGECKO</code>, <code>MANUAL</code> and ><code>COINGECKO</code>, <code>GHOSTFOLIO</code> (available with
<code>YAHOO</code> are officially supported while all other data <a
providers are considered experimental.</mat-card-content class="align-items-center d-inline-flex"
target="_blank"
[href]="pricingUrl"
>Ghostfolio Premium<gf-premium-indicator
class="d-inline-block ml-1"
[enableLink]="false" /></a
>), <code>MANUAL</code>, and <code>YAHOO</code> are officially
supported while all other data providers are considered
experimental.</mat-card-content
> >
</mat-card> </mat-card>
<mat-card appearance="outlined" class="mb-3"> <mat-card appearance="outlined" class="mb-3">
@ -147,7 +155,8 @@
> >
</mat-card-header> </mat-card-header>
<mat-card-content <mat-card-content
>Yes, access to a professional data provider is included with a >Yes, access to a professional data provider (<code>GHOSTFOLIO</code>)
is included with a
<a <a
class="align-items-center d-inline-flex" class="align-items-center d-inline-flex"
target="_blank" target="_blank"

38
package-lock.json

@ -1,12 +1,12 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.225.0", "version": "2.226.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.225.0", "version": "2.226.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "AGPL-3.0", "license": "AGPL-3.0",
"dependencies": { "dependencies": {
@ -53,7 +53,7 @@
"chartjs-plugin-datalabels": "2.2.0", "chartjs-plugin-datalabels": "2.2.0",
"cheerio": "1.0.0", "cheerio": "1.0.0",
"class-transformer": "0.5.1", "class-transformer": "0.5.1",
"class-validator": "0.14.2", "class-validator": "0.14.3",
"color": "5.0.3", "color": "5.0.3",
"countries-and-timezones": "3.8.0", "countries-and-timezones": "3.8.0",
"countries-list": "3.2.0", "countries-list": "3.2.0",
@ -88,7 +88,7 @@
"svgmap": "2.14.0", "svgmap": "2.14.0",
"tablemark": "4.1.0", "tablemark": "4.1.0",
"twitter-api-v2": "1.27.0", "twitter-api-v2": "1.27.0",
"yahoo-finance2": "3.10.2", "yahoo-finance2": "3.11.2",
"zone.js": "0.16.0" "zone.js": "0.16.0"
}, },
"devDependencies": { "devDependencies": {
@ -124,6 +124,7 @@
"@types/big.js": "6.2.2", "@types/big.js": "6.2.2",
"@types/google-spreadsheet": "3.1.5", "@types/google-spreadsheet": "3.1.5",
"@types/jest": "30.0.0", "@types/jest": "30.0.0",
"@types/jsonpath": "0.2.4",
"@types/lodash": "4.17.20", "@types/lodash": "4.17.20",
"@types/node": "22.15.17", "@types/node": "22.15.17",
"@types/papaparse": "5.3.7", "@types/papaparse": "5.3.7",
@ -12436,6 +12437,13 @@
"dev": true, "dev": true,
"license": "MIT" "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": { "node_modules/@types/jsonwebtoken": {
"version": "9.0.10", "version": "9.0.10",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz",
@ -12687,9 +12695,9 @@
"optional": true "optional": true
}, },
"node_modules/@types/validator": { "node_modules/@types/validator": {
"version": "13.15.2", "version": "13.15.10",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.2.tgz", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz",
"integrity": "sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q==", "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/ws": { "node_modules/@types/ws": {
@ -15635,14 +15643,14 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/class-validator": { "node_modules/class-validator": {
"version": "0.14.2", "version": "0.14.3",
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.2.tgz", "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.3.tgz",
"integrity": "sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==", "integrity": "sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/validator": "^13.11.8", "@types/validator": "^13.15.3",
"libphonenumber-js": "^1.11.1", "libphonenumber-js": "^1.11.1",
"validator": "^13.9.0" "validator": "^13.15.20"
} }
}, },
"node_modules/clean-css": { "node_modules/clean-css": {
@ -35183,9 +35191,9 @@
} }
}, },
"node_modules/yahoo-finance2": { "node_modules/yahoo-finance2": {
"version": "3.10.2", "version": "3.11.2",
"resolved": "https://registry.npmjs.org/yahoo-finance2/-/yahoo-finance2-3.10.2.tgz", "resolved": "https://registry.npmjs.org/yahoo-finance2/-/yahoo-finance2-3.11.2.tgz",
"integrity": "sha512-MH4EdugRurygLTMd1UryPwfYR8aWSOeyh++JSarMrf+bROfvNGmE0lAi/C9TuTc3mH8ORuRdt+O9PEeCCmzTLg==", "integrity": "sha512-SIvMXjrOktBRD8m+qXAGCK+vR1vwBKuMgCnvmbxv29+t6LTDu0vAUxNYfbigsMRTmBzS4F9TQwbYF90g3Om4HA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@deno/shim-deno": "~0.18.0", "@deno/shim-deno": "~0.18.0",

7
package.json

@ -1,6 +1,6 @@
{ {
"name": "ghostfolio", "name": "ghostfolio",
"version": "2.225.0", "version": "2.226.0",
"homepage": "https://ghostfol.io", "homepage": "https://ghostfol.io",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"repository": "https://github.com/ghostfolio/ghostfolio", "repository": "https://github.com/ghostfolio/ghostfolio",
@ -97,7 +97,7 @@
"chartjs-plugin-datalabels": "2.2.0", "chartjs-plugin-datalabels": "2.2.0",
"cheerio": "1.0.0", "cheerio": "1.0.0",
"class-transformer": "0.5.1", "class-transformer": "0.5.1",
"class-validator": "0.14.2", "class-validator": "0.14.3",
"color": "5.0.3", "color": "5.0.3",
"countries-and-timezones": "3.8.0", "countries-and-timezones": "3.8.0",
"countries-list": "3.2.0", "countries-list": "3.2.0",
@ -132,7 +132,7 @@
"svgmap": "2.14.0", "svgmap": "2.14.0",
"tablemark": "4.1.0", "tablemark": "4.1.0",
"twitter-api-v2": "1.27.0", "twitter-api-v2": "1.27.0",
"yahoo-finance2": "3.10.2", "yahoo-finance2": "3.11.2",
"zone.js": "0.16.0" "zone.js": "0.16.0"
}, },
"devDependencies": { "devDependencies": {
@ -168,6 +168,7 @@
"@types/big.js": "6.2.2", "@types/big.js": "6.2.2",
"@types/google-spreadsheet": "3.1.5", "@types/google-spreadsheet": "3.1.5",
"@types/jest": "30.0.0", "@types/jest": "30.0.0",
"@types/jsonpath": "0.2.4",
"@types/lodash": "4.17.20", "@types/lodash": "4.17.20",
"@types/node": "22.15.17", "@types/node": "22.15.17",
"@types/papaparse": "5.3.7", "@types/papaparse": "5.3.7",

Loading…
Cancel
Save