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
							 | 
						||
| 
								 | 
							
								}
							 |