|
16 | 16 | */
|
17 | 17 |
|
18 | 18 | import { Code, FirestoreError } from '../util/error';
|
| 19 | +// API extractor fails importing 'property' unless we also explicitly import 'Property'. |
| 20 | +// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports-ts |
| 21 | +import { Property, property, validateJSON } from '../util/json_validation'; |
19 | 22 | import { primitiveComparator } from '../util/misc';
|
20 | 23 |
|
21 | 24 | /**
|
@@ -90,52 +93,30 @@ export class GeoPoint {
|
90 | 93 | );
|
91 | 94 | }
|
92 | 95 |
|
| 96 | + static _jsonSchemaVersion: string = 'firestore/geoPoint/1.0'; |
| 97 | + static _jsonSchema = { |
| 98 | + type: property('string', GeoPoint._jsonSchemaVersion), |
| 99 | + latitude: property('number'), |
| 100 | + longitude: property('number') |
| 101 | + }; |
| 102 | + |
93 | 103 | /** Returns a JSON-serializable representation of this GeoPoint. */
|
94 | 104 | toJSON(): { latitude: number; longitude: number; type: string } {
|
95 | 105 | return {
|
96 | 106 | latitude: this._lat,
|
97 | 107 | longitude: this._long,
|
98 |
| - type: 'firestore/geopoint/1.0' |
| 108 | + type: GeoPoint._jsonSchemaVersion |
99 | 109 | };
|
100 | 110 | }
|
101 | 111 |
|
102 | 112 | /** Builds a `Timestamp` instance from a JSON serialized version of `Bytes`. */
|
103 | 113 | static fromJSON(json: object): GeoPoint {
|
104 |
| - const requiredFields = ['type', 'latitude', 'longitude']; |
105 |
| - let error: string | undefined = undefined; |
106 |
| - let lat: number = 0; |
107 |
| - let long: number = 0; |
108 |
| - for (const key of requiredFields) { |
109 |
| - if (!(key in json)) { |
110 |
| - error = `json missing required field: ${key}`; |
111 |
| - } |
112 |
| - // eslint-disable-next-line @typescript-eslint/no-explicit-any |
113 |
| - const value = (json as any)[key]; |
114 |
| - if (key === 'type') { |
115 |
| - if (typeof value !== 'string') { |
116 |
| - error = `json field 'type' must be a string.`; |
117 |
| - break; |
118 |
| - } else if (value !== 'firestore/geopoint/1.0') { |
119 |
| - error = "Expected 'type' field to equal 'firestore/geopoint/1.0'"; |
120 |
| - break; |
121 |
| - } |
122 |
| - } else if (key === 'latitude') { |
123 |
| - if (typeof value !== 'number') { |
124 |
| - error = `json field 'latitude' must be a number.`; |
125 |
| - break; |
126 |
| - } |
127 |
| - lat = value; |
128 |
| - } else { |
129 |
| - if (typeof value !== 'number') { |
130 |
| - error = `json field 'longitude' must be a string.`; |
131 |
| - break; |
132 |
| - } |
133 |
| - long = value; |
134 |
| - } |
135 |
| - } |
136 |
| - if (error) { |
137 |
| - throw new FirestoreError(Code.INVALID_ARGUMENT, error); |
| 114 | + if (validateJSON(json, GeoPoint._jsonSchema)) { |
| 115 | + return new GeoPoint(json.latitude, json.longitude); |
138 | 116 | }
|
139 |
| - return new GeoPoint(lat, long); |
| 117 | + throw new FirestoreError( |
| 118 | + Code.INTERNAL, |
| 119 | + 'Unexpected error creating GeoPoint from JSON.' |
| 120 | + ); |
140 | 121 | }
|
141 | 122 | }
|
0 commit comments