UNPKG

validata

Version:

Type safe data validation and sanitization

102 lines 4.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.maybeAsObject = exports.asObject = exports.maybeObject = exports.isObject = 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 = (options) => (value) => { if (typeof value === 'string' && value[0] === '{' && value[value.length - 1] === '}') { try { return JSON.parse(value, options === null || options === void 0 ? void 0 : options.reviver); } catch (_a) { return undefined; } } return undefined; }; this.process = (contract, target, path) => { const issues = []; Object.keys(target).forEach((key) => { if (!(key in contract)) { issues.push(types_1.Issue.forPath([...path, key], target[key], 'unexpected-property')); } }); const output = {}; const keys = Object.keys(contract); keys.forEach((key) => { const check = contract[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.value === undefined && !(key in target)) 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 = Object.assign({}, value); if (!options.contract) return next(coerced, path); const ignoredProperties = {}; if (options.stripExtraProperties || options.ignoreExtraProperties) { const allowedProperties = new Set(Object.keys(options.contract)); Object.keys(coerced).forEach((key) => { if (allowedProperties.has(key)) return; ignoredProperties[key] = coerced[key]; delete coerced[key]; }); } const result = this.process(options.contract, coerced, path); if ((0, types_1.isIssue)(result)) return result; if (result) { coerced = result.value; if (options.ignoreExtraProperties) { Object.keys(ignoredProperties).forEach((key) => { coerced[key] = ignoredProperties[key]; }); } } return next(coerced, path); }; this.validate = (value, path, options) => (0, common_1.basicValidation)(value, path, options); } } const isObject = (contract, options) => { const generic = new Generic(); return (0, common_1.createIsCheck)('object', generic.check, generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { contract })); }; exports.isObject = isObject; const maybeObject = (contract, options) => { const generic = new Generic(); return (0, common_1.createMaybeCheck)('object', generic.check, generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { contract })); }; exports.maybeObject = maybeObject; const asObject = (contract, options) => { const generic = new Generic(); return (0, common_1.createAsCheck)('object', generic.check, generic.convert(options), generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { contract })); }; exports.asObject = asObject; const maybeAsObject = (contract, options) => { const generic = new Generic(); return (0, common_1.createMaybeAsCheck)('object', generic.check, generic.convert(options), generic.coerce, generic.validate)(Object.assign(Object.assign({}, options), { contract })); }; exports.maybeAsObject = maybeAsObject; //# sourceMappingURL=object.js.map