dilswer
Version:
Blazingly fast data validation library with TypeScript integration.
835 lines (833 loc) • 27.4 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/validation-algorithms/compile-fast-validator.ts
var KNOWN_GLOBAL_CLASSES = /* @__PURE__ */ new Map([
[Map, "Map"],
[Set, "Set"],
[RegExp, "RegExp"],
[Date, "Date"],
[Error, "Error"],
[EvalError, "EvalError"],
[RangeError, "RangeError"],
[ReferenceError, "ReferenceError"],
[SyntaxError, "SyntaxError"],
[TypeError, "TypeError"],
[URIError, "URIError"],
[AggregateError, "AggregateError"],
[Array, "Array"],
[Object, "Object"],
[WeakMap, "WeakMap"],
[WeakSet, "WeakSet"],
[Function, "Function"],
[String, "String"],
[Number, "Number"],
[Boolean, "Boolean"],
[Int8Array, "Int8Array"],
[Uint8Array, "Uint8Array"],
[Uint8ClampedArray, "Uint8ClampedArray"],
[Int16Array, "Int16Array"],
[Uint16Array, "Uint16Array"],
[Int32Array, "Int32Array"],
[Uint32Array, "Uint32Array"],
[Float32Array, "Float32Array"],
[Float64Array, "Float64Array"],
[BigInt64Array, "BigInt64Array"],
[BigUint64Array, "BigUint64Array"],
[ArrayBuffer, "ArrayBuffer"],
[DataView, "DataView"],
[Promise, "Promise"]
]);
if (typeof SharedArrayBuffer !== "undefined") {
KNOWN_GLOBAL_CLASSES.set(SharedArrayBuffer, "SharedArrayBuffer");
}
var propertyAccessor = (propertyName) => {
if (propertyName.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/)) {
return `.${propertyName}`;
}
return `[${JSON.stringify(propertyName)}]`;
};
var ConditionBuilder = class {
constructor(type) {
this.type = type;
__publicField(this, "conditions", []);
}
add(condition) {
this.conditions.push(condition);
return this;
}
build() {
if (this.conditions.length === 0) {
return "true";
}
if (this.conditions.length === 1) {
const c = this.conditions[0];
return typeof c === "string" ? c : c.build();
}
const separator = this.type === "||" ? " || " : " && ";
return "(" + this.conditions.map((c) => typeof c === "string" ? c : c.build()).join(separator) + ")";
}
};
var $dependency = (depName) => `_$getDependency(${JSON.stringify(depName)})`;
var $condition = (type) => new ConditionBuilder(type);
var $type = (varname, type) => {
return `typeof ${varname} === "${type}"`;
};
var _serialize = (value) => {
return JSON.stringify(value);
};
var $defineFn = (fnName, argName, body) => {
return {
declaration: `const ${fnName} = (${argName}) => ${body};`,
$invokeWith(varname) {
return `${fnName}(${varname})`;
}
};
};
var $defineRegexp = (name, regexp) => {
return {
declaration: `const ${name} = new RegExp(${JSON.stringify(
regexp.source
)}, ${JSON.stringify(regexp.flags)});`,
$test(varname) {
return `${name}.test(${varname})`;
}
};
};
var $lte = (name, value) => {
return `${name} <= ${value}`;
};
var $gte = (name, value) => {
return `${name} >= ${value}`;
};
var $equal = (varname, value) => {
return `${varname} === ${_serialize(value)}`;
};
var $notEqual = (varname, value) => {
return `${varname} !== ${_serialize(value)}`;
};
var $laxNotEqual = (varname, value) => {
return `${varname} != ${_serialize(value)}`;
};
var $isArray = (varname) => {
return `Array.isArray(${varname})`;
};
var $isSet = (varname) => {
return $equal(`${varname}[Symbol.toStringTag]`, "Set");
};
var $isInteger = (varname) => {
return `Number.isInteger(${varname})`;
};
var $notNaN = (varname) => {
return `!Number.isNaN(${varname})`;
};
var $has = (varname, key) => {
return `${_serialize(key)} in ${varname}`;
};
var $ternary = (condition) => {
return {
then(thenValue) {
return {
else(elseValue) {
return `(${typeof condition === "string" ? condition : condition.build()} ? ${thenValue} : ${elseValue})`;
}
};
}
};
};
var $length = (varname, is, than) => {
switch (is) {
case "==":
return `${varname}.length === ${than}`;
case ">":
return `${varname}.length > ${than}`;
case "<":
return `${varname}.length < ${than}`;
case ">=":
return `${varname}.length >= ${than}`;
case "<=":
return `${varname}.length <= ${than}`;
}
};
var $every = (generator, varname, predicate, startIndex) => {
generator.includes.every = true;
const elemName = generator.getUniqueVarName();
const indexName = generator.getUniqueVarName();
if (startIndex != null) {
return `_$every(${varname}, (${elemName}, ${indexName}) => ${predicate(elemName, indexName)}, ${startIndex})`;
}
return `_$every(${varname}, (${elemName}, ${indexName}) => ${predicate(elemName, indexName)})`;
};
var $everySome = (generator, varname, everyPredicate, somePredicate, startIdx) => {
generator.includes.everySome = true;
const elemName1 = generator.getUniqueVarName();
const indexName1 = generator.getUniqueVarName();
const elemName2 = generator.getUniqueVarName();
const indexName2 = generator.getUniqueVarName();
if (startIdx != null) {
return `_$everySome(${varname}, (${elemName1}, ${indexName1}) => ${everyPredicate(elemName1, indexName1)}, (${elemName2}, ${indexName2}) => ${somePredicate(elemName2, indexName2)}, ${startIdx})`;
}
return `_$everySome(${varname}, (${elemName1}, ${indexName1}) => ${everyPredicate(elemName1, indexName1)}, (${elemName2}, ${indexName2}) => ${somePredicate(elemName2, indexName2)})`;
};
var $everyObjectValue = (generator, varname, predicate) => {
const elemName = generator.getUniqueVarName();
return `_$everyObjectValue(${varname}, (${elemName}) => ${predicate(elemName)})`;
};
var $everyInSet = (generator, varname, predicate) => {
const elemName = generator.getUniqueVarName();
return `_$everyInSet(${varname}, (${elemName}) => ${predicate(elemName)})`;
};
var $charCode = (varname, is) => {
if (Array.isArray(is)) {
return `${varname}.charCodeAt(0) >= ${is[0]} && ${varname}.charCodeAt(0) <= ${is[1]}`;
}
return `${varname}.charCodeAt(0) === ${is}`;
};
var $charCount = (generator, varname, char, is, expected) => {
generator.includes.charCount = true;
return `_$countChar(${varname}, ${JSON.stringify(char)}) ${is} ${expected}`;
};
var $instanceof = (generator, varname, constructor) => {
if (KNOWN_GLOBAL_CLASSES.has(constructor)) {
return `(${varname} instanceof ${KNOWN_GLOBAL_CLASSES.get(constructor)})`;
}
const name = generator.getUniqueVarName();
generator.addDependency(name, constructor);
return `(${varname} instanceof ${$dependency(name)})`;
};
var ValidateGenerator = class {
constructor(get$validate) {
this.get$validate = get$validate;
}
$validate(varname) {
const validate = this.get$validate(varname, this);
if (typeof validate === "string") {
return validate;
}
return validate.build();
}
};
var DataTypeValidatorVisitor = class {
constructor() {
__publicField(this, "includes", {
every: false,
everySome: false,
charCount: false,
stringNumeral: false,
stringInteger: false,
recursive: false,
set: false,
dict: false,
array: false,
custom: false,
instanceof: false
});
__publicField(this, "circValidationFnNames", /* @__PURE__ */ new Map());
__publicField(this, "_counter1", 0);
__publicField(this, "_counter2", 0);
__publicField(this, "_counter3", 0);
__publicField(this, "knownTypes", /* @__PURE__ */ new Map());
__publicField(this, "outerDeclarations", []);
__publicField(this, "innerDeclarations", []);
__publicField(this, "dependencies", []);
}
addDeclaration(type, inlined) {
if (type === "inner") {
this.innerDeclarations.push(inlined);
} else {
this.outerDeclarations.push(inlined);
}
return this;
}
addDependency(name, value) {
this.dependencies.push([name, value]);
return this;
}
getUniqueStringForType(type) {
if (this.knownTypes.has(type)) {
return this.knownTypes.get(type);
}
const name = `_$t${++this._counter3}`;
this.knownTypes.set(type, name);
return name;
}
getUniqueVarName() {
return `_$a${++this._counter1}`;
}
getUniqueFnName() {
return `_$v${++this._counter2}`;
}
visitPrimitive(type) {
switch (type.simpleType) {
case "boolean":
return new ValidateGenerator(
(varname) => $type(varname, "boolean")
);
case "integer":
return new ValidateGenerator(
(varname) => {
const cond = $condition("&&").add($type(varname, "number")).add($isInteger(varname));
if (type.options.max != null) {
cond.add($lte(varname, type.options.max));
}
if (type.options.min != null) {
cond.add($gte(varname, type.options.min));
}
return cond;
}
);
case "null":
return new ValidateGenerator(
(varname) => $equal(varname, null)
);
case "number":
return new ValidateGenerator(
(varname) => {
let cond = $condition("&&").add($type(varname, "number")).add($notNaN(varname));
if (type.options.max != null) {
cond = cond.add($lte(varname, type.options.max));
}
if (type.options.min != null) {
cond = cond.add($gte(varname, type.options.min));
}
return cond;
}
);
case "string":
return new ValidateGenerator(
(varname) => {
const cond = $condition("&&").add($type(varname, "string"));
if (type.options.max != null) {
cond.add($length(varname, "<=", type.options.max));
}
if (type.options.min != null) {
cond.add($length(varname, ">=", type.options.min));
}
return cond;
}
);
case "stringinteger":
this.includes.stringInteger = true;
if (type.options.negative === false && type.options.positive === false) {
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add(
$ternary($charCode(varname, 45 /* Minus */)).then($every(
this,
varname,
(char) => $charCode(char, 48 /* Zero */),
1
// start from the second char
)).else($every(
this,
varname,
(char) => $charCode(char, 48 /* Zero */)
))
)
);
}
if (type.options.negative === false) {
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add(
$everySome(
this,
varname,
(char) => $charCode(char, [48 /* Zero */, 57 /* Nine */]),
// each char must be a digit
(char) => $charCode(char, [49 /* One */, 57 /* Nine */])
// at least one char must be a non-zero digit
)
)
);
}
if (type.options.positive === false) {
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add($charCode(varname, 45 /* Minus */)).add(
$everySome(
this,
varname,
(char) => $charCode(char, [48 /* Zero */, 57 /* Nine */]),
// each char must be a digit
(char) => $charCode(char, [49 /* One */, 57 /* Nine */]),
// at least one char must be a non-zero digit
1
// start from the second char
)
)
);
}
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add(
$ternary($charCode(varname, 45 /* Minus */)).then($every(
this,
varname,
(char) => $charCode(char, [48 /* Zero */, 57 /* Nine */]),
1
// start from the second char
)).else($every(
this,
varname,
(char) => $charCode(char, [48 /* Zero */, 57 /* Nine */])
))
)
);
case "stringnumeral":
this.includes.stringNumeral = true;
if (type.options.negative === false && type.options.positive === false) {
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add(
$ternary($charCode(varname, 45 /* Minus */)).then(
$every(
this,
varname,
(char) => $condition("||").add($charCode(char, 48 /* Zero */)).add($charCode(char, 46 /* Dot */)).build(),
1
// start from the second char
)
).else(
$every(
this,
varname,
(char) => $condition("||").add($charCode(char, 48 /* Zero */)).add($charCode(char, 46 /* Dot */)).build()
)
)
).add($charCount(this, varname, ".", "<", 2))
);
}
if (type.options.negative === false) {
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add(
$everySome(
this,
varname,
(char) => $condition("||").add($charCode(char, [48 /* Zero */, 57 /* Nine */])).add($charCode(char, 46 /* Dot */)).build(),
(char) => $charCode(char, [49 /* One */, 57 /* Nine */])
)
).add($charCount(this, varname, ".", "<", 2))
);
}
if (type.options.positive === false) {
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add($charCode(varname, 45 /* Minus */)).add(
$everySome(
this,
varname,
(char) => $condition("||").add($charCode(char, [48 /* Zero */, 57 /* Nine */])).add($charCode(char, 46 /* Dot */)).build(),
(char) => $charCode(char, [49 /* One */, 57 /* Nine */]),
1
)
).add($charCount(this, varname, ".", "<", 2))
);
}
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add($length(varname, ">", 0)).add(
$ternary($charCode(varname, 45 /* Minus */)).then($every(
this,
varname,
(char) => $condition("||").add($charCode(char, [48 /* Zero */, 57 /* Nine */])).add($charCode(char, 46 /* Dot */)).build(),
1
)).else($every(
this,
varname,
(char) => $condition("||").add($charCode(char, [48 /* Zero */, 57 /* Nine */])).add($charCode(char, 46 /* Dot */)).build()
))
).add($charCount(this, varname, ".", "<", 2))
);
case "function":
return new ValidateGenerator(
(varname) => $type(varname, "function")
);
case "symbol":
return new ValidateGenerator(
(varname) => $type(varname, "symbol")
);
case "undefined":
return new ValidateGenerator(
(varname) => $type(varname, "undefined")
);
case "unknown":
return new ValidateGenerator(() => "true");
}
}
visitArrayOf(type, children) {
this.includes.array = true;
if (children && children.length > 0) {
const oneof = this.visitOneOf(type["union"], children);
return new ValidateGenerator(
(varname) => $condition("&&").add($isArray(varname)).add($every(this, varname, (elem) => oneof.$validate(elem)))
);
}
return new ValidateGenerator(
(varname) => $isArray(varname)
);
}
visitTuple(type, children) {
return new ValidateGenerator((varname) => {
const cond = $condition("&&").add($isArray(varname)).add($length(varname, "==", type.tuple.length));
if (children && children.length > 0) {
for (const [index, c] of children.entries()) {
cond.add(c.$validate(`${varname}[${index}]`));
}
}
return cond;
});
}
visitRecordOf(type, children = []) {
const getRecordConditions = (varName) => {
const cond = $condition("&&").add($type(varName, "object")).add($laxNotEqual(varName, null));
if (children && children.length > 0) {
for (const c of children) {
const accessor = propertyAccessor(c.propertyName);
const nextName = `${varName}${accessor}`;
if (c.required !== true) {
cond.add(
$ternary(
$condition("&&").add($has(varName, c.propertyName)).add($notEqual(nextName, void 0))
).then(c.child.$validate(nextName)).else("true")
);
} else {
cond.add($has(varName, c.propertyName));
cond.add(c.child.$validate(nextName));
}
}
}
return cond;
};
return new ValidateGenerator((varname) => {
if (varname.split(/\[|\./).length > 2) {
const fnName = this.getUniqueFnName();
const argName = this.getUniqueVarName();
const validateFn = $defineFn(
fnName,
argName,
getRecordConditions(argName).build()
);
this.addDeclaration("inner", validateFn.declaration);
return validateFn.$invokeWith(varname);
} else {
return getRecordConditions(varname);
}
});
}
visitDict(type, children) {
this.includes.dict = true;
const isDictConditions = (varName) => {
return $condition("&&").add($type(varName, "object")).add($laxNotEqual(varName, null));
};
if (children && children.length > 0) {
const oneof = this.visitOneOf(type["union"], children);
return new ValidateGenerator(
(varname) => isDictConditions(varname).add(
$everyObjectValue(this, varname, (elem) => oneof.$validate(elem))
)
);
} else {
return new ValidateGenerator(
(varname) => isDictConditions(varname)
);
}
}
visitSetOf(type, children = []) {
this.includes.set = true;
const getBaseSetConditions = (varName) => {
return $condition("&&").add($type(varName, "object")).add($laxNotEqual(varName, null)).add($isSet(varName));
};
if (children && children.length > 0) {
const oneof = this.visitOneOf(type["union"], children);
return new ValidateGenerator(
(varname) => getBaseSetConditions(varname).add(
$everyInSet(this, varname, (elem) => oneof.$validate(elem))
)
);
}
return new ValidateGenerator(
(varname) => getBaseSetConditions(varname)
);
}
visitOneOf(type, children) {
return new ValidateGenerator((varname) => {
const cond = $condition("||");
for (const c of children) {
cond.add(c.$validate(varname));
}
return cond;
});
}
visitAllOf(type, children) {
return new ValidateGenerator((varname) => {
const cond = $condition("&&");
for (const c of children) {
cond.add(c.$validate(varname));
}
return cond;
});
}
visitLiteral(type) {
return new ValidateGenerator(
(varname) => $equal(varname, type.literal)
);
}
visitEnum(type) {
const enumKeys = Object.keys(type.enumInstance).filter(
(key) => Number.isNaN(Number(key))
);
return new ValidateGenerator((varname) => {
const cond = $condition("||");
for (const key of enumKeys) {
const member = type.enumInstance[key];
cond.add($equal(varname, member));
}
return cond;
});
}
visitEnumMember(type) {
return new ValidateGenerator(
(varname) => $equal(varname, type.enumMember)
);
}
visitInstanceOf(type) {
if (!KNOWN_GLOBAL_CLASSES.has(type.instanceOf)) {
this.includes.instanceof = true;
}
return new ValidateGenerator(
(varname) => $condition("&&").add($instanceof(this, varname, type.instanceOf))
);
}
visitCustom(type) {
this.includes.custom = true;
const customDepName = this.getUniqueVarName();
this.addDependency(customDepName, type.custom);
return new ValidateGenerator(
(varname) => `${$dependency(customDepName)}(${varname})`
);
}
visitStringMatching(type) {
const regexp = $defineRegexp(this.getUniqueVarName(), type.pattern);
this.addDeclaration("outer", regexp.declaration);
return new ValidateGenerator(
(varname) => $condition("&&").add($type(varname, "string")).add(regexp.$test(varname))
);
}
visitRecursive(circular, children) {
const [childSchema] = children;
const child = circular.type;
if (this.circValidationFnNames.has(child)) {
const validatorFnName = this.circValidationFnNames.get(child);
const argName = this.getUniqueVarName();
const typeUniqueName = this.getUniqueStringForType(child);
const validateFn = $defineFn(
validatorFnName,
argName,
$ternary(
`_$wasRecursivelyValidated(${_serialize(typeUniqueName)}, ${argName})`
).then("true").else(childSchema.$validate(argName))
);
this.includes.recursive = true;
this.addDeclaration("inner", validateFn.declaration);
return new ValidateGenerator(
(varname) => validateFn.$invokeWith(varname)
);
}
return childSchema;
}
visitRecursiveRef(type) {
const referencedType = type._getReferencedType();
if (this.circValidationFnNames.has(referencedType)) {
const validatorFnName2 = this.circValidationFnNames.get(referencedType);
return new ValidateGenerator(
(varname) => `${validatorFnName2}(${varname})`
);
}
const validatorFnName = this.getUniqueFnName();
this.circValidationFnNames.set(referencedType, validatorFnName);
return new ValidateGenerator(
(varname) => `${validatorFnName}(${varname})`
);
}
visit(type, children) {
switch (type.kind) {
case "simple":
return this.visitPrimitive(type);
case "array":
return this.visitArrayOf(type, children);
case "tuple":
return this.visitTuple(type, children);
case "record":
return this.visitRecordOf(type, children);
case "dictionary":
return this.visitDict(type, children);
case "set":
return this.visitSetOf(type, children);
case "union":
return this.visitOneOf(type, children);
case "intersection":
return this.visitAllOf(type, children);
case "literal":
return this.visitLiteral(type);
case "enumUnion":
return this.visitEnum(type);
case "enumMember":
return this.visitEnumMember(type);
case "instanceOf":
return this.visitInstanceOf(type);
case "custom":
return this.visitCustom(type);
case "stringMatching":
return this.visitStringMatching(type);
case "circular":
return this.visitRecursive(type, children);
case "circularRef":
return this.visitRecursiveRef(type);
}
}
};
var e = eval;
var every = (
/* js */
`
function _$every(_$arr, _$predicate, _$start = 0) {
for (let _$i = _$start; _$i < _$arr.length; _$i++) {
if (!_$predicate(_$arr[_$i], _$i))
return false;
}
return true;
};
`.trim()
);
var everySome = (
/* js */
`
function _$everySome(_$arr, _$everyPredicate, _$somePredicate, _$start = 0) {
let _$someSatisfied = false;
for (let _$i = _$start; _$i < _$arr.length; _$i++) {
if (!_$everyPredicate(_$arr[_$i], _$i))
return false;
if (!_$someSatisfied) {
_$someSatisfied = _$somePredicate(_$arr[_$i], _$i);
}
}
return _$someSatisfied;
};
`.trim()
);
var everyInSet = (
/* js */
`
function _$everyInSet(_$set, _$predicate) {
for (let _$item of _$set) {
if (!_$predicate(_$item))
return false;
}
return true;
};
`.trim()
);
var everyObjectValue = (
/* js */
`
function _$everyObjectValue(_$obj, _$predicate) {
for (let _$key in _$obj) {
if (!_$predicate(_$obj[_$key]))
return false;
}
return true;
};
`.trim()
);
var recursiveTracker = (
/* js */
`
const _$validatedRecursiveValues = new Map();
function _$wasRecursivelyValidated(_$tn, _$d) {
let _$set = _$validatedRecursiveValues.get(_$tn);
if (!_$set) {
_$set = new Set([_$d]);
_$validatedRecursiveValues.set(_$tn, _$set);
return false;
}
if (_$set.has(_$d)) {
return true;
}
_$set.add(_$d);
return false;
};
`.trim()
);
var countChar = (
/* js */
`
function _$countChar(_$str, _$char) {
let _$count = 0;
for (let _$i = 0; _$i < _$str.length; _$i++) {
if (_$str[_$i] === _$char)
_$count++;
}
return _$count;
};
`.trim()
);
var compileFastValidator = (dataType) => {
const visitor = new DataTypeValidatorVisitor();
const generator = dataType._acceptVisitor(visitor);
const validation = generator.$validate("data");
const outerDeclarations = [];
const innerDeclarations = [];
if (visitor.includes.every) {
outerDeclarations.push(every);
}
if (visitor.includes.everySome) {
outerDeclarations.push(everySome);
}
if (visitor.includes.set) {
outerDeclarations.push(everyInSet);
}
if (visitor.includes.dict) {
outerDeclarations.push(everyObjectValue);
}
if (visitor.includes.charCount) {
outerDeclarations.push(countChar);
}
if (visitor.outerDeclarations) {
outerDeclarations.push(...visitor.outerDeclarations);
}
if (visitor.includes.recursive) {
innerDeclarations.push(recursiveTracker);
}
if (visitor.innerDeclarations) {
innerDeclarations.push(...visitor.innerDeclarations);
}
const validatorStr = `(_$getDependency) => {
${outerDeclarations.join("\n ")}
return function validate(data) {
${innerDeclarations.join("\n ")}
return ${validation};
}
}`;
const deps = new Map(visitor.dependencies);
const _$getDependency = (name) => {
return deps.get(name);
};
const evaluatedCode = e(validatorStr);
const validator = evaluatedCode(_$getDependency);
const { includes } = visitor;
validator.asString = (name = "validate") => {
if (includes.custom) {
throw new Error(
"Validators with Custom type validation cannot be compiled to standalone code"
);
}
if (includes.instanceof) {
throw new Error(
"Validators with InstanceOf type validation cannot be compiled to standalone code"
);
}
return `${outerDeclarations.join("\n")}
function ${name}(data) {
${innerDeclarations.join("\n ")}
return ${validation}
}`;
};
return validator;
};
export {
compileFastValidator
};