From c0b298bab040d5d5c5bc94eac2ed2348a8d475c9 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Mon, 13 May 2024 12:35:34 +0800 Subject: [PATCH] Update function signature for query conversion Use key-value to ensure less duplicates in coercing query param values. --- .../core/src/backend/data-source/queries.ts | 48 ++++++++++++++----- packages/core/test/features/query.test.ts | 15 ++++-- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/packages/core/src/backend/data-source/queries.ts b/packages/core/src/backend/data-source/queries.ts index a0bf9ee..1763508 100644 --- a/packages/core/src/backend/data-source/queries.ts +++ b/packages/core/src/backend/data-source/queries.ts @@ -27,27 +27,47 @@ export interface DataSourceQueryAndGrouping { expressions: DataSourceQueryOrGrouping[]; } -export const COERCE_VALUES_TYPES = [ - 'number', - 'string', - 'boolean', -] as const; +interface ProcessEntryBase { + type: string; +} + +export interface ProcessEntryString extends ProcessEntryBase { + type: 'string'; + startsWith?: boolean; + endsWith?: boolean; + caseInsensitive?: boolean; + includes?: boolean; +} + +export interface ProcessEntryNumber extends ProcessEntryBase { + type: 'number'; +} -export type CoerceValuesType = typeof COERCE_VALUES_TYPES[number]; +export interface ProcessEntryBoolean extends ProcessEntryBase { + type: 'boolean'; + truthyStrings?: string[]; +} -type CoerceValues = Partial>; +export type ProcessEntry = ProcessEntryString | ProcessEntryNumber | ProcessEntryBoolean; interface ConvertToDataSourceQueryCollectionOptions { - coerceValues: CoerceValues; + processEntries: Record; + //coerceValues: CoerceValues; + //stringSearch: StringSearch; } -const normalizeRhs = (lhs: string, rhs: string, coerceValues: CoerceValues) => { - if (coerceValues?.number?.includes(lhs)) { +const normalizeRhs = (rhs: string, coerceValues?: ProcessEntry) => { + if (coerceValues?.type === 'number') { return Number(rhs); } - if (coerceValues?.boolean?.includes(lhs)) { - return rhs.trim().toLowerCase() === 'true'; + if (coerceValues?.type === 'boolean') { + const truthyStrings = [ + ...(coerceValues.truthyStrings ?? []).map((s) => s.trim().toLowerCase()), + 'true', + ]; + + return truthyStrings.includes(rhs); } return rhs?.toString() ?? ''; @@ -67,7 +87,7 @@ export const convertToDataSourceQueryCollection = ( expressions: [], }; const existingLhs = existingOr.expressions.find((ex) => ex.lhs === key); - const rhs = normalizeRhs(key, value, options.coerceValues); + const rhs = normalizeRhs(value, options.processEntries?.[key]); if (typeof existingLhs === 'undefined') { return { @@ -115,3 +135,5 @@ export const convertToDataSourceQueryCollection = ( // all the queries are to be treated as "AND", as suggested by the & character to separate the query param entries }; + +// TODO add more operators diff --git a/packages/core/test/features/query.test.ts b/packages/core/test/features/query.test.ts index c0f26a7..1281595 100644 --- a/packages/core/test/features/query.test.ts +++ b/packages/core/test/features/query.test.ts @@ -16,8 +16,10 @@ describe('query', () => { const collection = convertToDataSourceQueryCollection( q, { - coerceValues: { - number: ['attr'], + processEntries: { + attr: { + type: 'number' + } }, }, ); @@ -58,8 +60,13 @@ describe('query', () => { const collection = convertToDataSourceQueryCollection( q, { - coerceValues: { - boolean: ['attr', 'attr2'], + processEntries: { + attr: { + type: 'boolean', + }, + attr2: { + type: 'boolean', + } }, }, );