From 329f1f5e6318dcabf10a092a50f66c5fe71d6a43 Mon Sep 17 00:00:00 2001 From: Simon Hofer Date: Thu, 16 Apr 2026 15:52:51 +0200 Subject: [PATCH 1/3] refactor: add correct type safety to orderBy --- .../static/queriesWithQueryLanguage.ts.txt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt index fb90dc8..fe72e7d 100644 --- a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt +++ b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt @@ -126,36 +126,36 @@ export type QueryFilter = SingleFilterExpr & { }; }; -export type ConditionalOrderByCase = { - WHEN: QueryFilter; - THEN: number | FieldOrderBy; +export type ConditionalOrderByCase = { + WHEN: QueryFilter; + THEN: number | FieldOrderBy; }; -export type ConditionalOrderBy = { - CASE: ConditionalOrderByCase[]; - ELSE: number | FieldOrderBy; +export type ConditionalOrderBy = { + CASE: ConditionalOrderByCase[]; + ELSE: number | FieldOrderBy; SORT?: 'asc' | 'desc'; }; -export type FieldPath = { +export type FieldPath = Depth['length'] extends 3 ? never : { [K in keyof T & string]: NonNullable extends Array ? U extends Record - ? `${K}.${FieldPath}` + ? `${K}.${FieldPath}` : never : NonNullable extends Record - ? K | `${K}.${FieldPath>}` + ? K | `${K}.${FieldPath, [...Depth, 0]>}` : K; }[keyof T & string]; -export type FieldOrderBy = { - FIELD: FieldPath; +export type FieldOrderBy = { + FIELD: FieldPath; SORT?: 'asc' | 'desc'; LOWER?: boolean; TRIM?: boolean; LENGTH?: boolean; }; -export type OrderBy = FieldOrderBy | ConditionalOrderBy; +export type OrderBy = FieldOrderBy | ConditionalOrderBy; export type CountQuery = { where?: QueryFilter; @@ -171,7 +171,7 @@ type SomeQueryBase = { }; export type SomeQuery = SomeQueryBase & - ({ sort?: Sort[]; orderBy?: never } | { sort?: never; orderBy?: OrderBy[] }); + ({ sort?: Sort[]; orderBy?: never } | { sort?: never; orderBy?: OrderBy[] }); const comparisonOperatorList: ComparisonOperator[] = [ 'EQ', From 64640044e04a11b6c45cc0008a9cb167075dc2f6 Mon Sep 17 00:00:00 2001 From: Simon Hofer Date: Fri, 17 Apr 2026 12:25:21 +0200 Subject: [PATCH 2/3] refactor: add correct type safety to orderBy --- .../static/queriesWithQueryLanguage.ts.txt | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt index fe72e7d..ed7bfc2 100644 --- a/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt +++ b/src/generator/01-base/static/queriesWithQueryLanguage.ts.txt @@ -19,11 +19,17 @@ const flattenOrderBy = (orderBy: OrderBy[] = []): string[] => { ): orderByItem is ConditionalOrderBy => !!orderByItem && typeof orderByItem === 'object' && 'CASE' in orderByItem; + /** Converts a OrderableField object to a dot-notation string. OrderableField guarantees exactly one key per level. */ + const flattenField = (field: OrderableField): string => { + const [[key, value]] = Object.entries(field); + return typeof value === 'object' && value !== null ? `${key}.${flattenField(value as OrderableField)}` : key; + }; + const flattenValue = (value: number | FieldOrderBy): string => { if (typeof value === 'number') { return value.toString(); } - return applyModifiers(value.FIELD, value); + return applyModifiers(flattenField(value.FIELD), value); }; const flattenConditional = (item: ConditionalOrderBy): string => { @@ -43,7 +49,7 @@ const flattenOrderBy = (orderBy: OrderBy[] = []): string[] => { } const field = orderByItem as FieldOrderBy; - const property = applyModifiers(field.FIELD, field); + const property = applyModifiers(flattenField(field.FIELD), field); const sort = field.SORT === 'desc' ? 'desc' : 'asc'; return `${property} ${sort}`; }; @@ -137,18 +143,14 @@ export type ConditionalOrderBy = { SORT?: 'asc' | 'desc'; }; -export type FieldPath = Depth['length'] extends 3 ? never : { - [K in keyof T & string]: NonNullable extends Array - ? U extends Record - ? `${K}.${FieldPath}` - : never - : NonNullable extends Record - ? K | `${K}.${FieldPath, [...Depth, 0]>}` - : K; -}[keyof T & string]; +export type OrderableField = { + [K in keyof F]-?: NonNullable extends Record + ? { [P in K]: OrderableField> } & { [P in Exclude]?: never } + : { [P in K]: boolean } & { [P in Exclude]?: never }; +}[keyof F]; export type FieldOrderBy = { - FIELD: FieldPath; + FIELD: OrderableField; SORT?: 'asc' | 'desc'; LOWER?: boolean; TRIM?: boolean; From 142d55f2eb6500189d0770cba034be209b714214 Mon Sep 17 00:00:00 2001 From: Simon Hofer Date: Fri, 17 Apr 2026 16:15:25 +0200 Subject: [PATCH 3/3] refactor: add correct type safety to orderBy Change documentation --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index aeb196e..3dfa406 100644 --- a/README.md +++ b/README.md @@ -423,7 +423,7 @@ With the some function you can order requested data. You can either merely order * ?orderBy=createdDate asc */ wServices['article'].some({ - orderBy: [{ FIELD: 'createdDate', SORT: 'asc' }] + orderBy: [{ FIELD: { createdDate: true }, SORT: 'asc' }] }); ``` @@ -435,7 +435,7 @@ wServices['article'].some({ * ?orderBy=createdDate asc, articleNumber desc */ wServices['article'].some({ - orderBy: [{ FIELD: 'createdDate' }, { FIELD: 'articleNumber', SORT: 'desc' }] + orderBy: [{ FIELD: { createdDate: true } }, { FIELD: { articleNumber: true }, SORT: 'desc' }] }); ``` @@ -457,7 +457,7 @@ wServices['article'].some({ ELSE: 3, SORT: 'asc' }, - { FIELD: 'articleNumber' } + { FIELD: { articleNumber: true } } ] }); ``` @@ -474,8 +474,8 @@ The `THEN` and `ELSE` values can also be a `FieldOrderBy` to fall back to a fiel wServices['article'].some({ orderBy: [ { - CASE: [{ WHEN: { internalNote: { NULL: false } }, THEN: { FIELD: 'articleNumber' } }], - ELSE: { FIELD: 'createdDate' }, + CASE: [{ WHEN: { internalNote: { NULL: false } }, THEN: { FIELD: { articleNumber: true } } }], + ELSE: { FIELD: { createdDate: true } }, SORT: 'asc' } ] @@ -491,7 +491,7 @@ For properties that are objects or arrays of objects, use dot-notation to refere * ?orderBy=articlePrices.price asc */ wServices['article'].some({ - orderBy: [{ FIELD: 'articlePrices.price', SORT: 'asc' }] + orderBy: [{ FIELD: { articlePrices: { price: true } }, SORT: 'asc' }] }); ``` @@ -511,7 +511,7 @@ wServices['party'].some({ TRIM: true, SORT: 'desc' }, - { FIELD: 'firstName' } + { FIELD: { firstName: true } } ] }); ```