castage
Version:
A type-safe library for dynamic object casting and ensuring type consistency in JavaScript/TypeScript.
54 lines (53 loc) • 2.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.struct = void 0;
const resultage_1 = require("resultage");
const engine_js_1 = require("./engine.js");
const casting_error_js_1 = require("./casting-error.js");
const types_js_1 = require("./types.js");
const predicates_js_1 = require("./predicates.js");
const tools_js_1 = require("./tools.js");
const errMissingValue = (error, caster) => (0, casting_error_js_1.castingErr)(types_js_1.ERR_MISSING_VALUE, error.path, { expected: caster.name });
const defaultStructName = (casters) => `{ ${Object.entries(casters)
.map(([k, v]) => `${String(k)}: ${v.name}`)
.join(', ')} }`;
const transform = (casters) => (value, path) => {
const result = {};
const keys = (0, tools_js_1.propertyKeys)(casters);
for (let i = 0; i < keys.length; i += 1) {
const k = keys[i];
const caster = casters[k];
const v = value[k];
const kResult = caster(v, [...path, String(k)]).mapErr((error) => !(0, tools_js_1.hasOwn)(value, k) ? errMissingValue(error, caster) : error);
if (kResult.isErr)
return kResult;
result[k] = kResult.unwrap();
}
return (0, resultage_1.ok)(result);
};
const parse = (casters) => (value, path) => {
const result = {};
const keys = (0, tools_js_1.propertyKeys)(casters);
const errors = [];
for (let i = 0; i < keys.length; i += 1) {
const k = keys[i];
const caster = casters[k];
const v = value[k];
const kResult = caster
.parse(v, [...path, String(k)])
.mapErr((errors) => errors.map((error) => !(0, tools_js_1.hasOwn)(value, k) ? errMissingValue(error, caster) : error));
if (kResult.isErr) {
errors.push(...kResult.error);
continue;
}
result[k] = kResult.unwrap();
}
return errors.length === 0 ? (0, resultage_1.ok)(result) : (0, resultage_1.err)(errors);
};
const struct = (casters, name = defaultStructName(casters)) => Object.defineProperties((0, engine_js_1.fromGuardAndTransform)(predicates_js_1.isObject, transform(casters), name, types_js_1.ERR_INVALID_VALUE_TYPE, parse(casters)), {
schema: {
enumerable: true,
get: () => casters,
},
});
exports.struct = struct;