tsioc
Version:
tsioc is AOP, Ioc container, via typescript decorator
503 lines (501 loc) • 18.6 kB
JavaScript
;
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