Browse Source

Task/improve type safety in API helpers (#8352)

Improve type safety
pull/8237/merge
Kenrick Tandrian 4 days ago
committed by GitHub
parent
commit
a8193354d8
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      apps/api/src/helper/bearer-token.helper.ts
  2. 2
      apps/api/src/helper/country.helper.ts
  3. 6
      apps/api/src/helper/data-source.helper.spec.ts
  4. 4
      apps/api/src/helper/data-source.helper.ts
  5. 2
      apps/api/src/helper/markdown-table.helper.ts
  6. 4
      apps/api/src/helper/portfolio.helper.ts
  7. 2
      apps/api/src/helper/string.helper.ts

10
apps/api/src/helper/bearer-token.helper.ts

@ -40,8 +40,9 @@ export function getActiveImpersonationOfBearerToken(
* hence the transport lists only the tools which the access covers. * hence the transport lists only the tools which the access covers.
*/ */
export function getMcpUserOfBearerToken(request: unknown) { export function getMcpUserOfBearerToken(request: unknown) {
const impersonationOfBearerToken = const impersonationOfBearerToken = getActiveImpersonationOfBearerToken(
getActiveImpersonationOfBearerToken(request); request as Pick<RequestWithUser, 'impersonationOfBearerToken'>
);
return impersonationOfBearerToken return impersonationOfBearerToken
? { scopes: impersonationOfBearerToken.scopes } ? { scopes: impersonationOfBearerToken.scopes }
@ -54,8 +55,9 @@ export function getMcpUserOfBearerToken(request: unknown) {
* they apply only to an access which reads the monetary values. * they apply only to an access which reads the monetary values.
*/ */
export function hasLimitsOfBasicSubscriptionOfBearerToken(request: unknown) { export function hasLimitsOfBasicSubscriptionOfBearerToken(request: unknown) {
const impersonationOfBearerToken = const impersonationOfBearerToken = getActiveImpersonationOfBearerToken(
getActiveImpersonationOfBearerToken(request); request as Pick<RequestWithUser, 'impersonationOfBearerToken'>
);
return ( return (
impersonationOfBearerToken?.userSubscription?.type === impersonationOfBearerToken?.userSubscription?.type ===

2
apps/api/src/helper/country.helper.ts

@ -9,7 +9,7 @@ export function getCountryCodeByName({
aliases?: Record<string, string>; aliases?: Record<string, string>;
dataSource?: string; dataSource?: string;
name: string; name: string;
}): string { }): string | undefined {
if (aliases[name]) { if (aliases[name]) {
return aliases[name]; return aliases[name];
} }

6
apps/api/src/helper/data-source.helper.spec.ts

@ -29,9 +29,9 @@ function createConfigurationService({
describe('DataSourceHelper', () => { describe('DataSourceHelper', () => {
describe('isValidEncodedDataSource', () => { describe('isValidEncodedDataSource', () => {
it('Accepts an encoded data source', () => { it('Accepts an encoded data source', () => {
expect(isValidEncodedDataSource(encodeDataSource(DataSource.YAHOO))).toBe( expect(
true isValidEncodedDataSource(encodeDataSource(DataSource.YAHOO) ?? '')
); ).toBe(true);
}); });
it('Refuses a data source which is not encoded', () => { it('Refuses a data source which is not encoded', () => {

4
apps/api/src/helper/data-source.helper.ts

@ -64,7 +64,7 @@ function hashDataSource(dataSource: DataSource) {
return createHash('sha256').update(dataSource).digest('hex').slice(0, 8); return createHash('sha256').update(dataSource).digest('hex').slice(0, 8);
} }
export function decodeDataSource(encodedDataSource: string) { export function decodeDataSource(encodedDataSource?: string) {
if (!encodedDataSource) { if (!encodedDataSource) {
return undefined; return undefined;
} }
@ -128,7 +128,7 @@ export function transformDataSourceInRequest({
configurationService: ConfigurationService; configurationService: ConfigurationService;
dataSource?: string; dataSource?: string;
}) { }) {
if (Object.hasOwn(DataSource, dataSource)) { if (dataSource && Object.hasOwn(DataSource, dataSource)) {
return getUnmaskedGhostfolioDataSource({ return getUnmaskedGhostfolioDataSource({
dataSource: dataSource as DataSource, dataSource: dataSource as DataSource,
ghostfolioDataSources: getGhostfolioDataSources({ configurationService }) ghostfolioDataSources: getGhostfolioDataSources({ configurationService })

2
apps/api/src/helper/markdown-table.helper.ts

@ -17,7 +17,7 @@ export function getTableInput<T, C = void>({
rows: rows.map((row) => { rows: rows.map((row) => {
return columnDefinitions.reduce( return columnDefinitions.reduce(
(tableRow, { getValue, name }) => { (tableRow, { getValue, name }) => {
tableRow[name] = getValue(row, context); tableRow[name] = getValue(row, context as C);
return tableRow; return tableRow;
}, },

4
apps/api/src/helper/portfolio.helper.ts

@ -21,7 +21,7 @@ export function convertValuesToPercentages({
const totalValue = holdings const totalValue = holdings
.map(({ valueInBaseCurrency }) => { .map(({ valueInBaseCurrency }) => {
return valueInBaseCurrency; return valueInBaseCurrency ?? 0;
}) })
.reduce((a, b) => { .reduce((a, b) => {
return a + b; return a + b;
@ -32,7 +32,7 @@ export function convertValuesToPercentages({
? holding.investment / totalInvestment ? holding.investment / totalInvestment
: 0; : 0;
holding.valueInPercentage = totalValue holding.valueInPercentage = totalValue
? holding.valueInBaseCurrency / totalValue ? (holding.valueInBaseCurrency ?? 0) / totalValue
: 0; : 0;
} }

2
apps/api/src/helper/string.helper.ts

@ -3,7 +3,7 @@ import { randomBytes } from 'node:crypto';
export function getRandomString(length: number) { export function getRandomString(length: number) {
const bytes = randomBytes(length); const bytes = randomBytes(length);
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
const result = []; const result: string[] = [];
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
const randomByte = bytes[i]; const randomByte = bytes[i];

Loading…
Cancel
Save