Skip to content

Commit a5fb4d7

Browse files
Make FieldPath a Compat class
1 parent 4c4b2d1 commit a5fb4d7

File tree

7 files changed

+152
-159
lines changed

7 files changed

+152
-159
lines changed

packages/firestore/exp/test/shim.ts

Lines changed: 36 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,10 @@ import * as exp from '../index';
2323

2424
import {
2525
addDoc,
26-
arrayRemove,
27-
arrayUnion,
2826
clearIndexedDbPersistence,
2927
collection,
3028
collectionGroup,
3129
deleteDoc,
32-
deleteField,
3330
disableNetwork,
3431
doc,
3532
DocumentReference as DocumentReferenceExp,
@@ -43,15 +40,13 @@ import {
4340
getDocs,
4441
getDocsFromCache,
4542
getDocsFromServer,
46-
increment,
4743
initializeFirestore,
4844
onSnapshot,
4945
onSnapshotsInSync,
5046
query,
5147
queryEqual,
5248
refEqual,
5349
runTransaction,
54-
serverTimestamp,
5550
setDoc,
5651
snapshotEqual,
5752
terminate,
@@ -71,18 +66,20 @@ import {
7166
import { UntypedFirestoreDataConverter } from '../../src/api/user_data_reader';
7267
import { isPartialObserver, PartialObserver } from '../../src/api/observer';
7368
import { isPlainObject } from '../../src/util/input_validation';
69+
import { Compat } from '../../src/compat/compat';
7470

7571
export { GeoPoint, Timestamp } from '../index';
72+
export { FieldValue } from '../../src/compat/field_value';
7673

7774
/* eslint-disable @typescript-eslint/no-explicit-any */
7875

7976
// This module defines a shim layer that implements the legacy API on top
8077
// of the experimental SDK. This shim is used to run integration tests against
8178
// both SDK versions.
8279

83-
export class FirebaseApp implements FirebaseAppLegacy {
84-
constructor(readonly _delegate: FirebaseAppExp) {}
85-
80+
export class FirebaseApp
81+
extends Compat<FirebaseAppExp>
82+
implements FirebaseAppLegacy {
8683
name = this._delegate.name;
8784
options = this._delegate.options;
8885
automaticDataCollectionEnabled = this._delegate
@@ -93,9 +90,9 @@ export class FirebaseApp implements FirebaseAppLegacy {
9390
}
9491
}
9592

96-
export class FirebaseFirestore implements legacy.FirebaseFirestore {
97-
constructor(private readonly _delegate: exp.FirebaseFirestore) {}
98-
93+
export class FirebaseFirestore
94+
extends Compat<exp.FirebaseFirestore>
95+
implements legacy.FirebaseFirestore {
9996
app = new FirebaseApp(this._delegate.app);
10097

10198
settings(settings: legacy.Settings): void {
@@ -170,11 +167,15 @@ export class FirebaseFirestore implements legacy.FirebaseFirestore {
170167
};
171168
}
172169

173-
export class Transaction implements legacy.Transaction {
170+
export class Transaction
171+
extends Compat<exp.Transaction>
172+
implements legacy.Transaction {
174173
constructor(
175174
private readonly _firestore: FirebaseFirestore,
176-
private readonly _delegate: exp.Transaction
177-
) {}
175+
private readonly delegate: exp.Transaction
176+
) {
177+
super(delegate);
178+
}
178179

179180
get<T>(documentRef: DocumentReference<T>): Promise<DocumentSnapshot<T>> {
180181
return this._delegate
@@ -231,9 +232,9 @@ export class Transaction implements legacy.Transaction {
231232
}
232233
}
233234

234-
export class WriteBatch implements legacy.WriteBatch {
235-
constructor(private readonly _delegate: exp.WriteBatch) {}
236-
235+
export class WriteBatch
236+
extends Compat<exp.WriteBatch>
237+
implements legacy.WriteBatch {
237238
set<T>(
238239
documentRef: DocumentReference<T>,
239240
data: T,
@@ -288,11 +289,14 @@ export class WriteBatch implements legacy.WriteBatch {
288289
}
289290

290291
export class DocumentReference<T = legacy.DocumentData>
292+
extends Compat<exp.DocumentReference<T>>
291293
implements legacy.DocumentReference<T> {
292294
constructor(
293295
readonly firestore: FirebaseFirestore,
294-
readonly _delegate: exp.DocumentReference<T>
295-
) {}
296+
delegate: exp.DocumentReference<T>
297+
) {
298+
super(delegate);
299+
}
296300

297301
readonly id = this._delegate.id;
298302
readonly path = this._delegate.path;
@@ -407,11 +411,14 @@ export class DocumentReference<T = legacy.DocumentData>
407411
}
408412

409413
export class DocumentSnapshot<T = legacy.DocumentData>
414+
extends Compat<exp.DocumentSnapshot<T>>
410415
implements legacy.DocumentSnapshot<T> {
411416
constructor(
412417
private readonly _firestore: FirebaseFirestore,
413-
readonly _delegate: exp.DocumentSnapshot<T>
414-
) {}
418+
delegate: exp.DocumentSnapshot<T>
419+
) {
420+
super(delegate);
421+
}
415422

416423
readonly ref = new DocumentReference<T>(this._firestore, this._delegate.ref);
417424
readonly id = this._delegate.id;
@@ -449,11 +456,12 @@ export class QueryDocumentSnapshot<T = legacy.DocumentData>
449456
}
450457
}
451458

452-
export class Query<T = legacy.DocumentData> implements legacy.Query<T> {
453-
constructor(
454-
readonly firestore: FirebaseFirestore,
455-
readonly _delegate: exp.Query<T>
456-
) {}
459+
export class Query<T = legacy.DocumentData>
460+
extends Compat<exp.Query<T>>
461+
implements legacy.Query<T> {
462+
constructor(readonly firestore: FirebaseFirestore, delegate: exp.Query<T>) {
463+
super(delegate);
464+
}
457465

458466
where(
459467
fieldPath: string | FieldPath,
@@ -680,34 +688,6 @@ export class CollectionReference<T = legacy.DocumentData>
680688
}
681689
}
682690

683-
export class FieldValue implements legacy.FieldValue {
684-
constructor(readonly _delegate: exp.FieldValue) {}
685-
686-
static serverTimestamp(): FieldValue {
687-
return new FieldValue(serverTimestamp());
688-
}
689-
690-
static delete(): FieldValue {
691-
return new FieldValue(deleteField());
692-
}
693-
694-
static arrayUnion(...elements: any[]): FieldValue {
695-
return new FieldValue(arrayUnion(...unwrap(elements)));
696-
}
697-
698-
static arrayRemove(...elements: any[]): FieldValue {
699-
return new FieldValue(arrayRemove(...unwrap(elements)));
700-
}
701-
702-
static increment(n: number): FieldValue {
703-
return new FieldValue(increment(n));
704-
}
705-
706-
isEqual(other: FieldValue): boolean {
707-
return this._delegate.isEqual(other._delegate);
708-
}
709-
}
710-
711691
export class FieldPath implements legacy.FieldPath {
712692
private readonly fieldNames: string[];
713693

@@ -728,9 +708,7 @@ export class FieldPath implements legacy.FieldPath {
728708
}
729709
}
730710

731-
export class Blob implements legacy.Blob {
732-
constructor(readonly _delegate: BytesExp) {}
733-
711+
export class Blob extends Compat<BytesExp> implements legacy.Blob {
734712
static fromBase64String(base64: string): Blob {
735713
return new Blob(BytesExp.fromBase64String(base64));
736714
}
@@ -790,17 +768,7 @@ function wrap(value: any): any {
790768
function unwrap(value: any): any {
791769
if (Array.isArray(value)) {
792770
return value.map(v => unwrap(v));
793-
} else if (value instanceof FieldPath) {
794-
return value._delegate;
795-
} else if (value instanceof FieldValue) {
796-
return value._delegate;
797-
} else if (value instanceof Blob) {
798-
return value._delegate;
799-
} else if (value instanceof DocumentReference) {
800-
return value._delegate;
801-
} else if (value instanceof DocumentSnapshot) {
802-
return value._delegate;
803-
} else if (value instanceof QueryDocumentSnapshot) {
771+
} else if (value instanceof Compat) {
804772
return value._delegate;
805773
} else if (isPlainObject(value)) {
806774
const obj: any = {};

packages/firestore/src/api/field_value.ts

Lines changed: 5 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@
1515
* limitations under the License.
1616
*/
1717

18-
import { FieldValue as PublicFieldValue } from '@firebase/firestore-types';
19-
import {
20-
validateArgType,
21-
validateAtLeastNumberOfArgs,
22-
validateExactNumberOfArgs,
23-
validateNoArgs
24-
} from '../util/input_validation';
2518
import { FieldTransform } from '../model/mutation';
2619
import {
2720
ArrayRemoveTransformOperation,
@@ -81,7 +74,7 @@ export class DeleteFieldValueImpl extends _SerializableFieldValue {
8174
return null;
8275
}
8376

84-
isEqual(other: FieldValue): boolean {
77+
isEqual(other: DeleteFieldValueImpl): boolean {
8578
return other instanceof DeleteFieldValueImpl;
8679
}
8780
}
@@ -129,7 +122,7 @@ export class ServerTimestampFieldValueImpl extends _SerializableFieldValue {
129122
return new FieldTransform(context.path!, new ServerTimestampTransform());
130123
}
131124

132-
isEqual(other: FieldValue): boolean {
125+
isEqual(other: ServerTimestampFieldValueImpl): boolean {
133126
return other instanceof ServerTimestampFieldValueImpl;
134127
}
135128
}
@@ -155,7 +148,7 @@ export class ArrayUnionFieldValueImpl extends _SerializableFieldValue {
155148
return new FieldTransform(context.path!, arrayUnion);
156149
}
157150

158-
isEqual(other: FieldValue): boolean {
151+
isEqual(other: ArrayUnionFieldValueImpl): boolean {
159152
// TODO(mrschmidt): Implement isEquals
160153
return this === other;
161154
}
@@ -179,7 +172,7 @@ export class ArrayRemoveFieldValueImpl extends _SerializableFieldValue {
179172
return new FieldTransform(context.path!, arrayUnion);
180173
}
181174

182-
isEqual(other: FieldValue): boolean {
175+
isEqual(other: ArrayRemoveFieldValueImpl): boolean {
183176
// TODO(mrschmidt): Implement isEquals
184177
return this === other;
185178
}
@@ -198,86 +191,8 @@ export class NumericIncrementFieldValueImpl extends _SerializableFieldValue {
198191
return new FieldTransform(context.path!, numericIncrement);
199192
}
200193

201-
isEqual(other: FieldValue): boolean {
194+
isEqual(other: NumericIncrementFieldValueImpl): boolean {
202195
// TODO(mrschmidt): Implement isEquals
203196
return this === other;
204197
}
205198
}
206-
207-
/** The public FieldValue class of the lite API. */
208-
export abstract class FieldValue
209-
extends _SerializableFieldValue
210-
implements PublicFieldValue {
211-
protected constructor() {
212-
super();
213-
}
214-
215-
static delete(): PublicFieldValue {
216-
validateNoArgs('FieldValue.delete', arguments);
217-
return new FieldValueDelegate(
218-
new DeleteFieldValueImpl('FieldValue.delete')
219-
);
220-
}
221-
222-
static serverTimestamp(): PublicFieldValue {
223-
validateNoArgs('FieldValue.serverTimestamp', arguments);
224-
return new FieldValueDelegate(
225-
new ServerTimestampFieldValueImpl('FieldValue.serverTimestamp')
226-
);
227-
}
228-
229-
static arrayUnion(...elements: unknown[]): PublicFieldValue {
230-
validateAtLeastNumberOfArgs('FieldValue.arrayUnion', arguments, 1);
231-
// NOTE: We don't actually parse the data until it's used in set() or
232-
// update() since we'd need the Firestore instance to do this.
233-
return new FieldValueDelegate(
234-
new ArrayUnionFieldValueImpl('FieldValue.arrayUnion', elements)
235-
);
236-
}
237-
238-
static arrayRemove(...elements: unknown[]): PublicFieldValue {
239-
validateAtLeastNumberOfArgs('FieldValue.arrayRemove', arguments, 1);
240-
// NOTE: We don't actually parse the data until it's used in set() or
241-
// update() since we'd need the Firestore instance to do this.
242-
return new FieldValueDelegate(
243-
new ArrayRemoveFieldValueImpl('FieldValue.arrayRemove', elements)
244-
);
245-
}
246-
247-
static increment(n: number): PublicFieldValue {
248-
validateArgType('FieldValue.increment', 'number', 1, n);
249-
validateExactNumberOfArgs('FieldValue.increment', arguments, 1);
250-
return new FieldValueDelegate(
251-
new NumericIncrementFieldValueImpl('FieldValue.increment', n)
252-
);
253-
}
254-
}
255-
256-
/**
257-
* A delegate class that allows the FieldValue implementations returned by
258-
* deleteField(), serverTimestamp(), arrayUnion(), arrayRemove() and
259-
* increment() to be an instance of the legacy FieldValue class declared above.
260-
*
261-
* We don't directly subclass `FieldValue` in the various field value
262-
* implementations as the base FieldValue class differs between the lite, full
263-
* and legacy SDK.
264-
*/
265-
class FieldValueDelegate extends FieldValue implements PublicFieldValue {
266-
readonly _methodName: string;
267-
268-
constructor(readonly _delegate: _SerializableFieldValue) {
269-
super();
270-
this._methodName = _delegate._methodName;
271-
}
272-
273-
_toFieldTransform(context: ParseContext): FieldTransform | null {
274-
return this._delegate._toFieldTransform(context);
275-
}
276-
277-
isEqual(other: PublicFieldValue): boolean {
278-
if (!(other instanceof FieldValueDelegate)) {
279-
return false;
280-
}
281-
return this._delegate.isEqual(other._delegate);
282-
}
283-
}

packages/firestore/src/api/user_data_reader.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { DeleteFieldValueImpl, _SerializableFieldValue } from './field_value';
5151
import { GeoPoint } from './geo_point';
5252
import { newSerializer } from '../platform/serializer';
5353
import { Bytes } from '../../lite/src/api/bytes';
54+
import { Compat } from '../compat/compat';
5455

5556
const RESERVED_FIELD_REGEX = /^__.*__$/;
5657

@@ -566,6 +567,12 @@ export function parseData(
566567
input: unknown,
567568
context: ParseContext
568569
): ProtoValue | null {
570+
// Unwrap the API type from the Compat SDK. This will return the API type
571+
// from firestore-exp.
572+
if (input instanceof Compat) {
573+
input = input._delegate;
574+
}
575+
569576
if (looksLikeJsonObject(input)) {
570577
validatePlainObject('Unsupported field value:', context, input);
571578
return parseObject(input, context);

0 commit comments

Comments
 (0)