mirror of https://github.com/actions/setup-node
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
|
||
|
}
|