jet-schema
Version:
Simple, typescript-first schema validation tool
301 lines • 11.8 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
const util_1 = require("./util");
const error_stuff_1 = require("./error-stuff");
function jetSchema(options) {
var _a, _b, _c;
const globalsMap = _setupGlobalsMap((_a = options === null || options === void 0 ? void 0 : options.globals) !== null && _a !== void 0 ? _a : []), cloneFn = ((_b = options === null || options === void 0 ? void 0 : options.cloneFn) !== null && _b !== void 0 ? _b : util_1.defaultCloneFn), onError = ((_c = options === null || options === void 0 ? void 0 : options.onError) !== null && _c !== void 0 ? _c : error_stuff_1.defaultOnError);
return (schemaFnObjArg, ...options) => {
const [schemaOptions] = options, optionsF = _processOptions(schemaOptions);
if (!optionsF.optional && (optionsF.init === false || (0, util_1.isUndef)(optionsF.init))) {
const err = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.Init, '.schema', optionsF.schemaId);
onError(err);
}
const ret = _setupAllVldtrsHolder(schemaFnObjArg, globalsMap, cloneFn, onError, optionsF.schemaId), newFn = _setupNewFn(ret.allVldtrsHolder, cloneFn, onError, optionsF.schemaId), testFn = _setupTestFn(ret.allVldtrsHolder, optionsF, onError), parseFn = _setupParseFn(ret.allVldtrsHolder, optionsF, onError);
return {
new: newFn,
test: testFn,
pick: (p) => {
const prop = schemaFnObjArg[p], key = p, vldrObj = ret.allVldtrsHolder[key], transformFn = vldrObj.transform;
let testFn = vldrObj.vf;
if (!!transformFn) {
testFn = (val) => {
val = transformFn(val);
return vldrObj.vf(val);
};
}
if (!!prop) {
return Object.assign({ default: vldrObj.default, test: testFn }, (_isSchemaObj(prop) && {
pick: prop.pick,
new: ret.childSchemaNewFns[key],
schema: () => (Object.assign({}, prop)),
}));
}
},
parse: parseFn,
_schemaOptions: optionsF,
};
};
}
function _setupAllVldtrsHolder(schemaArgObj, globalsMap, cloneFn, onError, schemaId) {
const allVldtrsHolder = {}, childSchemaNewFns = {}, errors = [];
for (const key in schemaArgObj) {
const vldrHolderObj = {
vf: (arg) => !!arg,
default: () => undefined,
formatError: (error) => error,
};
const schemaArgProp = schemaArgObj[key];
if (schemaArgProp === Date) {
vldrHolderObj.vf = util_1.isDate;
vldrHolderObj.transform = (arg) => new Date(arg);
vldrHolderObj.default = () => new Date();
}
else if ((typeof schemaArgProp === 'function') ||
_isValidatorObj(schemaArgProp)) {
let vdlrFn, defaultVal, hasLocalDefault = false;
if (_isValidatorObj(schemaArgProp)) {
const localObj = schemaArgProp;
vdlrFn = localObj.vf;
if ('default' in localObj) {
defaultVal = localObj.default;
hasLocalDefault = true;
}
if (!!localObj.transform) {
vldrHolderObj.transform = localObj.transform;
}
if (!!localObj.formatError) {
vldrHolderObj.formatError = localObj.formatError;
}
}
else {
vdlrFn = schemaArgProp;
}
const globalsObj = globalsMap.get(vdlrFn);
if (!!globalsObj) {
if (!hasLocalDefault && 'default' in globalsObj) {
defaultVal = globalsObj.default;
}
if (!vldrHolderObj.transform && !!globalsObj.transform) {
vldrHolderObj.transform = globalsObj.transform;
}
if (!vldrHolderObj.formatError && !!globalsObj.formatError) {
vldrHolderObj.formatError = globalsObj.formatError;
}
}
if (!(0, util_1.isUndef)(defaultVal)) {
const defaultF = cloneFn(defaultVal);
vldrHolderObj.default = () => defaultF;
}
else {
vldrHolderObj.default = () => undefined;
}
vldrHolderObj.vf = vdlrFn;
}
else if (_isSchemaObj(schemaArgProp)) {
const childSchema = schemaArgProp, dflt = childSchema._schemaOptions.init;
if (dflt === true) {
vldrHolderObj.default = () => childSchema.new();
}
else if (dflt === null) {
vldrHolderObj.default = () => null;
}
else {
vldrHolderObj.default = () => undefined;
}
childSchemaNewFns[key] = () => childSchema.new();
vldrHolderObj.vf = childSchema.test;
}
else if ((0, util_1.isEnum)(schemaArgProp)) {
const [dflt, vldr] = (0, util_1.processEnum)(schemaArgProp);
vldrHolderObj.default = () => cloneFn(dflt);
vldrHolderObj.vf = vldr;
}
else {
const errObj = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.Init, '_setupAllVldtrsHolder', schemaId, key);
errors.push(errObj);
}
const dfltVal = vldrHolderObj.default();
if (!vldrHolderObj.vf(dfltVal)) {
const errObj = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.DefaultVal, '_setupAllVldtrsHolder', schemaId, key, dfltVal);
const errFin = vldrHolderObj.formatError(errObj);
errors.push(errFin);
}
allVldtrsHolder[key] = vldrHolderObj;
}
if (errors.length > 0) {
onError(errors);
}
return {
childSchemaNewFns,
allVldtrsHolder,
};
}
function _isSchemaObj(arg) {
return ((0, util_1.isObj)(arg) && '_schemaOptions' in arg);
}
function _isValidatorObj(arg) {
return ((0, util_1.isObj)(arg) && ('vf' in arg) && typeof arg.vf === 'function');
}
function _setupNewFn(allVldtrsHolder, cloneFn, onError, schemaId) {
return (partial = {}) => {
const retVal = {}, errors = [];
for (const key in allVldtrsHolder) {
const val = allVldtrsHolder[key].default();
if (val !== undefined) {
retVal[key] = val;
}
}
for (const key in partial) {
const vldrObj = allVldtrsHolder[key];
if (!vldrObj) {
continue;
}
let val = partial[key];
if (!!vldrObj.transform) {
val = vldrObj.transform(val);
}
retVal[key] = cloneFn(val);
if (!vldrObj.vf(val)) {
const errObj = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.PropValidation, '.new', schemaId, key, val);
const errFin = vldrObj.formatError(errObj);
errors.push(errFin);
}
}
if (errors.length > 0) {
onError(errors);
}
return retVal;
};
}
function _setupTestFn(allVldtrsHolder, options, onError) {
const { schemaId, safety } = options, NotOptErr = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.UndefButNotOpt, '.test', schemaId), NullErr = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.NullButNotNullable, '.test', schemaId), runValidations = _setupRunValidations(allVldtrsHolder, safety, '.test', schemaId);
return (arg) => {
if ((0, util_1.isUndef)(arg)) {
if (options.optional) {
return true;
}
else {
onError(NotOptErr);
return false;
}
}
else if (arg === null) {
if (options.nullable) {
return true;
}
else {
onError(NullErr);
return false;
}
}
if (!(0, util_1.isObj)(arg)) {
return false;
}
const errors = runValidations(arg);
if (errors.length > 0) {
onError(errors);
return false;
}
else {
return true;
}
};
}
function _setupParseFn(allVldtrsHolder, options, onError) {
const { schemaId, safety } = options, notAnObjErr = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.NotAnObj, '.parse', schemaId), runValidations = _setupRunValidations(allVldtrsHolder, safety, '.parse', schemaId);
return (arg) => {
if (!(0, util_1.isObj)(arg)) {
onError(notAnObjErr);
return arg;
}
const errors = runValidations(arg);
if (errors.length > 0) {
onError(errors);
}
return arg;
};
}
function _setupGlobalsMap(globalsArr) {
const map = new Map();
for (const obj of globalsArr) {
const { vf } = obj, rest = __rest(obj, ["vf"]);
map.set(vf, rest);
}
return map;
}
function _processOptions(options) {
const retVal = {
optional: false,
nullable: false,
init: true,
safety: 'filter',
};
if ((0, util_1.isUndef)(options)) {
return retVal;
}
if (!(0, util_1.isUndef)(options.init)) {
retVal.init = options.init;
}
if (!!options.id) {
retVal.schemaId = options.id;
}
if (!!options.safety) {
retVal.safety = options.safety;
}
if (!(0, util_1.isUndef)(options.optional)) {
retVal.optional = !!options.optional;
}
if (!(0, util_1.isUndef)(options.nullable)) {
retVal.nullable = !!options.nullable;
}
if (('nullish' in options) && !(0, util_1.isUndef)(options.nullish)) {
retVal.optional = options.nullish;
retVal.nullable = options.nullish;
}
return retVal;
}
function _setupRunValidations(allVldtrsHolder, safety, location, schemaId) {
return (arg) => {
const errors = [];
for (const key in allVldtrsHolder) {
const vldrObj = allVldtrsHolder[key];
let val = arg[key];
if (!!vldrObj.transform) {
val = vldrObj.transform(val);
arg[key] = val;
}
if (!vldrObj.vf(val)) {
const errObj = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.PropValidation, location, schemaId, key, val);
const errFin = vldrObj.formatError(errObj);
errors.push(errFin);
}
}
if (safety !== 'pass') {
for (const key in arg) {
if (key in allVldtrsHolder) {
continue;
}
else if (safety === 'strict') {
const errObj = (0, error_stuff_1.getErrObj)(error_stuff_1.Errors.StrictMode, location, schemaId, key);
errors.push(errObj);
}
Reflect.deleteProperty(arg, key);
}
}
return errors;
};
}
exports.default = jetSchema;
//# sourceMappingURL=jetSchema.js.map