2025-04-19 23:12:19 -04:00

446 lines
11 KiB
JavaScript

'use strict';
module.exports = function generate_custom(it, $keyword, $ruleType) {
var out = ' ';
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $errorKeyword;
var $data = 'data' + ($dataLvl || '');
var $valid = 'valid' + $lvl;
var $errs = 'errs__' + $lvl;
var $isData = it.opts.$data && $schema && $schema.$data,
$schemaValue;
if ($isData) {
out +=
' var schema' +
$lvl +
' = ' +
it.util.getData($schema.$data, $dataLvl, it.dataPathArr) +
'; ';
$schemaValue = 'schema' + $lvl;
} else {
$schemaValue = $schema;
}
var $rule = this,
$definition = 'definition' + $lvl,
$rDef = $rule.definition,
$closingBraces = '';
var $compile, $inline, $macro, $ruleValidate, $validateCode;
if ($isData && $rDef.$data) {
$validateCode = 'keywordValidate' + $lvl;
var $validateSchema = $rDef.validateSchema;
out +=
' var ' +
$definition +
" = RULES.custom['" +
$keyword +
"'].definition; var " +
$validateCode +
' = ' +
$definition +
'.validate;';
} else {
$ruleValidate = it.useCustomRule($rule, $schema, it.schema, it);
if (!$ruleValidate) return;
$schemaValue = 'validate.schema' + $schemaPath;
$validateCode = $ruleValidate.code;
$compile = $rDef.compile;
$inline = $rDef.inline;
$macro = $rDef.macro;
}
var $ruleErrs = $validateCode + '.errors',
$i = 'i' + $lvl,
$ruleErr = 'ruleErr' + $lvl,
$asyncKeyword = $rDef.async;
if ($asyncKeyword && !it.async)
throw new Error('async keyword in sync schema');
if (!($inline || $macro)) {
out += '' + $ruleErrs + ' = null;';
}
out += 'var ' + $errs + ' = errors;var ' + $valid + ';';
if ($isData && $rDef.$data) {
$closingBraces += '}';
out +=
' if (' +
$schemaValue +
' === undefined) { ' +
$valid +
' = true; } else { ';
if ($validateSchema) {
$closingBraces += '}';
out +=
' ' +
$valid +
' = ' +
$definition +
'.validateSchema(' +
$schemaValue +
'); if (' +
$valid +
') { ';
}
}
if ($inline) {
if ($rDef.statements) {
out += ' ' + $ruleValidate.validate + ' ';
} else {
out += ' ' + $valid + ' = ' + $ruleValidate.validate + '; ';
}
} else if ($macro) {
var $it = it.util.copy(it);
var $closingBraces = '';
$it.level++;
var $nextValid = 'valid' + $it.level;
$it.schema = $ruleValidate.validate;
$it.schemaPath = '';
var $wasComposite = it.compositeRule;
it.compositeRule = $it.compositeRule = true;
var $code = it.validate($it).replace(/validate\.schema/g, $validateCode);
it.compositeRule = $it.compositeRule = $wasComposite;
out += ' ' + $code;
} else {
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = '';
out += ' ' + $validateCode + '.call( ';
if (it.opts.passContext) {
out += 'this';
} else {
out += 'self';
}
if ($compile || $rDef.schema === false) {
out += ' , ' + $data + ' ';
} else {
out +=
' , ' +
$schemaValue +
' , ' +
$data +
' , validate.schema' +
it.schemaPath +
' ';
}
out += " , (dataPath || '')";
if (it.errorPath != '""') {
out += ' + ' + it.errorPath;
}
var $parentData = $dataLvl ? 'data' + ($dataLvl - 1 || '') : 'parentData',
$parentDataProperty =
$dataLvl ? it.dataPathArr[$dataLvl] : 'parentDataProperty';
out +=
' , ' + $parentData + ' , ' + $parentDataProperty + ' , rootData ) ';
var def_callRuleValidate = out;
out = $$outStack.pop();
if ($rDef.errors === false) {
out += ' ' + $valid + ' = ';
if ($asyncKeyword) {
out += 'await ';
}
out += '' + def_callRuleValidate + '; ';
} else {
if ($asyncKeyword) {
$ruleErrs = 'customErrors' + $lvl;
out +=
' var ' +
$ruleErrs +
' = null; try { ' +
$valid +
' = await ' +
def_callRuleValidate +
'; } catch (e) { ' +
$valid +
' = false; if (e instanceof ValidationError) ' +
$ruleErrs +
' = e.errors; else throw e; } ';
} else {
out +=
' ' +
$ruleErrs +
' = null; ' +
$valid +
' = ' +
def_callRuleValidate +
'; ';
}
}
}
if ($rDef.modifying) {
out +=
' if (' +
$parentData +
') ' +
$data +
' = ' +
$parentData +
'[' +
$parentDataProperty +
'];';
}
out += '' + $closingBraces;
if ($rDef.valid) {
if ($breakOnError) {
out += ' if (true) { ';
}
} else {
out += ' if ( ';
if ($rDef.valid === undefined) {
out += ' !';
if ($macro) {
out += '' + $nextValid;
} else {
out += '' + $valid;
}
} else {
out += ' ' + !$rDef.valid + ' ';
}
out += ') { ';
$errorKeyword = $rule.keyword;
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = '';
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out +=
" { keyword: '" +
($errorKeyword || 'custom') +
"' , dataPath: (dataPath || '') + " +
it.errorPath +
' , schemaPath: ' +
it.util.toQuotedString($errSchemaPath) +
" , params: { keyword: '" +
$rule.keyword +
"' } ";
if (it.opts.messages !== false) {
out +=
' , message: \'should pass "' +
$rule.keyword +
'" keyword validation\' ';
}
if (it.opts.verbose) {
out +=
' , schema: validate.schema' +
$schemaPath +
' , parentSchema: validate.schema' +
it.schemaPath +
' , data: ' +
$data +
' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) {
/* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + __err + ']); ';
} else {
out += ' validate.errors = [' + __err + ']; return false; ';
}
} else {
out +=
' var err = ' +
__err +
'; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
var def_customError = out;
out = $$outStack.pop();
if ($inline) {
if ($rDef.errors) {
if ($rDef.errors != 'full') {
out +=
' for (var ' +
$i +
'=' +
$errs +
'; ' +
$i +
'<errors; ' +
$i +
'++) { var ' +
$ruleErr +
' = vErrors[' +
$i +
']; if (' +
$ruleErr +
'.dataPath === undefined) ' +
$ruleErr +
".dataPath = (dataPath || '') + " +
it.errorPath +
'; if (' +
$ruleErr +
'.schemaPath === undefined) { ' +
$ruleErr +
'.schemaPath = "' +
$errSchemaPath +
'"; } ';
if (it.opts.verbose) {
out +=
' ' +
$ruleErr +
'.schema = ' +
$schemaValue +
'; ' +
$ruleErr +
'.data = ' +
$data +
'; ';
}
out += ' } ';
}
} else {
if ($rDef.errors === false) {
out += ' ' + def_customError + ' ';
} else {
out +=
' if (' +
$errs +
' == errors) { ' +
def_customError +
' } else { for (var ' +
$i +
'=' +
$errs +
'; ' +
$i +
'<errors; ' +
$i +
'++) { var ' +
$ruleErr +
' = vErrors[' +
$i +
']; if (' +
$ruleErr +
'.dataPath === undefined) ' +
$ruleErr +
".dataPath = (dataPath || '') + " +
it.errorPath +
'; if (' +
$ruleErr +
'.schemaPath === undefined) { ' +
$ruleErr +
'.schemaPath = "' +
$errSchemaPath +
'"; } ';
if (it.opts.verbose) {
out +=
' ' +
$ruleErr +
'.schema = ' +
$schemaValue +
'; ' +
$ruleErr +
'.data = ' +
$data +
'; ';
}
out += ' } } ';
}
}
} else if ($macro) {
out += ' var err = '; /* istanbul ignore else */
if (it.createErrors !== false) {
out +=
" { keyword: '" +
($errorKeyword || 'custom') +
"' , dataPath: (dataPath || '') + " +
it.errorPath +
' , schemaPath: ' +
it.util.toQuotedString($errSchemaPath) +
" , params: { keyword: '" +
$rule.keyword +
"' } ";
if (it.opts.messages !== false) {
out +=
' , message: \'should pass "' +
$rule.keyword +
'" keyword validation\' ';
}
if (it.opts.verbose) {
out +=
' , schema: validate.schema' +
$schemaPath +
' , parentSchema: validate.schema' +
it.schemaPath +
' , data: ' +
$data +
' ';
}
out += ' } ';
} else {
out += ' {} ';
}
out +=
'; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
if (!it.compositeRule && $breakOnError) {
/* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError(vErrors); ';
} else {
out += ' validate.errors = vErrors; return false; ';
}
}
} else {
if ($rDef.errors === false) {
out += ' ' + def_customError + ' ';
} else {
out +=
' if (Array.isArray(' +
$ruleErrs +
')) { if (vErrors === null) vErrors = ' +
$ruleErrs +
'; else vErrors = vErrors.concat(' +
$ruleErrs +
'); errors = vErrors.length; for (var ' +
$i +
'=' +
$errs +
'; ' +
$i +
'<errors; ' +
$i +
'++) { var ' +
$ruleErr +
' = vErrors[' +
$i +
']; if (' +
$ruleErr +
'.dataPath === undefined) ' +
$ruleErr +
".dataPath = (dataPath || '') + " +
it.errorPath +
'; ' +
$ruleErr +
'.schemaPath = "' +
$errSchemaPath +
'"; ';
if (it.opts.verbose) {
out +=
' ' +
$ruleErr +
'.schema = ' +
$schemaValue +
'; ' +
$ruleErr +
'.data = ' +
$data +
'; ';
}
out += ' } } else { ' + def_customError + ' } ';
}
}
out += ' } ';
if ($breakOnError) {
out += ' else { ';
}
}
return out;
};