From 7fca3a52e7f7f6eda146709caa8ad5f69a3f8bdd Mon Sep 17 00:00:00 2001 From: Simon Hofer Date: Thu, 9 Apr 2026 16:37:26 +0200 Subject: [PATCH 1/2] refactor: simplify ternary operator --- .../static/queriesWithQueryLanguage.ts.txt | 90 ++++++------------- 1 file changed, 25 insertions(+), 65 deletions(-) diff --git a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt index eeaee53..17d297c 100644 --- a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt +++ b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt @@ -64,25 +64,9 @@ export type LengthOperator = 'LENGTH'; export type ArrayOperator = 'IN'; -export type CaseOperator = 'CASE'; - -export type CaseNode = { - [K in CaseOperator]: CaseExpression; -}; - -type InCaseNode = Case extends CaseNode ? CaseNode : never; - -export type CaseExpression = { - IF: SingleFilterExpr; - THEN: PropType | CaseNode; - ELSE: PropType | CaseNode; -}; - export type NullOperator = 'NULL'; -export type Operator = ComparisonOperator | ArrayOperator | CaseOperator | NullOperator; - -export type BinaryOperator = Exclude; +export type Operator = ComparisonOperator | ArrayOperator | NullOperator; export type ModifierFunction = 'LOWER' | 'TRIM'; @@ -104,37 +88,42 @@ export type LengthExprWithModifier = { [K in NullOperator]?: never } & { [K in ModifierFunction]?: boolean }; -export type FilterExpr = - { [K in ComparisonOperator]?: T | Case } & - { [K in ArrayOperator]?: T[] | InCaseNode } & +export type FilterExpr = + { [K in ComparisonOperator]?: T } & + { [K in ArrayOperator]?: T[] } & { [K in keyof LengthExpr]?: never }; -export type FilterExprWithoutNull = - RequireAtLeastOne> & +export type FilterExprWithoutNull = + RequireAtLeastOne> & { [K in NullOperator]?: never } & { [K in ModifierFunction]?: boolean }; -export type FilterExprWithNull = - FilterExpr & +export type FilterExprWithNull = + FilterExpr & { [K in NullOperator]?: boolean} & { [K in ModifierFunction]?: never }; -export type MapOperators = LengthExprWithModifier | FilterExprWithoutNull | FilterExprWithNull; +export type MapOperators = LengthExprWithModifier | FilterExprWithoutNull | FilterExprWithNull; export type SingleFilterExpr = { [P in keyof T]?: T[P] extends Array | undefined ? U extends Record ? SingleFilterExpr | { NOT?: SingleFilterExpr } - : MapOperators> + : MapOperators : T[P] extends Record | undefined ? SingleFilterExpr | { NOT?: SingleFilterExpr } - : MapOperators>; + : MapOperators; }; export type QueryFilter = SingleFilterExpr & { OR?: QueryFilter[]; AND?: QueryFilter[]; NOT?: QueryFilter; + CASE?: { + IF: QueryFilter; + THEN: QueryFilter; + ELSE: QueryFilter; + }; }; export type ConditionalOrderByCase = { @@ -194,7 +183,7 @@ const comparisonOperatorList: ComparisonOperator[] = [ 'LIKE' ]; -const comparisonOperatorMap: Record = { +const comparisonOperatorMap: Record = { EQ: '=', NE: '!=', LT: '<', @@ -259,7 +248,7 @@ const flattenWhere = ( `not ${flattedNot.length > 1 ? '(' : ''}${flattedNot.join(' and ')}${flattedNot.length > 1 ? ')' : ''}` ); } else if (prop === 'CASE') { - entries.push(evaluateCaseExpression(propValue as CaseExpression, setModifiers, nestedPaths)); + entries.push(evaluateCaseExpression(propValue as QueryFilter, nestedPaths)); } else if (propValue) { for (const [operator, value] of Object.entries(propValue)) { if (value === undefined) continue; @@ -268,40 +257,27 @@ const flattenWhere = ( `${setModifiers.reduce( (acc, [first]) => `${first.toLowerCase()}(${acc})`, nestedPaths.some((path) => path === prop) ? nestedPaths.join('.') : [...nestedPaths, prop].join('.') - )} ${comparisonOperatorMap[operator as BinaryOperator]} ${ - typeof value === 'object' - ? flattenWhere(value, nestedPaths) - : typeof value === 'string' - ? setModifiers.reduce((acc, [first]) => `${first}(${acc})`, JSON.stringify(value)) - : value + )} ${comparisonOperatorMap[operator as Operator]} ${ + typeof value === 'string' ? JSON.stringify(value) : value }` ); } else if ((operator as Operator) === 'NULL') { entries.push( - `${!value ? 'not ' : ''}${nestedPaths.some((path) => path === prop) ? nestedPaths.join('.') : [...nestedPaths, prop].join('.')} ${comparisonOperatorMap[operator as BinaryOperator]}` + `${!value ? 'not ' : ''}${nestedPaths.some((path) => path === prop) ? nestedPaths.join('.') : [...nestedPaths, prop].join('.')} ${comparisonOperatorMap[operator as Operator]}` ); } else if ((operator as Operator) === 'IN') { - if (typeof value === 'object' && !Array.isArray(value) && value.CASE) { - entries.push( - `${setModifiers.reduce( - (acc, [first]) => `${first}(${acc})`, - nestedPaths.some((path) => path === prop) ? nestedPaths.join('.') : [...nestedPaths, prop].join('.') - )} ${comparisonOperatorMap[operator as BinaryOperator]} ${evaluateCaseExpression(value.CASE as CaseExpression, setModifiers, nestedPaths)}` - ); - } else if(value.length === 0) { + if(value.length === 0) { entries.push('1 = 0') } else { entries.push( `${setModifiers.reduce( (acc, [first]) => `${first.toLowerCase()}(${acc})`, nestedPaths.some((path) => path === prop) ? nestedPaths.join('.') : [...nestedPaths, prop].join('.') - )} ${comparisonOperatorMap[operator as BinaryOperator]} [${value.map((v: string | number) => + )} ${comparisonOperatorMap[operator as Operator]} [${value.map((v: string | number) => typeof v === 'string' ? setModifiers.reduce((acc, [first]) => `${first}(${acc})`, JSON.stringify(v)) : v )}]` ); } - } else if ((operator as Operator) === 'CASE') { - entries.push(evaluateCaseExpression(value as CaseExpression, setModifiers, nestedPaths)); } else if ((operator as LengthOperator) === 'LENGTH') { const lengthProp = `length(${setModifiers.reduce( (acc, [first]) => `${first.toLowerCase()}(${acc})`, @@ -326,24 +302,8 @@ const flattenWhere = ( return entries; }; -const evaluateCaseExpression = ( - exp: CaseExpression, - setModifiers: [string, any][], - nestedPaths: string[] -): string => - `(${flattenWhere(exp.IF, nestedPaths)} ? ${ - typeof exp.THEN === 'string' || Array.isArray(exp.THEN) - ? setModifiers.reduce((acc, [first]) => `${first}(${acc})`, JSON.stringify(exp.THEN)) - : typeof exp.THEN === 'number' || typeof exp.THEN === 'boolean' - ? exp.THEN - : evaluateCaseExpression((exp.THEN as CaseNode).CASE, setModifiers, nestedPaths) - } : ${ - typeof exp.ELSE === 'string' || Array.isArray(exp.ELSE) - ? setModifiers.reduce((acc, [first]) => `${first}(${acc})`, JSON.stringify(exp.ELSE)) - : typeof exp.ELSE === 'number' || typeof exp.ELSE === 'boolean' - ? exp.ELSE - : evaluateCaseExpression((exp.ELSE as CaseNode).CASE, setModifiers, nestedPaths) - })`; +const evaluateCaseExpression = (exp: QueryFilter, nestedPaths: string[]): string => + `(${flattenWhere(exp.IF as QueryFilter, nestedPaths)} ? ${flattenWhere(exp.THEN as QueryFilter, nestedPaths)} : ${flattenWhere(exp.ELSE as QueryFilter, nestedPaths)})`; const assembleOrderBy = (orderBy: OrderBy[] = []): Record => { if(!orderBy.length) { From c670b2bb55272c9990b9c426d2e18735865f8aaa Mon Sep 17 00:00:00 2001 From: Simon Hofer Date: Fri, 10 Apr 2026 09:06:26 +0200 Subject: [PATCH 2/2] refactor: simplify ternary operator Concat multiple operators with 'and' --- .../01-base/static/queriesWithQueryLanguage.ts.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt index 17d297c..a5785fe 100644 --- a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt +++ b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt @@ -302,8 +302,12 @@ const flattenWhere = ( return entries; }; -const evaluateCaseExpression = (exp: QueryFilter, nestedPaths: string[]): string => - `(${flattenWhere(exp.IF as QueryFilter, nestedPaths)} ? ${flattenWhere(exp.THEN as QueryFilter, nestedPaths)} : ${flattenWhere(exp.ELSE as QueryFilter, nestedPaths)})`; +const evaluateCaseExpression = (exp: QueryFilter, nestedPaths: string[]): string => { + const ifExp = flattenWhere(exp.IF as QueryFilter, nestedPaths).join(' and '); + const thenBranch = flattenWhere(exp.THEN as QueryFilter, nestedPaths).join(' and '); + const elseBranch = flattenWhere(exp.ELSE as QueryFilter, nestedPaths).join(' and '); + return `(${ifExp} ? ${thenBranch} : ${elseBranch})`; +}; const assembleOrderBy = (orderBy: OrderBy[] = []): Record => { if(!orderBy.length) {