UNPKG

@lucaspaganini/value-objects

Version:

TypeScript first validation and class creation library

140 lines 4.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VOObject = void 0; var utils_1 = require("../utils"); var errors_1 = require("./errors"); var functions_1 = require("./functions"); /** * Function to create an object wrapper over a given map of value * object constructors. Useful if you have different classes and * want to aggregate them. * * @template Schema Object mapping to value object constructors. * @param schema Object mapping to value object constructors. * @param options Customizations for the returned class constructor. * @return Class constructor that accepts an object mapping it's keys * and values to what the inner value object constructors expect. * Calling {@link VOObjectInstance.valueOf} calls `valueOf()` for all it's inner instances * and returns them in an object. * * @example * ```typescript * class Email extends VOString({ ... }) { * getHost(): string { ... } * } * * class Name extends VOString({ ... }) {} * * class Password extends VOString({ ... }) {} * * class User extends VOObject({ * name: Name, * email: Email, * password: Password * }) {} * * new User({ * name: 'Lucas', * email: 'me@lucaspaganini.com', * password: 'Secret123' * }); // OK * * new User({ * name: 'Lucas', * email: 123, * password: 'Secret123' * }); // Compilation error: `.email` expects a string * * new User({ * name: 'Lucas', * email: 'lucaspaganini.com', * password: 'Secret123' * }); // Runtime error: `.email` Value doesn't match pattern * * const user = new User({ * name: 'Lucas', * email: 'me@lucaspaganini.com', * password: 'Secret123' * }); * * user.valueOf(); // { name: 'Lucas', email: 'me@lucaspaganini.com', password: 'Secret123' } * user.email.getHost(); // lucaspaganini.com * ``` * * @example * ```typescript * class Test { * constructor(shouldThrow: boolean) { * if (shouldThrow) throw Error('I was instructed to throw'); * } * } * new Test(false); // OK * new Test(true); // Runtime error: I was instructed to throw * * class TestsObject extends VoObject({ * aaa: Test, * bbb: Test, * ccc: Test * }, { maxErrors: 2 }) {} * new TestsArray({ aaa: false, bbb: false, ccc: false }); // OK * new TestsArray({ aaa: true, bbb: true, ccc: true }); // Runtime error: ["I was instructed to throw", "I was instructed to throw"] * ``` */ var VOObject = function (schema, options) { var _a; if (options === void 0) { options = {}; } if (utils_1.isDefined(options.maxErrors)) { if (typeof options.maxErrors !== 'number') throw new errors_1.RawTypeError('number', typeof options.maxErrors, 'options.maxErrors'); if (!Number.isInteger(options.maxErrors)) throw new errors_1.NotIntegerError(options.maxErrors, 'options.maxErrors'); if (options.maxErrors < 0) throw new errors_1.MinSizeError(options.maxErrors, 0); } var maxErrors = (_a = options.maxErrors) !== null && _a !== void 0 ? _a : 1; return /** @class */ (function () { function class_1(raw) { if (utils_1.isNil(raw)) throw new errors_1.RawTypeError('object', typeof raw, 'raw'); var errors = []; var _loop_1 = function (prop, VO) { var fromRaw = functions_1.makeFromRawInit(VO); var either = fromRaw(raw[prop]); if (utils_1.isLeft(either)) { var errorsWithProp = either.left.map(function (e) { if (errors_1.VOError.is(e)) e.path.push(prop); return e; }); errors.push.apply(errors, errorsWithProp); if (errors.length >= maxErrors) throw errors; } else { ; this_1[prop] = either.right; } }; var this_1 = this; for (var _i = 0, _a = Object.entries(schema); _i < _a.length; _i++) { var _b = _a[_i], prop = _b[0], VO = _b[1]; _loop_1(prop, VO); } if (errors.length > 0) throw errors; } class_1.prototype.valueOf = function () { var _this = this; return Object.keys(schema).reduce(function (acc, key) { acc[key] = _this[key].valueOf(); return acc; }, {}); }; class_1.prototype.toRaw = function () { return this.valueOf(); }; return class_1; }()); }; exports.VOObject = VOObject; //# sourceMappingURL=object.js.map