Skip to content

Commit 51bc4bc

Browse files
committed
Use jsonSchemas
1 parent fccd633 commit 51bc4bc

File tree

1 file changed

+48
-64
lines changed

1 file changed

+48
-64
lines changed

packages/firestore/src/api/snapshot.ts

Lines changed: 48 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,14 @@ export class DocumentSnapshot<
513513
return undefined;
514514
}
515515

516+
static _jsonSchemaVersion: string = 'firestore/documentSnapshot/1.0';
517+
static _jsonSchema = {
518+
type: property('string', DocumentSnapshot._jsonSchemaVersion),
519+
bundleSource: property('string', 'DocumentSnapshot'),
520+
bundleName: property('string'),
521+
bundle: property('string')
522+
};
523+
516524
/**
517525
* Returns a JSON-serializable representation of this `DocumentSnapshot` instance.
518526
*
@@ -522,6 +530,7 @@ export class DocumentSnapshot<
522530
const document = this._document;
523531
// eslint-disable-next-line @typescript-eslint/no-explicit-any
524532
const result: any = {};
533+
result['type'] = DocumentSnapshot._jsonSchemaVersion;
525534
result['bundle'] = '';
526535
result['bundleSource'] = 'DocumentSnapshot';
527536
result['bundleName'] = this._key.toString();
@@ -577,68 +586,47 @@ export class DocumentSnapshot<
577586
json: object,
578587
converter: FirestoreDataConverter<AppModelType, DbModelType>
579588
): DocumentSnapshot<AppModelType, DbModelType> {
580-
const requiredFields = ['bundle', 'bundleName', 'bundleSource'];
581-
let error: string | undefined = undefined;
582-
let bundleString: string = '';
583-
for (const key of requiredFields) {
584-
if (!(key in json)) {
585-
error = `json missing required field: ${key}`;
589+
if (validateJSON(json, DocumentSnapshot._jsonSchema)) {
590+
let error : string | undefined = undefined;
591+
// Parse the bundle data.
592+
const serializer = newSerializer(db._databaseId);
593+
const elements = createBundleReaderSync(
594+
json.bundle,
595+
serializer
596+
).getElements();
597+
if (elements.length === 0) {
598+
error = 'No snapshat data was found in the bundle.';
599+
} else if (
600+
elements.length !== 2 ||
601+
!elements[0].payload.documentMetadata ||
602+
!elements[1].payload.document
603+
) {
604+
error =
605+
'DocumentSnapshot bundle data must contain one metadata and then one document.';
586606
}
587-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
588-
const value = (json as any)[key];
589-
if (key === 'bundleSource') {
590-
if (typeof value !== 'string') {
591-
error = `json field 'bundleSource' must be a string.`;
592-
break;
593-
} else if (value !== 'DocumentSnapshot') {
594-
error = "Expected 'bundleSource' field to equal 'DocumentSnapshot'";
595-
break;
596-
}
597-
} else if (key === 'bundle') {
598-
if (typeof value !== 'string') {
599-
error = `json field 'bundle' must be a string.`;
600-
break;
601-
}
602-
bundleString = value;
607+
if (error) {
608+
throw new FirestoreError(Code.INVALID_ARGUMENT, error);
603609
}
610+
// convert bundle data into the types that the DocumentSnapshot constructore requires.
611+
const bundleConverter = new BundleConverterImpl(serializer);
612+
const documentSnapshotData =
613+
bundleConverter.toDocumentSnapshotData(elements);
614+
const liteUserDataWriter = new LiteUserDataWriter(db);
615+
return new DocumentSnapshot(
616+
db,
617+
liteUserDataWriter,
618+
documentSnapshotData.documentKey,
619+
documentSnapshotData.mutableDoc,
620+
new SnapshotMetadata(
621+
/* hasPendingWrites= */ false,
622+
/* fromCache= */ false
623+
),
624+
converter
625+
);
604626
}
605-
if (error) {
606-
throw new FirestoreError(Code.INVALID_ARGUMENT, error);
607-
}
608-
// Parse the bundle data.
609-
const serializer = newSerializer(db._databaseId);
610-
const elements = createBundleReaderSync(
611-
bundleString,
612-
serializer
613-
).getElements();
614-
if (elements.length === 0) {
615-
error = 'No snapshat data was found in the bundle.';
616-
} else if (
617-
elements.length !== 2 ||
618-
!elements[0].payload.documentMetadata ||
619-
!elements[1].payload.document
620-
) {
621-
error =
622-
'DocumentSnapshot bundle data must contain one metadata and then one document.';
623-
}
624-
if (error) {
625-
throw new FirestoreError(Code.INVALID_ARGUMENT, error);
626-
}
627-
// convert bundle data into the types that the DocumentSnapshot constructore requires.
628-
const bundleConverter = new BundleConverterImpl(serializer);
629-
const documentSnapshotData =
630-
bundleConverter.toDocumentSnapshotData(elements);
631-
const liteUserDataWriter = new LiteUserDataWriter(db);
632-
return new DocumentSnapshot(
633-
db,
634-
liteUserDataWriter,
635-
documentSnapshotData.documentKey,
636-
documentSnapshotData.mutableDoc,
637-
new SnapshotMetadata(
638-
/* hasPendingWrites= */ false,
639-
/* fromCache= */ false
640-
),
641-
converter
627+
throw new FirestoreError(
628+
Code.INTERNAL,
629+
'Unexpected error creating DocumentSnapshot from JSON.'
642630
);
643631
}
644632
}
@@ -800,7 +788,7 @@ export class QuerySnapshot<
800788
static _jsonSchemaVersion: string = 'firestore/querySnapshot/1.0';
801789
static _jsonSchema = {
802790
type: property('string', QuerySnapshot._jsonSchemaVersion),
803-
bundleSource: property('string'),
791+
bundleSource: property('string', 'QuerySnapshot'),
804792
bundleName: property('string'),
805793
bundle: property('string')
806794
};
@@ -877,9 +865,6 @@ export class QuerySnapshot<
877865
json: object
878866
): QuerySnapshot<AppModelType, DbModelType> | null {
879867
if (validateJSON(json, QuerySnapshot._jsonSchema)) {
880-
if (json.bundleSource !== 'QuerySnapshot') {
881-
throw new FirestoreError(Code.INVALID_ARGUMENT, "Expected 'bundleSource' field to equal 'QuerySnapshot'");
882-
}
883868
// Parse the bundle data.
884869
const serializer = newSerializer(db._databaseId);
885870
const bundleReader = createBundleReaderSync(json.bundle, serializer);
@@ -935,7 +920,6 @@ export class QuerySnapshot<
935920
viewSnapshot
936921
);
937922
}
938-
939923
throw new FirestoreError(
940924
Code.INTERNAL,
941925
'Unexpected error creating QuerySnapshot from JSON.'

0 commit comments

Comments
 (0)