Skip to content

Commit fde5adf

Browse files
Markduckworth/or queries (#6694)
Implementation of Firestore OR Queries without the public API. The public API will be released later. Several minor API changes are included in this release: Functions in the Firestore package that return QueryConstraints (for example: where(...), limit(...), and orderBy(...)) now return a more specific type, which extends QueryConstraint. This is a non-breaking change that will support OR Queries.
1 parent ab3f16c commit fde5adf

33 files changed

+4539
-1081
lines changed

.changeset/lucky-games-arrive.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@firebase/firestore": minor
3+
"firebase": minor
4+
---
5+
6+
Functions in the Firestore package that return QueryConstraints (for example: `where(...)`, `limit(...)`, and `orderBy(...)`)
7+
now return a more specific type, which extends QueryConstraint. Refactoring and code that supports future features is also
8+
included in this release.

common/api-review/firestore-lite.api.md

+40-12
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,16 @@ export class DocumentSnapshot<T = DocumentData> {
140140
export { EmulatorMockTokenOptions }
141141

142142
// @public
143-
export function endAt(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
143+
export function endAt(snapshot: DocumentSnapshot<unknown>): QueryEndAtConstraint;
144144

145145
// @public
146-
export function endAt(...fieldValues: unknown[]): QueryConstraint;
146+
export function endAt(...fieldValues: unknown[]): QueryEndAtConstraint;
147147

148148
// @public
149-
export function endBefore(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
149+
export function endBefore(snapshot: DocumentSnapshot<unknown>): QueryEndAtConstraint;
150150

151151
// @public
152-
export function endBefore(...fieldValues: unknown[]): QueryConstraint;
152+
export function endBefore(...fieldValues: unknown[]): QueryEndAtConstraint;
153153

154154
// @public
155155
export class FieldPath {
@@ -222,10 +222,10 @@ export function increment(n: number): FieldValue;
222222
export function initializeFirestore(app: FirebaseApp, settings: Settings): Firestore;
223223

224224
// @public
225-
export function limit(limit: number): QueryConstraint;
225+
export function limit(limit: number): QueryLimitConstraint;
226226

227227
// @public
228-
export function limitToLast(limit: number): QueryConstraint;
228+
export function limitToLast(limit: number): QueryLimitConstraint;
229229

230230
export { LogLevel }
231231

@@ -235,7 +235,7 @@ export type NestedUpdateFields<T extends Record<string, unknown>> = UnionToInter
235235
}[keyof T & string]>;
236236

237237
// @public
238-
export function orderBy(fieldPath: string | FieldPath, directionStr?: OrderByDirection): QueryConstraint;
238+
export function orderBy(fieldPath: string | FieldPath, directionStr?: OrderByDirection): QueryOrderByConstraint;
239239

240240
// @public
241241
export type OrderByDirection = 'desc' | 'asc';
@@ -275,9 +275,32 @@ export class QueryDocumentSnapshot<T = DocumentData> extends DocumentSnapshot<T>
275275
data(): T;
276276
}
277277

278+
// @public
279+
export class QueryEndAtConstraint extends QueryConstraint {
280+
readonly type: 'endBefore' | 'endAt';
281+
}
282+
278283
// @public
279284
export function queryEqual<T>(left: Query<T>, right: Query<T>): boolean;
280285

286+
// @public
287+
export class QueryFieldFilterConstraint extends QueryConstraint {
288+
readonly type = "where";
289+
}
290+
291+
// @public
292+
export class QueryLimitConstraint extends QueryConstraint {
293+
readonly type: 'limit' | 'limitToLast';
294+
}
295+
296+
// @public
297+
export type QueryNonFilterConstraint = QueryOrderByConstraint | QueryLimitConstraint | QueryStartAtConstraint | QueryEndAtConstraint;
298+
299+
// @public
300+
export class QueryOrderByConstraint extends QueryConstraint {
301+
readonly type = "orderBy";
302+
}
303+
281304
// @public
282305
export class QuerySnapshot<T = DocumentData> {
283306
get docs(): Array<QueryDocumentSnapshot<T>>;
@@ -287,6 +310,11 @@ export class QuerySnapshot<T = DocumentData> {
287310
get size(): number;
288311
}
289312

313+
// @public
314+
export class QueryStartAtConstraint extends QueryConstraint {
315+
readonly type: 'startAt' | 'startAfter';
316+
}
317+
290318
// @public
291319
export function refEqual<T>(left: DocumentReference<T> | CollectionReference<T>, right: DocumentReference<T> | CollectionReference<T>): boolean;
292320

@@ -323,16 +351,16 @@ export interface Settings {
323351
export function snapshotEqual<T>(left: DocumentSnapshot<T> | QuerySnapshot<T>, right: DocumentSnapshot<T> | QuerySnapshot<T>): boolean;
324352

325353
// @public
326-
export function startAfter(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
354+
export function startAfter(snapshot: DocumentSnapshot<unknown>): QueryStartAtConstraint;
327355

328356
// @public
329-
export function startAfter(...fieldValues: unknown[]): QueryConstraint;
357+
export function startAfter(...fieldValues: unknown[]): QueryStartAtConstraint;
330358

331359
// @public
332-
export function startAt(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
360+
export function startAt(snapshot: DocumentSnapshot<unknown>): QueryStartAtConstraint;
333361

334362
// @public
335-
export function startAt(...fieldValues: unknown[]): QueryConstraint;
363+
export function startAt(...fieldValues: unknown[]): QueryStartAtConstraint;
336364

337365
// @public
338366
export function terminate(firestore: Firestore): Promise<void>;
@@ -388,7 +416,7 @@ export function updateDoc<T>(reference: DocumentReference<T>, data: UpdateData<T
388416
export function updateDoc(reference: DocumentReference<unknown>, field: string | FieldPath, value: unknown, ...moreFieldsAndValues: unknown[]): Promise<void>;
389417

390418
// @public
391-
export function where(fieldPath: string | FieldPath, opStr: WhereFilterOp, value: unknown): QueryConstraint;
419+
export function where(fieldPath: string | FieldPath, opStr: WhereFilterOp, value: unknown): QueryFieldFilterConstraint;
392420

393421
// @public
394422
export type WhereFilterOp = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'array-contains' | 'in' | 'array-contains-any' | 'not-in';

common/api-review/firestore.api.md

+40-12
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,16 @@ export function enableMultiTabIndexedDbPersistence(firestore: Firestore): Promis
170170
export function enableNetwork(firestore: Firestore): Promise<void>;
171171

172172
// @public
173-
export function endAt(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
173+
export function endAt(snapshot: DocumentSnapshot<unknown>): QueryEndAtConstraint;
174174

175175
// @public
176-
export function endAt(...fieldValues: unknown[]): QueryConstraint;
176+
export function endAt(...fieldValues: unknown[]): QueryEndAtConstraint;
177177

178178
// @public
179-
export function endBefore(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
179+
export function endBefore(snapshot: DocumentSnapshot<unknown>): QueryEndAtConstraint;
180180

181181
// @public
182-
export function endBefore(...fieldValues: unknown[]): QueryConstraint;
182+
export function endBefore(...fieldValues: unknown[]): QueryEndAtConstraint;
183183

184184
// @public
185185
export class FieldPath {
@@ -298,10 +298,10 @@ export interface IndexField {
298298
export function initializeFirestore(app: FirebaseApp, settings: FirestoreSettings, databaseId?: string): Firestore;
299299

300300
// @public
301-
export function limit(limit: number): QueryConstraint;
301+
export function limit(limit: number): QueryLimitConstraint;
302302

303303
// @public
304-
export function limitToLast(limit: number): QueryConstraint;
304+
export function limitToLast(limit: number): QueryLimitConstraint;
305305

306306
// @public
307307
export function loadBundle(firestore: Firestore, bundleData: ReadableStream<Uint8Array> | ArrayBuffer | string): LoadBundleTask;
@@ -383,7 +383,7 @@ export function onSnapshotsInSync(firestore: Firestore, observer: {
383383
export function onSnapshotsInSync(firestore: Firestore, onSync: () => void): Unsubscribe;
384384

385385
// @public
386-
export function orderBy(fieldPath: string | FieldPath, directionStr?: OrderByDirection): QueryConstraint;
386+
export function orderBy(fieldPath: string | FieldPath, directionStr?: OrderByDirection): QueryOrderByConstraint;
387387

388388
// @public
389389
export type OrderByDirection = 'desc' | 'asc';
@@ -428,9 +428,32 @@ export class QueryDocumentSnapshot<T = DocumentData> extends DocumentSnapshot<T>
428428
data(options?: SnapshotOptions): T;
429429
}
430430

431+
// @public
432+
export class QueryEndAtConstraint extends QueryConstraint {
433+
readonly type: 'endBefore' | 'endAt';
434+
}
435+
431436
// @public
432437
export function queryEqual<T>(left: Query<T>, right: Query<T>): boolean;
433438

439+
// @public
440+
export class QueryFieldFilterConstraint extends QueryConstraint {
441+
readonly type = "where";
442+
}
443+
444+
// @public
445+
export class QueryLimitConstraint extends QueryConstraint {
446+
readonly type: 'limit' | 'limitToLast';
447+
}
448+
449+
// @public
450+
export type QueryNonFilterConstraint = QueryOrderByConstraint | QueryLimitConstraint | QueryStartAtConstraint | QueryEndAtConstraint;
451+
452+
// @public
453+
export class QueryOrderByConstraint extends QueryConstraint {
454+
readonly type = "orderBy";
455+
}
456+
434457
// @public
435458
export class QuerySnapshot<T = DocumentData> {
436459
docChanges(options?: SnapshotListenOptions): Array<DocumentChange<T>>;
@@ -442,6 +465,11 @@ export class QuerySnapshot<T = DocumentData> {
442465
get size(): number;
443466
}
444467

468+
// @public
469+
export class QueryStartAtConstraint extends QueryConstraint {
470+
readonly type: 'startAt' | 'startAfter';
471+
}
472+
445473
// @public
446474
export function refEqual<T>(left: DocumentReference<T> | CollectionReference<T>, right: DocumentReference<T> | CollectionReference<T>): boolean;
447475

@@ -494,16 +522,16 @@ export interface SnapshotOptions {
494522
}
495523

496524
// @public
497-
export function startAfter(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
525+
export function startAfter(snapshot: DocumentSnapshot<unknown>): QueryStartAtConstraint;
498526

499527
// @public
500-
export function startAfter(...fieldValues: unknown[]): QueryConstraint;
528+
export function startAfter(...fieldValues: unknown[]): QueryStartAtConstraint;
501529

502530
// @public
503-
export function startAt(snapshot: DocumentSnapshot<unknown>): QueryConstraint;
531+
export function startAt(snapshot: DocumentSnapshot<unknown>): QueryStartAtConstraint;
504532

505533
// @public
506-
export function startAt(...fieldValues: unknown[]): QueryConstraint;
534+
export function startAt(...fieldValues: unknown[]): QueryStartAtConstraint;
507535

508536
// @public
509537
export type TaskState = 'Error' | 'Running' | 'Success';
@@ -570,7 +598,7 @@ export function updateDoc(reference: DocumentReference<unknown>, field: string |
570598
export function waitForPendingWrites(firestore: Firestore): Promise<void>;
571599

572600
// @public
573-
export function where(fieldPath: string | FieldPath, opStr: WhereFilterOp, value: unknown): QueryConstraint;
601+
export function where(fieldPath: string | FieldPath, opStr: WhereFilterOp, value: unknown): QueryFieldFilterConstraint;
574602

575603
// @public
576604
export type WhereFilterOp = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'array-contains' | 'in' | 'array-contains-any' | 'not-in';

packages/firestore/lite/index.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,29 @@ export {
6868
} from '../src/lite-api/reference';
6969

7070
export {
71+
and,
7172
endAt,
7273
endBefore,
7374
startAt,
7475
startAfter,
7576
limit,
7677
limitToLast,
77-
orderBy,
78-
OrderByDirection,
7978
where,
80-
WhereFilterOp,
79+
or,
80+
orderBy,
8181
query,
8282
QueryConstraint,
83-
QueryConstraintType
83+
QueryConstraintType,
84+
QueryCompositeFilterConstraint,
85+
QueryFilterConstraint,
86+
QueryFieldFilterConstraint,
87+
QueryOrderByConstraint,
88+
QueryLimitConstraint,
89+
QueryNonFilterConstraint,
90+
QueryStartAtConstraint,
91+
QueryEndAtConstraint,
92+
OrderByDirection,
93+
WhereFilterOp
8494
} from '../src/lite-api/query';
8595

8696
export {

packages/firestore/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
"test:all:ci": "run-p test:browser test:lite:browser test:travis",
3131
"test:all": "run-p test:browser test:lite:browser test:travis test:minified",
3232
"test:browser": "karma start --single-run",
33+
"test:browser:emulator:debug": "karma start --browsers=Chrome --local",
34+
"test:browser:emulator": "karma start --single-run --local",
3335
"test:browser:unit": "karma start --single-run --unit",
3436
"test:browser:debug": "karma start --browsers=Chrome --auto-watch",
3537
"test:node": "node ./scripts/run-tests.js --main=test/register.ts --emulator 'test/{,!(browser|lite)/**/}*.test.ts'",

packages/firestore/src/api.ts

+10
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,27 @@ export {
8585
} from './api/reference';
8686

8787
export {
88+
and,
8889
endAt,
8990
endBefore,
9091
startAt,
9192
startAfter,
9293
limit,
9394
limitToLast,
9495
where,
96+
or,
9597
orderBy,
9698
query,
9799
QueryConstraint,
98100
QueryConstraintType,
101+
QueryCompositeFilterConstraint,
102+
QueryFilterConstraint,
103+
QueryFieldFilterConstraint,
104+
QueryOrderByConstraint,
105+
QueryLimitConstraint,
106+
QueryNonFilterConstraint,
107+
QueryStartAtConstraint,
108+
QueryEndAtConstraint,
99109
OrderByDirection,
100110
WhereFilterOp
101111
} from './api/filter';

packages/firestore/src/api/filter.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,27 @@
1616
*/
1717

1818
export {
19+
and,
1920
endAt,
2021
endBefore,
2122
startAfter,
2223
startAt,
2324
limitToLast,
2425
limit,
26+
or,
2527
orderBy,
2628
OrderByDirection,
2729
where,
2830
WhereFilterOp,
2931
query,
32+
QueryCompositeFilterConstraint,
3033
QueryConstraint,
31-
QueryConstraintType
34+
QueryConstraintType,
35+
QueryFilterConstraint,
36+
QueryFieldFilterConstraint,
37+
QueryOrderByConstraint,
38+
QueryLimitConstraint,
39+
QueryStartAtConstraint,
40+
QueryEndAtConstraint,
41+
QueryNonFilterConstraint
3242
} from '../lite-api/query';

0 commit comments

Comments
 (0)