skema
Version:
Skema provides a handy & composable way to validate / transform / purify the input data.
165 lines (134 loc) • 3.44 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Processor = void 0;
var _options = require("./options");
var _future = require("./future");
var _util = require("./util");
// Processor to run the flow async or sync
///////////////////////////////////////////////////////////
const defineHidden = (object, key) => (0, _util.defineProperty)(object, key, {
writable: true
});
const config = (skema, name) => {
const value = skema[(0, _util.getKey)(name, _util.PREFIX_IS)]();
return (0, _util.isDefined)(value) ? value : true;
};
class Processor {
constructor(options) {
Object.assign(this, options);
const {
key,
rawParent,
input
} = this.context;
const {
isDefault
} = this.options;
this.isDefault = isDefault(rawParent, key);
this.input = input;
this.set = null;
}
mapKey() {
const {
skema,
options,
context
} = this;
const key = skema.hasKey() ? skema.key(this.args, context, options) : context.key;
return options.promise.resolve(key);
}
make() {
const {
values,
skema,
args,
context,
options
} = this;
const {
key,
input
} = context;
const symbolKey = (0, _future.symbol)(key);
defineHidden(values, symbolKey);
if (!this._clean) {
values[symbolKey] = input;
}
const writable = config(skema, 'writable');
const set = this.set = this.setters[key] = (value, // For the first time, we ignore writable
force, // Context
c) => {
if (!c) {
c = context;
}
c.input = value;
if (!writable && !force) {
throw c.errorByCode('NOT_WRITABLE', key);
}
const result = skema.f(args, c, options).then(value => {
return values[symbolKey] = value;
});
return options.promise.resolve(result, true);
};
(0, _util.defineProperty)(values, key, {
set: options.async ? () => {
throw context.errorByCode('ASSIGN_ASYNC');
} : v => set(v),
get: () => values[symbolKey],
configurable: config(skema, 'configurable'),
enumerable: config(skema, 'enumerable')
});
}
process() {
return this.mapKey().then(key => {
this.context.key = key;
this.make();
return this.shouldSkip();
}).then(skip => {
if (skip) {
return;
}
return this.set(this.input, true);
});
} // Returns whether we should skip checking
shouldSkip() {
const {
skema
} = this;
if (!skema.hasWhen()) {
return this._shouldSkip();
}
return skema.when(this.args, this.context, this.options).then(hit => {
if (!hit) {
// Skip
return true;
}
return this._shouldSkip();
});
}
_shouldSkip() {
const {
skema
} = this; // has the key
if (!this.isDefault) {
// not skip
return false;
} // If the key is required,
// optional and default are mutual exclusive,
// so we simply check optional first.
if (!skema.isOptional()) {
throw this.context.errorByCode('NOT_OPTIONAL', this.context.rawKey);
}
if (!skema.hasDefault()) {
// skip
return true;
}
return skema.default(this.args, this.context, this.options).then(value => {
this.input = value;
return false;
});
}
}
exports.Processor = Processor;