@tanstack/db 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/dist/cjs/collection.cjs +117 -104
  2. package/dist/cjs/collection.cjs.map +1 -1
  3. package/dist/cjs/collection.d.cts +19 -22
  4. package/dist/cjs/index.cjs +35 -13
  5. package/dist/cjs/index.cjs.map +1 -1
  6. package/dist/cjs/index.d.cts +0 -1
  7. package/dist/cjs/query/builder/functions.cjs +107 -0
  8. package/dist/cjs/query/builder/functions.cjs.map +1 -0
  9. package/dist/cjs/query/builder/functions.d.cts +38 -0
  10. package/dist/cjs/query/builder/index.cjs +499 -0
  11. package/dist/cjs/query/builder/index.cjs.map +1 -0
  12. package/dist/cjs/query/builder/index.d.cts +324 -0
  13. package/dist/cjs/query/builder/ref-proxy.cjs +96 -0
  14. package/dist/cjs/query/builder/ref-proxy.cjs.map +1 -0
  15. package/dist/cjs/query/builder/ref-proxy.d.cts +28 -0
  16. package/dist/cjs/query/builder/types.d.cts +80 -0
  17. package/dist/cjs/query/compiler/evaluators.cjs +261 -0
  18. package/dist/cjs/query/compiler/evaluators.cjs.map +1 -0
  19. package/dist/cjs/query/compiler/evaluators.d.cts +11 -0
  20. package/dist/cjs/query/compiler/group-by.cjs +271 -0
  21. package/dist/cjs/query/compiler/group-by.cjs.map +1 -0
  22. package/dist/cjs/query/compiler/group-by.d.cts +7 -0
  23. package/dist/cjs/query/compiler/index.cjs +181 -0
  24. package/dist/cjs/query/compiler/index.cjs.map +1 -0
  25. package/dist/cjs/query/compiler/index.d.cts +15 -0
  26. package/dist/cjs/query/compiler/joins.cjs +116 -0
  27. package/dist/cjs/query/compiler/joins.cjs.map +1 -0
  28. package/dist/cjs/query/compiler/joins.d.cts +11 -0
  29. package/dist/cjs/query/compiler/order-by.cjs +89 -0
  30. package/dist/cjs/query/compiler/order-by.cjs.map +1 -0
  31. package/dist/cjs/query/compiler/order-by.d.cts +9 -0
  32. package/dist/cjs/query/compiler/select.cjs +57 -0
  33. package/dist/cjs/query/compiler/select.cjs.map +1 -0
  34. package/dist/cjs/query/compiler/select.d.cts +15 -0
  35. package/dist/cjs/query/index.d.cts +6 -5
  36. package/dist/cjs/query/ir.cjs +57 -0
  37. package/dist/cjs/query/ir.cjs.map +1 -0
  38. package/dist/cjs/query/ir.d.cts +81 -0
  39. package/dist/cjs/query/live-query-collection.cjs +224 -0
  40. package/dist/cjs/query/live-query-collection.cjs.map +1 -0
  41. package/dist/cjs/query/live-query-collection.d.cts +124 -0
  42. package/dist/cjs/transactions.cjs +20 -13
  43. package/dist/cjs/transactions.cjs.map +1 -1
  44. package/dist/cjs/transactions.d.cts +13 -4
  45. package/dist/cjs/types.d.cts +14 -1
  46. package/dist/esm/collection.d.ts +19 -22
  47. package/dist/esm/collection.js +118 -105
  48. package/dist/esm/collection.js.map +1 -1
  49. package/dist/esm/index.d.ts +0 -1
  50. package/dist/esm/index.js +34 -12
  51. package/dist/esm/index.js.map +1 -1
  52. package/dist/esm/query/builder/functions.d.ts +38 -0
  53. package/dist/esm/query/builder/functions.js +107 -0
  54. package/dist/esm/query/builder/functions.js.map +1 -0
  55. package/dist/esm/query/builder/index.d.ts +324 -0
  56. package/dist/esm/query/builder/index.js +499 -0
  57. package/dist/esm/query/builder/index.js.map +1 -0
  58. package/dist/esm/query/builder/ref-proxy.d.ts +28 -0
  59. package/dist/esm/query/builder/ref-proxy.js +96 -0
  60. package/dist/esm/query/builder/ref-proxy.js.map +1 -0
  61. package/dist/esm/query/builder/types.d.ts +80 -0
  62. package/dist/esm/query/compiler/evaluators.d.ts +11 -0
  63. package/dist/esm/query/compiler/evaluators.js +261 -0
  64. package/dist/esm/query/compiler/evaluators.js.map +1 -0
  65. package/dist/esm/query/compiler/group-by.d.ts +7 -0
  66. package/dist/esm/query/compiler/group-by.js +271 -0
  67. package/dist/esm/query/compiler/group-by.js.map +1 -0
  68. package/dist/esm/query/compiler/index.d.ts +15 -0
  69. package/dist/esm/query/compiler/index.js +181 -0
  70. package/dist/esm/query/compiler/index.js.map +1 -0
  71. package/dist/esm/query/compiler/joins.d.ts +11 -0
  72. package/dist/esm/query/compiler/joins.js +116 -0
  73. package/dist/esm/query/compiler/joins.js.map +1 -0
  74. package/dist/esm/query/compiler/order-by.d.ts +9 -0
  75. package/dist/esm/query/compiler/order-by.js +89 -0
  76. package/dist/esm/query/compiler/order-by.js.map +1 -0
  77. package/dist/esm/query/compiler/select.d.ts +15 -0
  78. package/dist/esm/query/compiler/select.js +57 -0
  79. package/dist/esm/query/compiler/select.js.map +1 -0
  80. package/dist/esm/query/index.d.ts +6 -5
  81. package/dist/esm/query/ir.d.ts +81 -0
  82. package/dist/esm/query/ir.js +57 -0
  83. package/dist/esm/query/ir.js.map +1 -0
  84. package/dist/esm/query/live-query-collection.d.ts +124 -0
  85. package/dist/esm/query/live-query-collection.js +224 -0
  86. package/dist/esm/query/live-query-collection.js.map +1 -0
  87. package/dist/esm/transactions.d.ts +13 -4
  88. package/dist/esm/transactions.js +20 -13
  89. package/dist/esm/transactions.js.map +1 -1
  90. package/dist/esm/types.d.ts +14 -1
  91. package/package.json +3 -4
  92. package/src/collection.ts +152 -129
  93. package/src/index.ts +0 -1
  94. package/src/query/builder/functions.ts +267 -0
  95. package/src/query/builder/index.ts +648 -0
  96. package/src/query/builder/ref-proxy.ts +156 -0
  97. package/src/query/builder/types.ts +278 -0
  98. package/src/query/compiler/evaluators.ts +315 -0
  99. package/src/query/compiler/group-by.ts +428 -0
  100. package/src/query/compiler/index.ts +276 -0
  101. package/src/query/compiler/joins.ts +228 -0
  102. package/src/query/compiler/order-by.ts +139 -0
  103. package/src/query/compiler/select.ts +173 -0
  104. package/src/query/index.ts +64 -5
  105. package/src/query/ir.ts +128 -0
  106. package/src/query/live-query-collection.ts +509 -0
  107. package/src/transactions.ts +34 -19
  108. package/src/types.ts +16 -1
  109. package/dist/cjs/query/compiled-query.cjs +0 -160
  110. package/dist/cjs/query/compiled-query.cjs.map +0 -1
  111. package/dist/cjs/query/compiled-query.d.cts +0 -20
  112. package/dist/cjs/query/evaluators.cjs +0 -161
  113. package/dist/cjs/query/evaluators.cjs.map +0 -1
  114. package/dist/cjs/query/evaluators.d.cts +0 -14
  115. package/dist/cjs/query/extractors.cjs +0 -122
  116. package/dist/cjs/query/extractors.cjs.map +0 -1
  117. package/dist/cjs/query/extractors.d.cts +0 -22
  118. package/dist/cjs/query/functions.cjs +0 -152
  119. package/dist/cjs/query/functions.cjs.map +0 -1
  120. package/dist/cjs/query/functions.d.cts +0 -21
  121. package/dist/cjs/query/group-by.cjs +0 -88
  122. package/dist/cjs/query/group-by.cjs.map +0 -1
  123. package/dist/cjs/query/group-by.d.cts +0 -40
  124. package/dist/cjs/query/joins.cjs +0 -141
  125. package/dist/cjs/query/joins.cjs.map +0 -1
  126. package/dist/cjs/query/joins.d.cts +0 -14
  127. package/dist/cjs/query/order-by.cjs +0 -185
  128. package/dist/cjs/query/order-by.cjs.map +0 -1
  129. package/dist/cjs/query/order-by.d.cts +0 -3
  130. package/dist/cjs/query/pipeline-compiler.cjs +0 -89
  131. package/dist/cjs/query/pipeline-compiler.cjs.map +0 -1
  132. package/dist/cjs/query/pipeline-compiler.d.cts +0 -10
  133. package/dist/cjs/query/query-builder.cjs +0 -307
  134. package/dist/cjs/query/query-builder.cjs.map +0 -1
  135. package/dist/cjs/query/query-builder.d.cts +0 -225
  136. package/dist/cjs/query/schema.d.cts +0 -100
  137. package/dist/cjs/query/select.cjs +0 -130
  138. package/dist/cjs/query/select.cjs.map +0 -1
  139. package/dist/cjs/query/select.d.cts +0 -3
  140. package/dist/cjs/query/types.d.cts +0 -189
  141. package/dist/cjs/query/utils.cjs +0 -154
  142. package/dist/cjs/query/utils.cjs.map +0 -1
  143. package/dist/cjs/query/utils.d.cts +0 -37
  144. package/dist/cjs/utils.cjs +0 -17
  145. package/dist/cjs/utils.cjs.map +0 -1
  146. package/dist/cjs/utils.d.cts +0 -3
  147. package/dist/esm/query/compiled-query.d.ts +0 -20
  148. package/dist/esm/query/compiled-query.js +0 -160
  149. package/dist/esm/query/compiled-query.js.map +0 -1
  150. package/dist/esm/query/evaluators.d.ts +0 -14
  151. package/dist/esm/query/evaluators.js +0 -161
  152. package/dist/esm/query/evaluators.js.map +0 -1
  153. package/dist/esm/query/extractors.d.ts +0 -22
  154. package/dist/esm/query/extractors.js +0 -122
  155. package/dist/esm/query/extractors.js.map +0 -1
  156. package/dist/esm/query/functions.d.ts +0 -21
  157. package/dist/esm/query/functions.js +0 -152
  158. package/dist/esm/query/functions.js.map +0 -1
  159. package/dist/esm/query/group-by.d.ts +0 -40
  160. package/dist/esm/query/group-by.js +0 -88
  161. package/dist/esm/query/group-by.js.map +0 -1
  162. package/dist/esm/query/joins.d.ts +0 -14
  163. package/dist/esm/query/joins.js +0 -141
  164. package/dist/esm/query/joins.js.map +0 -1
  165. package/dist/esm/query/order-by.d.ts +0 -3
  166. package/dist/esm/query/order-by.js +0 -185
  167. package/dist/esm/query/order-by.js.map +0 -1
  168. package/dist/esm/query/pipeline-compiler.d.ts +0 -10
  169. package/dist/esm/query/pipeline-compiler.js +0 -89
  170. package/dist/esm/query/pipeline-compiler.js.map +0 -1
  171. package/dist/esm/query/query-builder.d.ts +0 -225
  172. package/dist/esm/query/query-builder.js +0 -307
  173. package/dist/esm/query/query-builder.js.map +0 -1
  174. package/dist/esm/query/schema.d.ts +0 -100
  175. package/dist/esm/query/select.d.ts +0 -3
  176. package/dist/esm/query/select.js +0 -130
  177. package/dist/esm/query/select.js.map +0 -1
  178. package/dist/esm/query/types.d.ts +0 -189
  179. package/dist/esm/query/utils.d.ts +0 -37
  180. package/dist/esm/query/utils.js +0 -154
  181. package/dist/esm/query/utils.js.map +0 -1
  182. package/dist/esm/utils.d.ts +0 -3
  183. package/dist/esm/utils.js +0 -17
  184. package/dist/esm/utils.js.map +0 -1
  185. package/src/query/compiled-query.ts +0 -234
  186. package/src/query/evaluators.ts +0 -250
  187. package/src/query/extractors.ts +0 -214
  188. package/src/query/functions.ts +0 -297
  189. package/src/query/group-by.ts +0 -139
  190. package/src/query/joins.ts +0 -260
  191. package/src/query/order-by.ts +0 -264
  192. package/src/query/pipeline-compiler.ts +0 -149
  193. package/src/query/query-builder.ts +0 -902
  194. package/src/query/schema.ts +0 -268
  195. package/src/query/select.ts +0 -208
  196. package/src/query/types.ts +0 -418
  197. package/src/query/utils.ts +0 -245
  198. package/src/utils.ts +0 -15
@@ -1,100 +0,0 @@
1
- import { Context, InputReference, PropertyReference, PropertyReferenceString, Schema, WildcardReferenceString } from './types.js';
2
- import { Collection } from '../collection.js';
3
- export type ColumnName<TColumnNames extends string> = TColumnNames;
4
- export type JSONLike = string | number | boolean | Date | null | Array<JSONLike> | {
5
- [key: string]: JSONLike;
6
- };
7
- export type LiteralValue = (string & {}) | number | boolean | Date | null | undefined;
8
- export type ComparatorValue<T extends Comparator, TContext extends Context<Schema>> = T extends `in` | `not in` ? Array<LiteralValue> : PropertyReferenceString<TContext> | LiteralValue;
9
- export type SafeString<T extends string> = T extends `@${string}` ? never : T;
10
- export type OptionalSafeString<T extends any> = T extends string ? SafeString<T> : never;
11
- export type LiteralValueWithSafeString<T extends any> = (OptionalSafeString<T> & {}) | number | boolean | Date | null | undefined;
12
- export interface ExplicitLiteral {
13
- value: JSONLike;
14
- }
15
- export type AllowedFunctionName = `DATE` | `JSON_EXTRACT` | `JSON_EXTRACT_PATH` | `UPPER` | `LOWER` | `COALESCE` | `CONCAT` | `LENGTH` | `ORDER_INDEX`;
16
- export type FunctionCall<TContext extends Context = Context> = {
17
- [K in AllowedFunctionName]: {
18
- [key in K]: ConditionOperand<TContext> | Array<ConditionOperand<TContext>>;
19
- };
20
- }[AllowedFunctionName];
21
- export type AggregateFunctionName = `SUM` | `COUNT` | `AVG` | `MIN` | `MAX` | `MEDIAN` | `MODE`;
22
- export type AggregateFunctionCall<TContext extends Context = Context> = {
23
- [K in AggregateFunctionName]: {
24
- [key in K]: ConditionOperand<TContext> | Array<ConditionOperand<TContext>>;
25
- };
26
- }[AggregateFunctionName];
27
- /**
28
- * An operand in a condition may be:
29
- * - A literal value (LiteralValue)
30
- * - A column reference (a string starting with "@" or an explicit { col: string } object)
31
- * - An explicit literal (to wrap arbitrary JSON or Date values) as { value: ... }
32
- * - A function call (as defined above)
33
- * - An array of operands (for example, for "in" clauses)
34
- */
35
- export type ConditionOperand<TContext extends Context = Context, T extends any = any> = LiteralValue | PropertyReference<TContext> | ExplicitLiteral | FunctionCall<TContext> | Array<ConditionOperand<TContext, T>>;
36
- export type Comparator = `=` | `!=` | `<` | `<=` | `>` | `>=` | `like` | `not like` | `in` | `not in` | `is` | `is not`;
37
- export type LogicalOperator = `and` | `or`;
38
- export type SimpleCondition<TContext extends Context = Context, T extends any = any> = [ConditionOperand<TContext, T>, Comparator, ConditionOperand<TContext, T>];
39
- export type FlatCompositeCondition<TContext extends Context = Context, T extends any = any> = [
40
- ConditionOperand<TContext, T>,
41
- Comparator,
42
- ConditionOperand<TContext, T>,
43
- ...Array<LogicalOperator | ConditionOperand<TContext, T> | Comparator>
44
- ];
45
- export type NestedCompositeCondition<TContext extends Context = Context, T extends any = any> = [
46
- SimpleCondition<TContext, T> | FlatCompositeCondition<TContext, T>,
47
- ...Array<LogicalOperator | SimpleCondition<TContext, T> | FlatCompositeCondition<TContext, T>>
48
- ];
49
- export type Condition<TContext extends Context = Context, T extends any = any> = SimpleCondition<TContext, T> | FlatCompositeCondition<TContext, T> | NestedCompositeCondition<TContext, T>;
50
- export interface JoinClause<TContext extends Context = Context> {
51
- type: `inner` | `left` | `right` | `full` | `cross`;
52
- from: string;
53
- as?: string;
54
- on: Condition<TContext>;
55
- }
56
- export type OrderBy<TContext extends Context = Context> = PropertyReferenceString<TContext> | {
57
- [column in PropertyReferenceString<TContext>]?: `asc` | `desc`;
58
- } | Record<PropertyReferenceString<TContext>, `asc` | `desc`> | Array<PropertyReferenceString<TContext> | {
59
- [column in PropertyReferenceString<TContext>]?: `asc` | `desc`;
60
- }>;
61
- export type Select<TContext extends Context = Context> = PropertyReferenceString<TContext> | {
62
- [alias: string]: PropertyReference<TContext> | FunctionCall<TContext> | AggregateFunctionCall<TContext>;
63
- } | WildcardReferenceString<TContext> | SelectCallback<TContext>;
64
- export type SelectCallback<TContext extends Context = Context> = (context: TContext extends {
65
- schema: infer S;
66
- } ? S : any) => any;
67
- export type As<_TContext extends Context = Context> = string;
68
- export type From<TContext extends Context = Context> = InputReference<{
69
- baseSchema: TContext[`baseSchema`];
70
- schema: TContext[`baseSchema`];
71
- }>;
72
- export type WhereCallback<TContext extends Context = Context> = (context: TContext extends {
73
- schema: infer S;
74
- } ? S : any) => boolean;
75
- export type Where<TContext extends Context = Context> = Array<Condition<TContext> | WhereCallback<TContext>>;
76
- export type Having<TContext extends Context = Context> = Where<TContext>;
77
- export type GroupBy<TContext extends Context = Context> = PropertyReference<TContext> | Array<PropertyReference<TContext>>;
78
- export type Limit<_TContext extends Context = Context> = number;
79
- export type Offset<_TContext extends Context = Context> = number;
80
- export interface BaseQuery<TContext extends Context = Context> {
81
- select?: Array<Select<TContext>>;
82
- as?: As<TContext>;
83
- from: From<TContext>;
84
- join?: Array<JoinClause<TContext>>;
85
- where?: Where<TContext>;
86
- groupBy?: GroupBy<TContext>;
87
- having?: Having<TContext>;
88
- orderBy?: OrderBy<TContext>;
89
- limit?: Limit<TContext>;
90
- offset?: Offset<TContext>;
91
- }
92
- export interface Query<TContext extends Context = Context> extends BaseQuery<TContext> {
93
- with?: Array<WithQuery<TContext>>;
94
- collections?: {
95
- [K: string]: Collection<any>;
96
- };
97
- }
98
- export interface WithQuery<TContext extends Context = Context> extends BaseQuery<TContext> {
99
- as: string;
100
- }
@@ -1,3 +0,0 @@
1
- import { Query } from './schema.js';
2
- import { KeyedStream, NamespacedAndKeyedStream } from '../types.js';
3
- export declare function processSelect(pipeline: NamespacedAndKeyedStream, query: Query, mainTableAlias: string, inputs: Record<string, KeyedStream>): KeyedStream;
@@ -1,130 +0,0 @@
1
- import { map } from "@electric-sql/d2mini";
2
- import { extractValueFromNamespacedRow, evaluateOperandOnNamespacedRow } from "./extractors.js";
3
- function processSelect(pipeline, query, mainTableAlias, inputs) {
4
- return pipeline.pipe(
5
- map(([key, namespacedRow]) => {
6
- const result = {};
7
- const isGroupedResult = query.groupBy && Object.keys(namespacedRow).some(
8
- (namespaceKey) => !Object.keys(inputs).includes(namespaceKey) && typeof namespacedRow[namespaceKey] !== `object`
9
- );
10
- if (!query.select) {
11
- throw new Error(`Cannot process missing SELECT clause`);
12
- }
13
- for (const item of query.select) {
14
- if (typeof item === `function`) {
15
- const callback = item;
16
- const callbackResult = callback(namespacedRow);
17
- if (callbackResult && typeof callbackResult === `object` && !Array.isArray(callbackResult)) {
18
- Object.assign(result, callbackResult);
19
- } else {
20
- console.warn(
21
- `SelectCallback returned a non-object value. SelectCallbacks should return objects with key-value pairs.`
22
- );
23
- }
24
- continue;
25
- }
26
- if (typeof item === `string`) {
27
- if (item === `@*`) {
28
- if (isGroupedResult) {
29
- Object.assign(result, namespacedRow);
30
- } else {
31
- Object.assign(
32
- result,
33
- extractAllColumnsFromAllTables(namespacedRow)
34
- );
35
- }
36
- continue;
37
- }
38
- if (item.startsWith(`@`) && item.endsWith(`.*`)) {
39
- const tableAlias = item.slice(1, -2);
40
- if (isGroupedResult) {
41
- continue;
42
- } else {
43
- Object.assign(
44
- result,
45
- extractAllColumnsFromTable(namespacedRow, tableAlias)
46
- );
47
- }
48
- continue;
49
- }
50
- if (item.startsWith(`@`)) {
51
- const columnRef = item.substring(1);
52
- const alias = columnRef;
53
- if (isGroupedResult && columnRef in namespacedRow) {
54
- result[alias] = namespacedRow[columnRef];
55
- } else {
56
- result[alias] = extractValueFromNamespacedRow(
57
- namespacedRow,
58
- columnRef,
59
- mainTableAlias,
60
- void 0
61
- );
62
- }
63
- if (alias.includes(`.`)) {
64
- const columnName = alias.split(`.`)[1];
65
- result[columnName] = result[alias];
66
- delete result[alias];
67
- }
68
- }
69
- } else {
70
- for (const [alias, expr] of Object.entries(item)) {
71
- if (typeof expr === `string` && expr.startsWith(`@`)) {
72
- const columnRef = expr.substring(1);
73
- if (isGroupedResult && columnRef in namespacedRow) {
74
- result[alias] = namespacedRow[columnRef];
75
- } else {
76
- result[alias] = extractValueFromNamespacedRow(
77
- namespacedRow,
78
- columnRef,
79
- mainTableAlias,
80
- void 0
81
- );
82
- }
83
- } else if (typeof expr === `object`) {
84
- if (isGroupedResult && alias in namespacedRow) {
85
- result[alias] = namespacedRow[alias];
86
- } else if (expr.ORDER_INDEX) {
87
- result[alias] = namespacedRow[mainTableAlias][alias];
88
- } else {
89
- result[alias] = evaluateOperandOnNamespacedRow(
90
- namespacedRow,
91
- expr,
92
- mainTableAlias,
93
- void 0
94
- );
95
- }
96
- }
97
- }
98
- }
99
- }
100
- return [key, result];
101
- })
102
- );
103
- }
104
- function extractAllColumnsFromAllTables(namespacedRow) {
105
- const result = {};
106
- for (const [tableAlias, tableData] of Object.entries(namespacedRow)) {
107
- if (tableData && typeof tableData === `object`) {
108
- Object.assign(
109
- result,
110
- extractAllColumnsFromTable(namespacedRow, tableAlias)
111
- );
112
- }
113
- }
114
- return result;
115
- }
116
- function extractAllColumnsFromTable(namespacedRow, tableAlias) {
117
- const result = {};
118
- const tableData = namespacedRow[tableAlias];
119
- if (!tableData || typeof tableData !== `object`) {
120
- return result;
121
- }
122
- for (const [columnName, value] of Object.entries(tableData)) {
123
- result[columnName] = value;
124
- }
125
- return result;
126
- }
127
- export {
128
- processSelect
129
- };
130
- //# sourceMappingURL=select.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"select.js","sources":["../../../src/query/select.ts"],"sourcesContent":["import { map } from \"@electric-sql/d2mini\"\nimport {\n evaluateOperandOnNamespacedRow,\n extractValueFromNamespacedRow,\n} from \"./extractors\"\nimport type { ConditionOperand, Query, SelectCallback } from \"./schema\"\nimport type { KeyedStream, NamespacedAndKeyedStream } from \"../types\"\n\nexport function processSelect(\n pipeline: NamespacedAndKeyedStream,\n query: Query,\n mainTableAlias: string,\n inputs: Record<string, KeyedStream>\n): KeyedStream {\n return pipeline.pipe(\n map(([key, namespacedRow]) => {\n const result: Record<string, unknown> = {}\n\n // Check if this is a grouped result (has no nested table structure)\n // If it's a grouped result, we need to handle it differently\n const isGroupedResult =\n query.groupBy &&\n Object.keys(namespacedRow).some(\n (namespaceKey) =>\n !Object.keys(inputs).includes(namespaceKey) &&\n typeof namespacedRow[namespaceKey] !== `object`\n )\n\n if (!query.select) {\n throw new Error(`Cannot process missing SELECT clause`)\n }\n\n for (const item of query.select) {\n // Handle callback functions\n if (typeof item === `function`) {\n const callback = item as SelectCallback\n const callbackResult = callback(namespacedRow)\n\n // If the callback returns an object, merge its properties into the result\n if (\n callbackResult &&\n typeof callbackResult === `object` &&\n !Array.isArray(callbackResult)\n ) {\n Object.assign(result, callbackResult)\n } else {\n // If the callback returns a primitive value, we can't merge it\n // This would need a specific key, but since we don't have one, we'll skip it\n // In practice, select callbacks should return objects with keys\n console.warn(\n `SelectCallback returned a non-object value. SelectCallbacks should return objects with key-value pairs.`\n )\n }\n continue\n }\n\n if (typeof item === `string`) {\n // Handle wildcard select - all columns from all tables\n if ((item as string) === `@*`) {\n // For grouped results, just return the row as is\n if (isGroupedResult) {\n Object.assign(result, namespacedRow)\n } else {\n // Extract all columns from all tables\n Object.assign(\n result,\n extractAllColumnsFromAllTables(namespacedRow)\n )\n }\n continue\n }\n\n // Handle @table.* syntax - all columns from a specific table\n if (\n (item as string).startsWith(`@`) &&\n (item as string).endsWith(`.*`)\n ) {\n const tableAlias = (item as string).slice(1, -2) // Remove the '@' and '.*' parts\n\n // For grouped results, check if we have columns from this table\n if (isGroupedResult) {\n // In grouped results, we don't have the nested structure anymore\n // So we can't extract by table. Just continue to the next item.\n continue\n } else {\n // Extract all columns from the specified table\n Object.assign(\n result,\n extractAllColumnsFromTable(namespacedRow, tableAlias)\n )\n }\n continue\n }\n\n // Handle simple column references like \"@table.column\" or \"@column\"\n if ((item as string).startsWith(`@`)) {\n const columnRef = (item as string).substring(1)\n const alias = columnRef\n\n // For grouped results, check if the column is directly in the row first\n if (isGroupedResult && columnRef in namespacedRow) {\n result[alias] = namespacedRow[columnRef]\n } else {\n // Extract the value from the nested structure\n result[alias] = extractValueFromNamespacedRow(\n namespacedRow,\n columnRef,\n mainTableAlias,\n undefined\n )\n }\n\n // If the alias contains a dot (table.column),\n // use just the column part as the field name\n if (alias.includes(`.`)) {\n const columnName = alias.split(`.`)[1]\n result[columnName!] = result[alias]\n delete result[alias]\n }\n }\n } else {\n // Handle aliased columns like { alias: \"@column_name\" }\n for (const [alias, expr] of Object.entries(item)) {\n if (typeof expr === `string` && (expr as string).startsWith(`@`)) {\n const columnRef = (expr as string).substring(1)\n\n // For grouped results, check if the column is directly in the row first\n if (isGroupedResult && columnRef in namespacedRow) {\n result[alias] = namespacedRow[columnRef]\n } else {\n // Extract the value from the nested structure\n result[alias] = extractValueFromNamespacedRow(\n namespacedRow,\n columnRef,\n mainTableAlias,\n undefined\n )\n }\n } else if (typeof expr === `object`) {\n // For grouped results, the aggregate results are already in the row\n if (isGroupedResult && alias in namespacedRow) {\n result[alias] = namespacedRow[alias]\n } else if ((expr as { ORDER_INDEX: unknown }).ORDER_INDEX) {\n result[alias] = namespacedRow[mainTableAlias]![alias]\n } else {\n // This might be a function call\n result[alias] = evaluateOperandOnNamespacedRow(\n namespacedRow,\n expr as ConditionOperand,\n mainTableAlias,\n undefined\n )\n }\n }\n }\n }\n }\n\n return [key, result] as [string, typeof result]\n })\n )\n}\n\n// Helper function to extract all columns from all tables in a nested row\nfunction extractAllColumnsFromAllTables(\n namespacedRow: Record<string, unknown>\n): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n\n // Process each table in the nested row\n for (const [tableAlias, tableData] of Object.entries(namespacedRow)) {\n if (tableData && typeof tableData === `object`) {\n // Add all columns from this table to the result\n // If there are column name conflicts, the last table's columns will overwrite previous ones\n Object.assign(\n result,\n extractAllColumnsFromTable(namespacedRow, tableAlias)\n )\n }\n }\n\n return result\n}\n\n// Helper function to extract all columns from a table in a nested row\nfunction extractAllColumnsFromTable(\n namespacedRow: Record<string, unknown>,\n tableAlias: string\n): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n\n // Get the table data\n const tableData = namespacedRow[tableAlias] as\n | Record<string, unknown>\n | null\n | undefined\n\n if (!tableData || typeof tableData !== `object`) {\n return result\n }\n\n // Add all columns from the table to the result\n for (const [columnName, value] of Object.entries(tableData)) {\n result[columnName] = value\n }\n\n return result\n}\n"],"names":[],"mappings":"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"}
@@ -1,189 +0,0 @@
1
- import { ConditionOperand, ExplicitLiteral, FunctionCall, LiteralValue, Select } from './schema.js';
2
- export type Input = Record<string, unknown>;
3
- export type Schema = Record<string, Input>;
4
- export type Context<TBaseSchema extends Schema = Schema, TSchema extends Schema = Schema> = {
5
- baseSchema: TBaseSchema;
6
- schema: TSchema;
7
- default?: keyof TSchema;
8
- result?: Record<string, unknown>;
9
- hasJoin?: boolean;
10
- };
11
- export type Flatten<T> = {
12
- [K in keyof T]: T[K];
13
- } & {};
14
- type UniqueSecondLevelKeys<T> = {
15
- [K in keyof T]: Exclude<keyof T[K], {
16
- [P in Exclude<keyof T, K>]: keyof T[P];
17
- }[Exclude<keyof T, K>]>;
18
- }[keyof T];
19
- type InputNames<TSchema extends Schema> = RemoveIndexSignature<{
20
- [I in keyof TSchema]: I;
21
- }>[keyof RemoveIndexSignature<{
22
- [I in keyof TSchema]: I;
23
- }>];
24
- type UniquePropertyNames<TSchema extends Schema> = UniqueSecondLevelKeys<RemoveIndexSignature<TSchema>>;
25
- export type RemoveIndexSignature<T> = {
26
- [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
27
- };
28
- type QualifiedReferencesOfSchemaString<TSchema extends Schema> = RemoveIndexSignature<{
29
- [I in keyof TSchema]: {
30
- [P in keyof RemoveIndexSignature<TSchema[I]>]: `@${string & I}.${string & P}`;
31
- }[keyof RemoveIndexSignature<TSchema[I]>];
32
- }>;
33
- type QualifiedReferenceString<TContext extends Context<Schema>> = QualifiedReferencesOfSchemaString<TContext[`schema`]>[keyof QualifiedReferencesOfSchemaString<TContext[`schema`]>];
34
- type QualifiedReferencesOfSchemaObject<TSchema extends Schema> = RemoveIndexSignature<{
35
- [I in keyof TSchema]: {
36
- [P in keyof RemoveIndexSignature<TSchema[I]>]: {
37
- col: `${string & I}.${string & P}`;
38
- };
39
- }[keyof RemoveIndexSignature<TSchema[I]>];
40
- }>;
41
- type QualifiedReferenceObject<TContext extends Context<Schema>> = QualifiedReferencesOfSchemaObject<TContext[`schema`]>[keyof QualifiedReferencesOfSchemaObject<TContext[`schema`]>];
42
- type QualifiedReference<TContext extends Context<Schema>> = QualifiedReferenceString<TContext> | QualifiedReferenceObject<TContext>;
43
- type DefaultReferencesOfSchemaString<TSchema extends Schema, TDefault extends keyof TSchema> = RemoveIndexSignature<{
44
- [P in keyof TSchema[TDefault]]: `@${string & P}`;
45
- }>;
46
- type DefaultReferenceString<TContext extends Context<Schema>> = TContext[`default`] extends undefined ? never : DefaultReferencesOfSchemaString<TContext[`schema`], Exclude<TContext[`default`], undefined>>[keyof DefaultReferencesOfSchemaString<TContext[`schema`], Exclude<TContext[`default`], undefined>>];
47
- type DefaultReferencesOfSchemaObject<TSchema extends Schema, TDefault extends keyof TSchema> = RemoveIndexSignature<{
48
- [P in keyof TSchema[TDefault]]: {
49
- col: `${string & P}`;
50
- };
51
- }>;
52
- type DefaultReferenceObject<TContext extends Context<Schema>> = TContext[`default`] extends undefined ? never : DefaultReferencesOfSchemaObject<TContext[`schema`], Exclude<TContext[`default`], undefined>>[keyof DefaultReferencesOfSchemaObject<TContext[`schema`], Exclude<TContext[`default`], undefined>>];
53
- type DefaultReference<TContext extends Context<Schema>> = DefaultReferenceString<TContext> | DefaultReferenceObject<TContext>;
54
- type UniqueReferencesOfSchemaString<TSchema extends Schema> = RemoveIndexSignature<{
55
- [I in keyof TSchema]: {
56
- [P in keyof TSchema[I]]: P extends UniquePropertyNames<TSchema> ? `@${string & P}` : never;
57
- }[keyof TSchema[I]];
58
- }>;
59
- type UniqueReferenceString<TContext extends Context<Schema>> = UniqueReferencesOfSchemaString<TContext[`schema`]>[keyof UniqueReferencesOfSchemaString<TContext[`schema`]>];
60
- type UniqueReferencesOfSchemaObject<TSchema extends Schema> = RemoveIndexSignature<{
61
- [I in keyof TSchema]: {
62
- [P in keyof TSchema[I]]: P extends UniquePropertyNames<TSchema> ? {
63
- col: `${string & P}`;
64
- } : never;
65
- }[keyof TSchema[I]];
66
- }>;
67
- type UniqueReferenceObject<TContext extends Context<Schema>> = UniqueReferencesOfSchemaObject<TContext[`schema`]>[keyof UniqueReferencesOfSchemaObject<TContext[`schema`]>];
68
- type UniqueReference<TContext extends Context<Schema>> = UniqueReferenceString<TContext> | UniqueReferenceObject<TContext>;
69
- type InputWildcardString<TContext extends Context<Schema>> = Flatten<{
70
- [I in InputNames<TContext[`schema`]>]: `@${I}.*`;
71
- }[InputNames<TContext[`schema`]>]>;
72
- type InputWildcardObject<TContext extends Context<Schema>> = Flatten<{
73
- [I in InputNames<TContext[`schema`]>]: {
74
- col: `${I}.*`;
75
- };
76
- }[InputNames<TContext[`schema`]>]>;
77
- type InputWildcard<TContext extends Context<Schema>> = InputWildcardString<TContext> | InputWildcardObject<TContext>;
78
- type AllWildcardString = `@*`;
79
- type AllWildcardObject = {
80
- col: `*`;
81
- };
82
- type AllWildcard = AllWildcardString | AllWildcardObject;
83
- export type PropertyReferenceString<TContext extends Context<Schema>> = DefaultReferenceString<TContext> | QualifiedReferenceString<TContext> | UniqueReferenceString<TContext>;
84
- export type WildcardReferenceString<TContext extends Context<Schema>> = InputWildcardString<TContext> | AllWildcardString;
85
- export type PropertyReferenceObject<TContext extends Context<Schema>> = DefaultReferenceObject<TContext> | QualifiedReferenceObject<TContext> | UniqueReferenceObject<TContext>;
86
- export type WildcardReferenceObject<TContext extends Context<Schema>> = InputWildcardObject<TContext> | AllWildcardObject;
87
- export type PropertyReference<TContext extends Context<Schema>> = DefaultReference<TContext> | QualifiedReference<TContext> | UniqueReference<TContext>;
88
- export type WildcardReference<TContext extends Context<Schema>> = InputWildcard<TContext> | AllWildcard;
89
- type InputWithProperty<TSchema extends Schema, TProperty extends string> = {
90
- [I in keyof RemoveIndexSignature<TSchema>]: TProperty extends keyof TSchema[I] ? I : never;
91
- }[keyof RemoveIndexSignature<TSchema>];
92
- export type TypeFromPropertyReference<TContext extends Context<Schema>, TReference extends PropertyReference<TContext>> = TReference extends `@${infer InputName}.${infer PropName}` | {
93
- col: `${infer InputName}.${infer PropName}`;
94
- } ? InputName extends keyof TContext[`schema`] ? PropName extends keyof TContext[`schema`][InputName] ? TContext[`schema`][InputName][PropName] : never : never : TReference extends `@${infer PropName}` | {
95
- col: `${infer PropName}`;
96
- } ? PropName extends keyof TContext[`schema`][Exclude<TContext[`default`], undefined>] ? TContext[`schema`][Exclude<TContext[`default`], undefined>][PropName] : TContext[`schema`][InputWithProperty<TContext[`schema`], PropName>][PropName] : never;
97
- /**
98
- * Return the key that would be used in the result of the query for a given property
99
- * reference.
100
- * - `@id` -> `id`
101
- * - `@employees.id` -> `id`
102
- * - `{ col: 'id' }` -> `id`
103
- * - `{ col: 'employees.id' }` -> `id`
104
- */
105
- export type ResultKeyFromPropertyReference<TContext extends Context<Schema>, TReference extends PropertyReference<TContext>> = TReference extends `@${infer _InputName}.${infer PropName}` ? PropName : TReference extends {
106
- col: `${infer _InputName}.${infer PropName}`;
107
- } ? PropName : TReference extends `@${infer PropName}` ? PropName : TReference extends {
108
- col: `${infer PropName}`;
109
- } ? PropName : never;
110
- export type InputReference<TContext extends Context<Schema>> = {
111
- [I in InputNames<TContext[`schema`]>]: I;
112
- }[InputNames<TContext[`schema`]>];
113
- export type RenameInput<TSchema extends Schema, TInput extends keyof TSchema, TNewName extends string> = Flatten<{
114
- [K in Exclude<keyof TSchema, TInput>]: TSchema[K];
115
- } & {
116
- [P in TNewName]: TSchema[TInput];
117
- }>;
118
- export type MaybeRenameInput<TSchema extends Schema, TInput extends keyof TSchema, TNewName extends string | undefined> = TNewName extends undefined ? TSchema : RenameInput<TSchema, TInput, Exclude<TNewName, undefined>>;
119
- /**
120
- * Helper type to combine result types from each select item in a tuple
121
- */
122
- export type InferResultTypeFromSelectTuple<TContext extends Context<Schema>, TSelects extends ReadonlyArray<Select<TContext>>> = UnionToIntersection<{
123
- [K in keyof TSelects]: TSelects[K] extends Select<TContext> ? InferResultType<TContext, TSelects[K]> : never;
124
- }[number]>;
125
- /**
126
- * Convert a union type to an intersection type
127
- */
128
- type UnionToIntersection<TUnion> = (TUnion extends any ? (x: TUnion) => void : never) extends (x: infer I) => void ? I : never;
129
- /**
130
- * Infers the result type from a single select item
131
- */
132
- type InferResultType<TContext extends Context<Schema>, TSelect extends Select<TContext>> = TSelect extends PropertyReferenceString<TContext> ? {
133
- [K in ResultKeyFromPropertyReference<TContext, TSelect>]: TypeFromPropertyReference<TContext, TSelect>;
134
- } : TSelect extends WildcardReferenceString<TContext> ? TSelect extends `@*` ? InferAllColumnsType<TContext> : TSelect extends `@${infer TableName}.*` ? TableName extends keyof TContext[`schema`] ? InferTableColumnsType<TContext, TableName> : {} : {} : TSelect extends {
135
- [alias: string]: PropertyReference<TContext> | FunctionCall<TContext>;
136
- } ? {
137
- [K in keyof TSelect]: TSelect[K] extends PropertyReference<TContext> ? TypeFromPropertyReference<TContext, TSelect[K]> : TSelect[K] extends FunctionCall<TContext> ? InferFunctionCallResultType<TContext, TSelect[K]> : never;
138
- } : {};
139
- /**
140
- * Infers the result type for all columns from all tables
141
- */
142
- type InferAllColumnsType<TContext extends Context<Schema>> = {
143
- [K in keyof TContext[`schema`]]: {
144
- [P in keyof TContext[`schema`][K]]: TContext[`schema`][K][P];
145
- };
146
- }[keyof TContext[`schema`]];
147
- /**
148
- * Infers the result type for all columns from a specific table
149
- */
150
- type InferTableColumnsType<TContext extends Context<Schema>, TTable extends keyof TContext[`schema`]> = {
151
- [P in keyof TContext[`schema`][TTable]]: TContext[`schema`][TTable][P];
152
- };
153
- /**
154
- * Infers the result type for a function call
155
- */
156
- type InferFunctionCallResultType<TContext extends Context<Schema>, TFunctionCall extends FunctionCall<TContext>> = TFunctionCall extends {
157
- SUM: any;
158
- } ? number : TFunctionCall extends {
159
- COUNT: any;
160
- } ? number : TFunctionCall extends {
161
- AVG: any;
162
- } ? number : TFunctionCall extends {
163
- MIN: any;
164
- } ? InferOperandType<TContext, TFunctionCall[`MIN`]> : TFunctionCall extends {
165
- MAX: any;
166
- } ? InferOperandType<TContext, TFunctionCall[`MAX`]> : TFunctionCall extends {
167
- DATE: any;
168
- } ? string : TFunctionCall extends {
169
- JSON_EXTRACT: any;
170
- } ? unknown : TFunctionCall extends {
171
- JSON_EXTRACT_PATH: any;
172
- } ? unknown : TFunctionCall extends {
173
- UPPER: any;
174
- } ? string : TFunctionCall extends {
175
- LOWER: any;
176
- } ? string : TFunctionCall extends {
177
- COALESCE: any;
178
- } ? InferOperandType<TContext, TFunctionCall[`COALESCE`]> : TFunctionCall extends {
179
- CONCAT: any;
180
- } ? string : TFunctionCall extends {
181
- LENGTH: any;
182
- } ? number : TFunctionCall extends {
183
- ORDER_INDEX: any;
184
- } ? number : unknown;
185
- /**
186
- * Infers the type of an operand
187
- */
188
- type InferOperandType<TContext extends Context<Schema>, TOperand extends ConditionOperand<TContext>> = TOperand extends PropertyReference<TContext> ? TypeFromPropertyReference<TContext, TOperand> : TOperand extends LiteralValue ? TOperand : TOperand extends ExplicitLiteral ? TOperand[`value`] : TOperand extends FunctionCall<TContext> ? InferFunctionCallResultType<TContext, TOperand> : TOperand extends Array<ConditionOperand<TContext>> ? InferOperandType<TContext, TOperand[number]> : unknown;
189
- export {};
@@ -1,37 +0,0 @@
1
- /**
2
- * Helper function to determine if an object is a function call with an aggregate function
3
- */
4
- export declare function isAggregateFunctionCall(obj: any): boolean;
5
- /**
6
- * Helper function to determine if an object is an ORDER_INDEX function call
7
- */
8
- export declare function isOrderIndexFunctionCall(obj: any): boolean;
9
- /**
10
- * Type guard to check if a value is comparable (can be used with <, >, <=, >= operators)
11
- * @param value The value to check
12
- * @returns True if the value is comparable
13
- */
14
- export declare function isComparable(value: unknown): value is number | string | Date | boolean;
15
- /**
16
- * Performs a comparison between two values, ensuring they are of compatible types
17
- * @param left The left operand
18
- * @param right The right operand
19
- * @param operator The comparison operator
20
- * @returns The result of the comparison
21
- * @throws Error if the values are not comparable
22
- */
23
- export declare function compareValues(left: unknown, right: unknown, operator: `<` | `<=` | `>` | `>=`): boolean;
24
- /**
25
- * Converts a SQL LIKE pattern to a JavaScript regex pattern
26
- * @param pattern The SQL LIKE pattern to convert
27
- * @returns A regex-compatible pattern string
28
- */
29
- export declare function convertLikeToRegex(pattern: string): string;
30
- /**
31
- * Helper function to check if a value is in an array, with special handling for various types
32
- * @param value The value to check for
33
- * @param array The array to search in
34
- * @param caseInsensitive Optional flag to enable case-insensitive matching for strings (default: false)
35
- * @returns True if the value is found in the array
36
- */
37
- export declare function isValueInArray(value: unknown, array: Array<unknown>, caseInsensitive?: boolean): boolean;
@@ -1,154 +0,0 @@
1
- function isAggregateFunctionCall(obj) {
2
- if (!obj || typeof obj !== `object`) return false;
3
- const aggregateFunctions = [
4
- `SUM`,
5
- `COUNT`,
6
- `AVG`,
7
- `MIN`,
8
- `MAX`,
9
- `MEDIAN`,
10
- `MODE`
11
- ];
12
- const keys = Object.keys(obj);
13
- return keys.length === 1 && aggregateFunctions.includes(keys[0]);
14
- }
15
- function isOrderIndexFunctionCall(obj) {
16
- if (!obj || typeof obj !== `object`) return false;
17
- const keys = Object.keys(obj);
18
- return keys.length === 1 && keys[0] === `ORDER_INDEX`;
19
- }
20
- function isComparable(value) {
21
- return typeof value === `number` || typeof value === `string` || typeof value === `boolean` || value instanceof Date;
22
- }
23
- function compareValues(left, right, operator) {
24
- if (!isComparable(left) || !isComparable(right)) {
25
- throw new Error(
26
- `Cannot compare non-comparable values: ${typeof left} and ${typeof right}`
27
- );
28
- }
29
- if (typeof left !== typeof right && (typeof left === `string` || typeof left === `number`) && (typeof right === `string` || typeof right === `number`)) {
30
- const leftStr = String(left);
31
- const rightStr = String(right);
32
- switch (operator) {
33
- case `<`:
34
- return leftStr < rightStr;
35
- case `<=`:
36
- return leftStr <= rightStr;
37
- case `>`:
38
- return leftStr > rightStr;
39
- case `>=`:
40
- return leftStr >= rightStr;
41
- }
42
- }
43
- if (left instanceof Date && right instanceof Date) {
44
- const leftTime = left.getTime();
45
- const rightTime = right.getTime();
46
- switch (operator) {
47
- case `<`:
48
- return leftTime < rightTime;
49
- case `<=`:
50
- return leftTime <= rightTime;
51
- case `>`:
52
- return leftTime > rightTime;
53
- case `>=`:
54
- return leftTime >= rightTime;
55
- }
56
- }
57
- if (typeof left === typeof right) {
58
- switch (operator) {
59
- case `<`:
60
- return left < right;
61
- case `<=`:
62
- return left <= right;
63
- case `>`:
64
- return left > right;
65
- case `>=`:
66
- return left >= right;
67
- }
68
- }
69
- throw new Error(
70
- `Cannot compare incompatible types: ${typeof left} and ${typeof right}`
71
- );
72
- }
73
- function convertLikeToRegex(pattern) {
74
- let finalPattern = ``;
75
- let i = 0;
76
- while (i < pattern.length) {
77
- const char = pattern[i];
78
- if (char === `\\` && i + 1 < pattern.length) {
79
- finalPattern += pattern[i + 1];
80
- i += 2;
81
- continue;
82
- }
83
- switch (char) {
84
- case `%`:
85
- finalPattern += `.*`;
86
- break;
87
- case `_`:
88
- finalPattern += `.`;
89
- break;
90
- // Handle regex special characters
91
- case `.`:
92
- case `^`:
93
- case `$`:
94
- case `*`:
95
- case `+`:
96
- case `?`:
97
- case `(`:
98
- case `)`:
99
- case `[`:
100
- case `]`:
101
- case `{`:
102
- case `}`:
103
- case `|`:
104
- case `/`:
105
- finalPattern += `\\` + char;
106
- break;
107
- default:
108
- finalPattern += char;
109
- }
110
- i++;
111
- }
112
- return finalPattern;
113
- }
114
- function isValueInArray(value, array, caseInsensitive = false) {
115
- if (array.includes(value)) {
116
- return true;
117
- }
118
- if (value === null || value === void 0) {
119
- return array.some((item) => item === null || item === void 0);
120
- }
121
- if (typeof value === `number` || typeof value === `string`) {
122
- return array.some((item) => {
123
- if (typeof item === typeof value) {
124
- if (typeof value === `string` && caseInsensitive) {
125
- return value.toLowerCase() === item.toLowerCase();
126
- }
127
- return item === value;
128
- }
129
- if ((typeof item === `number` || typeof item === `string`) && (typeof value === `number` || typeof value === `string`)) {
130
- return String(item) === String(value);
131
- }
132
- return false;
133
- });
134
- }
135
- if (typeof value === `object`) {
136
- const valueStr = JSON.stringify(value);
137
- return array.some((item) => {
138
- if (typeof item === `object` && item !== null) {
139
- return JSON.stringify(item) === valueStr;
140
- }
141
- return false;
142
- });
143
- }
144
- return false;
145
- }
146
- export {
147
- compareValues,
148
- convertLikeToRegex,
149
- isAggregateFunctionCall,
150
- isComparable,
151
- isOrderIndexFunctionCall,
152
- isValueInArray
153
- };
154
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/query/utils.ts"],"sourcesContent":["/**\n * Helper function to determine if an object is a function call with an aggregate function\n */\nexport function isAggregateFunctionCall(obj: any): boolean {\n if (!obj || typeof obj !== `object`) return false\n\n const aggregateFunctions = [\n `SUM`,\n `COUNT`,\n `AVG`,\n `MIN`,\n `MAX`,\n `MEDIAN`,\n `MODE`,\n ]\n const keys = Object.keys(obj)\n\n return keys.length === 1 && aggregateFunctions.includes(keys[0]!)\n}\n\n/**\n * Helper function to determine if an object is an ORDER_INDEX function call\n */\nexport function isOrderIndexFunctionCall(obj: any): boolean {\n if (!obj || typeof obj !== `object`) return false\n\n const keys = Object.keys(obj)\n return keys.length === 1 && keys[0] === `ORDER_INDEX`\n}\n\n/**\n * Type guard to check if a value is comparable (can be used with <, >, <=, >= operators)\n * @param value The value to check\n * @returns True if the value is comparable\n */\nexport function isComparable(\n value: unknown\n): value is number | string | Date | boolean {\n return (\n typeof value === `number` ||\n typeof value === `string` ||\n typeof value === `boolean` ||\n value instanceof Date\n )\n}\n\n/**\n * Performs a comparison between two values, ensuring they are of compatible types\n * @param left The left operand\n * @param right The right operand\n * @param operator The comparison operator\n * @returns The result of the comparison\n * @throws Error if the values are not comparable\n */\nexport function compareValues(\n left: unknown,\n right: unknown,\n operator: `<` | `<=` | `>` | `>=`\n): boolean {\n // First check if both values are comparable\n if (!isComparable(left) || !isComparable(right)) {\n throw new Error(\n `Cannot compare non-comparable values: ${typeof left} and ${typeof right}`\n )\n }\n\n // If they're different types but both are strings or numbers, convert to strings\n if (\n typeof left !== typeof right &&\n (typeof left === `string` || typeof left === `number`) &&\n (typeof right === `string` || typeof right === `number`)\n ) {\n // Convert to strings for comparison (follows JavaScript's coercion rules)\n const leftStr = String(left)\n const rightStr = String(right)\n\n switch (operator) {\n case `<`:\n return leftStr < rightStr\n case `<=`:\n return leftStr <= rightStr\n case `>`:\n return leftStr > rightStr\n case `>=`:\n return leftStr >= rightStr\n }\n }\n\n // For Date objects, convert to timestamps\n if (left instanceof Date && right instanceof Date) {\n const leftTime = left.getTime()\n const rightTime = right.getTime()\n\n switch (operator) {\n case `<`:\n return leftTime < rightTime\n case `<=`:\n return leftTime <= rightTime\n case `>`:\n return leftTime > rightTime\n case `>=`:\n return leftTime >= rightTime\n }\n }\n\n // For other cases where types match\n if (typeof left === typeof right) {\n switch (operator) {\n case `<`:\n return left < right\n case `<=`:\n return left <= right\n case `>`:\n return left > right\n case `>=`:\n return left >= right\n }\n }\n\n // If we get here, it means the values are technically comparable but not compatible\n throw new Error(\n `Cannot compare incompatible types: ${typeof left} and ${typeof right}`\n )\n}\n\n/**\n * Converts a SQL LIKE pattern to a JavaScript regex pattern\n * @param pattern The SQL LIKE pattern to convert\n * @returns A regex-compatible pattern string\n */\nexport function convertLikeToRegex(pattern: string): string {\n let finalPattern = ``\n let i = 0\n\n while (i < pattern.length) {\n const char = pattern[i]\n\n // Handle escape character\n if (char === `\\\\` && i + 1 < pattern.length) {\n // Add the next character as a literal (escaped)\n finalPattern += pattern[i + 1]\n i += 2 // Skip both the escape and the escaped character\n continue\n }\n\n // Handle SQL LIKE special characters\n switch (char) {\n case `%`:\n // % matches any sequence of characters (including empty)\n finalPattern += `.*`\n break\n case `_`:\n // _ matches any single character\n finalPattern += `.`\n break\n // Handle regex special characters\n case `.`:\n case `^`:\n case `$`:\n case `*`:\n case `+`:\n case `?`:\n case `(`:\n case `)`:\n case `[`:\n case `]`:\n case `{`:\n case `}`:\n case `|`:\n case `/`:\n // Escape regex special characters\n finalPattern += `\\\\` + char\n break\n default:\n // Regular character, just add it\n finalPattern += char\n }\n\n i++\n }\n\n return finalPattern\n}\n\n/**\n * Helper function to check if a value is in an array, with special handling for various types\n * @param value The value to check for\n * @param array The array to search in\n * @param caseInsensitive Optional flag to enable case-insensitive matching for strings (default: false)\n * @returns True if the value is found in the array\n */\nexport function isValueInArray(\n value: unknown,\n array: Array<unknown>,\n caseInsensitive: boolean = false\n): boolean {\n // Direct inclusion check first (fastest path)\n if (array.includes(value)) {\n return true\n }\n\n // Handle null/undefined\n if (value === null || value === undefined) {\n return array.some((item) => item === null || item === undefined)\n }\n\n // Handle numbers and strings with type coercion\n if (typeof value === `number` || typeof value === `string`) {\n return array.some((item) => {\n // Same type, direct comparison\n if (typeof item === typeof value) {\n if (typeof value === `string` && caseInsensitive) {\n // Case-insensitive comparison for strings (only if explicitly enabled)\n return value.toLowerCase() === (item as string).toLowerCase()\n }\n return item === value\n }\n\n // Different types, try coercion for number/string\n if (\n (typeof item === `number` || typeof item === `string`) &&\n (typeof value === `number` || typeof value === `string`)\n ) {\n // Convert both to strings for comparison\n return String(item) === String(value)\n }\n\n return false\n })\n }\n\n // Handle objects/arrays by comparing stringified versions\n if (typeof value === `object`) {\n const valueStr = JSON.stringify(value)\n return array.some((item) => {\n if (typeof item === `object` && item !== null) {\n return JSON.stringify(item) === valueStr\n }\n return false\n })\n }\n\n // Fallback\n return false\n}\n"],"names":[],"mappings":"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"}