UNPKG

tsioc

Version:

tsioc is AOP, Ioc container, via typescript decorator

503 lines (501 loc) 18.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); require("reflect-metadata"); var DecoratorType_1 = require("./DecoratorType"); var ArgsIterator_1 = require("./ArgsIterator"); var index_1 = require("../../utils/index"); exports.ParamerterName = 'paramerter_names'; /** * create dectorator for class params props methods. * * @export * @template T * @param {string} name * @param {MetadataAdapter} [adapter] metadata adapter * @param {MetadataExtends<T>} [metadataExtends] add extents for metadata. * @returns {*} */ function createDecorator(name, adapter, metadataExtends) { var metaName = "@" + name; var factory = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var metadata = null; if (args.length < 1) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return storeMetadata(name, metaName, args, metadata, metadataExtends); }; } metadata = argsToMetadata(args, adapter); if (metadata) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return storeMetadata(name, metaName, args, metadata, metadataExtends); }; } else { if (args.length === 1) { if (!index_1.isClass(args[0])) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return storeMetadata(name, metaName, args, metadata, metadataExtends); }; } } } return storeMetadata(name, metaName, args, metadata, metadataExtends); }; factory.toString = function () { return metaName; }; factory.decoratorType = DecoratorType_1.DecoratorType.All; return factory; } exports.createDecorator = createDecorator; function argsToMetadata(args, adapter) { var metadata = null; if (args.length) { if (args.length === 1 && index_1.isMetadataObject(args[0])) { metadata = args[0]; } else if (adapter) { var iterator = new ArgsIterator_1.ArgsIterator(args); adapter(iterator); metadata = iterator.getMetadata(); } } return metadata; } function storeMetadata(name, metaName, args, metadata, metadataExtends) { var target; switch (args.length) { case 1: target = args[0]; if (index_1.isClass(target) || index_1.isAbstractDecoratorClass(target)) { setTypeMetadata(name, metaName, target, metadata, metadataExtends); return target; } break; case 2: target = args[0]; var propertyKey = args[1]; setPropertyMetadata(name, metaName, target, propertyKey, metadata, metadataExtends); break; case 3: if (index_1.isNumber(args[2])) { target = args[0]; var propertyKey_1 = args[1]; var parameterIndex = args[2]; setParamMetadata(name, metaName, target, propertyKey_1, parameterIndex, metadata, metadataExtends); } else if (index_1.isUndefined(args[2])) { target = args[0]; var propertyKey_2 = args[1]; setPropertyMetadata(name, metaName, target, propertyKey_2, metadata, metadataExtends); } else { target = args[0]; var propertyKey_3 = args[1]; var descriptor = args[2]; setMethodMetadata(name, metaName, target, propertyKey_3, descriptor, metadata, metadataExtends); return descriptor; } break; default: throw new Error("Invalid @" + name + " Decorator declaration."); } } /** * get all class metadata of one specail decorator in target type. * * @export * @template T * @param {(string | Function)} decorator * @param {Type<any>} target * @returns */ function getTypeMetadata(decorator, target) { var annotations = Reflect.getOwnMetadata(index_1.isFunction(decorator) ? decorator.toString() : decorator, target); annotations = index_1.isArray(annotations) ? annotations : []; return annotations; } exports.getTypeMetadata = getTypeMetadata; /** * get own class metadata of one specail decorator in target type. * * @export * @template T * @param {(string | Function)} decorator * @param {Type<any>} target * @returns */ function getOwnTypeMetadata(decorator, target) { var annotations = Reflect.getOwnMetadata(index_1.isFunction(decorator) ? decorator.toString() : decorator, target); annotations = index_1.isArray(annotations) ? annotations : []; return annotations; } exports.getOwnTypeMetadata = getOwnTypeMetadata; /** * has class decorator metadata. * * @export * @param {(string | Function)} decorator * @param {(Type<any> | object)} target * @returns {boolean} */ function hasClassMetadata(decorator, target) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; return Reflect.hasMetadata(name, target); } exports.hasClassMetadata = hasClassMetadata; /** * has own class decorator metadata. * * @export * @param {(string | Function)} decorator * @param {(Type<any> | object)} target * @returns {boolean} */ function hasOwnClassMetadata(decorator, target) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; return Reflect.hasOwnMetadata(name, target); } exports.hasOwnClassMetadata = hasOwnClassMetadata; function setTypeMetadata(name, metaName, target, metadata, metadataExtends) { var annotations = getOwnTypeMetadata(metaName, target).slice(0); // let designParams = Reflect.getMetadata('design:paramtypes', target) || []; var typeMetadata = (metadata || {}); if (!typeMetadata.type) { typeMetadata.type = target; } typeMetadata.decorator = name; if (metadataExtends) { typeMetadata = metadataExtends(typeMetadata); } annotations.unshift(typeMetadata); setParamerterNames(target); Reflect.defineMetadata(metaName, annotations, target); } var methodMetadataExt = '__method'; /** * get all method metadata of one specail decorator in target type. * * @export * @template T * @param {(string | Function)} decorator * @param {Type<any>} target * @returns {ObjectMap<T[]>} */ function getMethodMetadata(decorator, target) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; var meta = Reflect.getMetadata(name + methodMetadataExt, target); if (!meta || index_1.isArray(meta) || Object.keys(meta).length < 0) { meta = Reflect.getMetadata(name + methodMetadataExt, target.constructor); } return index_1.isArray(meta) ? {} : (meta || {}); } exports.getMethodMetadata = getMethodMetadata; /** * get own method metadata of one specail decorator in target type. * * @export * @template T * @param {(string | Function)} decorator * @param {Type<any>} target * @returns {ObjectMap<T[]>} */ function getOwnMethodMetadata(decorator, target) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; var meta = Reflect.getOwnMetadata(name + methodMetadataExt, target); if (!meta || index_1.isArray(meta) || Object.keys(meta).length < 0) { meta = Reflect.getOwnMetadata(name + methodMetadataExt, target.constructor); } return index_1.isArray(meta) ? {} : (meta || {}); } exports.getOwnMethodMetadata = getOwnMethodMetadata; /** * has own method decorator metadata. * * @export * @param {(string | Function)} decorator * @param {Type<any>} target * @param {(string | symbol)} [propertyKey] * @returns {boolean} */ function hasOwnMethodMetadata(decorator, target, propertyKey) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; if (propertyKey) { var meta = getOwnMethodMetadata(name, target); return meta && meta.hasOwnProperty(propertyKey); } else { return Reflect.hasOwnMetadata(name + methodMetadataExt, target); } } exports.hasOwnMethodMetadata = hasOwnMethodMetadata; /** * has method decorator metadata. * * @export * @param {(string | Function)} decorator * @param {Type<any>} target * @param {(string | symbol)} [propertyKey] * @returns {boolean} */ function hasMethodMetadata(decorator, target, propertyKey) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; if (propertyKey) { var meta = getMethodMetadata(name, target); return meta && meta.hasOwnProperty(propertyKey); } else { return Reflect.hasMetadata(name + methodMetadataExt, target); } } exports.hasMethodMetadata = hasMethodMetadata; function setMethodMetadata(name, metaName, target, propertyKey, descriptor, metadata, metadataExtends) { var meta = Object.assign({}, getMethodMetadata(metaName, target)); meta[propertyKey] = meta[propertyKey] || []; var methodMeadata = (metadata || {}); methodMeadata.decorator = name; methodMeadata.propertyKey = propertyKey; // methodMeadata.descriptor = descriptor; if (metadataExtends) { methodMeadata = metadataExtends(methodMeadata); } meta[propertyKey].unshift(methodMeadata); Reflect.defineMetadata(metaName + methodMetadataExt, meta, target.constructor); } var propertyMetadataExt = '__props'; /** * get all property metadata of one specail decorator in target type. * * @export * @template T * @param {(string | Function)} decorator * @param {Type<any>} target * @returns {ObjectMap<T[]>} */ function getPropertyMetadata(decorator, target) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; var meta = Reflect.getMetadata(name + propertyMetadataExt, target); if (!meta || index_1.isArray(meta) || Object.keys(meta).length < 0) { meta = Reflect.getMetadata(name + propertyMetadataExt, target.constructor); } return index_1.isArray(meta) ? {} : (meta || {}); } exports.getPropertyMetadata = getPropertyMetadata; /** * get own property metadata of one specail decorator in target type. * * @export * @template T * @param {(string | Function)} decorator * @param {Type<any>} target * @returns {ObjectMap<T[]>} */ function getOwnPropertyMetadata(decorator, target) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; var meta = Reflect.getOwnMetadata(name + propertyMetadataExt, target); if (!meta || index_1.isArray(meta) || Object.keys(meta).length < 0) { meta = Reflect.getOwnMetadata(name + propertyMetadataExt, target.constructor); } return index_1.isArray(meta) ? {} : (meta || {}); } exports.getOwnPropertyMetadata = getOwnPropertyMetadata; /** * has property decorator metadata. * * @export * @param {(string | Function)} decorator * @param {Type<any>} target * @param {(string | symbol)} [propertyKey] * @returns {boolean} */ function hasPropertyMetadata(decorator, target, propertyKey) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; if (propertyKey) { var meta = getPropertyMetadata(name, target); return meta && meta.hasOwnProperty(propertyKey); } else { return Reflect.hasMetadata(name + propertyMetadataExt, target); } } exports.hasPropertyMetadata = hasPropertyMetadata; function setPropertyMetadata(name, metaName, target, propertyKey, metadata, metadataExtends) { var meta = Object.assign({}, getPropertyMetadata(metaName, target)); var propmetadata = (metadata || {}); propmetadata.propertyKey = propertyKey; propmetadata.decorator = name; if (!propmetadata.type) { var t = Reflect.getMetadata('design:type', target, propertyKey); if (!t) { // Needed to support react native inheritance t = Reflect.getMetadata('design:type', target.constructor, propertyKey); } propmetadata.type = t; } if (metadataExtends) { propmetadata = metadataExtends(propmetadata); } if (!meta[propertyKey] || !index_1.isArray(meta[propertyKey])) { meta[propertyKey] = []; } meta[propertyKey].unshift(propmetadata); Reflect.defineMetadata(metaName + propertyMetadataExt, meta, target.constructor); } var paramsMetadataExt = '__params'; /** * get paramerter metadata of one specail decorator in target method. * * @export * @template T * @param {(string | Function)} decorator * @param {(Type<any> | object)} target * @param {(string | symbol)} propertyKey * @returns {T[][]} */ function getParamMetadata(decorator, target, propertyKey) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; var parameters = Reflect.getMetadata(name + paramsMetadataExt, target, propertyKey); parameters = index_1.isArray(parameters) ? parameters : []; return parameters; } exports.getParamMetadata = getParamMetadata; /** * get own paramerter metadata of one specail decorator in target method. * * @export * @template T * @param {(string | Function)} decorator * @param {(Type<any> | object)} target * @param {(string | symbol)} propertyKey * @returns {T[][]} */ function getOwnParamMetadata(decorator, target, propertyKey) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; var parameters = Reflect.getOwnMetadata(name + paramsMetadataExt, target, propertyKey); parameters = index_1.isArray(parameters) ? parameters : []; return parameters; } exports.getOwnParamMetadata = getOwnParamMetadata; /** * has param decorator metadata. * * @export * @param {(string | Function)} decorator * @param {(Type<any> | object)} target * @param {(string | symbol)} propertyKey * @returns {boolean} */ function hasParamMetadata(decorator, target, propertyKey) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; return Reflect.hasMetadata(name + paramsMetadataExt, target, propertyKey); } exports.hasParamMetadata = hasParamMetadata; /** * has param decorator metadata. * * @export * @param {(string | Function)} decorator * @param {(Type<any> | object)} target * @param {(string | symbol)} propertyKey * @returns {boolean} */ function hasOwnParamMetadata(decorator, target, propertyKey) { var name = index_1.isFunction(decorator) ? decorator.toString() : decorator; return Reflect.hasOwnMetadata(name + paramsMetadataExt, target, propertyKey); } exports.hasOwnParamMetadata = hasOwnParamMetadata; function setParamMetadata(name, metaName, target, propertyKey, parameterIndex, metadata, metadataExtends) { var parameters = getOwnParamMetadata(metaName, target, propertyKey).slice(0); // there might be gaps if some in between parameters do not have annotations. // we pad with nulls. while (parameters.length <= parameterIndex) { parameters.push(null); } parameters[parameterIndex] = parameters[parameterIndex] || []; var paramMeadata = (metadata || {}); if (!paramMeadata.type) { var t = Reflect.getOwnMetadata('design:type', target, propertyKey); if (!t) { // Needed to support react native inheritance t = Reflect.getOwnMetadata('design:type', target.constructor, propertyKey); } paramMeadata.type = t; } paramMeadata.propertyKey = propertyKey; paramMeadata.decorator = name; paramMeadata.index = parameterIndex; if (metadataExtends) { paramMeadata = metadataExtends(paramMeadata); } parameters[parameterIndex].unshift(paramMeadata); Reflect.defineMetadata(metaName + paramsMetadataExt, parameters, target, propertyKey); } function getParamerterNames(target) { var meta = Reflect.getMetadata(exports.ParamerterName, target); if (!meta || index_1.isArray(meta) || Object.keys(meta).length < 0) { meta = Reflect.getMetadata(exports.ParamerterName, target.constructor); } return index_1.isArray(meta) ? {} : (meta || {}); } exports.getParamerterNames = getParamerterNames; function getOwnParamerterNames(target) { var meta = Reflect.getOwnMetadata(exports.ParamerterName, target); if (!meta || index_1.isArray(meta) || Object.keys(meta).length < 0) { meta = Reflect.getOwnMetadata(exports.ParamerterName, target.constructor); } return index_1.isArray(meta) ? {} : (meta || {}); } exports.getOwnParamerterNames = getOwnParamerterNames; function setParamerterNames(target) { var meta = Object.assign({}, getParamerterNames(target)); var descriptors = Object.getOwnPropertyDescriptors(target.prototype); var isUglify = /^[a-z]/.test(target.name); var anName = ''; if (target.classAnnations && target.classAnnations.params) { anName = target.classAnnations.name; meta = Object.assign(meta, target.classAnnations.params); } if (!isUglify && target.name !== anName) { Object.keys(descriptors).forEach(function (name) { if (name !== 'constructor') { if (descriptors[name].value) { meta[name] = getParamNames(descriptors[name].value); } if (descriptors[name].set) { meta[name] = getParamNames(descriptors[name].set); } } }); meta['constructor'] = getParamNames(target.prototype.constructor); } Reflect.defineMetadata(exports.ParamerterName, meta, target); } exports.setParamerterNames = setParamerterNames; var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; var ARGUMENT_NAMES = /([^\s,]+)/g; function getParamNames(func) { if (!index_1.isFunction(func)) { return []; } var fnStr = func.toString().replace(STRIP_COMMENTS, ''); var result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); if (result === null) { result = []; } return result; } //# sourceMappingURL=../../sourcemaps/core/factories/DecoratorFactory.js.map