ts-comply
Version:
TypeTools is a Typescript library for providing extensible tooling runtime validations and type helpers.
478 lines • 22.6 kB
JavaScript
"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