uql-orm 0.19.0 → 0.20.1
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.
- package/CHANGELOG.md +66 -0
- package/README.md +1 -1
- package/dist/browser/uql-browser.min.js +2 -2
- package/dist/browser/uql-browser.min.js.map +3 -3
- package/dist/bunSql/bunSqlCockroachDialect.d.ts +1 -1
- package/dist/bunSql/bunSqlCockroachDialect.js +1 -1
- package/dist/dialect/abstractSqlDialect.d.ts +130 -58
- package/dist/dialect/abstractSqlDialect.d.ts.map +1 -1
- package/dist/dialect/abstractSqlDialect.js +226 -178
- package/dist/dialect/abstractSqlDialect.js.map +1 -1
- package/dist/dialect/jsonArrayElemMatchUtils.d.ts +5 -6
- package/dist/dialect/jsonArrayElemMatchUtils.d.ts.map +1 -1
- package/dist/dialect/jsonArrayElemMatchUtils.js +9 -19
- package/dist/dialect/jsonArrayElemMatchUtils.js.map +1 -1
- package/dist/dialect/jsonSql.d.ts +44 -0
- package/dist/dialect/jsonSql.d.ts.map +1 -0
- package/dist/dialect/jsonSql.js +57 -0
- package/dist/dialect/jsonSql.js.map +1 -0
- package/dist/dialect/mysqlLikeSqlDialect.d.ts +42 -2
- package/dist/dialect/mysqlLikeSqlDialect.d.ts.map +1 -1
- package/dist/dialect/mysqlLikeSqlDialect.js +73 -22
- package/dist/dialect/mysqlLikeSqlDialect.js.map +1 -1
- package/dist/dialect/pgLikeSqlDialect.d.ts +28 -10
- package/dist/dialect/pgLikeSqlDialect.d.ts.map +1 -1
- package/dist/dialect/pgLikeSqlDialect.js +56 -49
- package/dist/dialect/pgLikeSqlDialect.js.map +1 -1
- package/dist/dialect/queryContext.d.ts +13 -1
- package/dist/dialect/queryContext.d.ts.map +1 -1
- package/dist/dialect/queryContext.js +17 -2
- package/dist/dialect/queryContext.js.map +1 -1
- package/dist/dialect/vectorSqlDialect.d.ts +54 -0
- package/dist/dialect/vectorSqlDialect.d.ts.map +1 -0
- package/dist/dialect/vectorSqlDialect.js +70 -0
- package/dist/dialect/vectorSqlDialect.js.map +1 -0
- package/dist/entity/decorator/index-decorator.d.ts +6 -13
- package/dist/entity/decorator/index-decorator.d.ts.map +1 -1
- package/dist/entity/decorator/index-decorator.js.map +1 -1
- package/dist/http/handler.d.ts +5 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js.map +1 -1
- package/dist/maria/mariaDialect.d.ts +15 -4
- package/dist/maria/mariaDialect.d.ts.map +1 -1
- package/dist/maria/mariaDialect.js +25 -13
- package/dist/maria/mariaDialect.js.map +1 -1
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts +1 -1
- package/dist/migrate/generator/mongoSchemaGenerator.d.ts.map +1 -1
- package/dist/mongo/mongoDialect.d.ts +27 -6
- package/dist/mongo/mongoDialect.d.ts.map +1 -1
- package/dist/mongo/mongoDialect.js +107 -14
- package/dist/mongo/mongoDialect.js.map +1 -1
- package/dist/mongo/mongodbQuerier.d.ts.map +1 -1
- package/dist/mongo/mongodbQuerier.js +5 -4
- package/dist/mongo/mongodbQuerier.js.map +1 -1
- package/dist/mysql/mysqlDialect.d.ts +0 -1
- package/dist/mysql/mysqlDialect.d.ts.map +1 -1
- package/dist/mysql/mysqlDialect.js +0 -1
- package/dist/mysql/mysqlDialect.js.map +1 -1
- package/dist/postgres/postgresWireDriverCapabilities.d.ts +1 -1
- package/dist/postgres/postgresWireDriverCapabilities.js +1 -1
- package/dist/schema/schemaAST.d.ts.map +1 -1
- package/dist/schema/schemaAST.js +7 -19
- package/dist/schema/schemaAST.js.map +1 -1
- package/dist/schema/types.d.ts +1 -1
- package/dist/sqlite/sqliteDialect.d.ts +28 -8
- package/dist/sqlite/sqliteDialect.d.ts.map +1 -1
- package/dist/sqlite/sqliteDialect.js +65 -80
- package/dist/sqlite/sqliteDialect.js.map +1 -1
- package/dist/type/dialect.d.ts +199 -0
- package/dist/type/dialect.d.ts.map +1 -0
- package/dist/type/dialect.js +2 -0
- package/dist/type/dialect.js.map +1 -0
- package/dist/type/entity.d.ts +64 -43
- package/dist/type/entity.d.ts.map +1 -1
- package/dist/type/entity.js.map +1 -1
- package/dist/type/index.d.ts +5 -0
- package/dist/type/index.d.ts.map +1 -1
- package/dist/type/index.js +5 -0
- package/dist/type/index.js.map +1 -1
- package/dist/type/querier.d.ts +3 -5
- package/dist/type/querier.d.ts.map +1 -1
- package/dist/type/querier.js.map +1 -1
- package/dist/type/query.d.ts +5 -711
- package/dist/type/query.d.ts.map +1 -1
- package/dist/type/query.js +1 -51
- package/dist/type/query.js.map +1 -1
- package/dist/type/queryAggregate.d.ts +191 -0
- package/dist/type/queryAggregate.d.ts.map +1 -0
- package/dist/type/queryAggregate.js +39 -0
- package/dist/type/queryAggregate.js.map +1 -0
- package/dist/type/queryRaw.d.ts +35 -0
- package/dist/type/queryRaw.d.ts.map +1 -0
- package/dist/type/queryRaw.js +11 -0
- package/dist/type/queryRaw.js.map +1 -0
- package/dist/type/queryWhere.d.ts +271 -0
- package/dist/type/queryWhere.d.ts.map +1 -0
- package/dist/type/queryWhere.js +2 -0
- package/dist/type/queryWhere.js.map +1 -0
- package/dist/type/universalQuerier.d.ts +2 -1
- package/dist/type/universalQuerier.d.ts.map +1 -1
- package/dist/type/utility.d.ts +8 -1
- package/dist/type/utility.d.ts.map +1 -1
- package/dist/type/vector.d.ts +55 -0
- package/dist/type/vector.d.ts.map +1 -0
- package/dist/type/vector.js +2 -0
- package/dist/type/vector.js.map +1 -0
- package/dist/util/ansiSqlLiteral.d.ts +2 -0
- package/dist/util/ansiSqlLiteral.d.ts.map +1 -1
- package/dist/util/ansiSqlLiteral.js +5 -1
- package/dist/util/ansiSqlLiteral.js.map +1 -1
- package/dist/util/dialect.util.d.ts +5 -5
- package/dist/util/dialect.util.d.ts.map +1 -1
- package/dist/util/dialect.util.js +15 -10
- package/dist/util/dialect.util.js.map +1 -1
- package/dist/util/object.util.d.ts +12 -1
- package/dist/util/object.util.d.ts.map +1 -1
- package/dist/util/object.util.js +18 -0
- package/dist/util/object.util.js.map +1 -1
- package/dist/util/relationQuery.util.js +1 -1
- package/dist/util/relationQuery.util.js.map +1 -1
- package/package.json +2 -2
package/dist/type/query.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import type { FieldKey,
|
|
2
|
-
import type {
|
|
1
|
+
import type { FieldKey, JsonFieldPaths, RelationKey } from './entity.js';
|
|
2
|
+
import type { QueryRaw } from './queryRaw.js';
|
|
3
|
+
import type { QueryWhere } from './queryWhere.js';
|
|
4
|
+
import type { BooleanLike, PrimaryKey, Unpacked } from './utility.js';
|
|
5
|
+
import type { QueryVectorSearch } from './vector.js';
|
|
3
6
|
export type QueryOptions = {
|
|
4
7
|
/**
|
|
5
8
|
* Toggle named entity filters for this query. `false` disables all filters;
|
|
@@ -65,267 +68,6 @@ export type QueryConflictPaths<E> = {
|
|
|
65
68
|
export type QueryPopulateRelationOptions<E> = (E extends unknown[] ? Query<Unpacked<E>> : QueryUnique<Unpacked<E>>) & {
|
|
66
69
|
$required?: boolean;
|
|
67
70
|
};
|
|
68
|
-
/**
|
|
69
|
-
* options for full-text-search operator.
|
|
70
|
-
*/
|
|
71
|
-
export type QueryTextSearchOptions<E> = {
|
|
72
|
-
/**
|
|
73
|
-
* text to search for.
|
|
74
|
-
*/
|
|
75
|
-
$value: string;
|
|
76
|
-
/**
|
|
77
|
-
* list of fields to search on.
|
|
78
|
-
*/
|
|
79
|
-
$fields?: FieldKey<E>[];
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* comparison by fields.
|
|
83
|
-
*/
|
|
84
|
-
export type QueryWhereFieldMap<E> = {
|
|
85
|
-
[K in FieldKey<E>]?: QueryWhereFieldValue<E[K]>;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Field comparison, JSON dot-path access, and relation filtering - all fully typed.
|
|
89
|
-
* JSON dot-paths are restricted to real JSON fields, and typed payloads type each path's value
|
|
90
|
-
* (untyped `Json` payloads accept any `field.suffix` path with a permissive value). Relations are
|
|
91
|
-
* filtered via nested typed objects; dotted relation paths are not supported (the dialects throw
|
|
92
|
-
* for non-JSON dotted keys).
|
|
93
|
-
*/
|
|
94
|
-
export type QueryWhereMap<E> = QueryWhereFieldMap<E> & QueryWhereRootOperator<E> & {
|
|
95
|
-
[P in JsonFieldPaths<E>]?: QueryWhereFieldValue<JsonFieldPathValue<E, P>>;
|
|
96
|
-
} & {
|
|
97
|
-
[K in RelationKey<E>]?: QueryWhereMap<Unpacked<NonNullable<E[K]>>> | QueryRelationSizeFilter;
|
|
98
|
-
};
|
|
99
|
-
/**
|
|
100
|
-
* Filter a to-many relation by its row count.
|
|
101
|
-
* @example { users: { $size: 2 } }
|
|
102
|
-
* @example { users: { $size: { $gte: 2 } } }
|
|
103
|
-
*/
|
|
104
|
-
export type QueryRelationSizeFilter = {
|
|
105
|
-
readonly $size: number | QuerySizeComparisonOps;
|
|
106
|
-
};
|
|
107
|
-
export type QueryWhereRootOperator<E> = {
|
|
108
|
-
/**
|
|
109
|
-
* joins query clauses with a logical `AND`, returns records that match all the clauses.
|
|
110
|
-
*/
|
|
111
|
-
$and?: QueryWhereArray<E>;
|
|
112
|
-
/**
|
|
113
|
-
* joins query clauses with a logical `OR`, returns records that match any of the clauses.
|
|
114
|
-
*/
|
|
115
|
-
$or?: QueryWhereArray<E>;
|
|
116
|
-
/**
|
|
117
|
-
* joins query clauses with a logical `AND`, returns records that do not match all the clauses.
|
|
118
|
-
* @see {@link QueryWhereFieldOperatorMap.$not} for per-field negation.
|
|
119
|
-
*/
|
|
120
|
-
$not?: QueryWhereArray<E>;
|
|
121
|
-
/**
|
|
122
|
-
* joins query clauses with a logical `OR`, returns records that do not match any of the clauses.
|
|
123
|
-
*/
|
|
124
|
-
$nor?: QueryWhereArray<E>;
|
|
125
|
-
/**
|
|
126
|
-
* whether the specified fields match against a full-text search of the given string.
|
|
127
|
-
*/
|
|
128
|
-
$text?: QueryTextSearchOptions<E>;
|
|
129
|
-
/**
|
|
130
|
-
* whether the record exists in the given sub-query.
|
|
131
|
-
*/
|
|
132
|
-
$exists?: QueryRaw;
|
|
133
|
-
/**
|
|
134
|
-
* whether the record does not exists in the given sub-query.
|
|
135
|
-
*/
|
|
136
|
-
$nexists?: QueryRaw;
|
|
137
|
-
};
|
|
138
|
-
/**
|
|
139
|
-
* Per-field negation operators. `Pick`'s constraint ties this back to
|
|
140
|
-
* {@link QueryWhereRootOperator} so a rename there breaks this union at compile time.
|
|
141
|
-
*/
|
|
142
|
-
export type QueryNegateOp = keyof Pick<QueryWhereRootOperator<unknown>, '$not' | '$nor'>;
|
|
143
|
-
/**
|
|
144
|
-
* Comparison operators accepted by `$size` for range queries: {@link QueryHavingOp} plus `$between`.
|
|
145
|
-
* Strips `null` from picked operators since array size is always numeric.
|
|
146
|
-
*/
|
|
147
|
-
export type QuerySizeComparisonOps = {
|
|
148
|
-
[K in QueryHavingOp | '$between']?: NonNullable<QueryWhereFieldOperatorMap<number>[K]>;
|
|
149
|
-
};
|
|
150
|
-
export type QueryWhereFieldOperatorMap<T> = {
|
|
151
|
-
/**
|
|
152
|
-
* whether a value is equal to the given value.
|
|
153
|
-
*/
|
|
154
|
-
$eq?: ExpandScalar<T> | null;
|
|
155
|
-
/**
|
|
156
|
-
* whether a value is not equal to the given value.
|
|
157
|
-
*/
|
|
158
|
-
$ne?: ExpandScalar<T> | null;
|
|
159
|
-
/**
|
|
160
|
-
* negates the given comparison for a single field.
|
|
161
|
-
* @see {@link QueryWhereRootOperator.$not} for root-level clause negation.
|
|
162
|
-
*/
|
|
163
|
-
$not?: QueryWhereFieldValue<T>;
|
|
164
|
-
/**
|
|
165
|
-
* whether a value is less than the given value.
|
|
166
|
-
*/
|
|
167
|
-
$lt?: ExpandScalar<T>;
|
|
168
|
-
/**
|
|
169
|
-
* whether a value is less than or equal to the given value.
|
|
170
|
-
*/
|
|
171
|
-
$lte?: ExpandScalar<T>;
|
|
172
|
-
/**
|
|
173
|
-
* whether a value is greater than the given value.
|
|
174
|
-
*/
|
|
175
|
-
$gt?: ExpandScalar<T>;
|
|
176
|
-
/**
|
|
177
|
-
* whether a value is greater than or equal to the given value.
|
|
178
|
-
*/
|
|
179
|
-
$gte?: ExpandScalar<T>;
|
|
180
|
-
/**
|
|
181
|
-
* whether a value is between two values (inclusive). Shorthand for $gte + $lte.
|
|
182
|
-
* @example { age: { $between: [18, 65] } }
|
|
183
|
-
*/
|
|
184
|
-
$between?: [ExpandScalar<T>, ExpandScalar<T>];
|
|
185
|
-
/**
|
|
186
|
-
* whether a string begins with the given string (case sensitive).
|
|
187
|
-
*/
|
|
188
|
-
$startsWith?: string;
|
|
189
|
-
/**
|
|
190
|
-
* whether a string begins with the given string (case insensitive).
|
|
191
|
-
*/
|
|
192
|
-
$istartsWith?: string;
|
|
193
|
-
/**
|
|
194
|
-
* whether a string ends with the given string (case sensitive).
|
|
195
|
-
*/
|
|
196
|
-
$endsWith?: string;
|
|
197
|
-
/**
|
|
198
|
-
* whether a string ends with the given string (case insensitive).
|
|
199
|
-
*/
|
|
200
|
-
$iendsWith?: string;
|
|
201
|
-
/**
|
|
202
|
-
* whether a string is contained within the given string (case sensitive).
|
|
203
|
-
*/
|
|
204
|
-
$includes?: string;
|
|
205
|
-
/**
|
|
206
|
-
* whether a string is contained within the given string (case insensitive).
|
|
207
|
-
*/
|
|
208
|
-
$iincludes?: string;
|
|
209
|
-
/**
|
|
210
|
-
* whether a string fulfills the given pattern (case sensitive).
|
|
211
|
-
*/
|
|
212
|
-
$like?: string;
|
|
213
|
-
/**
|
|
214
|
-
* whether a string fulfills the given pattern (case insensitive).
|
|
215
|
-
*/
|
|
216
|
-
$ilike?: string;
|
|
217
|
-
/**
|
|
218
|
-
* whether a string matches the given regular expression.
|
|
219
|
-
*/
|
|
220
|
-
$regex?: string;
|
|
221
|
-
/**
|
|
222
|
-
* whether a value matches any of the given values.
|
|
223
|
-
*/
|
|
224
|
-
$in?: ExpandScalar<T>[];
|
|
225
|
-
/**
|
|
226
|
-
* whether a value does not match any of the given values.
|
|
227
|
-
*/
|
|
228
|
-
$nin?: ExpandScalar<T>[];
|
|
229
|
-
/**
|
|
230
|
-
* whether a value is null.
|
|
231
|
-
* @example { deletedAt: { $isNull: true } }
|
|
232
|
-
*/
|
|
233
|
-
$isNull?: boolean;
|
|
234
|
-
/**
|
|
235
|
-
* whether a value is not null.
|
|
236
|
-
* @example { email: { $isNotNull: true } }
|
|
237
|
-
*/
|
|
238
|
-
$isNotNull?: boolean;
|
|
239
|
-
/**
|
|
240
|
-
* whether an array contains all the specified values.
|
|
241
|
-
* @example { tags: { $all: ['typescript', 'orm'] } }
|
|
242
|
-
*/
|
|
243
|
-
$all?: unknown extends T ? unknown[] : NonNullable<T> extends readonly (infer U)[] ? ExpandScalar<U>[] : never;
|
|
244
|
-
/**
|
|
245
|
-
* whether an array has the specified length.
|
|
246
|
-
* Accepts a number for exact match, or a comparison operator object for range queries.
|
|
247
|
-
* @example { roles: { $size: 3 } }
|
|
248
|
-
* @example { roles: { $size: { $gte: 2 } } }
|
|
249
|
-
* @example { roles: { $size: { $gt: 0, $lte: 5 } } }
|
|
250
|
-
*/
|
|
251
|
-
$size?: number | QuerySizeComparisonOps;
|
|
252
|
-
/**
|
|
253
|
-
* whether an array contains at least one element matching all specified conditions.
|
|
254
|
-
* Each key of the element type maps to a value or an operator map for that key.
|
|
255
|
-
* @example { addresses: { $elemMatch: { city: 'NYC', zip: '10001' } } }
|
|
256
|
-
* @example { addresses: { $elemMatch: { city: { $like: 'New%' } } } }
|
|
257
|
-
*/
|
|
258
|
-
$elemMatch?: unknown extends T ? QueryWhereElemMatch<unknown> : NonNullable<T> extends readonly (infer U)[] ? QueryWhereElemMatch<U> : never;
|
|
259
|
-
};
|
|
260
|
-
/**
|
|
261
|
-
* Element-level conditions for `$elemMatch`. Scalar elements take an operator map for the element
|
|
262
|
-
* itself (`{ tags: { $elemMatch: { $startsWith: 'ad' } } }`); object elements map each key to a
|
|
263
|
-
* field comparison. An untyped element (`unknown`) accepts any keys but still requires the
|
|
264
|
-
* object-of-conditions shape (a bare scalar is rejected).
|
|
265
|
-
*/
|
|
266
|
-
export type QueryWhereElemMatch<U> = unknown extends U ? {
|
|
267
|
-
[key: string]: QueryWhereFieldValue<unknown> | undefined;
|
|
268
|
-
} : NonNullable<U> extends Scalar ? QueryWhereFieldOperators<NonNullable<U>> : {
|
|
269
|
-
[K in keyof NonNullable<U>]?: QueryWhereFieldValue<NonNullable<U>[K]>;
|
|
270
|
-
};
|
|
271
|
-
/**
|
|
272
|
-
* Simple relational comparison operators. `Pick`'s constraint ties this back to
|
|
273
|
-
* {@link QueryWhereFieldOperatorMap} so a rename there breaks this union at compile time.
|
|
274
|
-
*/
|
|
275
|
-
export type QueryCompareOp = keyof Pick<QueryWhereFieldOperatorMap<unknown>, '$gt' | '$gte' | '$lt' | '$lte'>;
|
|
276
|
-
/**
|
|
277
|
-
* String pattern-matching operators. `Pick`'s constraint ties this back to
|
|
278
|
-
* {@link QueryWhereFieldOperatorMap} so a rename there breaks this union at compile time.
|
|
279
|
-
*/
|
|
280
|
-
export type QueryLikeOp = keyof Pick<QueryWhereFieldOperatorMap<unknown>, '$startsWith' | '$istartsWith' | '$endsWith' | '$iendsWith' | '$includes' | '$iincludes' | '$like' | '$ilike'>;
|
|
281
|
-
/**
|
|
282
|
-
* `HAVING` clause operators: {@link QueryCompareOp} plus `$eq`/`$ne`. `Pick`'s constraint ties the
|
|
283
|
-
* latter back to {@link QueryWhereFieldOperatorMap} so a rename there breaks this union at compile time.
|
|
284
|
-
*/
|
|
285
|
-
export type QueryHavingOp = QueryCompareOp | keyof Pick<QueryWhereFieldOperatorMap<number>, '$eq' | '$ne'>;
|
|
286
|
-
/**
|
|
287
|
-
* String pattern-matching operators: {@link QueryLikeOp} plus `$regex`. `Pick`'s constraint ties
|
|
288
|
-
* the latter back to {@link QueryWhereFieldOperatorMap} so a rename there breaks this union.
|
|
289
|
-
*/
|
|
290
|
-
type QueryStringOp = QueryLikeOp | keyof Pick<QueryWhereFieldOperatorMap<unknown>, '$regex'>;
|
|
291
|
-
/**
|
|
292
|
-
* Array-only operators. `Pick`'s constraint ties this back to {@link QueryWhereFieldOperatorMap}
|
|
293
|
-
* so a rename there breaks this union at compile time.
|
|
294
|
-
*/
|
|
295
|
-
type QueryArrayOp = keyof Pick<QueryWhereFieldOperatorMap<unknown>, '$all' | '$size' | '$elemMatch'>;
|
|
296
|
-
/**
|
|
297
|
-
* Ordering operators: {@link QueryCompareOp} plus `$between`.
|
|
298
|
-
*/
|
|
299
|
-
type QueryOrderedOp = QueryCompareOp | keyof Pick<QueryWhereFieldOperatorMap<unknown>, '$between'>;
|
|
300
|
-
/**
|
|
301
|
-
* Operators applicable to every field type: equality, membership, negation, and null checks.
|
|
302
|
-
*/
|
|
303
|
-
type QueryCommonOp = Exclude<keyof QueryWhereFieldOperatorMap<unknown>, QueryStringOp | QueryArrayOp | QueryOrderedOp>;
|
|
304
|
-
/**
|
|
305
|
-
* Operator keys applicable to a field of type `T`. Brackets prevent union distribution so an
|
|
306
|
-
* optional field (`string | undefined`) or a literal union (`'a' | 'b'`) gates as one type.
|
|
307
|
-
*/
|
|
308
|
-
type QueryAllowedOp<T> = QueryCommonOp | ([NonNullable<T>] extends [QueryComparableScalar] ? QueryOrderedOp : never) | ([NonNullable<T>] extends [string] ? QueryStringOp : never) | ([NonNullable<T>] extends [readonly unknown[]] ? QueryArrayOp : never);
|
|
309
|
-
/**
|
|
310
|
-
* Operators applicable to a field of type `T`: string operators require string fields, ordering
|
|
311
|
-
* operators comparable fields, array operators array fields. `unknown` stays fully permissive
|
|
312
|
-
* (untyped JSON dot-paths, erased dialect shapes).
|
|
313
|
-
*/
|
|
314
|
-
export type QueryWhereFieldOperators<T> = unknown extends T ? QueryWhereFieldOperatorMap<T> : Pick<QueryWhereFieldOperatorMap<T>, QueryAllowedOp<T>>;
|
|
315
|
-
/**
|
|
316
|
-
* Value for a field comparison. A bare array is an implicit `$in` for scalar fields only:
|
|
317
|
-
* on array-typed fields (e.g. a vector `number[]`) an array of arrays is ambiguous, so
|
|
318
|
-
* membership there requires an explicit operator.
|
|
319
|
-
*/
|
|
320
|
-
export type QueryWhereFieldValue<T> = T | ([NonNullable<T>] extends [readonly unknown[]] ? never : T[]) | QueryWhereFieldOperators<T> | QueryRaw;
|
|
321
|
-
/**
|
|
322
|
-
* query filter array - used for `$and`, `$or`, `$not`, `$nor` operators.
|
|
323
|
-
*/
|
|
324
|
-
export type QueryWhereArray<E> = (QueryWhereMap<E> | QueryRaw)[];
|
|
325
|
-
/**
|
|
326
|
-
* query filter.
|
|
327
|
-
*/
|
|
328
|
-
export type QueryWhere<E> = IdValue<E> | IdValue<E>[] | QueryWhereMap<E> | QueryWhereArray<E> | QueryRaw;
|
|
329
71
|
/**
|
|
330
72
|
* Ambient per-request context (e.g. `{ tenantId, userId, roles }`) resolved by parameterized
|
|
331
73
|
* filters. Set with `withContext(ctx, cb)`. It's an `interface` (not a type alias) so you can type
|
|
@@ -365,56 +107,14 @@ export type FilterOptions<E = unknown> = {
|
|
|
365
107
|
/** What to do when the condition returns `undefined`. Defaults to `skip`, or `throw` for `security`. */
|
|
366
108
|
readonly onMissing?: FilterOnMissing;
|
|
367
109
|
};
|
|
368
|
-
/**
|
|
369
|
-
* Resolved filter metadata stored on `EntityMeta.filters`.
|
|
370
|
-
*/
|
|
371
|
-
export type FilterMeta<E = unknown> = FilterOptions<E>;
|
|
372
110
|
/**
|
|
373
111
|
* direction for the sort.
|
|
374
112
|
*/
|
|
375
113
|
export type QuerySortDirection = -1 | 1 | 'asc' | 'desc';
|
|
376
|
-
/**
|
|
377
|
-
* Distance metrics supported by vector similarity search.
|
|
378
|
-
* - `cosine` - best for text/LLM embeddings (default)
|
|
379
|
-
* - `l2` - Euclidean distance
|
|
380
|
-
* - `inner` - inner (dot) product
|
|
381
|
-
* - `l1` - Manhattan distance
|
|
382
|
-
* - `hamming` - for binary vectors
|
|
383
|
-
*/
|
|
384
|
-
export type VectorDistance = 'cosine' | 'l2' | 'inner' | 'l1' | 'hamming';
|
|
385
|
-
/**
|
|
386
|
-
* Vector similarity search options - used inside `$sort` on vector fields.
|
|
387
|
-
*
|
|
388
|
-
* @example
|
|
389
|
-
* ```ts
|
|
390
|
-
* querier.findMany(Article, {
|
|
391
|
-
* $sort: { embedding: { $vector: queryVec } },
|
|
392
|
-
* $limit: 10,
|
|
393
|
-
* });
|
|
394
|
-
* ```
|
|
395
|
-
*/
|
|
396
|
-
export interface QueryVectorSearch {
|
|
397
|
-
/** The query vector to compare against. */
|
|
398
|
-
readonly $vector: readonly number[];
|
|
399
|
-
/** Distance metric. Overrides entity-level default. Falls back to `'cosine'`. */
|
|
400
|
-
readonly $distance?: VectorDistance;
|
|
401
|
-
/** Project the computed distance as a named field in the result. */
|
|
402
|
-
readonly $project?: string;
|
|
403
|
-
}
|
|
404
114
|
/**
|
|
405
115
|
* Accepted value for a field in `$sort` - either a direction or a vector similarity search.
|
|
406
116
|
*/
|
|
407
117
|
export type QuerySortValue = QuerySortDirection | QueryVectorSearch;
|
|
408
|
-
/**
|
|
409
|
-
* Augments an entity with the distance field projected by a vector-search `$sort.$project`. The
|
|
410
|
-
* find methods return the plain entity, so annotate the result with this when you project a score:
|
|
411
|
-
* ```ts
|
|
412
|
-
* const results = (await querier.findMany(Article, {
|
|
413
|
-
* $sort: { embedding: { $vector: queryVec, $project: 'similarity' } },
|
|
414
|
-
* })) as WithDistance<Article, 'similarity'>[];
|
|
415
|
-
* ```
|
|
416
|
-
*/
|
|
417
|
-
export type WithDistance<E, K extends string = '_distance'> = E & Record<K, number>;
|
|
418
118
|
/**
|
|
419
119
|
* sort by map - supports field keys, JSON dot-notation paths (restricted to real JSON fields,
|
|
420
120
|
* like `QueryWhereMap`), relation sort via nested objects, and vector similarity search on
|
|
@@ -487,15 +187,6 @@ export type QueryOne<E> = Omit<Query<E>, '$limit'>;
|
|
|
487
187
|
* options to get an unique record.
|
|
488
188
|
*/
|
|
489
189
|
export type QueryUnique<E> = Pick<QueryOne<E>, '$select' | '$exclude' | '$populate' | '$where'>;
|
|
490
|
-
/**
|
|
491
|
-
* Maps the offending keys to `never`, turning an excess key into a compile error; resolves to
|
|
492
|
-
* `unknown` (an inert intersection member) when there are none. Used by `aggregate`'s `$group`,
|
|
493
|
-
* which is captured as a generic (a bare generic skips excess-property checking). The find methods
|
|
494
|
-
* don't need this: they take concrete `Query<E>` params, so TypeScript's native excess-property
|
|
495
|
-
* checking rejects stray keys directly.
|
|
496
|
-
* @internal
|
|
497
|
-
*/
|
|
498
|
-
type Reject<K> = [K] extends [never] ? unknown : Record<K & string, never>;
|
|
499
190
|
/**
|
|
500
191
|
* stringified query.
|
|
501
192
|
*/
|
|
@@ -526,401 +217,4 @@ export type QueryUpdateResult = {
|
|
|
526
217
|
*/
|
|
527
218
|
created?: boolean;
|
|
528
219
|
};
|
|
529
|
-
/**
|
|
530
|
-
* options for the `raw` function.
|
|
531
|
-
*/
|
|
532
|
-
export type QueryRawFnOptions = {
|
|
533
|
-
/**
|
|
534
|
-
* the current dialect.
|
|
535
|
-
*/
|
|
536
|
-
dialect?: QueryDialect;
|
|
537
|
-
/**
|
|
538
|
-
* the prefix.
|
|
539
|
-
*/
|
|
540
|
-
prefix?: string;
|
|
541
|
-
/**
|
|
542
|
-
* the escaped prefix.
|
|
543
|
-
*/
|
|
544
|
-
escapedPrefix?: string;
|
|
545
|
-
/**
|
|
546
|
-
* the query context.
|
|
547
|
-
*/
|
|
548
|
-
ctx?: QueryContext;
|
|
549
|
-
};
|
|
550
|
-
/**
|
|
551
|
-
* a `raw` function
|
|
552
|
-
*/
|
|
553
|
-
export type QueryRawFn = (opts?: QueryRawFnOptions) => void | Scalar;
|
|
554
|
-
export declare const RAW_VALUE: unique symbol;
|
|
555
|
-
export declare const RAW_ALIAS: unique symbol;
|
|
556
|
-
export declare class QueryRaw {
|
|
557
|
-
readonly [RAW_VALUE]: Scalar | QueryRawFn;
|
|
558
|
-
readonly [RAW_ALIAS]?: string;
|
|
559
|
-
constructor(value: Scalar | QueryRawFn, alias?: string);
|
|
560
|
-
}
|
|
561
|
-
/**
|
|
562
|
-
* comparison options.
|
|
563
|
-
*/
|
|
564
|
-
export type QueryComparisonOptions = QueryOptions & {
|
|
565
|
-
/**
|
|
566
|
-
* use precedence for the comparison or not.
|
|
567
|
-
*/
|
|
568
|
-
usePrecedence?: boolean;
|
|
569
|
-
};
|
|
570
|
-
/**
|
|
571
|
-
* query filter options.
|
|
572
|
-
*/
|
|
573
|
-
export type QueryWhereOptions = QueryComparisonOptions & {
|
|
574
|
-
/**
|
|
575
|
-
* clause to be used in the filter.
|
|
576
|
-
*/
|
|
577
|
-
clause?: 'WHERE' | 'AND' | false;
|
|
578
|
-
};
|
|
579
|
-
export interface QueryContext {
|
|
580
|
-
append(sql: string): this;
|
|
581
|
-
addValue(value: unknown): this;
|
|
582
|
-
pushValue(...values: unknown[]): this;
|
|
583
|
-
readonly sql: string;
|
|
584
|
-
readonly values: unknown[];
|
|
585
|
-
}
|
|
586
|
-
/**
|
|
587
|
-
* Capabilities of the database driver (transport layer).
|
|
588
|
-
*/
|
|
589
|
-
export interface DriverCapabilities {
|
|
590
|
-
/**
|
|
591
|
-
* Whether JSON bind parameters are cast via text first (`($n::text)::jsonb`).
|
|
592
|
-
* Bun SQL PostgreSQL uses this for reliable jsonb merge/push; `pg` does not.
|
|
593
|
-
*/
|
|
594
|
-
readonly explicitJsonCast: boolean;
|
|
595
|
-
/**
|
|
596
|
-
* Whether the driver natively supports JS arrays for the underlying database type.
|
|
597
|
-
* `PgDialect` keeps this `true` for node-postgres; Bun SQL PostgreSQL uses `false` and
|
|
598
|
-
* `toPgArray` string literals instead.
|
|
599
|
-
*/
|
|
600
|
-
readonly nativeArrays: boolean;
|
|
601
|
-
/** Whether the dialect natively supports the JSONB binary JSON type (Postgres/CockroachDB). */
|
|
602
|
-
readonly supportsJsonb: boolean;
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* How a dialect surfaces the IDs generated by an INSERT statement:
|
|
606
|
-
* - `'returning'`: the statement itself returns one row per inserted record (`RETURNING`,
|
|
607
|
-
* or MongoDB's `insertedIds`), so IDs are exact for every row.
|
|
608
|
-
* - `'firstId'`: the driver header only exposes the first generated ID (MySQL `insertId`);
|
|
609
|
-
* the remaining IDs are inferred by incrementing it.
|
|
610
|
-
* - `'lastId'`: the driver header only exposes the last generated ID (SQLite `lastInsertRowid`);
|
|
611
|
-
* the remaining IDs are inferred backwards from it.
|
|
612
|
-
*/
|
|
613
|
-
export type InsertIdSource = 'returning' | 'firstId' | 'lastId';
|
|
614
|
-
/**
|
|
615
|
-
* Features of the database engine (SQL syntax layer).
|
|
616
|
-
*/
|
|
617
|
-
export interface EngineFeatures {
|
|
618
|
-
readonly ifNotExists: boolean;
|
|
619
|
-
readonly indexIfNotExists: boolean;
|
|
620
|
-
readonly dropTableCascade: boolean;
|
|
621
|
-
readonly renameColumn: boolean;
|
|
622
|
-
readonly foreignKeyAlter: boolean;
|
|
623
|
-
/** Whether the dialect supports inline COMMENT on columns (MySQL/MariaDB). */
|
|
624
|
-
readonly columnComment: boolean;
|
|
625
|
-
/**
|
|
626
|
-
* How vector indexes are emitted: inline in CREATE TABLE (MySQL/MariaDB), a standalone
|
|
627
|
-
* `CREATE INDEX ... USING <type> (col opclass)` (Postgres/SQLite), or a standalone
|
|
628
|
-
* `CREATE VECTOR INDEX (col opclass)` with no access-method keyword (CockroachDB's native type).
|
|
629
|
-
*/
|
|
630
|
-
readonly vectorIndexStyle: 'inline' | 'create' | 'native';
|
|
631
|
-
/** Whether the dialect requires/allows (n) length constraints on vector types. */
|
|
632
|
-
readonly vectorSupportsLength: boolean;
|
|
633
|
-
/** Whether the dialect natively supports the TIMESTAMPTZ alias/type. */
|
|
634
|
-
readonly supportsTimestamptz: boolean;
|
|
635
|
-
/** Whether the dialect defaults to TEXT for strings when no length is specified (e.g. Postgres). */
|
|
636
|
-
readonly defaultStringAsText: boolean;
|
|
637
|
-
}
|
|
638
|
-
export interface DialectFeatures extends EngineFeatures, DriverCapabilities {
|
|
639
|
-
}
|
|
640
|
-
export interface QueryDialect {
|
|
641
|
-
/**
|
|
642
|
-
* The dialect features.
|
|
643
|
-
*/
|
|
644
|
-
readonly features: DialectFeatures;
|
|
645
|
-
/**
|
|
646
|
-
* obtains the records matching the given search parameters.
|
|
647
|
-
* @param ctx the query context
|
|
648
|
-
* @param entity the target entity
|
|
649
|
-
* @param q the criteria options
|
|
650
|
-
* @param opts the query options
|
|
651
|
-
*/
|
|
652
|
-
find<E>(ctx: QueryContext, entity: Type<E>, q: Query<E>, opts?: QueryOptions): void;
|
|
653
|
-
/**
|
|
654
|
-
* counts the number of records matching the given search parameters.
|
|
655
|
-
* @param ctx the query context
|
|
656
|
-
* @param entity the target entity
|
|
657
|
-
* @param q the criteria options
|
|
658
|
-
* @param opts the query options
|
|
659
|
-
*/
|
|
660
|
-
count<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): void;
|
|
661
|
-
/**
|
|
662
|
-
* insert records.
|
|
663
|
-
* @param ctx the query context
|
|
664
|
-
* @param entity the target entity
|
|
665
|
-
* @param payload the payload
|
|
666
|
-
* @param opts the query options
|
|
667
|
-
*/
|
|
668
|
-
insert<E>(ctx: QueryContext, entity: Type<E>, payload: E | E[], opts?: QueryOptions): void;
|
|
669
|
-
/**
|
|
670
|
-
* update records.
|
|
671
|
-
* @param ctx the query context
|
|
672
|
-
* @param entity the target entity
|
|
673
|
-
* @param q the criteria options
|
|
674
|
-
* @param payload
|
|
675
|
-
* @param opts the query options
|
|
676
|
-
*/
|
|
677
|
-
update<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, payload: UpdatePayload<E>, opts?: QueryOptions): void;
|
|
678
|
-
/**
|
|
679
|
-
* upsert records.
|
|
680
|
-
* @param ctx the query context
|
|
681
|
-
* @param entity the target entity
|
|
682
|
-
* @param conflictPaths the conflict paths
|
|
683
|
-
* @param payload
|
|
684
|
-
*/
|
|
685
|
-
upsert<E>(ctx: QueryContext, entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E | E[]): void;
|
|
686
|
-
/**
|
|
687
|
-
* delete records.
|
|
688
|
-
* @param ctx the query context
|
|
689
|
-
* @param entity the target entity
|
|
690
|
-
* @param q the criteria options
|
|
691
|
-
* @param opts the query options
|
|
692
|
-
*/
|
|
693
|
-
delete<E>(ctx: QueryContext, entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): void;
|
|
694
|
-
/**
|
|
695
|
-
* escape an identifier.
|
|
696
|
-
* @param val the value to be escaped
|
|
697
|
-
* @param forbidQualified don't escape dots
|
|
698
|
-
* @param addDot use a dot as suffix
|
|
699
|
-
*/
|
|
700
|
-
escapeId(val: string, forbidQualified?: boolean, addDot?: boolean): string;
|
|
701
|
-
/**
|
|
702
|
-
* escape a value.
|
|
703
|
-
* @param val the value to escape
|
|
704
|
-
*/
|
|
705
|
-
escape(val: unknown): string;
|
|
706
|
-
/**
|
|
707
|
-
* add a value to the query.
|
|
708
|
-
* @param values the values array
|
|
709
|
-
* @param value the value to add
|
|
710
|
-
*/
|
|
711
|
-
addValue(values: unknown[], value: unknown): string;
|
|
712
|
-
/**
|
|
713
|
-
* normalizes a value according to the dialect.
|
|
714
|
-
* @param value the value to normalize
|
|
715
|
-
*/
|
|
716
|
-
normalizeValue(value: unknown): unknown;
|
|
717
|
-
/**
|
|
718
|
-
* create a new query context.
|
|
719
|
-
*/
|
|
720
|
-
createContext(): QueryContext;
|
|
721
|
-
}
|
|
722
|
-
/**
|
|
723
|
-
* Supported SQL dialect identifiers.
|
|
724
|
-
*/
|
|
725
|
-
export type SqlDialectName = 'postgres' | 'cockroachdb' | 'mysql' | 'mariadb' | 'sqlite';
|
|
726
|
-
/**
|
|
727
|
-
* Minimal dialect interface exposing escapeIdChar for SQL operations
|
|
728
|
-
*/
|
|
729
|
-
export interface SqlQueryDialect extends QueryDialect {
|
|
730
|
-
/**
|
|
731
|
-
* The SQL dialect name (postgres, mysql, mariadb, sqlite).
|
|
732
|
-
*/
|
|
733
|
-
readonly dialectName: SqlDialectName;
|
|
734
|
-
/**
|
|
735
|
-
* the escape character for identifiers.
|
|
736
|
-
*/
|
|
737
|
-
readonly escapeIdChar: '"' | '`';
|
|
738
|
-
/**
|
|
739
|
-
* Build an aggregate query.
|
|
740
|
-
*/
|
|
741
|
-
aggregate<E, G extends QueryGroupMap<E>, A extends QueryAggMap<E>>(ctx: QueryContext, entity: Type<E>, q: QueryAggregate<E, G, A>, opts?: QueryOptions): void;
|
|
742
|
-
/**
|
|
743
|
-
* Get the placeholder for a parameter at the given index (1-based).
|
|
744
|
-
* Default: '?' for MySQL/MariaDB/SQLite, '$n' for PostgreSQL.
|
|
745
|
-
*/
|
|
746
|
-
placeholder(index: number): string;
|
|
747
|
-
}
|
|
748
|
-
declare const QUERY_AGGREGATE_OPS: readonly ['$count', '$sum', '$avg', '$min', '$max'];
|
|
749
|
-
/**
|
|
750
|
-
* Supported aggregate operations.
|
|
751
|
-
*/
|
|
752
|
-
export type QueryAggregateOp = (typeof QUERY_AGGREGATE_OPS)[number];
|
|
753
|
-
/**
|
|
754
|
-
* Whether `op` is one of {@link QueryAggregateOp}'s known aggregate operators - validates operator
|
|
755
|
-
* keys parsed from query data before trusting them as `QueryAggregateOp`.
|
|
756
|
-
*/
|
|
757
|
-
export declare function isQueryAggregateOp(op: string): op is QueryAggregateOp;
|
|
758
|
-
/**
|
|
759
|
-
* DISTINCT-qualified aggregate ops, each mapped to the base op it applies to a field's distinct
|
|
760
|
-
* values: `$countDistinct` → `COUNT(DISTINCT col)`, and likewise `$sumDistinct`/`$avgDistinct`. Flat
|
|
761
|
-
* (not a nested `{ $distinct }` argument) so the op is self-documenting and greppable. `$min`/`$max`
|
|
762
|
-
* are omitted: DISTINCT is a no-op for them.
|
|
763
|
-
*/
|
|
764
|
-
declare const QUERY_AGGREGATE_DISTINCT_OP_BASE: {
|
|
765
|
-
readonly $countDistinct: '$count';
|
|
766
|
-
readonly $sumDistinct: '$sum';
|
|
767
|
-
readonly $avgDistinct: '$avg';
|
|
768
|
-
};
|
|
769
|
-
/** DISTINCT-qualified aggregate operators (the keys of {@link QUERY_AGGREGATE_DISTINCT_OP_BASE}). */
|
|
770
|
-
export type QueryAggregateDistinctOp = keyof typeof QUERY_AGGREGATE_DISTINCT_OP_BASE;
|
|
771
|
-
/**
|
|
772
|
-
* Resolve an aggregate op key into its base op and whether it is DISTINCT-qualified. A flat distinct
|
|
773
|
-
* op resolves to its base op with `distinct: true`; a plain op to `distinct: false`. Throws otherwise
|
|
774
|
-
* (`$min`/`$max` have no distinct variant).
|
|
775
|
-
*/
|
|
776
|
-
export declare function resolveAggregateOp(key: string): {
|
|
777
|
-
op: QueryAggregateOp;
|
|
778
|
-
distinct: boolean;
|
|
779
|
-
};
|
|
780
|
-
/** The argument of an aggregate function: a field, or `'*'` (only meaningful for `COUNT(*)`). */
|
|
781
|
-
export type QueryAggregateArg<E> = FieldKey<E> | '*';
|
|
782
|
-
/** Ops whose argument must be a plain field: every op except `$count` (which also accepts `'*'`). */
|
|
783
|
-
type QueryAggregateFieldOp = Exclude<QueryAggregateOp, '$count'> | QueryAggregateDistinctOp;
|
|
784
|
-
/** Every aggregate op mapped to its accepted argument: `$count` takes a field or `'*'`, the rest a field. */
|
|
785
|
-
type QueryAggregateArgMap<E> = Record<'$count', QueryAggregateArg<E>> & Record<QueryAggregateFieldOp, FieldKey<E>>;
|
|
786
|
-
/** Exactly one key of `T`: the chosen op with its value; every other op key is forbidden (`never`). */
|
|
787
|
-
type ExactlyOne<T> = {
|
|
788
|
-
[K in keyof T]: Readonly<Record<K, T[K]>> & Partial<Readonly<Record<Exclude<keyof T, K>, never>>>;
|
|
789
|
-
}[keyof T];
|
|
790
|
-
/**
|
|
791
|
-
* An aggregate function applied to a field. Exactly one operation per entry (a second op is a
|
|
792
|
-
* compile error). Only `$count` accepts `'*'` (i.e. `COUNT(*)`); every other op requires a field.
|
|
793
|
-
* DISTINCT variants are flat ops (`$countDistinct`/`$sumDistinct`/`$avgDistinct`) taking a field.
|
|
794
|
-
*
|
|
795
|
-
* @example { $count: '*' } → COUNT(*)
|
|
796
|
-
* @example { $countDistinct: 'id' } → COUNT(DISTINCT "id")
|
|
797
|
-
* @example { $sum: 'amount' } → SUM("amount")
|
|
798
|
-
* @example { $sumDistinct: 'amount' } → SUM(DISTINCT "amount")
|
|
799
|
-
* @example { $avg: 'age' } → AVG("age")
|
|
800
|
-
*/
|
|
801
|
-
export type QueryAggregateFn<E> = ExactlyOne<QueryAggregateArgMap<E>>;
|
|
802
|
-
/**
|
|
803
|
-
* Aggregate ops whose grouped column always resolves to `number`, regardless of the aggregated
|
|
804
|
-
* field's own type: the DISTINCT variants plus the base ops they map to (`$count`/`$sum`/`$avg`).
|
|
805
|
-
*/
|
|
806
|
-
type QueryAggregateNumericOp = QueryAggregateDistinctOp | (typeof QUERY_AGGREGATE_DISTINCT_OP_BASE)[QueryAggregateDistinctOp];
|
|
807
|
-
/** A single-key `{ [op]: unknown }` shape for each {@link QueryAggregateNumericOp}, matched to infer a `number` result. */
|
|
808
|
-
type QueryAggregateNumericFn = {
|
|
809
|
-
[K in QueryAggregateNumericOp]: {
|
|
810
|
-
readonly [P in K]: unknown;
|
|
811
|
-
};
|
|
812
|
-
}[QueryAggregateNumericOp];
|
|
813
|
-
/**
|
|
814
|
-
* Group-by columns: an object mapping entity field keys to `true`, exactly like {@link QuerySelect}.
|
|
815
|
-
* Typed against the entity, so a typo'd column is a compile error. Compute aggregate columns with
|
|
816
|
-
* {@link QueryAggMap} (the `$agg` key), not here.
|
|
817
|
-
*
|
|
818
|
-
* @example
|
|
819
|
-
* ```ts
|
|
820
|
-
* { status: true } // → GROUP BY "status"
|
|
821
|
-
* ```
|
|
822
|
-
*/
|
|
823
|
-
export type QueryGroupMap<E> = {
|
|
824
|
-
readonly [K in FieldKey<E>]?: true;
|
|
825
|
-
};
|
|
826
|
-
/**
|
|
827
|
-
* Computed aggregate columns: an object mapping your chosen output alias to an aggregate function.
|
|
828
|
-
* Alias names are free (you are naming new columns); the aggregated field reference inside each
|
|
829
|
-
* function is typed against the entity.
|
|
830
|
-
*
|
|
831
|
-
* @example
|
|
832
|
-
* ```ts
|
|
833
|
-
* { count: { $count: '*' }, avgAge: { $avg: 'age' } }
|
|
834
|
-
* // → COUNT(*) AS "count", AVG("age") AS "avgAge"
|
|
835
|
-
* ```
|
|
836
|
-
*/
|
|
837
|
-
export type QueryAggMap<E> = {
|
|
838
|
-
readonly [alias: string]: QueryAggregateFn<E>;
|
|
839
|
-
};
|
|
840
|
-
/** The entity type of an aggregated field reference `F`, or `unknown` if it is not a known field. */
|
|
841
|
-
type FieldValueType<E, F> = F extends keyof E ? E[F] : unknown;
|
|
842
|
-
/**
|
|
843
|
-
* Resolves a single computed column's type from its aggregate function: `$count`/`$sum`/`$avg` are
|
|
844
|
-
* always `number`; `$min`/`$max` keep the aggregated field's own type.
|
|
845
|
-
* @internal
|
|
846
|
-
*/
|
|
847
|
-
type QueryAggregateFnResult<E, Fn> = Fn extends QueryAggregateNumericFn ? number : Fn extends {
|
|
848
|
-
readonly $min: infer F;
|
|
849
|
-
} ? FieldValueType<E, F> : Fn extends {
|
|
850
|
-
readonly $max: infer F;
|
|
851
|
-
} ? FieldValueType<E, F> : unknown;
|
|
852
|
-
/**
|
|
853
|
-
* Flattens an intersection into a single object literal for readable editor hovers.
|
|
854
|
-
* @internal
|
|
855
|
-
*/
|
|
856
|
-
type Simplify<T> = {
|
|
857
|
-
[K in keyof T]: T[K];
|
|
858
|
-
} & {};
|
|
859
|
-
/**
|
|
860
|
-
* Infers the aggregated result row: grouped columns (`G`) keep their entity type; computed columns
|
|
861
|
-
* (`A`) resolve from their aggregate function via {@link QueryAggregateFnResult}.
|
|
862
|
-
*/
|
|
863
|
-
export type QueryAggregateResult<E, G, A> = Simplify<{
|
|
864
|
-
-readonly [K in keyof G & FieldKey<E>]: E[K];
|
|
865
|
-
} & {
|
|
866
|
-
-readonly [K in keyof A]: QueryAggregateFnResult<E, A[K]>;
|
|
867
|
-
}>;
|
|
868
|
-
/**
|
|
869
|
-
* Erased runtime shape of a HAVING clause (alias → comparison), consumed by the dialect builders.
|
|
870
|
-
* Values are `unknown` because the SQL is built generically; the typed, per-column value checking
|
|
871
|
-
* lives in {@link QueryAggregate.$having}.
|
|
872
|
-
*
|
|
873
|
-
* @example { count: { $gt: 5 } } → HAVING COUNT(*) > 5
|
|
874
|
-
*/
|
|
875
|
-
export type QueryHavingMap = {
|
|
876
|
-
readonly [alias: string]: QueryWhereFieldValue<unknown> | undefined;
|
|
877
|
-
};
|
|
878
|
-
/**
|
|
879
|
-
* Aggregate query - separate from `Query<E>` to keep return types honest.
|
|
880
|
-
* Used exclusively with `querier.aggregate()`.
|
|
881
|
-
*
|
|
882
|
-
* @example
|
|
883
|
-
* ```ts
|
|
884
|
-
* querier.aggregate(User, {
|
|
885
|
-
* $where: { deletedAt: { $isNull: true } },
|
|
886
|
-
* $group: { status: true },
|
|
887
|
-
* $agg: { count: { $count: '*' }, avgAge: { $avg: 'age' } },
|
|
888
|
-
* $having: { count: { $gt: 5 } },
|
|
889
|
-
* $sort: { count: -1 },
|
|
890
|
-
* });
|
|
891
|
-
* ```
|
|
892
|
-
*/
|
|
893
|
-
export type QueryAggregate<E, G extends QueryGroupMap<E> = QueryGroupMap<E>, A extends QueryAggMap<E> = QueryAggMap<E>> = {
|
|
894
|
-
/**
|
|
895
|
-
* Row-level filtering, applied before grouping (SQL `WHERE`, MongoDB `$match`).
|
|
896
|
-
*/
|
|
897
|
-
readonly $where?: QueryWhere<E>;
|
|
898
|
-
/**
|
|
899
|
-
* Columns to group by - `{ status: true }`, typed against the entity like `$select`. A computed
|
|
900
|
-
* aggregate wrongly placed here (it belongs in `$agg`) is rejected via {@link Reject}, since
|
|
901
|
-
* `$group` is captured as a generic and a bare generic skips excess-property checking.
|
|
902
|
-
*/
|
|
903
|
-
readonly $group?: G & Reject<Exclude<keyof G, FieldKey<E>>>;
|
|
904
|
-
/**
|
|
905
|
-
* Computed aggregate columns - `{ count: { $count: '*' }, avgAge: { $avg: 'age' } }`.
|
|
906
|
-
*/
|
|
907
|
-
readonly $agg?: A;
|
|
908
|
-
/**
|
|
909
|
-
* Post-aggregation filtering, applied after grouping (SQL `HAVING`, MongoDB post-group `$match`).
|
|
910
|
-
* Keyed by the result columns (grouped columns + computed aliases), and each value is typed to that
|
|
911
|
-
* column's result type - a `$min`/`$max` over a `Date` field compares against a `Date`, a grouped
|
|
912
|
-
* column against its own type - reusing {@link QueryAggregateResult}. A name that is neither is a
|
|
913
|
-
* compile error.
|
|
914
|
-
*/
|
|
915
|
-
readonly $having?: {
|
|
916
|
-
readonly [K in keyof QueryAggregateResult<E, G, A>]?: QueryWhereFieldValue<QueryAggregateResult<E, G, A>[K]>;
|
|
917
|
-
};
|
|
918
|
-
/**
|
|
919
|
-
* Sort the aggregated results by a grouped column, a computed alias, or an entity field.
|
|
920
|
-
*/
|
|
921
|
-
readonly $sort?: QuerySortMap<E> & {
|
|
922
|
-
readonly [K in (keyof G & string) | (keyof A & string)]?: QuerySortDirection;
|
|
923
|
-
};
|
|
924
|
-
} & QueryPager;
|
|
925
|
-
export {};
|
|
926
220
|
//# sourceMappingURL=query.d.ts.map
|