UNPKG

@yamamotok/dataobject

Version:

Decorator based JSON serializer and deserializer.

78 lines 3.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Factory = void 0; const factoryValueTransform_1 = require("./transformer/factoryValueTransform"); const getDescriptor_1 = require("./utils/getDescriptor"); const inContext_1 = require("./utils/inContext"); const validate_1 = require("./validator/validate"); const DataObjectError_1 = require("./DataObjectError"); const Decorator_1 = require("./Decorator"); const ValidationError_1 = require("./ValidationError"); class Factory { /** * Create factory method. * @param ctor the class * * Note: Avoid using `this` in this method. */ static createFactory(ctor) { return (_source, _context) => { const newObj = new ctor(); const source = (_source || {}); const properties = Decorator_1.Decorator.getPropertyMap(newObj); if (!properties) { throw new DataObjectError_1.DataObjectError('Implementation error, no decorated properties'); } properties.forEach((options, _key) => { const context = _context || Factory.DefaultContext; const key = _key; // Probably the property is just "getter". const newObjDescriptor = (0, getDescriptor_1.getDescriptor)(newObj, key); if (newObjDescriptor && !newObjDescriptor.writable && !newObjDescriptor.set) { return; } // Check if the given value to factory should be processed. // - It will be ignored if the value is `undefined`. // - `DataObjectError` will be thrown in case no value was given for `required()` decorated property. if (source[key] === undefined) { if (options === null || options === void 0 ? void 0 : options.required) { throw new DataObjectError_1.DataObjectError(`Required property "${key}" is missing`); } return; } // Skip property which is out of context if (!(0, inContext_1.inContext)(context, options === null || options === void 0 ? void 0 : options.context)) { return; } // Transform value const transformedValue = (0, factoryValueTransform_1.factoryValueTransform)({ key, sourceValue: source[key], context, options, }); newObj[key] = transformedValue; }); // Validation should be applied after the instance was created. const validationErrors = []; properties.forEach((options, _key) => { const context = _context || Factory.DefaultContext; const key = _key; if (!(0, inContext_1.inContext)(context, options === null || options === void 0 ? void 0 : options.context)) { return; } const validationError = (0, validate_1.validate)({ key, targetValue: newObj[key], options, context }); if (validationError) { validationErrors.push(validationError); } }); if (validationErrors.length > 0) { throw new ValidationError_1.ValidationError('Validation failed', validationErrors); } return newObj; }; } } exports.Factory = Factory; Factory.DefaultContext = 'factory'; //# sourceMappingURL=Factory.js.map