diff --git a/src/lib/db/feature-strategy-store.ts b/src/lib/db/feature-strategy-store.ts index b230aac436..6ecb5c6e0e 100644 --- a/src/lib/db/feature-strategy-store.ts +++ b/src/lib/db/feature-strategy-store.ts @@ -15,6 +15,8 @@ import { } from '../types/model'; import { IFeatureStrategiesStore } from '../types/stores/feature-strategies-store'; import { PartialSome } from '../types/partial'; +import { ensureStringValue } from '../util/ensureStringValue'; +import { mapValues } from '../util/map-values'; const COLUMNS = [ 'id', @@ -53,15 +55,6 @@ interface IFeatureStrategiesTable { created_at?: Date; } -function ensureStringValues(data: object): { [key: string]: string } { - const stringEntries = Object.entries(data).map(([key, value]) => [ - key, - String(value), - ]); - - return Object.fromEntries(stringEntries); -} - function mapRow(row: IFeatureStrategiesTable): IFeatureStrategy { return { id: row.id, @@ -69,7 +62,7 @@ function mapRow(row: IFeatureStrategiesTable): IFeatureStrategy { projectId: row.project_name, environment: row.environment, strategyName: row.strategy_name, - parameters: ensureStringValues(row.parameters), + parameters: mapValues(row.parameters || {}, ensureStringValue), constraints: (row.constraints as unknown as IConstraint[]) || [], createdAt: row.created_at, sortOrder: row.sort_order, diff --git a/src/lib/db/feature-toggle-client-store.ts b/src/lib/db/feature-toggle-client-store.ts index e97ac62f1c..96f005f149 100644 --- a/src/lib/db/feature-toggle-client-store.ts +++ b/src/lib/db/feature-toggle-client-store.ts @@ -11,6 +11,8 @@ import { IFeatureToggleClientStore } from '../types/stores/feature-toggle-client import { DEFAULT_ENV } from '../util/constants'; import { PartialDeep } from '../types/partial'; import EventEmitter from 'events'; +import { ensureStringValue } from '../util/ensureStringValue'; +import { mapValues } from '../util/map-values'; export interface FeaturesTable { name: string; @@ -180,7 +182,7 @@ export default class FeatureToggleClientStore id: row.strategy_id, name: row.strategy_name, constraints: row.constraints || [], - parameters: row.parameters, + parameters: mapValues(row.parameters || {}, ensureStringValue), }; } diff --git a/src/lib/util/ensureStringValue.test.ts b/src/lib/util/ensureStringValue.test.ts new file mode 100644 index 0000000000..dd8ccb6035 --- /dev/null +++ b/src/lib/util/ensureStringValue.test.ts @@ -0,0 +1,16 @@ +import { ensureStringValue } from './ensureStringValue'; + +test('ensureStringValue', () => { + expect(ensureStringValue(null)).toEqual(''); + expect(ensureStringValue(undefined)).toEqual(''); + expect(ensureStringValue('null')).toEqual('null'); + expect(ensureStringValue('undefined')).toEqual('undefined'); + + expect(ensureStringValue('')).toEqual(''); + expect(ensureStringValue('a')).toEqual('a'); + expect(ensureStringValue(0)).toEqual('0'); + expect(ensureStringValue(true)).toEqual('true'); + + expect(ensureStringValue({})).toEqual('{}'); + expect(ensureStringValue({ b: 1 })).toEqual('{"b":1}'); +}); diff --git a/src/lib/util/ensureStringValue.ts b/src/lib/util/ensureStringValue.ts new file mode 100644 index 0000000000..10c8f5e0c0 --- /dev/null +++ b/src/lib/util/ensureStringValue.ts @@ -0,0 +1,13 @@ +import { isDefined } from './isDefined'; + +export function ensureStringValue(value: unknown): string { + if (!isDefined(value)) { + return ''; + } + + if (typeof value === 'object') { + return JSON.stringify(value); + } + + return String(value); +}