|
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