specified
Version:
Type-safe typescript data specification verification
189 lines (188 loc) • 6.85 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var validation_error_1 = require("./validation_error");
exports.verify = function (spec, value, globalOptions, verifyOptions) {
if (globalOptions === void 0) { globalOptions = {}; }
if (verifyOptions === void 0) { verifyOptions = { errorClass: validation_error_1.ValidationError }; }
if (spec.version === 1) {
var result_1 = spec.eval(value, { global: globalOptions });
if (result_1.err) {
return {
err: result_1.err,
value: function () {
throw new verifyOptions.errorClass(result_1.err.message, result_1.err);
}
};
}
else {
return {
err: null,
value: function () { return result_1.value; }
};
}
}
else {
throw Error("Unknown spec version '" + spec.version + "'");
}
};
exports.alias = function (aliasName, spec) {
if (spec.version === 1) {
return {
version: 1,
definition: __assign({}, spec.definition, { alias: aliasName }),
eval: spec.eval
};
}
else {
throw Error("Unknown spec version '" + spec.version + "'");
}
};
var removeAlias = function (specDef) {
var def = __assign({}, specDef);
delete def.alias;
return def;
};
exports.constrain = function (spec, constraints) {
if (spec.version === 1) {
if (constraints.reduce(function (r, constraint) { return r && constraint.version === 1; }, true)) {
return {
version: 1,
definition: __assign({}, removeAlias(spec.definition), { constraints: (spec.definition.constraints || []).concat(constraints.map(function (c) { return c.definition; })) }),
eval: function (value, options) {
var candidateResult = spec.eval(value, options);
if (!candidateResult.err) {
for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) {
var c = constraints_1[_i];
var err = c.eval(candidateResult.value).err;
if (err) {
return { err: err };
}
}
}
return candidateResult;
}
};
}
else {
throw Error("Unknown constraint version '" + constraints.map(function (c) { return c.version; }) + "'");
}
}
else {
throw Error("Unknown spec version '" + spec.version + "'");
}
};
function optional(spec, options) {
if (spec.version === 1) {
if (options && typeof options.defaultValue !== "undefined") {
var defaultValue = options.hasOwnProperty("defaultValue") ? { defaultValue: options.defaultValue } : {};
return __assign({ version: 1, definition: __assign({}, spec.definition, { flags: (spec.definition.flags || []).concat(["optional"]) }, defaultValue), eval: spec.eval, optional: false }, defaultValue);
}
else {
return {
version: 1,
definition: __assign({}, spec.definition, { flags: (spec.definition.flags || []).concat(["optional"]) }),
eval: spec.eval,
optional: true
};
}
}
else {
throw Error("Unknown spec version '" + spec.version + "'");
}
}
exports.optional = optional;
exports.adjust = function (spec, adjustedOptions) {
if (spec.version === 1) {
return {
version: 1,
definition: __assign({}, removeAlias(spec.definition), { adjustments: __assign({}, adjustedOptions, spec.definition.adjustments) }),
eval: function (value, options) {
return spec.eval(value, { local: __assign({}, adjustedOptions, options.local), global: options.global });
}
};
}
else {
throw Error("Unknown spec version '" + spec.version + "'");
}
};
exports.definitionOf = function (spec) {
if (spec.version === 1) {
return spec.definition;
}
else {
throw Error("Unknown spec version '" + spec.version + "'");
}
};
var _extractAliases = function (def, aliases) {
var aliasedDefinition = __assign({}, def, (def.nested ? { nested: Object.keys(def.nested).reduce(function (o, k) {
var nt = def.nested[k];
o[k] = _extractAliases(nt, aliases);
return o;
}, {}) } : {}));
if (def.alias) {
aliases[def.alias] = aliasedDefinition;
return { alias: def.alias };
}
else {
return aliasedDefinition;
}
};
exports.extractAliases = function (def) {
var aliases = {};
return {
definition: _extractAliases(def, aliases),
aliases: aliases
};
};
exports.either = function () {
var specs = [];
for (var _i = 0; _i < arguments.length; _i++) {
specs[_i] = arguments[_i];
}
if (specs.reduce(function (r, spec) { return r && spec.version === 1; }, true)) {
var nested = specs.reduce(function (n, spec, index) {
n[index + 1] = spec.definition;
return n;
}, {});
return {
version: 1,
definition: {
type: "either",
nested: nested
},
eval: function (value, options) {
var validationErrors = [];
for (var _i = 0, specs_1 = specs; _i < specs_1.length; _i++) {
var spec = specs_1[_i];
var result = spec.eval(value, { global: options.global });
if (result.err) {
validationErrors.push(result.err);
}
else {
return result;
}
}
return { err: {
code: "either.no_matching_spec",
value: value,
message: "Evaluation of value failed for every possible spec.",
nestedErrors: validationErrors
} };
}
};
}
else {
throw Error("Unknown spec version '" + specs.map(function (spec) { return spec.version; }) + "'");
}
};