@quenk/preconditions
Version:
Make data satisfy constraints before using.
150 lines • 5.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.compileAsync = exports.AsyncFunctionContext = exports.compile = exports.FunctionContext = exports.defaultAvailables = void 0;
const base = require("../../");
const object = require("../../record");
const array = require("../../array");
const string = require("../../string");
const number = require("../../number");
const async = require("../../async");
const asyncObject = require("../../async/record");
const asyncArray = require("../../async/array");
const maybe_1 = require("@quenk/noni/lib/data/maybe");
const record_1 = require("@quenk/noni/lib/data/record");
const path_1 = require("@quenk/noni/lib/data/record/path");
const type_1 = require("@quenk/noni/lib/data/type");
const parse_1 = require("../parse");
const _1 = require(".");
/**
* @internal
*/
exports.defaultAvailables = {
base: {
identity: () => base.identity,
and: base.and,
or: base.or,
type: base.typeOf,
const: base.constant,
equal: base.eq,
notEqual: base.neq,
notNull: () => base.notNull,
optional: base.optional,
default: base.defaultValue,
discard: () => base.discard,
reject: base.reject,
every: base.every,
enum: base.exists,
log: () => base.log,
cast: base.cast
},
object: {
restrict: object.restrict,
intersect: object.intersect,
disjoint: object.disjoint,
union: object.union,
map: object.map
},
array: {
nonEmpty: () => array.nonEmpty,
minItems: array.minItems,
maxItems: array.maxItems,
filter: array.filter,
map: array.map,
tuple: array.tuple
},
string: {
minLength: string.minLength,
maxLength: string.maxLength,
pattern: string.matches,
lowerCase: () => string.lowercase,
upperCase: () => string.uppercase,
trim: () => string.trim,
split: string.split,
nonEmpty: () => string.nonEmpty
},
boolean: {},
number: {
min: number.min,
max: number.max
}
};
const recWrappers = {
restrict: object.restrict,
intersect: object.intersect,
disjoint: object.disjoint,
union: object.union
};
/**
* FunctionContext is used for compilation of a schema to a synchronous
* precondition function.
*/
class FunctionContext extends _1.CompileContext {
constructor() {
super(...arguments);
this.identity = base.identity;
this.optional = base.optional;
this.and = base.and;
this.or = base.or;
this.properties = (props, addProps) => object.schemaProperties(recWrappers[this.options.propMode], props, addProps);
this.items = (prec) => (base.and(base.typeOf('array'), array.map(prec)));
this.get = (spec) => doGet(this.options.preconditions, spec);
}
}
exports.FunctionContext = FunctionContext;
const doGet = (rec, spec) => {
if (Array.isArray(spec)) {
let [path, args] = spec;
return (0, path_1.get)(path, rec).chain(fn => (0, type_1.isFunction)(fn) ? (0, maybe_1.just)(fn.apply(null, args)) : (0, maybe_1.nothing)());
}
else if ((0, type_1.isFunction)(spec)) {
return (0, maybe_1.just)(spec);
}
else {
return (0, maybe_1.nothing)();
}
};
/**
* compile a schema into a single precondition function.
*/
const compile = (opts, schema) => (0, parse_1.parse)(new FunctionContext((0, record_1.merge3)({ key: 'preconditions', propMode: 'restrict', builtins: true }, opts, {
preconditions: (0, record_1.rmerge)(exports.defaultAvailables, opts.preconditions || {})
})), schema);
exports.compile = compile;
const asyncRecWrappers = {
restrict: asyncObject.restrict,
intersect: asyncObject.intersect,
disjoint: asyncObject.disjoint,
union: asyncObject.union
};
/**
* AsyncFunctionContext is used for compilation of a schema to an async
* precondition function.
*/
class AsyncFunctionContext extends _1.CompileContext {
constructor() {
super(...arguments);
this.identity = async.identity;
this.optional = async.optional;
this.and = async.and;
this.or = async.or;
this.properties = (asyncProps, addProps) => asyncObject.schemaProperties(asyncRecWrappers[this.options.propMode], asyncProps, addProps);
this.items = (prec) => (async.and(async.async(base.typeOf('array')), asyncArray.map(prec)));
this.get = (spec) => doGet(this.options.asyncPreconditions, spec);
}
}
exports.AsyncFunctionContext = AsyncFunctionContext;
/**
* compileAsync a schema into a single async precondition function.
*
* This function disables builtins and changes the default precondition key to
* "asyncPreconditions".
*/
const compileAsync = (opts, schema) => (0, parse_1.parse)(new AsyncFunctionContext((0, record_1.merge3)({
key: 'asyncPreconditions',
propMode: 'restrict'
}, opts, {
builtins: false,
asyncPreconditions: (0, record_1.rmerge)({}, opts.asyncPreconditions || {})
})), schema);
exports.compileAsync = compileAsync;
//# sourceMappingURL=function.js.map