|
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 | // The earliest date supported by Firestore timestamps (0001-01-01T00:00:00Z). |
@@ -174,53 +177,31 @@ export class Timestamp { |
174 | 177 | ); |
175 | 178 | } |
176 | 179 |
|
| 180 | + static _jsonSchemaVersion: string = 'firestore/timestamp/1.0'; |
| 181 | + static _jsonSchema = { |
| 182 | + type: property('string', Timestamp._jsonSchemaVersion), |
| 183 | + seconds: property('number'), |
| 184 | + nanoseconds: property('number') |
| 185 | + }; |
| 186 | + |
177 | 187 | /** Returns a JSON-serializable representation of this `Timestamp`. */ |
178 | 188 | toJSON(): { seconds: number; nanoseconds: number; type: string } { |
179 | 189 | return { |
| 190 | + type: Timestamp._jsonSchemaVersion, |
180 | 191 | seconds: this.seconds, |
181 | | - nanoseconds: this.nanoseconds, |
182 | | - type: 'firestore/timestamp/1.0' |
| 192 | + nanoseconds: this.nanoseconds |
183 | 193 | }; |
184 | 194 | } |
185 | 195 |
|
186 | 196 | /** Builds a `Timestamp` instance from a JSON serialized version of `Bytes`. */ |
187 | 197 | static fromJSON(json: object): Timestamp { |
188 | | - const requiredFields = ['type', 'seconds', 'nanoseconds']; |
189 | | - let error: string | undefined = undefined; |
190 | | - let seconds: number = 0; |
191 | | - let nanoseconds: number = 0; |
192 | | - for (const key of requiredFields) { |
193 | | - if (!(key in json)) { |
194 | | - error = `json missing required field: ${key}`; |
195 | | - } |
196 | | - // eslint-disable-next-line @typescript-eslint/no-explicit-any |
197 | | - const value = (json as any)[key]; |
198 | | - if (key === 'type') { |
199 | | - if (typeof value !== 'string') { |
200 | | - error = `json field 'type' must be a string.`; |
201 | | - break; |
202 | | - } else if (value !== 'firestore/timestamp/1.0') { |
203 | | - error = "Expected 'type' field to equal 'firestore/timestamp/1.0'"; |
204 | | - break; |
205 | | - } |
206 | | - } else if (key === 'seconds') { |
207 | | - if (typeof value !== 'number') { |
208 | | - error = `json field 'seconds' must be a number.`; |
209 | | - break; |
210 | | - } |
211 | | - seconds = value; |
212 | | - } else { |
213 | | - if (typeof value !== 'number') { |
214 | | - error = `json field 'nanoseconds' must be a number.`; |
215 | | - break; |
216 | | - } |
217 | | - nanoseconds = value; |
218 | | - } |
219 | | - } |
220 | | - if (error) { |
221 | | - throw new FirestoreError(Code.INVALID_ARGUMENT, error); |
| 198 | + if (validateJSON(json, Timestamp._jsonSchema)) { |
| 199 | + return new Timestamp(json.seconds, json.nanoseconds); |
222 | 200 | } |
223 | | - return new Timestamp(seconds, nanoseconds); |
| 201 | + throw new FirestoreError( |
| 202 | + Code.INTERNAL, |
| 203 | + 'Unexpected error creating Timestamp from JSON.' |
| 204 | + ); |
224 | 205 | } |
225 | 206 |
|
226 | 207 | /** |
|
0 commit comments