114 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			114 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict' | ||
|  | 
 | ||
|  | module.exports = validate | ||
|  | 
 | ||
|  | const { RequestError } = require('@octokit/request-error') | ||
|  | const get = require('lodash.get') | ||
|  | const set = require('lodash.set') | ||
|  | 
 | ||
|  | function validate (octokit, options) { | ||
|  |   if (!options.request.validate) { | ||
|  |     return | ||
|  |   } | ||
|  |   const { validate: params } = options.request | ||
|  | 
 | ||
|  |   Object.keys(params).forEach(parameterName => { | ||
|  |     const parameter = get(params, parameterName) | ||
|  | 
 | ||
|  |     const expectedType = parameter.type | ||
|  |     let parentParameterName | ||
|  |     let parentValue | ||
|  |     let parentParamIsPresent = true | ||
|  |     let parentParameterIsArray = false | ||
|  | 
 | ||
|  |     if (/\./.test(parameterName)) { | ||
|  |       parentParameterName = parameterName.replace(/\.[^.]+$/, '') | ||
|  |       parentParameterIsArray = parentParameterName.slice(-2) === '[]' | ||
|  |       if (parentParameterIsArray) { | ||
|  |         parentParameterName = parentParameterName.slice(0, -2) | ||
|  |       } | ||
|  |       parentValue = get(options, parentParameterName) | ||
|  |       parentParamIsPresent = parentParameterName === 'headers' || (typeof parentValue === 'object' && parentValue !== null) | ||
|  |     } | ||
|  | 
 | ||
|  |     const values = parentParameterIsArray | ||
|  |       ? (get(options, parentParameterName) || []).map(value => value[parameterName.split(/\./).pop()]) | ||
|  |       : [get(options, parameterName)] | ||
|  | 
 | ||
|  |     values.forEach((value, i) => { | ||
|  |       const valueIsPresent = typeof value !== 'undefined' | ||
|  |       const valueIsNull = value === null | ||
|  |       const currentParameterName = parentParameterIsArray | ||
|  |         ? parameterName.replace(/\[\]/, `[${i}]`) | ||
|  |         : parameterName | ||
|  | 
 | ||
|  |       if (!parameter.required && !valueIsPresent) { | ||
|  |         return | ||
|  |       } | ||
|  | 
 | ||
|  |       // if the parent parameter is of type object but allows null
 | ||
|  |       // then the child parameters can be ignored
 | ||
|  |       if (!parentParamIsPresent) { | ||
|  |         return | ||
|  |       } | ||
|  | 
 | ||
|  |       if (parameter.allowNull && valueIsNull) { | ||
|  |         return | ||
|  |       } | ||
|  | 
 | ||
|  |       if (!parameter.allowNull && valueIsNull) { | ||
|  |         throw new RequestError(`'${currentParameterName}' cannot be null`, 400, { | ||
|  |           request: options | ||
|  |         }) | ||
|  |       } | ||
|  | 
 | ||
|  |       if (parameter.required && !valueIsPresent) { | ||
|  |         throw new RequestError(`Empty value for parameter '${currentParameterName}': ${JSON.stringify(value)}`, 400, { | ||
|  |           request: options | ||
|  |         }) | ||
|  |       } | ||
|  | 
 | ||
|  |       // parse to integer before checking for enum
 | ||
|  |       // so that string "1" will match enum with number 1
 | ||
|  |       if (expectedType === 'integer') { | ||
|  |         const unparsedValue = value | ||
|  |         value = parseInt(value, 10) | ||
|  |         if (isNaN(value)) { | ||
|  |           throw new RequestError(`Invalid value for parameter '${currentParameterName}': ${JSON.stringify(unparsedValue)} is NaN`, 400, { | ||
|  |             request: options | ||
|  |           }) | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       if (parameter.enum && parameter.enum.indexOf(value) === -1) { | ||
|  |         throw new RequestError(`Invalid value for parameter '${currentParameterName}': ${JSON.stringify(value)}`, 400, { | ||
|  |           request: options | ||
|  |         }) | ||
|  |       } | ||
|  | 
 | ||
|  |       if (parameter.validation) { | ||
|  |         const regex = new RegExp(parameter.validation) | ||
|  |         if (!regex.test(value)) { | ||
|  |           throw new RequestError(`Invalid value for parameter '${currentParameterName}': ${JSON.stringify(value)}`, 400, { | ||
|  |             request: options | ||
|  |           }) | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       if (expectedType === 'object' && typeof value === 'string') { | ||
|  |         try { | ||
|  |           value = JSON.parse(value) | ||
|  |         } catch (exception) { | ||
|  |           throw new RequestError(`JSON parse error of value for parameter '${currentParameterName}': ${JSON.stringify(value)}`, 400, { | ||
|  |             request: options | ||
|  |           }) | ||
|  |         } | ||
|  |       } | ||
|  | 
 | ||
|  |       set(options, parameter.mapTo || currentParameterName, value) | ||
|  |     }) | ||
|  |   }) | ||
|  | 
 | ||
|  |   return options | ||
|  | } |