@@ -84,67 +84,108 @@ export type QueryConstraintType =
84
84
| 'startAt'
85
85
| 'startAfter'
86
86
| 'endAt'
87
- | 'endBefore'
88
- | 'and'
89
- | 'or' ;
87
+ | 'endBefore' ;
88
+
89
+ /**
90
+ * An `AppliableConstraint` is an abstraction of a constraint that can be applied
91
+ * to a Firestore query.
92
+ */
93
+ export abstract class AppliableConstraint {
94
+ /**
95
+ * Takes the provided {@link Query} and returns a copy of the {@link Query} with this
96
+ * {@link AppliableConstraint} applied.
97
+ */
98
+ abstract _apply < T > ( query : Query < T > ) : Query < T > ;
99
+ }
90
100
91
101
/**
92
102
* A `QueryConstraint` is used to narrow the set of documents returned by a
93
103
* Firestore query. `QueryConstraint`s are created by invoking {@link where},
94
- * {@link orderBy}, {@link ( startAt:1) }, {@link ( startAfter:1) }, {@link
95
- * ( endBefore:1) }, {@link ( endAt:1) }, {@link limit}, {@link limitToLast}, { @link or} or { @link and } and
104
+ * {@link orderBy}, {@link startAt}, {@link startAfter}, {@link
105
+ * endBefore}, {@link endAt}, {@link limit}, {@link limitToLast} and
96
106
* can then be passed to {@link query} to create a new query instance that
97
107
* also contains this `QueryConstraint`.
98
108
*/
99
- export abstract class QueryConstraint {
109
+ export abstract class QueryConstraint extends AppliableConstraint {
100
110
/** The type of this query constraint */
101
111
abstract readonly type : QueryConstraintType ;
102
112
103
113
/**
104
114
* Takes the provided {@link Query} and returns a copy of the {@link Query} with this
105
- * {@link QueryConstraint } applied.
115
+ * {@link AppliableConstraint } applied.
106
116
*/
107
117
abstract _apply < T > ( query : Query < T > ) : Query < T > ;
108
118
}
109
119
110
120
/**
111
- * Creates a new immutable instance of {@link Query} that is extended to also include
112
- * additional query constraints.
121
+ * Creates a new immutable instance of {@link Query} that is extended to also
122
+ * include additional query constraints.
123
+ *
124
+ * @param query - The {@link Query} instance to use as a base for the new
125
+ * constraints.
126
+ * @param compositeFilter - The {@link QueryCompositeFilterConstraint} to
127
+ * apply. Create {@link QueryCompositeFilterConstraint} using {@link and} or
128
+ * {@link or}.
129
+ * @param queryConstraints - Additional {@link QueryNonFilterConstraint}s to
130
+ * apply (e.g. {@link orderBy}, {@link limit}).
131
+ * @throws if any of the provided query constraints cannot be combined with the
132
+ * existing or new constraints.
133
+ */
134
+ export function query < T > (
135
+ query : Query < T > ,
136
+ compositeFilter : QueryCompositeFilterConstraint ,
137
+ ...queryConstraints : QueryNonFilterConstraint [ ]
138
+ ) : Query < T > ;
139
+
140
+ /**
141
+ * Creates a new immutable instance of {@link Query} that is extended to also
142
+ * include additional query constraints.
113
143
*
114
- * @param query - The {@link Query} instance to use as a base for the new constraints.
144
+ * @param query - The {@link Query} instance to use as a base for the new
145
+ * constraints.
115
146
* @param queryConstraints - The list of {@link QueryConstraint}s to apply.
116
147
* @throws if any of the provided query constraints cannot be combined with the
117
148
* existing or new constraints.
118
149
*/
119
150
export function query < T > (
120
151
query : Query < T > ,
121
152
...queryConstraints : QueryConstraint [ ]
153
+ ) : Query < T > ;
154
+
155
+ export function query < T > (
156
+ query : Query < T > ,
157
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
158
+ filterOrQueryConstraints : any ,
159
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
160
+ ...nonFilters : any
122
161
) : Query < T > {
162
+ let queryConstraints : AppliableConstraint [ ] = [ ] ;
163
+ if ( filterOrQueryConstraints instanceof AppliableConstraint ) {
164
+ queryConstraints . push ( filterOrQueryConstraints ) ;
165
+ } else if ( Array . isArray ( filterOrQueryConstraints ) ) {
166
+ queryConstraints . concat ( filterOrQueryConstraints as AppliableConstraint [ ] ) ;
167
+ }
168
+
169
+ if ( nonFilters !== undefined ) {
170
+ queryConstraints = queryConstraints . concat (
171
+ nonFilters as QueryNonFilterConstraint [ ]
172
+ ) ;
173
+ }
174
+
123
175
for ( const constraint of queryConstraints ) {
124
176
query = constraint . _apply ( query ) ;
125
177
}
126
178
return query ;
127
179
}
128
180
129
181
/**
130
- * A `QueryFilterConstraint ` is used to narrow the set of documents returned by
182
+ * A `QueryFieldFilterConstraint ` is used to narrow the set of documents returned by
131
183
* a Firestore query by filtering on one or more document fields.
132
- * `QueryFilterConstraint`s are created by invoking {@link where}, {@link or} or
133
- * {@link and} and can then be passed to {@link query} to create a new query
134
- * instance that also contains this `QueryFilterConstraint`.
135
- */
136
- export abstract class QueryFilterConstraint extends QueryConstraint {
137
- abstract _parse < T > ( query : Query < T > ) : Filter ;
138
- }
139
-
140
- /**
141
- * A `QueryFieldFilterConstraint` is used to narrow the set of documents
142
- * returned by a Firestore query by filtering on one document field.
143
- * `QueryFieldFilterConstraint`s are created by invoking {@link where} and
144
- * can then be passed to {@link query} to create a new query instance that
145
- * also contains this `QueryFieldFilterConstraint`.
184
+ * `QueryFieldFilterConstraint`s are created by invoking {@link where} and can then
185
+ * be passed to {@link query} to create a new query instance that also contains
186
+ * this `QueryFieldFilterConstraint`.
146
187
*/
147
- export class QueryFieldFilterConstraint extends QueryFilterConstraint {
188
+ export class QueryFieldFilterConstraint extends QueryConstraint {
148
189
/** The type of this query constraint */
149
190
readonly type = 'where' ;
150
191
@@ -233,12 +274,12 @@ export function where(
233
274
/**
234
275
* A `QueryCompositeFilterConstraint` is used to narrow the set of documents
235
276
* returned by a Firestore query by performing the logical OR or AND of multiple
236
- * {@link QueryFieldFilterConstraint} or {@link QueryCompositeFilterConstraint}.
277
+ * {@link QueryFieldFilterConstraint}s or {@link QueryCompositeFilterConstraint}s .
237
278
* `QueryCompositeFilterConstraint`s are created by invoking {@link or} or
238
279
* {@link and} and can then be passed to {@link query} to create a new query
239
- * instance that also contains this `QueryCompositeFilterConstraint`.
280
+ * instance that also contains the `QueryCompositeFilterConstraint`.
240
281
*/
241
- export class QueryCompositeFilterConstraint extends QueryFilterConstraint {
282
+ export class QueryCompositeFilterConstraint extends AppliableConstraint {
242
283
/**
243
284
* @internal
244
285
*/
@@ -287,7 +328,7 @@ export class QueryCompositeFilterConstraint extends QueryFilterConstraint {
287
328
) ;
288
329
}
289
330
290
- _getQueryConstraints ( ) : readonly QueryConstraint [ ] {
331
+ _getQueryConstraints ( ) : readonly AppliableConstraint [ ] {
291
332
return this . _queryConstraints ;
292
333
}
293
334
@@ -296,13 +337,39 @@ export class QueryCompositeFilterConstraint extends QueryFilterConstraint {
296
337
}
297
338
}
298
339
340
+ /**
341
+ * `QueryNonFilterConstraint` is a helper union type that represents
342
+ * QueryConstraints which are used to narrow or order the set of documents,
343
+ * but that do not explicitly filter on a document field.
344
+ * `QueryNonFilterConstraint`s are created by invoking {@link orderBy},
345
+ * {@link startAt}, {@link startAfter}, {@link endBefore}, {@link endAt},
346
+ * {@link limit} or {@link limitToLast} and can then be passed to {@link query}
347
+ * to create a new query instance that also contains the `QueryConstraint`.
348
+ */
349
+ export type QueryNonFilterConstraint =
350
+ | QueryOrderByConstraint
351
+ | QueryLimitConstraint
352
+ | QueryStartAtConstraint
353
+ | QueryEndAtConstraint ;
354
+
355
+ /**
356
+ * `QueryFilterConstraint` is a helper union type that represents
357
+ * {@link QueryFieldFilterConstraint} and {@link QueryCompositeFilterConstraint}.
358
+ * `QueryFilterConstraint`s are created by invoking {@link or} or {@link and}
359
+ * and can then be passed to {@link query} to create a new query instance that
360
+ * also contains the `QueryConstraint`.
361
+ */
362
+ export type QueryFilterConstraint =
363
+ | QueryFieldFilterConstraint
364
+ | QueryCompositeFilterConstraint ;
365
+
299
366
/**
300
367
* Creates a {@link QueryCompositeFilterConstraint} that performs a logical OR
301
- * of all the provided {@link QueryFilterConstraint}.
368
+ * of all the provided {@link QueryFilterConstraint}s .
302
369
*
303
- * @param queryConstraints - Optional. The {@link queryConstraints} for OR
304
- * operation. These must be created with calls to {@link where}, { @link or}, or
305
- * {@link and}.
370
+ * @param queryConstraints - Optional. The {@link QueryFilterConstraint}s
371
+ * for OR operation. These must be created with calls to {@link where},
372
+ * {@link or}, or { @link and}.
306
373
* @returns The created {@link QueryCompositeFilterConstraint}.
307
374
*/
308
375
export function or (
@@ -321,11 +388,11 @@ export function or(
321
388
322
389
/**
323
390
* Creates a {@link QueryCompositeFilterConstraint} that performs a logical AND
324
- * of all the provided {@link QueryFilterConstraint}.
391
+ * of all the provided {@link QueryFilterConstraint}s .
325
392
*
326
- * @param queryConstraints - Optional. The {@link queryConstraints} for AND
327
- * operation. These must be created with calls to {@link where}, { @link or}, or
328
- * {@link and}.
393
+ * @param queryConstraints - Optional. The {@link QueryFilterConstraint}s
394
+ * for AND operation. These must be created with calls to {@link where},
395
+ * {@link or}, or { @link and}.
329
396
* @returns The created {@link QueryCompositeFilterConstraint}.
330
397
*/
331
398
export function and (
@@ -1139,15 +1206,15 @@ function validateOrderByAndInequalityMatch(
1139
1206
1140
1207
export function validateQueryFilterConstraint (
1141
1208
functionName : string ,
1142
- queryConstraint : QueryConstraint
1209
+ queryConstraint : AppliableConstraint
1143
1210
) : void {
1144
1211
if (
1145
- ! ( queryConstraint instanceof QueryFilterConstraint ) &&
1212
+ ! ( queryConstraint instanceof QueryFieldFilterConstraint ) &&
1146
1213
! ( queryConstraint instanceof QueryCompositeFilterConstraint )
1147
1214
) {
1148
1215
throw new FirestoreError (
1149
1216
Code . INVALID_ARGUMENT ,
1150
- `Function ${ functionName } () requires QueryContraints created with a call to 'where(...)'.`
1217
+ `Function ${ functionName } () requires AppliableContraints created with a call to 'where(...)', 'or(...)', or 'and (...)'.`
1151
1218
) ;
1152
1219
}
1153
1220
}
0 commit comments