UNPKG

validata

Version:

Type safe data validation and sanitization

101 lines 4.32 kB
"use strict"; 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