This commit is contained in:
eric sciple 2020-01-24 12:20:19 -05:00
parent beb1329f9f
commit 2b95e76931
7736 changed files with 1874747 additions and 51184 deletions

View file

@ -1,7 +1,7 @@
module.exports = octokitValidate
module.exports = octokitValidate;
const validate = require('./validate')
const validate = require("./validate");
function octokitValidate (octokit) {
octokit.hook.before('request', validate.bind(null, octokit))
function octokitValidate(octokit) {
octokit.hook.before("request", validate.bind(null, octokit));
}

View file

@ -1,113 +1,151 @@
'use strict'
"use strict";
module.exports = validate
module.exports = validate;
const { RequestError } = require('@octokit/request-error')
const get = require('lodash.get')
const set = require('lodash.set')
const { RequestError } = require("@octokit/request-error");
const get = require("lodash.get");
const set = require("lodash.set");
function validate (octokit, options) {
function validate(octokit, options) {
if (!options.request.validate) {
return
return;
}
const { validate: params } = options.request
const { validate: params } = options.request;
Object.keys(params).forEach(parameterName => {
const parameter = get(params, parameterName)
const parameter = get(params, parameterName);
const expectedType = parameter.type
let parentParameterName
let parentValue
let parentParamIsPresent = true
let parentParameterIsArray = false
const expectedType = parameter.type;
let parentParameterName;
let parentValue;
let parentParamIsPresent = true;
let parentParameterIsArray = false;
if (/\./.test(parameterName)) {
parentParameterName = parameterName.replace(/\.[^.]+$/, '')
parentParameterIsArray = parentParameterName.slice(-2) === '[]'
parentParameterName = parameterName.replace(/\.[^.]+$/, "");
parentParameterIsArray = parentParameterName.slice(-2) === "[]";
if (parentParameterIsArray) {
parentParameterName = parentParameterName.slice(0, -2)
parentParameterName = parentParameterName.slice(0, -2);
}
parentValue = get(options, parentParameterName)
parentParamIsPresent = parentParameterName === 'headers' || (typeof parentValue === 'object' && parentValue !== null)
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)]
? (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 valueIsPresent = typeof value !== "undefined";
const valueIsNull = value === null;
const currentParameterName = parentParameterIsArray
? parameterName.replace(/\[\]/, `[${i}]`)
: parameterName
: parameterName;
if (!parameter.required && !valueIsPresent) {
return
return;
}
// if the parent parameter is of type object but allows null
// then the child parameters can be ignored
if (!parentParamIsPresent) {
return
return;
}
if (parameter.allowNull && valueIsNull) {
return
return;
}
if (!parameter.allowNull && valueIsNull) {
throw new RequestError(`'${currentParameterName}' cannot be null`, 400, {
request: options
})
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
})
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 (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
})
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.enum && parameter.enum.indexOf(String(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)
const regex = new RegExp(parameter.validation);
if (!regex.test(value)) {
throw new RequestError(`Invalid value for parameter '${currentParameterName}': ${JSON.stringify(value)}`, 400, {
request: options
})
throw new RequestError(
`Invalid value for parameter '${currentParameterName}': ${JSON.stringify(
value
)}`,
400,
{
request: options
}
);
}
}
if (expectedType === 'object' && typeof value === 'string') {
if (expectedType === "object" && typeof value === "string") {
try {
value = JSON.parse(value)
value = JSON.parse(value);
} catch (exception) {
throw new RequestError(`JSON parse error of value for parameter '${currentParameterName}': ${JSON.stringify(value)}`, 400, {
request: options
})
throw new RequestError(
`JSON parse error of value for parameter '${currentParameterName}': ${JSON.stringify(
value
)}`,
400,
{
request: options
}
);
}
}
set(options, parameter.mapTo || currentParameterName, value)
})
})
set(options, parameter.mapTo || currentParameterName, value);
});
});
return options
return options;
}