|
@@ -27,27 +27,47 @@ export interface DataSourceQueryAndGrouping { |
|
|
expressions: DataSourceQueryOrGrouping[]; |
|
|
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<Record<CoerceValuesType, string[]>>; |
|
|
|
|
|
|
|
|
export type ProcessEntry = ProcessEntryString | ProcessEntryNumber | ProcessEntryBoolean; |
|
|
|
|
|
|
|
|
interface ConvertToDataSourceQueryCollectionOptions { |
|
|
interface ConvertToDataSourceQueryCollectionOptions { |
|
|
coerceValues: CoerceValues; |
|
|
|
|
|
|
|
|
processEntries: Record<string, ProcessEntry>; |
|
|
|
|
|
//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); |
|
|
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() ?? ''; |
|
|
return rhs?.toString() ?? ''; |
|
@@ -67,7 +87,7 @@ export const convertToDataSourceQueryCollection = ( |
|
|
expressions: [], |
|
|
expressions: [], |
|
|
}; |
|
|
}; |
|
|
const existingLhs = existingOr.expressions.find((ex) => ex.lhs === key); |
|
|
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') { |
|
|
if (typeof existingLhs === 'undefined') { |
|
|
return { |
|
|
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 |
|
|
// all the queries are to be treated as "AND", as suggested by the & character to separate the query param entries |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// TODO add more operators |