UNPKG

skema

Version:

Skema provides a handy & composable way to validate / transform / purify the input data.

170 lines (125 loc) 3.42 kB
"use strict"; 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;