UNPKG

fluxtuate

Version:

a javascript ES7 library for handling complex data transactions

253 lines (190 loc) 11.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _class; var _coreDecorators = require("core-decorators"); var _getOwnPropertyDescriptors = require("../utils/getOwnPropertyDescriptors"); var _getOwnPropertyDescriptors2 = _interopRequireDefault(_getOwnPropertyDescriptors); var _internals = require("./_internals"); var _lang = require("lodash/lang"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var reservedWords = ["view", "payload"]; var injectionPropertyMap = Symbol("fluxtuateInjector_injectionPropertyMap"); var injectionClassMap = Symbol("fluxtuateInjector_injectionClassMap"); var hasInjection = Symbol("fluxtuateInjector_hasInjection"); var Injector = (0, _coreDecorators.autobind)(_class = function () { function Injector() { var _this = this; _classCallCheck(this, Injector); this[_internals.injectionValueMap] = {}; this[injectionPropertyMap] = {}; this[injectionClassMap] = {}; this[_internals.defaultValues] = {}; this[_internals.globalValues] = []; this[_internals.getInjectValue] = function (iKey) { var defaultInjection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var value = void 0; if (_this[_internals.injectionValueMap][iKey] !== undefined) value = _this[_internals.injectionValueMap][iKey];else if (_this[injectionPropertyMap][iKey] !== undefined) value = _this[injectionPropertyMap][iKey];else if (_this[injectionClassMap][iKey] !== undefined) value = _this[injectionClassMap][iKey];else if (defaultInjection[iKey] !== undefined) value = defaultInjection[iKey]; if (value[_internals.isPropertyInjection]) { _this.inject(value.object[value.property]); } else { _this.inject(value); } return value; }; this[_internals.applyInjectionSignature] = function (instance, signature) { instance[hasInjection] = signature; }; this[_internals.getInjectionSignature] = function (instance) { return instance[hasInjection]; }; } _createClass(Injector, [{ key: "hasInjection", value: function hasInjection(iKey) { return this[_internals.injectionValueMap][iKey] !== undefined || this[injectionPropertyMap][iKey] !== undefined || this[injectionClassMap][iKey] !== undefined; } }, { key: "mapKey", value: function mapKey(key) { if (reservedWords.indexOf(key) !== -1) throw new Error("\"" + key + "\" is a reserved word, use a different mapping for this value!"); if (Object.keys(this[_internals.defaultValues]).indexOf(key) !== -1) throw new Error("\"" + key + "\" is a reserved value in the injector! " + this[_internals.defaultValues][key] + "."); if (this[_internals.injectionValueMap][key]) throw new Error("The key " + key + " is already injected to value: " + this[_internals.injectionValueMap][key]); if (this[injectionPropertyMap][key]) throw new Error("The key " + key + " is already injected to value: " + this[injectionPropertyMap][key]); var self = this; return { toValue: function toValue(value) { if (self[injectionClassMap][key]) delete self[injectionClassMap][key]; if (self[injectionPropertyMap][key]) delete self[injectionPropertyMap][key]; self[_internals.injectionValueMap][key] = value; return self; }, toProperty: function toProperty(object, property) { if (self[_internals.injectionValueMap][key]) delete self[_internals.injectionValueMap][key]; if (self[injectionClassMap][key]) delete self[injectionClassMap][key]; self[injectionPropertyMap][key] = { object: object, property: property }; self[injectionPropertyMap][key][_internals.isPropertyInjection] = true; return self; }, toClass: function toClass(Class) { if (self[injectionClassMap][key]) { if (!(self[injectionClassMap][key] instanceof Class)) throw new Error("You are trying to inject a new class on a existing injection of " + key); return; } if (self[_internals.injectionValueMap][key]) delete self[_internals.injectionValueMap][key]; if (self[injectionPropertyMap][key]) delete self[injectionPropertyMap][key]; self[injectionClassMap][key] = new Class(); return self; } }; } }, { key: "removeKey", value: function removeKey(key) { if (reservedWords.indexOf(key) !== -1) throw new Error("\"" + key + "\" is a reserved word and can't be removed!"); if (Object.keys(this[_internals.defaultValues]).indexOf(key) !== -1) throw new Error("\"" + key + "\" is a reserved value in the context, and can't be removed! " + this[_internals.defaultValues][key] + "."); var keyMap = void 0; if (this[_internals.injectionValueMap][key]) { keyMap = this[_internals.injectionValueMap]; } else if (this[injectionPropertyMap][key]) { keyMap = this[injectionPropertyMap]; } else if (this[injectionClassMap][key]) { keyMap = this[injectionClassMap]; } if (!keyMap) return; delete keyMap[key]; } }, { key: "inherit", value: function inherit(injector) { for (var key in injector[_internals.injectionValueMap]) { if (reservedWords.indexOf(key) !== -1) continue; this[_internals.injectionValueMap][key] = injector[_internals.injectionValueMap][key]; } for (var _key in injector[injectionPropertyMap]) { if (reservedWords.indexOf(_key) !== -1) continue; this[injectionPropertyMap][_key] = injector[injectionPropertyMap][_key]; } for (var _key2 in injector[injectionClassMap]) { if (reservedWords.indexOf(_key2) !== -1) continue; this[injectionClassMap][_key2] = injector[injectionClassMap][_key2]; } } }, { key: "inject", value: function inject(instance) { var _this2 = this; var defaultInjection = {}; for (var _len = arguments.length, injections = Array(_len > 1 ? _len - 1 : 0), _key3 = 1; _key3 < _len; _key3++) { injections[_key3 - 1] = arguments[_key3]; } injections.forEach(function (injection) { if (!injection) return; if (injection instanceof Injector) { var parentInjector = injection; injection = Object.assign({}, injection[_internals.injectionValueMap], injection[injectionPropertyMap], injection[injectionClassMap], { parentInjector: parentInjector }); } if (!(0, _lang.isObject)(injection)) throw new Error("Injection defaults can only be a object literal!"); defaultInjection = Object.assign(defaultInjection, injection); }); var possibleInjections = Object.assign({}, defaultInjection, this[_internals.injectionValueMap], this[injectionPropertyMap], this[injectionClassMap]); var injectionSignature = JSON.stringify(Object.keys(possibleInjections)); if (this[_internals.getInjectionSignature](instance) === injectionSignature) return; var descriptorsInstance = instance; var descriptors = {}; while (descriptorsInstance && descriptorsInstance !== Object.prototype) { var newDescriptors = (0, _getOwnPropertyDescriptors2.default)(descriptorsInstance); for (var key in newDescriptors) { if (key === "constructor" || key === "__proto__" || key === "prototype") { continue; } if (!descriptors[key] || descriptors[key].configurable) { descriptors[key] = newDescriptors[key]; } } if (descriptorsInstance.prototype) { descriptorsInstance = descriptorsInstance.prototype; } else if (descriptorsInstance.__proto__) { descriptorsInstance = descriptorsInstance.__proto__; } else if (descriptorsInstance.constructor) { descriptorsInstance = descriptorsInstance.constructor.prototype; } else { descriptorsInstance = null; } } var _loop = function _loop(_key4) { var desc = descriptors[_key4]; if (!desc || !desc.value) return "continue"; var iKey = desc.value[_internals.injectionKey]; if (typeof desc.value === "function" || !iKey || possibleInjections[iKey] === undefined) { return "continue"; } if (!desc.configurable) return "continue"; var value = _this2[_internals.getInjectValue](iKey, defaultInjection); Object.defineProperty(instance, _key4, { get: function get() { if (value[_internals.isPropertyInjection]) { return value.object[value.property]; } else { return value; } }, enumerable: true, configurable: false }); }; for (var _key4 in descriptors) { var _ret = _loop(_key4); if (_ret === "continue") continue; } this[_internals.applyInjectionSignature](instance, injectionSignature); return instance; } }]); return Injector; }()) || _class; exports.default = Injector;