UNPKG

ran-boilerplate

Version:

React . Apollo (GraphQL) . Next.js Toolkit

145 lines (130 loc) 4.63 kB
/*! * Copyright 2017 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 'use strict'; const is = require('is'); /** * Formats the given word as plural conditionally given the preceding number. * * @private */ function formatPlural(num, str) { return `${num} ${str}` + (num === 1 ? '' : 's'); } /** * Provides argument validation for the Firestore Public API. Exposes validators * for strings, integers, numbers, objects and functions by default and can be * extended to provide custom validators. * * The exported validation functions follow the naming convention is{Type} and * isOptional{Type}, such as "isString" and "isOptionalString". * * To register custom validators, provide an object with a mapping from a type * name to a validation function. Validation functions return 'true' for valid * inputs and may throw errors with custom validation messages for easier * diagnosis. * * @param {Object.<string, function>} validators Mapping from types to * validator validators. * @returns {Object.<string, function>} Map with validators following the naming * convention is{Type} and isOptional{Type}. */ module.exports = validators => { validators = Object.assign( { function: is.function, integer: (value, min, max) => { min = is.defined(min) ? min : -Infinity; max = is.defined(max) ? max : Infinity; return is.integer(value) && value >= min && value <= max; }, number: (value, min, max) => { min = is.defined(min) ? min : -Infinity; max = is.defined(max) ? max : Infinity; return is.number(value) && value >= min && value <= max; }, object: is.object, string: is.string, }, validators ); let exports = {}; let register = type => { let camelCase = type.substring(0, 1).toUpperCase() + type.substring(1); exports[`is${camelCase}`] = function(argumentName, value) { let valid = false; let message = is.number(argumentName) ? `Argument at index ${argumentName} is not a valid ${type}.` : `Argument "${argumentName}" is not a valid ${type}.`; try { value = [].slice.call(arguments, 1); valid = validators[type].apply(null, value); } catch (err) { message += ` ${err.message}`; } if (valid !== true) { throw new Error(message); } }; exports[`isOptional${camelCase}`] = function(argumentName, value) { if (is.defined(value)) { exports[`is${camelCase}`].apply(null, arguments); } }; }; for (let type in validators) { if (validators.hasOwnProperty(type)) { register(type); } } /** * Verifies that 'args' has at least 'minSize' elements. * * @param {string} funcName - The function name to use in the error message. * @param {Array.<*>} args - The array (or array-like structure) to verify. * @param {number} minSize - The minimum number of elements to enforce. * @throws if the expectation is not met. * @returns {boolean} 'true' when the minimum number of elements is available. */ exports.minNumberOfArguments = (funcName, args, minSize) => { if (args.length < minSize) { throw new Error( `Function '${funcName}()' requires at least ` + `${formatPlural(minSize, 'argument')}.` ); } return true; }; /** * Verifies that 'args' has at most 'maxSize' elements. * * @param {string} funcName - The function name to use in the error message. * @param {Array.<*>} args - The array (or array-like structure) to verify. * @param {number} maxSize - The maximum number of elements to enforce. * @throws if the expectation is not met. * @returns {boolean} 'true' when only the maximum number of elements is * specified. */ exports.maxNumberOfArguments = (funcName, args, maxSize) => { if (args.length > maxSize) { throw new Error( `Function '${funcName}()' accepts at most ` + `${formatPlural(maxSize, 'argument')}.` ); } return true; }; return exports; };