1818import { FieldPath } from '../lite-api/field_path' ;
1919import { Timestamp } from '../lite-api/timestamp' ;
2020
21- /**
22- * Options to allow argument omission.
23- *
24- * @private
25- * @internal
26- */
27- export interface RequiredArgumentOptions {
28- optional ?: boolean ;
29- }
30-
31- /**
32- * Options to limit the range of numbers.
33- *
34- * @private
35- * @internal
36- */
37- export interface NumericRangeOptions {
38- minValue ?: number ;
39- maxValue ?: number ;
40- }
41-
42- /**
43- * Determines whether `value` is a JavaScript function.
44- *
45- * @private
46- * @internal
47- */
48- export function isFunction ( value : unknown ) : boolean {
49- return typeof value === 'function' ;
50- }
51-
52- /**
53- * Determines whether `value` is a JavaScript object.
54- *
55- * @private
56- * @internal
57- */
58- export function isObject ( value : unknown ) : value is { [ k : string ] : unknown } {
59- return Object . prototype . toString . call ( value ) === '[object Object]' ;
60- }
61-
62- /**
63- * Generates an error message to use with custom objects that cannot be
64- * serialized.
65- *
66- * @private
67- * @internal
68- * @param arg The argument name or argument index (for varargs methods).
69- * @param value The value that failed serialization.
70- * @param path The field path that the object is assigned to.
71- */
72- export function customObjectMessage (
73- arg : string | number ,
74- value : unknown ,
75- path ?: FieldPath
76- ) : string {
77- const fieldPathMessage = path ? ` (found in field "${ path } ")` : '' ;
78-
79- if ( isObject ( value ) ) {
80- // We use the base class name as the type name as the sentinel classes
81- // returned by the public FieldValue API are subclasses of FieldValue. By
82- // using the base name, we reduce the number of special cases below.
83- const typeName = value . constructor . name ;
84- switch ( typeName ) {
85- case 'DocumentReference' :
86- case 'FieldPath' :
87- case 'FieldValue' :
88- case 'GeoPoint' :
89- case 'Timestamp' :
90- return (
91- `${ invalidArgumentMessage (
92- arg ,
93- 'Firestore document'
94- ) } Detected an object of type "${ typeName } " that doesn't match the ` +
95- `expected instance${ fieldPathMessage } . Please ensure that the ` +
96- 'Firestore types you are using are from the same NPM package.)'
97- ) ;
98- case 'Object' :
99- return `${ invalidArgumentMessage (
100- arg ,
101- 'Firestore document'
102- ) } Invalid use of type "${ typeof value } " as a Firestore argument${ fieldPathMessage } .`;
103- default :
104- return (
105- `${ invalidArgumentMessage (
106- arg ,
107- 'Firestore document'
108- ) } Couldn't serialize object of type "${ typeName } "${ fieldPathMessage } . Firestore doesn't support JavaScript ` +
109- 'objects with custom prototypes (i.e. objects that were created ' +
110- 'via the "new" operator).'
111- ) ;
112- }
113- } else {
114- return `${ invalidArgumentMessage (
115- arg ,
116- 'Firestore document'
117- ) } Input is not a plain JavaScript object${ fieldPathMessage } .`;
118- }
119- }
120-
121- /**
122- * Validates that 'value' is a function.
123- *
124- * @private
125- * @internal
126- * @param arg The argument name or argument index (for varargs methods).
127- * @param value The input to validate.
128- * @param options Options that specify whether the function can be omitted.
129- */
130- export function validateFunction (
131- arg : string | number ,
132- value : unknown ,
133- options ?: RequiredArgumentOptions
134- ) : void {
135- if ( ! validateOptional ( value , options ) ) {
136- if ( ! isFunction ( value ) ) {
137- throw new Error ( invalidArgumentMessage ( arg , 'function' ) ) ;
138- }
139- }
140- }
141-
142- /**
143- * Validates that 'value' is an object.
144- *
145- * @private
146- * @internal
147- * @param arg The argument name or argument index (for varargs methods).
148- * @param value The input to validate.
149- * @param options Options that specify whether the object can be omitted.
150- */
151- export function validateObject (
152- arg : string | number ,
153- value : unknown ,
154- options ?: RequiredArgumentOptions
155- ) : void {
156- if ( ! validateOptional ( value , options ) ) {
157- if ( ! isObject ( value ) ) {
158- throw new Error ( invalidArgumentMessage ( arg , 'object' ) ) ;
159- }
160- }
161- }
162-
16321/**
16422 * Validates that 'value' is a string.
16523 *
@@ -171,161 +29,10 @@ export function validateObject(
17129 */
17230export function validateString (
17331 arg : string | number ,
174- value : unknown ,
175- options ?: RequiredArgumentOptions
176- ) : void {
177- if ( ! validateOptional ( value , options ) ) {
178- if ( typeof value !== 'string' ) {
179- throw new Error ( invalidArgumentMessage ( arg , 'string' ) ) ;
180- }
181- }
182- }
183-
184- /**
185- * Validates that 'value' is a host.
186- *
187- * @private
188- * @internal
189- * @param arg The argument name or argument index (for varargs methods).
190- * @param value The input to validate.
191- * @param options Options that specify whether the host can be omitted.
192- */
193- export function validateHost (
194- arg : string | number ,
195- value : unknown ,
196- options ?: RequiredArgumentOptions
197- ) : void {
198- if ( ! validateOptional ( value , options ) ) {
199- validateString ( arg , value ) ;
200- const urlString = `http://${ value } /` ;
201- let parsed ;
202- try {
203- parsed = new URL ( urlString ) ;
204- } catch ( e ) {
205- throw new Error ( invalidArgumentMessage ( arg , 'host' ) ) ;
206- }
207-
208- if (
209- parsed . search !== '' ||
210- parsed . pathname !== '/' ||
211- parsed . username !== ''
212- ) {
213- throw new Error ( invalidArgumentMessage ( arg , 'host' ) ) ;
214- }
215- }
216- }
217-
218- /**
219- * Validates that 'value' is a boolean.
220- *
221- * @private
222- * @internal
223- * @param arg The argument name or argument index (for varargs methods).
224- * @param value The input to validate.
225- * @param options Options that specify whether the boolean can be omitted.
226- */
227- export function validateBoolean (
228- arg : string | number ,
229- value : unknown ,
230- options ?: RequiredArgumentOptions
231- ) : void {
232- if ( ! validateOptional ( value , options ) ) {
233- if ( typeof value !== 'boolean' ) {
234- throw new Error ( invalidArgumentMessage ( arg , 'boolean' ) ) ;
235- }
236- }
237- }
238-
239- /**
240- * Validates that 'value' is a number.
241- *
242- * @private
243- * @internal
244- * @param arg The argument name or argument index (for varargs methods).
245- * @param value The input to validate.
246- * @param options Options that specify whether the number can be omitted.
247- */
248- export function validateNumber (
249- arg : string | number ,
250- value : unknown ,
251- options ?: RequiredArgumentOptions & NumericRangeOptions
32+ value : unknown
25233) : void {
253- const min =
254- options !== undefined && options . minValue !== undefined
255- ? options . minValue
256- : - Infinity ;
257- const max =
258- options !== undefined && options . maxValue !== undefined
259- ? options . maxValue
260- : Infinity ;
261-
262- if ( ! validateOptional ( value , options ) ) {
263- if ( typeof value !== 'number' || isNaN ( value ) ) {
264- throw new Error ( invalidArgumentMessage ( arg , 'number' ) ) ;
265- } else if ( value < min || value > max ) {
266- throw new Error (
267- `${ formatArgumentName (
268- arg
269- ) } must be within [${ min } , ${ max } ] inclusive, but was: ${ value } `
270- ) ;
271- }
272- }
273- }
274-
275- /**
276- * Validates that 'value' is a integer.
277- *
278- * @private
279- * @internal
280- * @param arg The argument name or argument index (for varargs methods).
281- * @param value The input to validate.
282- * @param options Options that specify whether the integer can be omitted.
283- */
284- export function validateInteger (
285- arg : string | number ,
286- value : unknown ,
287- options ?: RequiredArgumentOptions & NumericRangeOptions
288- ) : void {
289- const min =
290- options !== undefined && options . minValue !== undefined
291- ? options . minValue
292- : - Infinity ;
293- const max =
294- options !== undefined && options . maxValue !== undefined
295- ? options . maxValue
296- : Infinity ;
297-
298- if ( ! validateOptional ( value , options ) ) {
299- if ( typeof value !== 'number' || isNaN ( value ) || value % 1 !== 0 ) {
300- throw new Error ( invalidArgumentMessage ( arg , 'integer' ) ) ;
301- } else if ( value < min || value > max ) {
302- throw new Error (
303- `${ formatArgumentName (
304- arg
305- ) } must be within [${ min } , ${ max } ] inclusive, but was: ${ value } `
306- ) ;
307- }
308- }
309- }
310-
311- /**
312- * Validates that 'value' is a Timestamp.
313- *
314- * @private
315- * @internal
316- * @param arg The argument name or argument index (for varargs methods).
317- * @param value The input to validate.
318- * @param options Options that specify whether the Timestamp can be omitted.
319- */
320- export function validateTimestamp (
321- arg : string | number ,
322- value : unknown ,
323- options ?: RequiredArgumentOptions
324- ) : void {
325- if ( ! validateOptional ( value , options ) ) {
326- if ( ! ( value instanceof Timestamp ) ) {
327- throw new Error ( invalidArgumentMessage ( arg , 'Timestamp' ) ) ;
328- }
34+ if ( typeof value !== 'string' ) {
35+ throw new Error ( invalidArgumentMessage ( arg , 'string' ) ) ;
32936 }
33037}
33138
@@ -344,24 +51,6 @@ export function invalidArgumentMessage(
34451 return `${ formatArgumentName ( arg ) } is not a valid ${ expectedType } .` ;
34552}
34653
347- /**
348- * Enforces the 'options.optional' constraint for 'value'.
349- *
350- * @private
351- * @internal
352- * @param value The input to validate.
353- * @param options Whether the function can be omitted.
354- * @return Whether the object is omitted and is allowed to be omitted.
355- */
356- export function validateOptional (
357- value : unknown ,
358- options ?: RequiredArgumentOptions
359- ) : boolean {
360- return (
361- value === undefined && options !== undefined && options . optional === true
362- ) ;
363- }
364-
36554/**
36655 * Formats the given word as plural conditionally given the preceding number.
36756 *
@@ -432,38 +121,4 @@ export function validateMaxNumberOfArguments(
432121 `${ formatPlural ( maxSize , 'argument' ) } .`
433122 ) ;
434123 }
435- }
436-
437- /**
438- * Validates that the provided named option equals one of the expected values.
439- *
440- * @param arg The argument name or argument index (for varargs methods).).
441- * @param value The input to validate.
442- * @param allowedValues A list of expected values.
443- * @param options Whether the input can be omitted.
444- * @private
445- * @internal
446- */
447- export function validateEnumValue (
448- arg : string | number ,
449- value : unknown ,
450- allowedValues : string [ ] ,
451- options ?: RequiredArgumentOptions
452- ) : void {
453- if ( ! validateOptional ( value , options ) ) {
454- const expectedDescription : string [ ] = [ ] ;
455-
456- for ( const allowed of allowedValues ) {
457- if ( allowed === value ) {
458- return ;
459- }
460- expectedDescription . push ( allowed ) ;
461- }
462-
463- throw new Error (
464- `${ formatArgumentName (
465- arg
466- ) } is invalid. Acceptable values are: ${ expectedDescription . join ( ', ' ) } `
467- ) ;
468- }
469124}
0 commit comments