skema
Version:
Skema provides a handy & composable way to validate / transform / purify the input data.
170 lines (125 loc) • 3.42 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ArrayOfShape = exports.ObjectOfShape = exports.ArrayShape = exports.ObjectShape = exports.set = exports.TYPE_ARRAY = exports.TYPE_OBJECT = void 0;
var _util = require("./util");
var _processor = require("./processor");
var _context = require("./context");
var _error = require("./error");
var _future = require("./future");
var _inspect = require("./inspect");
const TYPE_OBJECT = 'TYPE_OBJECT';
exports.TYPE_OBJECT = TYPE_OBJECT;
const TYPE_ARRAY = 'TYPE_ARRAY';
exports.TYPE_ARRAY = TYPE_ARRAY;
const set = (object, key, value) => {
const setters = object[_future.SHAPE];
const setter = setters && setters[key];
const context = new _context.Context(value, key, object, [key]);
context.parent = object;
if (!setter) {
throw (0, _error.error)('SHAPE_NOT_FOUND');
}
return setter(value, false, context);
};
exports.set = set;
function clean(context) {
context.rawParent = context.parent = null;
}
const isObject = v => Object(v) === v;
function reducer(prev, factory) {
return factory.call(this, prev);
}
class Shape {
constructor(shape, clean) {
this._shape = shape;
this._clean = clean;
}
from(args, parentContext, options) {
if (!isObject(parentContext.input)) {
const error = parentContext.errorByCode('NOT_OBJECT', parentContext.key);
return options.promise.reject(error);
}
const values = this._create(parentContext);
const setters = Object.create(null);
(0, _util.defineValue)(values, _future.SHAPE, setters);
(0, _inspect.attach)(values);
const tasks = this._taskKeys(parentContext).map(key => () => {
const [context, skema] = this._task(key, parentContext);
context.parent = values;
return new _processor.Processor({
options,
skema,
args,
context,
values,
setters
}).process().then(() => clean(context), error => {
clean(context);
return options.promise.reject(error);
});
});
return options.promiseExtra.series(tasks, reducer).then(() => values);
}
}
class GenericObjectShape extends Shape {
_task(key, context) {
return [context.descend(key), this._shape[key]];
}
}
class ObjectShape extends GenericObjectShape {
_create(context) {
return this._clean ? Object.create(null) : (0, _util.simpleClone)(context.input);
}
_taskKeys() {
return Object.keys(this._shape);
}
}
exports.ObjectShape = ObjectShape;
class ArrayShape extends GenericObjectShape {
_create({
input
}) {
return this._clean ? [] : [].concat(input);
}
_taskKeys() {
return this._shape.map((_, i) => i);
}
}
exports.ArrayShape = ArrayShape;
class GenericOfShape extends Shape {
_task(key, context) {
return [context.descend(key), this._shape];
}
}
class ObjectOfShape extends GenericOfShape {
_create() {
return Object.create(null);
}
_taskKeys({
input
}) {
return Object.keys(input);
}
}
exports.ObjectOfShape = ObjectOfShape;
class ArrayOfShape extends GenericOfShape {
_create() {
return [];
}
_taskKeys({
input
}) {
const tasks = [];
const {
length
} = input;
let i = 0; // Iterate every array item
for (; i < length; i++) {
tasks.push(i);
}
return tasks;
}
}
exports.ArrayOfShape = ArrayOfShape;
;