UNPKG

ts-comply

Version:

TypeTools is a Typescript library for providing extensible tooling runtime validations and type helpers.

478 lines 22.6 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PropertiesController = exports.PropertiesControllerExtensionData = exports.PropertyController = exports.PropertyControlLayer = exports.PropertyAccessEvent = exports.PropertyAccessTrace = exports.PropertiesControllerSettings = void 0; var type_tools_1 = require("./type-tools"); var class_lineage_1 = require("./class-lineage"); var context_1 = require("./context"); var common_iface_1 = require("./upstream/common.iface"); var PropertiesControllerSettings = exports.PropertiesControllerSettings = (function (_super) { __extends(PropertiesControllerSettings, _super); function PropertiesControllerSettings(init) { var _this = _super.call(this, init) || this; _this.extensionPropertiesController = PropertiesControllerSettings.extensionPropertiesController; if (init) { Object.assign(_this, init); } return _this; } PropertiesControllerSettings.disabledGlobally = false; PropertiesControllerSettings.extensionPropertiesController = 'PropertiesController'; return PropertiesControllerSettings; }(type_tools_1.TypeToolsSettings)); var PropertyAccessTrace = (function () { function PropertyAccessTrace() { } return PropertyAccessTrace; }()); exports.PropertyAccessTrace = PropertyAccessTrace; var PropertyAccessEvent = (function () { function PropertyAccessEvent(init) { this.data = {}; this.ignoredClasses = []; if (init) { Object.assign(this, init); } } PropertyAccessEvent.prototype.clearData = function () { this.thrown = false; this.data = {}; this.ignoredClasses = []; this.value = null; this.oldValue = null; }; PropertyAccessEvent.prototype.cancel = function (message) { this.data.canceled = true; var e = { message: message, name: '', stack: '' }; this.data.cancelTrace = e; type_tools_1.TypeToolsBase.topCancel = e; context_1.Context.anyPropertyFailed = true; }; PropertyAccessEvent.prototype.throw = function (message) { this.thrown = true; this.data.stopped = true; var e = context_1.Context.throwErrors ? new Error(message) : { message: message, name: '', stack: '' }; this.data.error = e; type_tools_1.TypeToolsBase.topError = e; context_1.Context.anyPropertyFailed = true; }; PropertyAccessEvent.prototype.stopPropagation = function () { this.data.stopped = true; }; PropertyAccessEvent.prototype.transformValue = function (newValue) { this.value = this.data.value = newValue; }; PropertyAccessEvent.prototype.getStackTrace = function () { return new Error('PropertyAccessEvent Stack Trace').stack; }; PropertyAccessEvent.prototype.ignoreDefinitionsFrom = function () { var classes = []; for (var _i = 0; _i < arguments.length; _i++) { classes[_i] = arguments[_i]; } if (this.class === type_tools_1.UnknownClass) { throw type_tools_1.TypeToolsBase.reusedTrace('PropertyAccessEvent.ignoreDefinitionsFrom', "Cannot use ignoreDefinitionsFrom when class context is not specified; " + "consider using defineFor(className, () => {}) block when defining properties rubric."); } for (var _a = 0, classes_1 = classes; _a < classes_1.length; _a++) { var cls = classes_1[_a]; if (this.ignoredClasses.indexOf(cls) >= 0) { continue; } this.ignoredClasses.push(cls); } }; return PropertyAccessEvent; }()); exports.PropertyAccessEvent = PropertyAccessEvent; var PropertyControlLayer = (function () { function PropertyControlLayer(init) { this.throwError = true; if (init) { Object.assign(this, init); } } return PropertyControlLayer; }()); exports.PropertyControlLayer = PropertyControlLayer; var PropertyController = (function () { function PropertyController(init) { if (init) { Object.assign(this, init); } } PropertyController.prototype.orderHandlers = function () { this.getters = this.orderHandler(this.getters); this.setters = this.orderHandler(this.setters); this.changes = this.orderHandler(this.changes); }; PropertyController.prototype.orderHandler = function (handlers) { var fronts = []; var middles = []; var backs = []; for (var _i = 0, handlers_1 = handlers; _i < handlers_1.length; _i++) { var handler = handlers_1[_i]; if (handler.alwaysFront) { fronts.push(handler); } else if (handler.alwaysBack) { backs.push(handler); } else { middles.push(handler); } } fronts.sort(function (a, b) { return a.order - b.order; }); backs.sort(function (a, b) { return a.order - b.order; }); return fronts.concat(middles, backs); }; return PropertyController; }()); exports.PropertyController = PropertyController; var PropertiesControllerExtensionData = (function () { function PropertiesControllerExtensionData() { } return PropertiesControllerExtensionData; }()); exports.PropertiesControllerExtensionData = PropertiesControllerExtensionData; var PropertiesController = (function () { function PropertiesController(settings) { this.settings = (0, type_tools_1.settingsInitialize)(PropertiesControllerSettings, settings); } PropertiesController.getExtensionData = function (target, settings) { if (settings === void 0) { settings = PropertiesControllerSettings; } return type_tools_1.TypeToolsBase.getExtension(target, settings.extensionPropertiesController, settings); }; PropertiesController.typeCheck = function (target, settings) { if (settings === void 0) { settings = PropertiesControllerSettings; } return target && !!PropertiesController.getExtensionData(target, settings); }; PropertiesController.implementOn = function (target, settings) { if (settings === void 0) { settings = PropertiesControllerSettings; } if (!type_tools_1.TypeToolsBase.checkContext(PropertiesController)) { return false; } if (!PropertiesController.getExtensionData(target, settings)) { var extension = { managed: {}, errors: [], cancels: [], onerrors: [], oncancels: [], onpropertychanges: [], }; type_tools_1.TypeToolsBase.addExtension(target, settings.extensionPropertiesController, extension); Object.defineProperty(extension, '__meta_ignore', { value: { get: false, set: false } }); } return true; }; PropertiesController.manage = function (target, options, rubric, settings) { if (settings === void 0) { settings = PropertiesControllerSettings; } if (!PropertiesController.implementOn(target, settings)) { return; } if (!options) { options = {}; } var cls = context_1.Context.current ? context_1.Context.current : (type_tools_1.TypeToolsBase.slowResolveContext ? class_lineage_1.ClassLineage.getContextSlow(target) : type_tools_1.UnknownClass); var extension = PropertiesController.getExtensionData(target, settings); var errors = []; var orderBroken = options.alwaysFront || options.alwaysBack; if (orderBroken) { if (options.order === undefined || options.order === null) { options.order = 5; } } var targetProps = Object.keys(rubric); var _loop_1 = function (propName) { var propRubric = rubric[propName]; var reg = extension.managed[propName]; var typename = (0, common_iface_1.typeFullName)(cls); var accessMeta = new PropertyAccessEvent({ property: propName, className: typename, classRealPath: (0, common_iface_1.typeFullName)(cls), path: typename + '.' + propName, class: cls, }); if (propRubric.get) { propRubric.get.e = accessMeta; } if (propRubric.set) { propRubric.set.e = accessMeta; } if (propRubric.change) { propRubric.change.e = accessMeta; } if (propRubric.throwError === false) { propRubric.set.dontThrow = true; } if (reg) { if (propRubric.get) { if (options.prepend) { reg.getters.unshift(propRubric.get); } else { reg.getters.push(propRubric.get); } } if (propRubric.set) { if (options.prepend) { reg.setters.unshift(propRubric.set); } else { reg.setters.push(propRubric.set); } } if (propRubric.change) { if (options.prepend) { reg.changes.unshift(propRubric.change); } else { reg.changes.push(propRubric.change); } } } else { var proxiedValue_1 = { value: target[propName] }; reg = extension.managed[propName] = new PropertyController({ property: propName, valueKeeper: proxiedValue_1, getters: [], setters: [], changes: [], descriptor: null, getError: null, setError: null, extension: {}, }); if (propRubric.get) { if (options.prepend) { reg.getters.unshift(propRubric.get); } else { reg.getters.push(propRubric.get); } } if (propRubric.set) { if (options.prepend) { reg.setters.unshift(propRubric.set); } else { reg.setters.push(propRubric.set); } } if (propRubric.change) { if (options.prepend) { reg.changes.unshift(propRubric.change); } else { reg.changes.push(propRubric.change); } } reg.descriptor = { get: function () { if (context_1.Context.disabled || PropertiesControllerSettings.disabledGlobally) { return proxiedValue_1.value; } var value = proxiedValue_1.value; var ignoredClasses = {}; for (var _i = 0, _a = reg.getters; _i < _a.length; _i++) { var getter = _a[_i]; var evt = getter.e; if (ignoredClasses[(0, common_iface_1.typeFullName)(evt.class)] || context_1.Context.getter.ignoredClasses[(0, common_iface_1.typeFullName)(evt.class)]) { continue; } evt.clearData(); evt.value = value; var result = getter(value, evt); if (evt.data.value !== undefined) { value = evt.data.value; } if (evt.ignoredClasses.length > 0) { for (var _b = 0, _c = evt.ignoredClasses; _b < _c.length; _b++) { var ignoredClass = _c[_b]; ignoredClasses[(0, common_iface_1.typeFullName)(ignoredClass)] = true; } } if (result === false || evt.data.canceled) { break; } if (evt.data.stopped) { break; } } return value; }, set: function (newValue) { reg.setError = null; var oldValue = proxiedValue_1.value; if (context_1.Context.disabled || PropertiesControllerSettings.disabledGlobally) { proxiedValue_1.value = newValue; return newValue; } var errorTrace; var cancelTrace; var throwErrorDetected = context_1.Context.throwErrors; var ignoredClasses = {}; for (var _i = 0, _a = reg.setters; _i < _a.length; _i++) { var setter = _a[_i]; var evt = setter.e; try { if (ignoredClasses[(0, common_iface_1.typeFullName)(evt.class)] || context_1.Context.getter.ignoredClasses[(0, common_iface_1.typeFullName)(evt.class)]) { continue; } evt.clearData(); evt.oldValue = oldValue; evt.value = newValue; var result = setter(newValue, evt); if (evt.data.value !== undefined) { newValue = evt.data.value; } if (evt.ignoredClasses.length > 0) { for (var _b = 0, _c = evt.ignoredClasses; _b < _c.length; _b++) { var ignoredClass = _c[_b]; ignoredClasses[(0, common_iface_1.typeFullName)(ignoredClass)] = true; } } if (result === false || evt.data.canceled) { context_1.Context.anyPropertyFailed = true; newValue = proxiedValue_1.value; cancelTrace = { e: evt, trace: evt.data.cancelTrace ? evt.data.cancelTrace : type_tools_1.TypeToolsBase.reusedTrace(evt.path), }; break; } if (evt.data.stopped) { if (evt.data.error) { errorTrace = { e: evt, trace: evt.data.error }; } break; } } catch (e) { if (setter.dontThrow) { throwErrorDetected = false; } context_1.Context.anyPropertyFailed = true; type_tools_1.TypeToolsBase.topError = e; errorTrace = { trace: e, e: evt, }; break; } } if (cancelTrace) { if (context_1.Context.trackCancels) { extension.cancels.push(cancelTrace); } for (var _d = 0, _e = extension.oncancels; _d < _e.length; _d++) { var oncancel_1 = _e[_d]; oncancel_1(cancelTrace); } return oldValue; } if (errorTrace) { reg.setError = errorTrace.trace; if (context_1.Context.trackErrors) { extension.errors.push(errorTrace); } for (var _f = 0, _g = extension.onerrors; _f < _g.length; _f++) { var onerror_1 = _g[_f]; onerror_1(errorTrace); } if (throwErrorDetected) { throw errorTrace.trace; } return oldValue; } else { ignoredClasses = {}; proxiedValue_1.value = newValue; var subtreeProp = (oldValue && oldValue._get_args) || (newValue && newValue._get_args); if (oldValue !== newValue || subtreeProp) { for (var _h = 0, _j = reg.changes; _h < _j.length; _h++) { var onvaluechange = _j[_h]; var e = onvaluechange.e; if (ignoredClasses[(0, common_iface_1.typeFullName)(e.class)] || context_1.Context.change.ignoredClasses[(0, common_iface_1.typeFullName)(e.class)]) { continue; } e.clearData(); onvaluechange(oldValue, newValue, e); if (e.ignoredClasses.length > 0) { for (var _k = 0, _l = e.ignoredClasses; _k < _l.length; _k++) { var ignoredClass = _l[_k]; ignoredClasses[(0, common_iface_1.typeFullName)(ignoredClass)] = true; } } if (e.data.stopped) { break; } } } for (var _m = 0, _o = extension.onpropertychanges; _m < _o.length; _m++) { var onpropertychange = _o[_m]; onpropertychange(reg.property, oldValue, newValue, true); } return newValue; } }, }; try { Object.defineProperty(target, propName, reg.descriptor); } catch (e) { delete extension.managed[propName]; errors.push(e); return "continue"; } } if (orderBroken) { reg.extension.orderBroken = true; } }; for (var _i = 0, targetProps_1 = targetProps; _i < targetProps_1.length; _i++) { var propName = targetProps_1[_i]; _loop_1(propName); } for (var _a = 0, targetProps_2 = targetProps; _a < targetProps_2.length; _a++) { var propName = targetProps_2[_a]; var reg = extension.managed[propName]; if (reg && reg.extension.orderBroken) { reg.orderHandlers(); } } return errors; }; PropertiesController.getErrorTracesOf = function (target, settings) { if (settings === void 0) { settings = PropertiesControllerSettings; } var extension = PropertiesController.getExtensionData(target, settings); return extension.errors; }; PropertiesController.getCancelTracesOf = function (target, settings) { if (settings === void 0) { settings = PropertiesControllerSettings; } var extension = PropertiesController.getExtensionData(target, settings); return extension.cancels; }; PropertiesController.prototype.getExtensionData = function (target) { return PropertiesController.getExtensionData(target, this.settings); }; PropertiesController.prototype.typeCheck = function (target) { return PropertiesController.typeCheck(target, this.settings); }; PropertiesController.prototype.implementOn = function (target) { return PropertiesController.implementOn(target, this.settings); }; PropertiesController.prototype.manage = function (target, options, rubric) { return PropertiesController.manage(target, options, rubric, this.settings); }; return PropertiesController; }()); exports.PropertiesController = PropertiesController; //# sourceMappingURL=properties-controller.js.map