@qrvey/formula-lang
Version:
QFormula support for qrvey projects
87 lines • 3.7 kB
JavaScript
import { RESPONSE_LEVEL } from '../constants';
import { isNull } from '../utils/isNull';
import { validateParameters, FunctionArgumentsMismatch, ArgumentValidatorError, } from '../errors';
import { ERROR_DICTIONARY, ERROR_LIST } from '../errors/dictionary';
export function validateFuncStructure(definition, args, node) {
var _a, _b;
let parameterIndex = 0;
let argumentIndex = 0;
const parameters = definition.parameters || [];
const incrementCounter = () => {
parameterIndex += 1;
argumentIndex += 1;
};
const execValidators = [];
let invalidValidator = false;
let hasMismatch = false;
while (parameterIndex < parameters.length) {
const parameter = parameters[parameterIndex];
const { value, dataType } = (_a = args[argumentIndex]) !== null && _a !== void 0 ? _a : {};
if (isNull(value) && parameter.optional) {
incrementCounter();
continue;
}
if (isNull(value) && !parameter.optional) {
invalidValidator = true;
hasMismatch = true;
execValidators.push(Object.assign(Object.assign({ valid: false, source: RESPONSE_LEVEL.function }, ERROR_DICTIONARY[ERROR_LIST.missingArg]), { parameter,
argumentIndex }));
}
const validatorContext = {
fnNode: node,
argument: (_b = args[argumentIndex]) !== null && _b !== void 0 ? _b : {},
};
for (const validatorFunction of parameter.validator) {
const validator = validatorFunction(value, dataType, validatorContext);
execValidators.push(Object.assign(Object.assign({}, validator), { parameter,
argumentIndex }));
if (!validator.valid) {
if (validator.mismatchData && !hasMismatch)
hasMismatch = true;
if (!invalidValidator)
invalidValidator = true;
break;
}
}
incrementCounter();
const parameterListCompleted = parameterIndex === parameters.length;
const hasMoreArguments = argumentIndex < args.length;
const isRecursive = typeof (definition === null || definition === void 0 ? void 0 : definition.recursiveStartIn) === 'number';
if (parameterListCompleted && hasMoreArguments && isRecursive) {
parameterIndex = definition.recursiveStartIn;
}
}
if (invalidValidator) {
if (hasMismatch) {
throwFunctionMismatch(definition, args, node, {
validators: execValidators,
});
}
else {
const failedValidator = execValidators.find((val) => !val.valid);
if (failedValidator)
throwArgumentError(node, failedValidator);
}
}
if (argumentIndex < args.length) {
throwFunctionMismatch(definition, args, node, {
error: ERROR_LIST.tooManyArguments,
});
}
}
function throwFunctionMismatch(definition, args, node, validatorInfo, parameter) {
var _a;
const baseValidator = Object.assign({ valid: false, source: RESPONSE_LEVEL.function }, ERROR_DICTIONARY[(_a = validatorInfo.error) !== null && _a !== void 0 ? _a : ERROR_LIST.unknown]);
const { expected, received, validator } = validateParameters(definition, args, validatorInfo.validators);
throw new FunctionArgumentsMismatch({
node,
parameter,
validator: validator || baseValidator,
expected,
received,
});
}
function throwArgumentError(node, validator) {
throw new ArgumentValidatorError(node, validator);
}
//# sourceMappingURL=validateFuncStructure.js.map