validata
Version:
Type safe data validation and sanitization
101 lines • 4.32 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.maybeAsRecord = exports.asRecord = exports.maybeRecord = exports.isRecord = void 0;
const common_1 = require("./common");
const types_1 = require("./types");
class Generic {
constructor() {
this.check = (value) => {
return typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);
};
this.convert = (value) => {
if (this.check(value))
return value;
try {
const result = JSON.parse(value);
if (typeof result !== 'object')
return undefined;
return result;
}
catch (error) {
return undefined;
}
};
this.process = (check, target, path) => {
const issues = [];
const output = {};
const keys = Object.keys(target);
keys.forEach((key) => {
const value = target[key];
const childResult = check.process(value, [...path, key]);
if ((0, types_1.isIssue)(childResult)) {
issues.push(...childResult.issues);
return;
}
if (childResult) {
output[key] = childResult.value;
}
else {
output[key] = value;
}
});
return issues.length ? { issues } : { value: output };
};
this.coerce = (options) => (next) => (value, path) => {
if (!options)
return next(value, path);
let coerced = value;
if (options.check) {
const result = this.process(options.check, coerced, path);
if ((0, types_1.isIssue)(result)) {
return result;
}
if (result) {
coerced = result.value;
}
}
return next(coerced, path);
};
this.validate = (value, path, options) => {
const result = (0, common_1.basicValidation)(value, path, options);
const keyCount = Object.keys(value).length;
const keyRegex = options.keyRegex;
if (keyRegex !== undefined) {
result.issues.push(...Object.keys(value).reduce((acc, key) => {
if (!keyRegex.test(key)) {
acc.push(types_1.Issue.forPath(path, value, 'key-regex', { key, regex: keyRegex.toString() }));
}
return acc;
}, []));
}
if (options.minKeys !== undefined && keyCount < options.minKeys) {
result.issues.push(types_1.Issue.forPath(path, value, 'min-keys', { keyCount, min: options.minKeys }));
}
if (options.maxKeys !== undefined && keyCount > options.maxKeys) {
result.issues.push(types_1.Issue.forPath(path, value, 'max-keys', { keyCount, max: options.maxKeys }));
}
return result;
};
}
}
const isRecord = (check, options) => {
const generic = new Generic();
return (0, common_1.createIsCheck)('record', generic.check, generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { check }));
};
exports.isRecord = isRecord;
const maybeRecord = (check, options) => {
const generic = new Generic();
return (0, common_1.createMaybeCheck)('record', generic.check, generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { check }));
};
exports.maybeRecord = maybeRecord;
const asRecord = (check, options) => {
const generic = new Generic();
return (0, common_1.createAsCheck)('record', generic.check, generic.convert, generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { check }));
};
exports.asRecord = asRecord;
const maybeAsRecord = (check, options) => {
const generic = new Generic();
return (0, common_1.createMaybeAsCheck)('record', generic.check, generic.convert, generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { check }));
};
exports.maybeAsRecord = maybeAsRecord;
//# sourceMappingURL=record.js.map
;