tynder
Version:
TypeScript friendly Data validator for JavaScript.
133 lines • 4.48 kB
JavaScript
;
// Copyright (c) 2019 Shellyl_N and Authors
// license: ISC
// https://github.com/shellyln
Object.defineProperty(exports, "__esModule", { value: true });
exports.patch = exports.pick = exports.pickRoot = void 0;
const errors_1 = require("./lib/errors");
const protection_1 = require("./lib/protection");
const validator_1 = require("./validator");
function pickMapper(value, ty) {
switch (ty.kind) {
case 'object':
{
const ret = Array.isArray(value) ? [] : {};
const dataMembers = new Set();
if (!Array.isArray(value)) {
for (const m in value) {
if (Object.prototype.hasOwnProperty.call(value, m)) {
dataMembers.add(m);
}
}
}
for (const x of ty.members) {
if (Object.hasOwnProperty.call(value, x[0])) {
dataMembers.delete(x[0]);
ret[x[0]] = value[x[0]];
}
}
if (ty.additionalProps && 0 < ty.additionalProps.length) {
function* getAdditionalMembers() {
for (const m of dataMembers.values()) {
yield m;
}
if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
yield String(i);
}
}
}
for (const m of getAdditionalMembers()) {
ret[m] = value[m];
}
}
return ret;
}
default:
return value;
}
}
function pickRoot(data, ty, ctx) {
switch (ty.kind) {
case 'never':
throw new errors_1.ValidationError(`Type unmatched: ${ty.kind}`, ty, ctx);
case 'any':
// FALL_THRU
case 'unknown':
// FALL_THRU
case 'primitive':
// FALL_THRU
case 'primitive-value':
// FALL_THRU
case 'repeated':
// FALL_THRU
case 'sequence':
// FALL_THRU
case 'one-of':
// FALL_THRU
case 'enum':
// FALL_THRU
case 'object':
{
const r = validator_1.validate(data, ty, ctx);
if (r) {
return r.value;
}
else {
throw new errors_1.ValidationError('Validation failed.', ty, ctx);
}
}
case 'spread':
case 'optional':
case 'symlink':
case 'operator':
throw new errors_1.ValidationError(`Unexpected type assertion: ${ty.kind}`, ty, ctx);
default:
throw new errors_1.ValidationError(`Unknown type assertion: ${ty.kind}`, ty, ctx);
}
}
exports.pickRoot = pickRoot;
function pick(data, ty, ctx) {
const ctx2 = Object.assign(Object.assign({ errors: [], typeStack: [] }, (ctx || {})), { mapper: pickMapper });
try {
return pickRoot(data, ty, ctx2);
}
finally {
if (ctx) {
ctx.errors = ctx2.errors;
}
}
}
exports.pick = pick;
function merge(data, needle) {
if (data === null || data === void 0) {
return needle;
}
switch (typeof data) {
case 'object':
if (Array.isArray(data)) {
return [...needle];
}
else {
const r = Object.assign({}, data);
for (const k in needle) {
if (Object.prototype.hasOwnProperty.call(needle, k)) {
if (protection_1.isUnsafeVarNames(r, k)) {
continue;
}
r[k] = merge(r[k], needle[k]);
}
}
return r;
}
default:
return needle;
}
}
function patch(data, needle, ty, ctx) {
const ctx2 = Object.assign({ errors: [], typeStack: [] }, (ctx || {}));
const validated = pick(needle, ty, ctx2);
return merge(data, validated);
}
exports.patch = patch;
//# sourceMappingURL=picker.js.map