@tanstack/db 0.0.14 → 0.0.16

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 (197) 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 +18 -21
  4. package/dist/cjs/index.cjs +31 -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 +92 -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 +81 -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 +5 -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 +10 -1
  45. package/dist/cjs/types.d.cts +13 -0
  46. package/dist/esm/collection.d.ts +18 -21
  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 +30 -12
  51. package/dist/esm/query/builder/functions.d.ts +38 -0
  52. package/dist/esm/query/builder/functions.js +107 -0
  53. package/dist/esm/query/builder/functions.js.map +1 -0
  54. package/dist/esm/query/builder/index.d.ts +324 -0
  55. package/dist/esm/query/builder/index.js +499 -0
  56. package/dist/esm/query/builder/index.js.map +1 -0
  57. package/dist/esm/query/builder/ref-proxy.d.ts +28 -0
  58. package/dist/esm/query/builder/ref-proxy.js +92 -0
  59. package/dist/esm/query/builder/ref-proxy.js.map +1 -0
  60. package/dist/esm/query/builder/types.d.ts +81 -0
  61. package/dist/esm/query/compiler/evaluators.d.ts +11 -0
  62. package/dist/esm/query/compiler/evaluators.js +261 -0
  63. package/dist/esm/query/compiler/evaluators.js.map +1 -0
  64. package/dist/esm/query/compiler/group-by.d.ts +7 -0
  65. package/dist/esm/query/compiler/group-by.js +271 -0
  66. package/dist/esm/query/compiler/group-by.js.map +1 -0
  67. package/dist/esm/query/compiler/index.d.ts +15 -0
  68. package/dist/esm/query/compiler/index.js +181 -0
  69. package/dist/esm/query/compiler/index.js.map +1 -0
  70. package/dist/esm/query/compiler/joins.d.ts +11 -0
  71. package/dist/esm/query/compiler/joins.js +116 -0
  72. package/dist/esm/query/compiler/joins.js.map +1 -0
  73. package/dist/esm/query/compiler/order-by.d.ts +9 -0
  74. package/dist/esm/query/compiler/order-by.js +89 -0
  75. package/dist/esm/query/compiler/order-by.js.map +1 -0
  76. package/dist/esm/query/compiler/select.d.ts +15 -0
  77. package/dist/esm/query/compiler/select.js +57 -0
  78. package/dist/esm/query/compiler/select.js.map +1 -0
  79. package/dist/esm/query/index.d.ts +5 -5
  80. package/dist/esm/query/ir.d.ts +81 -0
  81. package/dist/esm/query/ir.js +57 -0
  82. package/dist/esm/query/ir.js.map +1 -0
  83. package/dist/esm/query/live-query-collection.d.ts +124 -0
  84. package/dist/esm/query/live-query-collection.js +224 -0
  85. package/dist/esm/query/live-query-collection.js.map +1 -0
  86. package/dist/esm/transactions.d.ts +10 -1
  87. package/dist/esm/transactions.js +20 -13
  88. package/dist/esm/transactions.js.map +1 -1
  89. package/dist/esm/types.d.ts +13 -0
  90. package/package.json +3 -4
  91. package/src/collection.ts +152 -129
  92. package/src/index.ts +0 -1
  93. package/src/query/builder/functions.ts +267 -0
  94. package/src/query/builder/index.ts +648 -0
  95. package/src/query/builder/ref-proxy.ts +156 -0
  96. package/src/query/builder/types.ts +282 -0
  97. package/src/query/compiler/evaluators.ts +315 -0
  98. package/src/query/compiler/group-by.ts +428 -0
  99. package/src/query/compiler/index.ts +276 -0
  100. package/src/query/compiler/joins.ts +228 -0
  101. package/src/query/compiler/order-by.ts +139 -0
  102. package/src/query/compiler/select.ts +173 -0
  103. package/src/query/index.ts +54 -5
  104. package/src/query/ir.ts +128 -0
  105. package/src/query/live-query-collection.ts +512 -0
  106. package/src/transactions.ts +27 -16
  107. package/src/types.ts +15 -0
  108. package/dist/cjs/query/compiled-query.cjs +0 -160
  109. package/dist/cjs/query/compiled-query.cjs.map +0 -1
  110. package/dist/cjs/query/compiled-query.d.cts +0 -20
  111. package/dist/cjs/query/evaluators.cjs +0 -161
  112. package/dist/cjs/query/evaluators.cjs.map +0 -1
  113. package/dist/cjs/query/evaluators.d.cts +0 -14
  114. package/dist/cjs/query/extractors.cjs +0 -122
  115. package/dist/cjs/query/extractors.cjs.map +0 -1
  116. package/dist/cjs/query/extractors.d.cts +0 -22
  117. package/dist/cjs/query/functions.cjs +0 -152
  118. package/dist/cjs/query/functions.cjs.map +0 -1
  119. package/dist/cjs/query/functions.d.cts +0 -21
  120. package/dist/cjs/query/group-by.cjs +0 -88
  121. package/dist/cjs/query/group-by.cjs.map +0 -1
  122. package/dist/cjs/query/group-by.d.cts +0 -40
  123. package/dist/cjs/query/joins.cjs +0 -141
  124. package/dist/cjs/query/joins.cjs.map +0 -1
  125. package/dist/cjs/query/joins.d.cts +0 -14
  126. package/dist/cjs/query/order-by.cjs +0 -185
  127. package/dist/cjs/query/order-by.cjs.map +0 -1
  128. package/dist/cjs/query/order-by.d.cts +0 -3
  129. package/dist/cjs/query/pipeline-compiler.cjs +0 -89
  130. package/dist/cjs/query/pipeline-compiler.cjs.map +0 -1
  131. package/dist/cjs/query/pipeline-compiler.d.cts +0 -10
  132. package/dist/cjs/query/query-builder.cjs +0 -307
  133. package/dist/cjs/query/query-builder.cjs.map +0 -1
  134. package/dist/cjs/query/query-builder.d.cts +0 -225
  135. package/dist/cjs/query/schema.d.cts +0 -100
  136. package/dist/cjs/query/select.cjs +0 -130
  137. package/dist/cjs/query/select.cjs.map +0 -1
  138. package/dist/cjs/query/select.d.cts +0 -3
  139. package/dist/cjs/query/types.d.cts +0 -189
  140. package/dist/cjs/query/utils.cjs +0 -154
  141. package/dist/cjs/query/utils.cjs.map +0 -1
  142. package/dist/cjs/query/utils.d.cts +0 -37
  143. package/dist/cjs/utils.cjs +0 -17
  144. package/dist/cjs/utils.cjs.map +0 -1
  145. package/dist/cjs/utils.d.cts +0 -3
  146. package/dist/esm/query/compiled-query.d.ts +0 -20
  147. package/dist/esm/query/compiled-query.js +0 -160
  148. package/dist/esm/query/compiled-query.js.map +0 -1
  149. package/dist/esm/query/evaluators.d.ts +0 -14
  150. package/dist/esm/query/evaluators.js +0 -161
  151. package/dist/esm/query/evaluators.js.map +0 -1
  152. package/dist/esm/query/extractors.d.ts +0 -22
  153. package/dist/esm/query/extractors.js +0 -122
  154. package/dist/esm/query/extractors.js.map +0 -1
  155. package/dist/esm/query/functions.d.ts +0 -21
  156. package/dist/esm/query/functions.js +0 -152
  157. package/dist/esm/query/functions.js.map +0 -1
  158. package/dist/esm/query/group-by.d.ts +0 -40
  159. package/dist/esm/query/group-by.js +0 -88
  160. package/dist/esm/query/group-by.js.map +0 -1
  161. package/dist/esm/query/joins.d.ts +0 -14
  162. package/dist/esm/query/joins.js +0 -141
  163. package/dist/esm/query/joins.js.map +0 -1
  164. package/dist/esm/query/order-by.d.ts +0 -3
  165. package/dist/esm/query/order-by.js +0 -185
  166. package/dist/esm/query/order-by.js.map +0 -1
  167. package/dist/esm/query/pipeline-compiler.d.ts +0 -10
  168. package/dist/esm/query/pipeline-compiler.js +0 -89
  169. package/dist/esm/query/pipeline-compiler.js.map +0 -1
  170. package/dist/esm/query/query-builder.d.ts +0 -225
  171. package/dist/esm/query/query-builder.js +0 -307
  172. package/dist/esm/query/query-builder.js.map +0 -1
  173. package/dist/esm/query/schema.d.ts +0 -100
  174. package/dist/esm/query/select.d.ts +0 -3
  175. package/dist/esm/query/select.js +0 -130
  176. package/dist/esm/query/select.js.map +0 -1
  177. package/dist/esm/query/types.d.ts +0 -189
  178. package/dist/esm/query/utils.d.ts +0 -37
  179. package/dist/esm/query/utils.js +0 -154
  180. package/dist/esm/query/utils.js.map +0 -1
  181. package/dist/esm/utils.d.ts +0 -3
  182. package/dist/esm/utils.js +0 -17
  183. package/dist/esm/utils.js.map +0 -1
  184. package/src/query/compiled-query.ts +0 -234
  185. package/src/query/evaluators.ts +0 -250
  186. package/src/query/extractors.ts +0 -214
  187. package/src/query/functions.ts +0 -297
  188. package/src/query/group-by.ts +0 -139
  189. package/src/query/joins.ts +0 -260
  190. package/src/query/order-by.ts +0 -264
  191. package/src/query/pipeline-compiler.ts +0 -149
  192. package/src/query/query-builder.ts +0 -902
  193. package/src/query/schema.ts +0 -268
  194. package/src/query/select.ts +0 -208
  195. package/src/query/types.ts +0 -418
  196. package/src/query/utils.ts +0 -245
  197. package/src/utils.ts +0 -15
@@ -1,225 +0,0 @@
1
- import { Collection } from '../collection.js';
2
- import { Comparator, ComparatorValue, Condition, Limit, LiteralValue, Offset, OrderBy, Query, Select, WhereCallback } from './schema.js';
3
- import { Context, Flatten, InferResultTypeFromSelectTuple, Input, InputReference, PropertyReference, PropertyReferenceString, RemoveIndexSignature, Schema } from './types.js';
4
- type CollectionRef = {
5
- [K: string]: Collection<any>;
6
- };
7
- export declare class BaseQueryBuilder<TContext extends Context<Schema>> {
8
- private readonly query;
9
- /**
10
- * Create a new QueryBuilder instance.
11
- */
12
- constructor(query?: Partial<Query<TContext>>);
13
- from<TCollectionRef extends CollectionRef>(collectionRef: TCollectionRef): QueryBuilder<{
14
- baseSchema: Flatten<TContext[`baseSchema`] & {
15
- [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
16
- }>;
17
- schema: Flatten<{
18
- [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
19
- }>;
20
- default: keyof TCollectionRef & string;
21
- }>;
22
- from<T extends InputReference<{
23
- baseSchema: TContext[`baseSchema`];
24
- schema: TContext[`baseSchema`];
25
- }>>(collection: T): QueryBuilder<{
26
- baseSchema: TContext[`baseSchema`];
27
- schema: {
28
- [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
29
- };
30
- default: T;
31
- }>;
32
- from<T extends InputReference<{
33
- baseSchema: TContext[`baseSchema`];
34
- schema: TContext[`baseSchema`];
35
- }>, TAs extends string>(collection: T, as: TAs): QueryBuilder<{
36
- baseSchema: TContext[`baseSchema`];
37
- schema: {
38
- [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
39
- };
40
- default: TAs;
41
- }>;
42
- private fromCollectionRef;
43
- private fromInputReference;
44
- /**
45
- * Specify what columns to select.
46
- * Overwrites any previous select clause.
47
- * Also supports callback functions that receive the row context and return selected data.
48
- *
49
- * @param selects The columns to select (can include callbacks)
50
- * @returns A new QueryBuilder with the select clause set
51
- */
52
- select<TSelects extends Array<Select<TContext>>>(this: QueryBuilder<TContext>, ...selects: TSelects): QueryBuilder<Flatten<Omit<TContext, `result`> & {
53
- result: InferResultTypeFromSelectTuple<TContext, TSelects>;
54
- }>>;
55
- /**
56
- * Add a where clause comparing two values.
57
- */
58
- where<T extends Comparator>(left: PropertyReferenceString<TContext> | LiteralValue, operator: T, right: ComparatorValue<T, TContext>): QueryBuilder<TContext>;
59
- /**
60
- * Add a where clause with a complete condition object.
61
- */
62
- where(condition: Condition<TContext>): QueryBuilder<TContext>;
63
- /**
64
- * Add a where clause with a callback function.
65
- */
66
- where(callback: WhereCallback<TContext>): QueryBuilder<TContext>;
67
- /**
68
- * Add a having clause comparing two values.
69
- * For filtering results after they have been grouped.
70
- */
71
- having(left: PropertyReferenceString<TContext> | LiteralValue, operator: Comparator, right: PropertyReferenceString<TContext> | LiteralValue): QueryBuilder<TContext>;
72
- /**
73
- * Add a having clause with a complete condition object.
74
- * For filtering results after they have been grouped.
75
- */
76
- having(condition: Condition<TContext>): QueryBuilder<TContext>;
77
- /**
78
- * Add a having clause with a callback function.
79
- * For filtering results after they have been grouped.
80
- */
81
- having(callback: WhereCallback<TContext>): QueryBuilder<TContext>;
82
- /**
83
- * Add a join clause to the query using a CollectionRef.
84
- */
85
- join<TCollectionRef extends CollectionRef>(joinClause: {
86
- type: `inner` | `left` | `right` | `full` | `cross`;
87
- from: TCollectionRef;
88
- on: Condition<Flatten<{
89
- baseSchema: TContext[`baseSchema`];
90
- schema: TContext[`schema`] & {
91
- [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
92
- };
93
- }>>;
94
- where?: Condition<Flatten<{
95
- baseSchema: TContext[`baseSchema`];
96
- schema: {
97
- [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
98
- };
99
- }>>;
100
- }): QueryBuilder<Flatten<Omit<TContext, `schema`> & {
101
- schema: TContext[`schema`] & {
102
- [K in keyof TCollectionRef & string]: RemoveIndexSignature<(TCollectionRef[keyof TCollectionRef] extends Collection<infer T> ? T : never) & Input>;
103
- };
104
- hasJoin: true;
105
- }>>;
106
- /**
107
- * Add a join clause to the query without specifying an alias.
108
- * The collection name will be used as the default alias.
109
- */
110
- join<T extends InputReference<{
111
- baseSchema: TContext[`baseSchema`];
112
- schema: TContext[`baseSchema`];
113
- }>>(joinClause: {
114
- type: `inner` | `left` | `right` | `full` | `cross`;
115
- from: T;
116
- on: Condition<Flatten<{
117
- baseSchema: TContext[`baseSchema`];
118
- schema: TContext[`schema`] & {
119
- [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
120
- };
121
- }>>;
122
- where?: Condition<Flatten<{
123
- baseSchema: TContext[`baseSchema`];
124
- schema: {
125
- [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
126
- };
127
- }>>;
128
- }): QueryBuilder<Flatten<Omit<TContext, `schema`> & {
129
- schema: TContext[`schema`] & {
130
- [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>;
131
- };
132
- hasJoin: true;
133
- }>>;
134
- /**
135
- * Add a join clause to the query with a specified alias.
136
- */
137
- join<TFrom extends InputReference<{
138
- baseSchema: TContext[`baseSchema`];
139
- schema: TContext[`baseSchema`];
140
- }>, TAs extends string>(joinClause: {
141
- type: `inner` | `left` | `right` | `full` | `cross`;
142
- from: TFrom;
143
- as: TAs;
144
- on: Condition<Flatten<{
145
- baseSchema: TContext[`baseSchema`];
146
- schema: TContext[`schema`] & {
147
- [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>;
148
- };
149
- }>>;
150
- where?: Condition<Flatten<{
151
- baseSchema: TContext[`baseSchema`];
152
- schema: {
153
- [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>;
154
- };
155
- }>>;
156
- }): QueryBuilder<Flatten<Omit<TContext, `schema`> & {
157
- schema: TContext[`schema`] & {
158
- [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>;
159
- };
160
- hasJoin: true;
161
- }>>;
162
- private joinCollectionRef;
163
- private joinInputReference;
164
- /**
165
- * Add an orderBy clause to sort the results.
166
- * Overwrites any previous orderBy clause.
167
- *
168
- * @param orderBy The order specification
169
- * @returns A new QueryBuilder with the orderBy clause set
170
- */
171
- orderBy(orderBy: OrderBy<TContext>): QueryBuilder<TContext>;
172
- /**
173
- * Set a limit on the number of results returned.
174
- *
175
- * @param limit Maximum number of results to return
176
- * @returns A new QueryBuilder with the limit set
177
- */
178
- limit(limit: Limit<TContext>): QueryBuilder<TContext>;
179
- /**
180
- * Set an offset to skip a number of results.
181
- *
182
- * @param offset Number of results to skip
183
- * @returns A new QueryBuilder with the offset set
184
- */
185
- offset(offset: Offset<TContext>): QueryBuilder<TContext>;
186
- /**
187
- * Add a groupBy clause to group the results by one or more columns.
188
- *
189
- * @param groupBy The column(s) to group by
190
- * @returns A new QueryBuilder with the groupBy clause set
191
- */
192
- groupBy(groupBy: PropertyReference<TContext> | Array<PropertyReference<TContext>>): QueryBuilder<TContext>;
193
- /**
194
- * Define a Common Table Expression (CTE) that can be referenced in the main query.
195
- * This allows referencing the CTE by name in subsequent from/join clauses.
196
- *
197
- * @param name The name of the CTE
198
- * @param queryBuilderCallback A function that builds the CTE query
199
- * @returns A new QueryBuilder with the CTE added
200
- */
201
- with<TName extends string, TResult = Record<string, unknown>>(name: TName, queryBuilderCallback: (builder: InitialQueryBuilder<{
202
- baseSchema: TContext[`baseSchema`];
203
- schema: {};
204
- }>) => QueryBuilder<any>): InitialQueryBuilder<{
205
- baseSchema: TContext[`baseSchema`] & {
206
- [K in TName]: TResult;
207
- };
208
- schema: TContext[`schema`];
209
- }>;
210
- get _query(): Query<TContext>;
211
- }
212
- export type InitialQueryBuilder<TContext extends Context<Schema>> = Pick<BaseQueryBuilder<TContext>, `from` | `with`>;
213
- export type QueryBuilder<TContext extends Context<Schema>> = Omit<BaseQueryBuilder<TContext>, `from`>;
214
- /**
215
- * Create a new query builder with the given schema
216
- */
217
- export declare function queryBuilder<TBaseSchema extends Schema = {}>(): InitialQueryBuilder<{
218
- baseSchema: TBaseSchema;
219
- schema: {};
220
- }>;
221
- export type ResultsFromContext<TContext extends Context<Schema>> = Flatten<TContext[`result`] extends object ? TContext[`result`] : TContext[`hasJoin`] extends true ? TContext[`schema`] : TContext[`default`] extends keyof TContext[`schema`] ? TContext[`schema`][TContext[`default`]] : never>;
222
- export type ResultFromQueryBuilder<TQueryBuilder> = Flatten<TQueryBuilder extends QueryBuilder<infer C> ? C extends {
223
- result: infer R;
224
- } ? R : never : never>;
225
- export {};
@@ -1,307 +0,0 @@
1
- class BaseQueryBuilder {
2
- /**
3
- * Create a new QueryBuilder instance.
4
- */
5
- constructor(query = {}) {
6
- this.query = {};
7
- this.query = query;
8
- }
9
- /**
10
- * Specify the collection to query from.
11
- * This is the first method that must be called in the chain.
12
- *
13
- * @param collection The collection name to query from
14
- * @param as Optional alias for the collection
15
- * @returns A new QueryBuilder with the from clause set
16
- */
17
- from(collection, as) {
18
- if (typeof collection === `object` && collection !== null) {
19
- return this.fromCollectionRef(collection);
20
- } else if (typeof collection === `string`) {
21
- return this.fromInputReference(
22
- collection,
23
- as
24
- );
25
- } else {
26
- throw new Error(`Invalid collection type`);
27
- }
28
- }
29
- fromCollectionRef(collectionRef) {
30
- var _a;
31
- const keys = Object.keys(collectionRef);
32
- if (keys.length !== 1) {
33
- throw new Error(`Expected exactly one key`);
34
- }
35
- const key = keys[0];
36
- const collection = collectionRef[key];
37
- const newBuilder = new BaseQueryBuilder();
38
- Object.assign(newBuilder.query, this.query);
39
- newBuilder.query.from = key;
40
- (_a = newBuilder.query).collections ?? (_a.collections = {});
41
- newBuilder.query.collections[key] = collection;
42
- return newBuilder;
43
- }
44
- fromInputReference(collection, as) {
45
- const newBuilder = new BaseQueryBuilder();
46
- Object.assign(newBuilder.query, this.query);
47
- newBuilder.query.from = collection;
48
- if (as) {
49
- newBuilder.query.as = as;
50
- }
51
- return newBuilder;
52
- }
53
- /**
54
- * Specify what columns to select.
55
- * Overwrites any previous select clause.
56
- * Also supports callback functions that receive the row context and return selected data.
57
- *
58
- * @param selects The columns to select (can include callbacks)
59
- * @returns A new QueryBuilder with the select clause set
60
- */
61
- select(...selects) {
62
- const validatedSelects = selects.map((select) => {
63
- if (typeof select === `object` && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
64
- select !== null && !Array.isArray(select)) {
65
- const result = {};
66
- for (const [key, value] of Object.entries(select)) {
67
- if (typeof value === `object` && value !== null && !Array.isArray(value)) {
68
- const keys = Object.keys(value);
69
- if (keys.length === 1) {
70
- const funcName = keys[0];
71
- const allowedFunctions = [
72
- `SUM`,
73
- `COUNT`,
74
- `AVG`,
75
- `MIN`,
76
- `MAX`,
77
- `DATE`,
78
- `JSON_EXTRACT`,
79
- `JSON_EXTRACT_PATH`,
80
- `UPPER`,
81
- `LOWER`,
82
- `COALESCE`,
83
- `CONCAT`,
84
- `LENGTH`,
85
- `ORDER_INDEX`
86
- ];
87
- if (!allowedFunctions.includes(funcName)) {
88
- console.warn(
89
- `Unsupported function: ${funcName}. Expected one of: ${allowedFunctions.join(`, `)}`
90
- );
91
- }
92
- }
93
- }
94
- result[key] = value;
95
- }
96
- return result;
97
- }
98
- return select;
99
- });
100
- if (this._query.orderBy) {
101
- validatedSelects.push({ _orderByIndex: { ORDER_INDEX: `fractional` } });
102
- }
103
- const newBuilder = new BaseQueryBuilder(
104
- this.query
105
- );
106
- newBuilder.query.select = validatedSelects;
107
- return newBuilder;
108
- }
109
- /**
110
- * Add a where clause to filter the results.
111
- * Can be called multiple times to add AND conditions.
112
- * Also supports callback functions that receive the row context.
113
- *
114
- * @param leftOrConditionOrCallback The left operand, complete condition, or callback function
115
- * @param operator Optional comparison operator
116
- * @param right Optional right operand
117
- * @returns A new QueryBuilder with the where clause added
118
- */
119
- where(leftOrConditionOrCallback, operator, right) {
120
- const newBuilder = new BaseQueryBuilder();
121
- Object.assign(newBuilder.query, this.query);
122
- let condition;
123
- if (typeof leftOrConditionOrCallback === `function`) {
124
- condition = leftOrConditionOrCallback;
125
- } else if (operator !== void 0 && right !== void 0) {
126
- condition = [leftOrConditionOrCallback, operator, right];
127
- } else {
128
- condition = leftOrConditionOrCallback;
129
- }
130
- if (!newBuilder.query.where) {
131
- newBuilder.query.where = [condition];
132
- } else {
133
- newBuilder.query.where = [...newBuilder.query.where, condition];
134
- }
135
- return newBuilder;
136
- }
137
- /**
138
- * Add a having clause to filter the grouped results.
139
- * Can be called multiple times to add AND conditions.
140
- * Also supports callback functions that receive the row context.
141
- *
142
- * @param leftOrConditionOrCallback The left operand, complete condition, or callback function
143
- * @param operator Optional comparison operator
144
- * @param right Optional right operand
145
- * @returns A new QueryBuilder with the having clause added
146
- */
147
- having(leftOrConditionOrCallback, operator, right) {
148
- const newBuilder = new BaseQueryBuilder();
149
- Object.assign(newBuilder.query, this.query);
150
- let condition;
151
- if (typeof leftOrConditionOrCallback === `function`) {
152
- condition = leftOrConditionOrCallback;
153
- } else if (operator !== void 0 && right !== void 0) {
154
- condition = [leftOrConditionOrCallback, operator, right];
155
- } else {
156
- condition = leftOrConditionOrCallback;
157
- }
158
- if (!newBuilder.query.having) {
159
- newBuilder.query.having = [condition];
160
- } else {
161
- newBuilder.query.having = [...newBuilder.query.having, condition];
162
- }
163
- return newBuilder;
164
- }
165
- join(joinClause) {
166
- if (typeof joinClause.from === `object` && joinClause.from !== null) {
167
- return this.joinCollectionRef(
168
- joinClause
169
- );
170
- } else {
171
- return this.joinInputReference(
172
- joinClause
173
- );
174
- }
175
- }
176
- joinCollectionRef(joinClause) {
177
- var _a;
178
- const newBuilder = new BaseQueryBuilder();
179
- Object.assign(newBuilder.query, this.query);
180
- const keys = Object.keys(joinClause.from);
181
- if (keys.length !== 1) {
182
- throw new Error(`Expected exactly one key in CollectionRef`);
183
- }
184
- const key = keys[0];
185
- const collection = joinClause.from[key];
186
- if (!collection) {
187
- throw new Error(`Collection not found for key: ${key}`);
188
- }
189
- const joinClauseCopy = {
190
- type: joinClause.type,
191
- from: key,
192
- on: joinClause.on,
193
- where: joinClause.where
194
- };
195
- if (!newBuilder.query.join) {
196
- newBuilder.query.join = [joinClauseCopy];
197
- } else {
198
- newBuilder.query.join = [...newBuilder.query.join, joinClauseCopy];
199
- }
200
- (_a = newBuilder.query).collections ?? (_a.collections = {});
201
- newBuilder.query.collections[key] = collection;
202
- return newBuilder;
203
- }
204
- joinInputReference(joinClause) {
205
- const newBuilder = new BaseQueryBuilder();
206
- Object.assign(newBuilder.query, this.query);
207
- const joinClauseCopy = { ...joinClause };
208
- if (!newBuilder.query.join) {
209
- newBuilder.query.join = [joinClauseCopy];
210
- } else {
211
- newBuilder.query.join = [...newBuilder.query.join, joinClauseCopy];
212
- }
213
- joinClause.as ?? joinClause.from;
214
- return newBuilder;
215
- }
216
- /**
217
- * Add an orderBy clause to sort the results.
218
- * Overwrites any previous orderBy clause.
219
- *
220
- * @param orderBy The order specification
221
- * @returns A new QueryBuilder with the orderBy clause set
222
- */
223
- orderBy(orderBy) {
224
- const newBuilder = new BaseQueryBuilder();
225
- Object.assign(newBuilder.query, this.query);
226
- newBuilder.query.orderBy = orderBy;
227
- newBuilder.query.select = [
228
- ...newBuilder.query.select ?? [],
229
- { _orderByIndex: { ORDER_INDEX: `fractional` } }
230
- ];
231
- return newBuilder;
232
- }
233
- /**
234
- * Set a limit on the number of results returned.
235
- *
236
- * @param limit Maximum number of results to return
237
- * @returns A new QueryBuilder with the limit set
238
- */
239
- limit(limit) {
240
- const newBuilder = new BaseQueryBuilder();
241
- Object.assign(newBuilder.query, this.query);
242
- newBuilder.query.limit = limit;
243
- return newBuilder;
244
- }
245
- /**
246
- * Set an offset to skip a number of results.
247
- *
248
- * @param offset Number of results to skip
249
- * @returns A new QueryBuilder with the offset set
250
- */
251
- offset(offset) {
252
- const newBuilder = new BaseQueryBuilder();
253
- Object.assign(newBuilder.query, this.query);
254
- newBuilder.query.offset = offset;
255
- return newBuilder;
256
- }
257
- /**
258
- * Add a groupBy clause to group the results by one or more columns.
259
- *
260
- * @param groupBy The column(s) to group by
261
- * @returns A new QueryBuilder with the groupBy clause set
262
- */
263
- groupBy(groupBy) {
264
- const newBuilder = new BaseQueryBuilder();
265
- Object.assign(newBuilder.query, this.query);
266
- newBuilder.query.groupBy = groupBy;
267
- return newBuilder;
268
- }
269
- /**
270
- * Define a Common Table Expression (CTE) that can be referenced in the main query.
271
- * This allows referencing the CTE by name in subsequent from/join clauses.
272
- *
273
- * @param name The name of the CTE
274
- * @param queryBuilderCallback A function that builds the CTE query
275
- * @returns A new QueryBuilder with the CTE added
276
- */
277
- with(name, queryBuilderCallback) {
278
- const newBuilder = new BaseQueryBuilder();
279
- Object.assign(newBuilder.query, this.query);
280
- const cteBuilder = new BaseQueryBuilder();
281
- const cteQueryBuilder = queryBuilderCallback(
282
- cteBuilder
283
- );
284
- const cteQuery = cteQueryBuilder._query;
285
- const withQuery = {
286
- ...cteQuery,
287
- as: name
288
- };
289
- if (!newBuilder.query.with) {
290
- newBuilder.query.with = [withQuery];
291
- } else {
292
- newBuilder.query.with = [...newBuilder.query.with, withQuery];
293
- }
294
- return newBuilder;
295
- }
296
- get _query() {
297
- return this.query;
298
- }
299
- }
300
- function queryBuilder() {
301
- return new BaseQueryBuilder();
302
- }
303
- export {
304
- BaseQueryBuilder,
305
- queryBuilder
306
- };
307
- //# sourceMappingURL=query-builder.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"query-builder.js","sources":["../../../src/query/query-builder.ts"],"sourcesContent":["import type { Collection } from \"../collection\"\nimport type {\n Comparator,\n ComparatorValue,\n Condition,\n From,\n JoinClause,\n Limit,\n LiteralValue,\n Offset,\n OrderBy,\n Query,\n Select,\n WhereCallback,\n WithQuery,\n} from \"./schema.js\"\nimport type {\n Context,\n Flatten,\n InferResultTypeFromSelectTuple,\n Input,\n InputReference,\n PropertyReference,\n PropertyReferenceString,\n RemoveIndexSignature,\n Schema,\n} from \"./types.js\"\n\ntype CollectionRef = { [K: string]: Collection<any> }\n\nexport class BaseQueryBuilder<TContext extends Context<Schema>> {\n private readonly query: Partial<Query<TContext>> = {}\n\n /**\n * Create a new QueryBuilder instance.\n */\n constructor(query: Partial<Query<TContext>> = {}) {\n this.query = query\n }\n\n from<TCollectionRef extends CollectionRef>(\n collectionRef: TCollectionRef\n ): QueryBuilder<{\n baseSchema: Flatten<\n TContext[`baseSchema`] & {\n [K in keyof TCollectionRef & string]: RemoveIndexSignature<\n (TCollectionRef[keyof TCollectionRef] extends Collection<infer T>\n ? T\n : never) &\n Input\n >\n }\n >\n schema: Flatten<{\n [K in keyof TCollectionRef & string]: RemoveIndexSignature<\n (TCollectionRef[keyof TCollectionRef] extends Collection<infer T>\n ? T\n : never) &\n Input\n >\n }>\n default: keyof TCollectionRef & string\n }>\n\n from<\n T extends InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>,\n >(\n collection: T\n ): QueryBuilder<{\n baseSchema: TContext[`baseSchema`]\n schema: {\n [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>\n }\n default: T\n }>\n\n from<\n T extends InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>,\n TAs extends string,\n >(\n collection: T,\n as: TAs\n ): QueryBuilder<{\n baseSchema: TContext[`baseSchema`]\n schema: {\n [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][T]>\n }\n default: TAs\n }>\n\n /**\n * Specify the collection to query from.\n * This is the first method that must be called in the chain.\n *\n * @param collection The collection name to query from\n * @param as Optional alias for the collection\n * @returns A new QueryBuilder with the from clause set\n */\n from<\n T extends\n | InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>\n | CollectionRef,\n TAs extends string | undefined,\n >(collection: T, as?: TAs) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof collection === `object` && collection !== null) {\n return this.fromCollectionRef(collection)\n } else if (typeof collection === `string`) {\n return this.fromInputReference(\n collection as InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>,\n as\n )\n } else {\n throw new Error(`Invalid collection type`)\n }\n }\n\n private fromCollectionRef<TCollectionRef extends CollectionRef>(\n collectionRef: TCollectionRef\n ) {\n const keys = Object.keys(collectionRef)\n if (keys.length !== 1) {\n throw new Error(`Expected exactly one key`)\n }\n\n const key = keys[0]!\n const collection = collectionRef[key]!\n\n const newBuilder = new BaseQueryBuilder()\n Object.assign(newBuilder.query, this.query)\n newBuilder.query.from = key as From<TContext>\n newBuilder.query.collections ??= {}\n newBuilder.query.collections[key] = collection\n\n return newBuilder as unknown as QueryBuilder<{\n baseSchema: TContext[`baseSchema`] & {\n [K in keyof TCollectionRef &\n string]: (TCollectionRef[keyof TCollectionRef] extends Collection<\n infer T\n >\n ? T\n : never) &\n Input\n }\n schema: {\n [K in keyof TCollectionRef &\n string]: (TCollectionRef[keyof TCollectionRef] extends Collection<\n infer T\n >\n ? T\n : never) &\n Input\n }\n default: keyof TCollectionRef & string\n }>\n }\n\n private fromInputReference<\n T extends InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>,\n TAs extends string | undefined,\n >(collection: T, as?: TAs) {\n const newBuilder = new BaseQueryBuilder()\n Object.assign(newBuilder.query, this.query)\n newBuilder.query.from = collection as From<TContext>\n if (as) {\n newBuilder.query.as = as\n }\n\n // Calculate the result type without deep nesting\n type ResultSchema = TAs extends undefined\n ? { [K in T]: TContext[`baseSchema`][T] }\n : { [K in string & TAs]: TContext[`baseSchema`][T] }\n\n type ResultDefault = TAs extends undefined ? T : string & TAs\n\n // Use simpler type assertion to avoid excessive depth\n return newBuilder as unknown as QueryBuilder<{\n baseSchema: TContext[`baseSchema`]\n schema: ResultSchema\n default: ResultDefault\n }>\n }\n\n /**\n * Specify what columns to select.\n * Overwrites any previous select clause.\n * Also supports callback functions that receive the row context and return selected data.\n *\n * @param selects The columns to select (can include callbacks)\n * @returns A new QueryBuilder with the select clause set\n */\n select<TSelects extends Array<Select<TContext>>>(\n this: QueryBuilder<TContext>,\n ...selects: TSelects\n ) {\n // Validate function calls in the selects\n // Need to use a type assertion to bypass deep recursive type checking\n const validatedSelects = selects.map((select) => {\n // If the select is an object with aliases, validate each value\n if (\n typeof select === `object` &&\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n select !== null &&\n !Array.isArray(select)\n ) {\n const result: Record<string, any> = {}\n\n for (const [key, value] of Object.entries(select)) {\n // If it's a function call (object with a single key that is an allowed function name)\n if (\n typeof value === `object` &&\n value !== null &&\n !Array.isArray(value)\n ) {\n const keys = Object.keys(value)\n if (keys.length === 1) {\n const funcName = keys[0]!\n // List of allowed function names from AllowedFunctionName\n const allowedFunctions = [\n `SUM`,\n `COUNT`,\n `AVG`,\n `MIN`,\n `MAX`,\n `DATE`,\n `JSON_EXTRACT`,\n `JSON_EXTRACT_PATH`,\n `UPPER`,\n `LOWER`,\n `COALESCE`,\n `CONCAT`,\n `LENGTH`,\n `ORDER_INDEX`,\n ]\n\n if (!allowedFunctions.includes(funcName)) {\n console.warn(\n `Unsupported function: ${funcName}. Expected one of: ${allowedFunctions.join(`, `)}`\n )\n }\n }\n }\n\n result[key] = value\n }\n\n return result\n }\n\n return select\n })\n\n // Ensure we have an orderByIndex in the select if we have an orderBy\n // This is required if select is called after orderBy\n if (this._query.orderBy) {\n validatedSelects.push({ _orderByIndex: { ORDER_INDEX: `fractional` } })\n }\n\n const newBuilder = new BaseQueryBuilder<TContext>(\n (this as BaseQueryBuilder<TContext>).query\n )\n newBuilder.query.select = validatedSelects as Array<Select<TContext>>\n\n return newBuilder as QueryBuilder<\n Flatten<\n Omit<TContext, `result`> & {\n result: InferResultTypeFromSelectTuple<TContext, TSelects>\n }\n >\n >\n }\n\n /**\n * Add a where clause comparing two values.\n */\n where<T extends Comparator>(\n left: PropertyReferenceString<TContext> | LiteralValue,\n operator: T,\n right: ComparatorValue<T, TContext>\n ): QueryBuilder<TContext>\n\n /**\n * Add a where clause with a complete condition object.\n */\n where(condition: Condition<TContext>): QueryBuilder<TContext>\n\n /**\n * Add a where clause with a callback function.\n */\n where(callback: WhereCallback<TContext>): QueryBuilder<TContext>\n\n /**\n * Add a where clause to filter the results.\n * Can be called multiple times to add AND conditions.\n * Also supports callback functions that receive the row context.\n *\n * @param leftOrConditionOrCallback The left operand, complete condition, or callback function\n * @param operator Optional comparison operator\n * @param right Optional right operand\n * @returns A new QueryBuilder with the where clause added\n */\n where(\n leftOrConditionOrCallback: any,\n operator?: any,\n right?: any\n ): QueryBuilder<TContext> {\n // Create a new builder with a copy of the current query\n // Use simplistic approach to avoid deep type errors\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n let condition: any\n\n // Determine if this is a callback, complete condition, or individual parts\n if (typeof leftOrConditionOrCallback === `function`) {\n // It's a callback function\n condition = leftOrConditionOrCallback\n } else if (operator !== undefined && right !== undefined) {\n // Create a condition from parts\n condition = [leftOrConditionOrCallback, operator, right]\n } else {\n // Use the provided condition directly\n condition = leftOrConditionOrCallback\n }\n\n // Where is always an array, so initialize or append\n if (!newBuilder.query.where) {\n newBuilder.query.where = [condition]\n } else {\n newBuilder.query.where = [...newBuilder.query.where, condition]\n }\n\n return newBuilder as unknown as QueryBuilder<TContext>\n }\n\n /**\n * Add a having clause comparing two values.\n * For filtering results after they have been grouped.\n */\n having(\n left: PropertyReferenceString<TContext> | LiteralValue,\n operator: Comparator,\n right: PropertyReferenceString<TContext> | LiteralValue\n ): QueryBuilder<TContext>\n\n /**\n * Add a having clause with a complete condition object.\n * For filtering results after they have been grouped.\n */\n having(condition: Condition<TContext>): QueryBuilder<TContext>\n\n /**\n * Add a having clause with a callback function.\n * For filtering results after they have been grouped.\n */\n having(callback: WhereCallback<TContext>): QueryBuilder<TContext>\n\n /**\n * Add a having clause to filter the grouped results.\n * Can be called multiple times to add AND conditions.\n * Also supports callback functions that receive the row context.\n *\n * @param leftOrConditionOrCallback The left operand, complete condition, or callback function\n * @param operator Optional comparison operator\n * @param right Optional right operand\n * @returns A new QueryBuilder with the having clause added\n */\n having(\n leftOrConditionOrCallback: any,\n operator?: any,\n right?: any\n ): QueryBuilder<TContext> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n let condition: any\n\n // Determine if this is a callback, complete condition, or individual parts\n if (typeof leftOrConditionOrCallback === `function`) {\n // It's a callback function\n condition = leftOrConditionOrCallback\n } else if (operator !== undefined && right !== undefined) {\n // Create a condition from parts\n condition = [leftOrConditionOrCallback, operator, right]\n } else {\n // Use the provided condition directly\n condition = leftOrConditionOrCallback\n }\n\n // Having is always an array, so initialize or append\n if (!newBuilder.query.having) {\n newBuilder.query.having = [condition]\n } else {\n newBuilder.query.having = [...newBuilder.query.having, condition]\n }\n\n return newBuilder as QueryBuilder<TContext>\n }\n\n /**\n * Add a join clause to the query using a CollectionRef.\n */\n join<TCollectionRef extends CollectionRef>(joinClause: {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: TCollectionRef\n on: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`schema`] & {\n [K in keyof TCollectionRef & string]: RemoveIndexSignature<\n (TCollectionRef[keyof TCollectionRef] extends Collection<infer T>\n ? T\n : never) &\n Input\n >\n }\n }>\n >\n where?: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: {\n [K in keyof TCollectionRef & string]: RemoveIndexSignature<\n (TCollectionRef[keyof TCollectionRef] extends Collection<infer T>\n ? T\n : never) &\n Input\n >\n }\n }>\n >\n }): QueryBuilder<\n Flatten<\n Omit<TContext, `schema`> & {\n schema: TContext[`schema`] & {\n [K in keyof TCollectionRef & string]: RemoveIndexSignature<\n (TCollectionRef[keyof TCollectionRef] extends Collection<infer T>\n ? T\n : never) &\n Input\n >\n }\n hasJoin: true\n }\n >\n >\n\n /**\n * Add a join clause to the query without specifying an alias.\n * The collection name will be used as the default alias.\n */\n join<\n T extends InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>,\n >(joinClause: {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: T\n on: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`schema`] & {\n [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>\n }\n }>\n >\n where?: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: { [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]> }\n }>\n >\n }): QueryBuilder<\n Flatten<\n Omit<TContext, `schema`> & {\n schema: TContext[`schema`] & {\n [K in T]: RemoveIndexSignature<TContext[`baseSchema`][T]>\n }\n hasJoin: true\n }\n >\n >\n\n /**\n * Add a join clause to the query with a specified alias.\n */\n join<\n TFrom extends InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>,\n TAs extends string,\n >(joinClause: {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: TFrom\n as: TAs\n on: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`schema`] & {\n [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>\n }\n }>\n >\n where?: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: {\n [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>\n }\n }>\n >\n }): QueryBuilder<\n Flatten<\n Omit<TContext, `schema`> & {\n schema: TContext[`schema`] & {\n [K in TAs]: RemoveIndexSignature<TContext[`baseSchema`][TFrom]>\n }\n hasJoin: true\n }\n >\n >\n\n join<\n TFrom extends\n | InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>\n | CollectionRef,\n TAs extends string | undefined = undefined,\n >(joinClause: {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: TFrom\n as?: TAs\n on: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`schema`] &\n (TFrom extends CollectionRef\n ? {\n [K in keyof TFrom & string]: RemoveIndexSignature<\n (TFrom[keyof TFrom] extends Collection<infer T> ? T : never) &\n Input\n >\n }\n : TFrom extends InputReference<infer TRef>\n ? {\n [K in keyof TRef & string]: RemoveIndexSignature<\n TRef[keyof TRef]\n >\n }\n : never)\n }>\n >\n where?: Condition<\n Flatten<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`schema`] &\n (TFrom extends CollectionRef\n ? {\n [K in keyof TFrom & string]: RemoveIndexSignature<\n (TFrom[keyof TFrom] extends Collection<infer T> ? T : never) &\n Input\n >\n }\n : TFrom extends InputReference<infer TRef>\n ? {\n [K in keyof TRef & string]: RemoveIndexSignature<\n TRef[keyof TRef]\n >\n }\n : never)\n }>\n >\n }): QueryBuilder<any> {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (typeof joinClause.from === `object` && joinClause.from !== null) {\n return this.joinCollectionRef(\n joinClause as {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: CollectionRef\n on: Condition<any>\n where?: Condition<any>\n }\n )\n } else {\n return this.joinInputReference(\n joinClause as {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>\n as?: TAs\n on: Condition<any>\n where?: Condition<any>\n }\n )\n }\n }\n\n private joinCollectionRef<TCollectionRef extends CollectionRef>(joinClause: {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: TCollectionRef\n on: Condition<any>\n where?: Condition<any>\n }): QueryBuilder<any> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n // Get the collection key\n const keys = Object.keys(joinClause.from)\n if (keys.length !== 1) {\n throw new Error(`Expected exactly one key in CollectionRef`)\n }\n const key = keys[0]!\n const collection = joinClause.from[key]\n if (!collection) {\n throw new Error(`Collection not found for key: ${key}`)\n }\n\n // Create a copy of the join clause for the query\n const joinClauseCopy = {\n type: joinClause.type,\n from: key,\n on: joinClause.on,\n where: joinClause.where,\n } as JoinClause<TContext>\n\n // Add the join clause to the query\n if (!newBuilder.query.join) {\n newBuilder.query.join = [joinClauseCopy]\n } else {\n newBuilder.query.join = [...newBuilder.query.join, joinClauseCopy]\n }\n\n // Add the collection to the collections map\n newBuilder.query.collections ??= {}\n newBuilder.query.collections[key] = collection\n\n // Return the new builder with updated schema type\n return newBuilder as QueryBuilder<\n Flatten<\n Omit<TContext, `schema`> & {\n schema: TContext[`schema`] & {\n [K in keyof TCollectionRef & string]: RemoveIndexSignature<\n (TCollectionRef[keyof TCollectionRef] extends Collection<infer T>\n ? T\n : never) &\n Input\n >\n }\n }\n >\n >\n }\n\n private joinInputReference<\n TFrom extends InputReference<{\n baseSchema: TContext[`baseSchema`]\n schema: TContext[`baseSchema`]\n }>,\n TAs extends string | undefined = undefined,\n >(joinClause: {\n type: `inner` | `left` | `right` | `full` | `cross`\n from: TFrom\n as?: TAs\n on: Condition<any>\n where?: Condition<any>\n }): QueryBuilder<any> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n // Create a copy of the join clause for the query\n const joinClauseCopy = { ...joinClause } as JoinClause<TContext>\n\n // Add the join clause to the query\n if (!newBuilder.query.join) {\n newBuilder.query.join = [joinClauseCopy]\n } else {\n newBuilder.query.join = [...newBuilder.query.join, joinClauseCopy]\n }\n\n // Determine the alias or use the collection name as default\n const _effectiveAlias = joinClause.as ?? joinClause.from\n\n // Return the new builder with updated schema type\n return newBuilder as QueryBuilder<\n Flatten<\n Omit<TContext, `schema`> & {\n schema: TContext[`schema`] & {\n [K in typeof _effectiveAlias]: TContext[`baseSchema`][TFrom]\n }\n }\n >\n >\n }\n\n /**\n * Add an orderBy clause to sort the results.\n * Overwrites any previous orderBy clause.\n *\n * @param orderBy The order specification\n * @returns A new QueryBuilder with the orderBy clause set\n */\n orderBy(orderBy: OrderBy<TContext>): QueryBuilder<TContext> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n // Set the orderBy clause\n newBuilder.query.orderBy = orderBy\n\n // Ensure we have an orderByIndex in the select if we have an orderBy\n // This is required if select is called before orderBy\n newBuilder.query.select = [\n ...(newBuilder.query.select ?? []),\n { _orderByIndex: { ORDER_INDEX: `fractional` } },\n ]\n\n return newBuilder as QueryBuilder<TContext>\n }\n\n /**\n * Set a limit on the number of results returned.\n *\n * @param limit Maximum number of results to return\n * @returns A new QueryBuilder with the limit set\n */\n limit(limit: Limit<TContext>): QueryBuilder<TContext> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n // Set the limit\n newBuilder.query.limit = limit\n\n return newBuilder as QueryBuilder<TContext>\n }\n\n /**\n * Set an offset to skip a number of results.\n *\n * @param offset Number of results to skip\n * @returns A new QueryBuilder with the offset set\n */\n offset(offset: Offset<TContext>): QueryBuilder<TContext> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n // Set the offset\n newBuilder.query.offset = offset\n\n return newBuilder as QueryBuilder<TContext>\n }\n\n /**\n * Add a groupBy clause to group the results by one or more columns.\n *\n * @param groupBy The column(s) to group by\n * @returns A new QueryBuilder with the groupBy clause set\n */\n groupBy(\n groupBy: PropertyReference<TContext> | Array<PropertyReference<TContext>>\n ): QueryBuilder<TContext> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n // Set the groupBy clause\n newBuilder.query.groupBy = groupBy\n\n return newBuilder as QueryBuilder<TContext>\n }\n\n /**\n * Define a Common Table Expression (CTE) that can be referenced in the main query.\n * This allows referencing the CTE by name in subsequent from/join clauses.\n *\n * @param name The name of the CTE\n * @param queryBuilderCallback A function that builds the CTE query\n * @returns A new QueryBuilder with the CTE added\n */\n with<TName extends string, TResult = Record<string, unknown>>(\n name: TName,\n queryBuilderCallback: (\n builder: InitialQueryBuilder<{\n baseSchema: TContext[`baseSchema`]\n schema: {}\n }>\n ) => QueryBuilder<any>\n ): InitialQueryBuilder<{\n baseSchema: TContext[`baseSchema`] & { [K in TName]: TResult }\n schema: TContext[`schema`]\n }> {\n // Create a new builder with a copy of the current query\n const newBuilder = new BaseQueryBuilder<TContext>()\n Object.assign(newBuilder.query, this.query)\n\n // Create a new builder for the CTE\n const cteBuilder = new BaseQueryBuilder<{\n baseSchema: TContext[`baseSchema`]\n schema: {}\n }>()\n\n // Get the CTE query from the callback\n const cteQueryBuilder = queryBuilderCallback(\n cteBuilder as InitialQueryBuilder<{\n baseSchema: TContext[`baseSchema`]\n schema: {}\n }>\n )\n\n // Get the query from the builder\n const cteQuery = cteQueryBuilder._query\n\n // Add an 'as' property to the CTE\n const withQuery: WithQuery<any> = {\n ...cteQuery,\n as: name,\n }\n\n // Add the CTE to the with array\n if (!newBuilder.query.with) {\n newBuilder.query.with = [withQuery]\n } else {\n newBuilder.query.with = [...newBuilder.query.with, withQuery]\n }\n\n // Use a type cast that simplifies the type structure to avoid recursion\n return newBuilder as unknown as InitialQueryBuilder<{\n baseSchema: TContext[`baseSchema`] & { [K in TName]: TResult }\n schema: TContext[`schema`]\n }>\n }\n\n get _query(): Query<TContext> {\n return this.query as Query<TContext>\n }\n}\n\nexport type InitialQueryBuilder<TContext extends Context<Schema>> = Pick<\n BaseQueryBuilder<TContext>,\n `from` | `with`\n>\n\nexport type QueryBuilder<TContext extends Context<Schema>> = Omit<\n BaseQueryBuilder<TContext>,\n `from`\n>\n\n/**\n * Create a new query builder with the given schema\n */\nexport function queryBuilder<TBaseSchema extends Schema = {}>() {\n return new BaseQueryBuilder<{\n baseSchema: TBaseSchema\n schema: {}\n }>() as InitialQueryBuilder<{\n baseSchema: TBaseSchema\n schema: {}\n }>\n}\n\nexport type ResultsFromContext<TContext extends Context<Schema>> = Flatten<\n TContext[`result`] extends object\n ? TContext[`result`] // If there is a select we will have a result type\n : TContext[`hasJoin`] extends true\n ? TContext[`schema`] // If there is a join, the query returns the namespaced schema\n : TContext[`default`] extends keyof TContext[`schema`]\n ? TContext[`schema`][TContext[`default`]] // If there is no join we return the flat default schema\n : never // Should never happen\n>\n\nexport type ResultFromQueryBuilder<TQueryBuilder> = Flatten<\n TQueryBuilder extends QueryBuilder<infer C>\n ? C extends { result: infer R }\n ? R\n : never\n : never\n>\n"],"names":[],"mappings":"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"}