diff --git a/dist/automapper.js b/dist/automapper.js index dfab145..ee7e2f7 100644 --- a/dist/automapper.js +++ b/dist/automapper.js @@ -5,7 +5,7 @@ * Copyright 2015 Bert Loedeman and other contributors * Released under the MIT license * - * Date: 2016-04-28T16:00:00.000Z + * Date: 2016-06-02T15:00:00.000Z */ var AutoMapperJs; (function (AutoMapperJs) { @@ -17,6 +17,9 @@ var AutoMapperJs; function AutoMapperHelper() { } AutoMapperHelper.getClassName = function (classType) { + if (classType && classType.name) { + return classType.name; + } // source: http://stackoverflow.com/a/13914278/702357 if (classType && classType.constructor) { var className = classType.toString(); diff --git a/dist/automapper.min.js b/dist/automapper.min.js index e72ebdc..3cb7d3d 100644 --- a/dist/automapper.min.js +++ b/dist/automapper.min.js @@ -5,9 +5,9 @@ * Copyright 2015 Bert Loedeman and other contributors * Released under the MIT license * - * Date: 2016-04-28T16:00:00.000Z + * Date: 2016-06-02T15:00:00.000Z */ -var AutoMapperJs;!function(n){"use strict";var r=function(){function n(){}return n.getClassName=function(n){if(n&&n.constructor){var r=n.toString();if(r){var t=r.match(/function\s*(\w+)/);if(t&&2===t.length)return t[1]}if(n.constructor.name)return n.constructor.name;if(n.constructor.toString()){var e=n.constructor.toString();if("["===e.charAt(0))var i=e.match(/\[\w+\s*(\w+)\]/);else var i=e.match(/function\s*(\w+)/);if(i&&2===i.length)return i[1]}}throw new Error("Unable to extract class name from type '"+n+"'")},n.getFunctionParameters=function(n){var r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,t=/([^\s,]+)/g,e=n.toString().replace(r,""),i=e.slice(e.indexOf("(")+1,e.indexOf(")")).match(t);return null===i&&(i=new Array),i},n.handleCurrying=function(n,r,t){function e(r,i,o){for(var a=i.slice(0),c=o,u=0;u=1?o[0]:"",c=e?r:n.getMapFromString(i,r,a),u={destination:r,source:c,sourceMapping:e,condition:null,ignore:n.getIgnoreFromString(i,r),async:2===o.length};return!u.async&&n.getFunctionCallIndex(i,"condition",a)>=0&&(u.condition=n.getConditionFromFunction(t,c)),u},n.getIgnoreFromString=function(r,t){var e=n.getFunctionCallIndex(r,"ignore",t);if(0>e)return!1;var i=r.indexOf("(",e)+1,o=r.indexOf(")",i);if(0>i||0>o)return!1;var a=r.substring(i,o).replace(/\r/g,"").replace(/\n/g,"").trim();return null===a||""===a},n.getMapFromString=function(r,t,e){var i=n.getFunctionCallIndex(r,"mapFrom",e);if(0>i)return t;var o=r.indexOf("(",i)+1,a=r.indexOf(")",o);if(0>o||0>a)return t;var c=r.substring(o,a).replace(/'/g,"").replace(/"/g,"").trim();return null===c||""===c?t:c},n.getFunctionCallIndex=function(n,r,t){var e=n.indexOf(t+"."+r);return 0>e&&(e=n.indexOf("."+r)),e},n.getConditionFromFunction=function(n,r){var t={};t[r]={};var e,i={ignore:function(){},condition:function(n){e=n},mapFrom:function(n){},sourceObject:t,sourcePropertyName:r,intermediatePropertyValue:{}};try{n(i)}catch(o){}return e},n}();n.AutoMapperHelper=r}(AutoMapperJs||(AutoMapperJs={})); +var AutoMapperJs;!function(n){"use strict";var r=function(){function n(){}return n.getClassName=function(n){if(n&&n.name)return n.name;if(n&&n.constructor){var r=n.toString();if(r){var t=r.match(/function\s*(\w+)/);if(t&&2===t.length)return t[1]}if(n.constructor.name)return n.constructor.name;if(n.constructor.toString()){var e=n.constructor.toString();if("["===e.charAt(0))var i=e.match(/\[\w+\s*(\w+)\]/);else var i=e.match(/function\s*(\w+)/);if(i&&2===i.length)return i[1]}}throw new Error("Unable to extract class name from type '"+n+"'")},n.getFunctionParameters=function(n){var r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,t=/([^\s,]+)/g,e=n.toString().replace(r,""),i=e.slice(e.indexOf("(")+1,e.indexOf(")")).match(t);return null===i&&(i=new Array),i},n.handleCurrying=function(n,r,t){function e(r,i,o){for(var a=i.slice(0),u=o,c=0;c=1?o[0]:"",u=e?r:n.getMapFromString(i,r,a),c={destination:r,source:u,sourceMapping:e,condition:null,ignore:n.getIgnoreFromString(i,r),async:2===o.length};return!c.async&&n.getFunctionCallIndex(i,"condition",a)>=0&&(c.condition=n.getConditionFromFunction(t,u)),c},n.getIgnoreFromString=function(r,t){var e=n.getFunctionCallIndex(r,"ignore",t);if(0>e)return!1;var i=r.indexOf("(",e)+1,o=r.indexOf(")",i);if(0>i||0>o)return!1;var a=r.substring(i,o).replace(/\r/g,"").replace(/\n/g,"").trim();return null===a||""===a},n.getMapFromString=function(r,t,e){var i=n.getFunctionCallIndex(r,"mapFrom",e);if(0>i)return t;var o=r.indexOf("(",i)+1,a=r.indexOf(")",o);if(0>o||0>a)return t;var u=r.substring(o,a).replace(/'/g,"").replace(/"/g,"").trim();return null===u||""===u?t:u},n.getFunctionCallIndex=function(n,r,t){var e=n.indexOf(t+"."+r);return 0>e&&(e=n.indexOf("."+r)),e},n.getConditionFromFunction=function(n,r){var t={};t[r]={};var e,i={ignore:function(){},condition:function(n){e=n},mapFrom:function(n){},sourceObject:t,sourcePropertyName:r,intermediatePropertyValue:{}};try{n(i)}catch(o){}return e},n}();n.AutoMapperHelper=r}(AutoMapperJs||(AutoMapperJs={})); var AutoMapperJs;!function(e){"use strict";var r=function(){function r(){}return r.assertConfigurationIsValid=function(e,t){for(var n in e)e.hasOwnProperty(n)&&r.assertMappingConfiguration(e[n],t)},r.assertMappingConfiguration=function(t,n){var o=t.sourceKey+"=>"+t.destinationKey,i=t.sourceTypeClass,a=t.destinationTypeClass,s=i?e.AutoMapperHelper.getClassName(i):void 0,p=a?e.AutoMapperHelper.getClassName(a):void 0;if(!i||!a){if(n===!1)return;throw new Error("Mapping '"+o+"' cannot be validated, since mapping.sourceType or mapping.destinationType are unspecified.")}for(var u=function(e){if(e)throw new Error("Mapping '"+o+"' is invalid: "+e+" (source: '"+s+"', destination: '"+p+"').")},d=new Array,c=new i,f=new a,y=0,g=t.properties;y=0||(u(r.validateProperty(v,f)),d.push(v)));for(var b in f)f.hasOwnProperty(b)&&(d.indexOf(b)>=0||u("Destination member '"+b+"' does not exist on source type"))},r.validatePropertyMapping=function(e,t,n,o){return e.sourceMapping?r.validateSourcePropertyMapping(e,t,n,o):r.validateDestinationPropertyMapping(e,t,n,o)},r.validateSourcePropertyMapping=function(e,r,t,n){if(!t.hasOwnProperty(r))return"Source member '"+r+"' is configured, but does not exist on source type";{if(!e.ignore)return n.hasOwnProperty(r)?void 0:"Source member '"+r+"' is configured to be mapped, but does not exist on destination type";if(n.hasOwnProperty(r))return"Source member '"+r+"' is ignored, but does exist on destination type"}},r.validateDestinationPropertyMapping=function(e,r,t,n){if(!n.hasOwnProperty(r))return"Destination member '"+r+"' is configured, but does not exist on destination type";{if(!e.ignore)return t.hasOwnProperty(r)?void 0:"Destination member '"+r+"' is configured to be mapped, but does not exist on source type";if(t.hasOwnProperty(r))return"Destination member '"+r+"' is ignored, but does exist on source type"}},r.validateProperty=function(e,r){return r.hasOwnProperty(e)?void 0:"Source member '"+e+"' is configured to be mapped, but does not exist on destination type"},r}();e.AutoMapperValidator=r}(AutoMapperJs||(AutoMapperJs={})); var AutoMapperJs;!function(e){"use strict";var t=function(){function t(){}return t.prototype.getMapping=function(e,t,r){var n=this.getKey(t),o=this.getKey(r),i=e[n+o];if(!i)throw new Error("Could not find map object with a source of "+n+" and a destination of "+o);return i},t.prototype.getKey=function(t){return"string"==typeof t?t:e.AutoMapperHelper.getClassName(t)},t.prototype.isArray=function(e){return e instanceof Array},t.prototype.handleArray=function(e,t,r){for(var n=t.length,o=new Array(t.length),i=0;n>i;i++){var a=t[i],p=void 0;null===a||void 0===a?p=a:(p=this.createDestinationObject(e.destinationTypeClass),r(a,p)),o[i]=p}return o},t.prototype.handleItem=function(e,t,r,n){var o=[],i=!1;for(var a in t)t.hasOwnProperty(a)&&(i=!0,o.push(a),n(a));for(var p=0,s=e.properties;p=0||(i=!0,n(l.name))}return!i&&null===t||void 0===t?t:r},t.prototype.handleProperty=function(e,t,r,n,o,i){var a=this.getMappingProperty(e.properties,r);a?this.handlePropertyWithPropertyMapping(e,a,t,r,o):this.handlePropertyWithAutoMapping(e,t,r,n,i)},t.prototype.setPropertyValue=function(e,t,r,n){if(e.forAllMemberMappings.length>0)for(var o=0,i=e.forAllMemberMappings;o0)for(var o=0,i=e.forAllMemberMappings;o0?this.setChildPropertyValues(e,t,r):n(e,t.name,r)},t.prototype.setNestedPropertyValue=function(e,t,r){t.children&&t.children.length>0?this.setChildPropertyValues(e,t,r):e[t.name]=r},t.prototype.setChildPropertyValues=function(e,t,r){var n;e.hasOwnProperty(t.name)&&e[t.name]?n=e[t.name]:e[t.name]=n={};for(var o=0,i=t.children.length;i>o;o++)this.setNestedPropertyValue(n,t.children[o],r)},t.prototype.getMappingProperty=function(e,t){for(var r=0,n=e;r=0;n--)""===r[n]&&r.splice(n,1);return e.destinationMemberNamingConvention.transformPropertyName(r)}catch(o){return t}},t}();e.AutoMapperBase=t}(AutoMapperJs||(AutoMapperJs={})); var __extends=this&&this.__extends||function(t,n){function e(){this.constructor=t}for(var r in n)n.hasOwnProperty(r)&&(t[r]=n[r]);t.prototype=null===n?Object.create(n):(e.prototype=n.prototype,new e)},AutoMapperJs;!function(t){"use strict";var n=function(n){function e(){n.call(this),e.asyncInstance=this}return __extends(e,n),e.prototype.createMapForMember=function(t,n,e){var r=this,o=t.metadata.mapping;o.async=!0,o.mapItemFunction=function(t,n,e,o){return r.mapItem(t,n,e,o)},t.async=!0,t.conversionValuesAndFunctions.push(n)},e.prototype.createMapConvertUsing=function(t,n){var e=this;t.async=!0,t.typeConverterFunction=n,t.mapItemFunction=function(t,n,r,o){return e.mapItemUsingTypeConverter(t,n,r,o)}},e.prototype.map=function(t,e,r,o,p){var a=this;switch(arguments.length){case 5:return void this.mapWithMapping(n.prototype.getMapping.call(this,t,e,r),o,p);case 4:return function(p){return a.mapWithMapping(n.prototype.getMapping.call(a,t,e,r),o,p)};case 3:return function(o,p){return a.mapWithMapping(n.prototype.getMapping.call(a,t,e,r),o,p)};case 2:return function(n,r,o){return a.map(t,e,n,r,o)};default:throw new Error("The AsyncAutoMapper.map function expects between 2 and 5 parameters, you provided "+arguments.length+".")}},e.prototype.mapWithMapping=function(t,e,r){return n.prototype.isArray.call(this,e)?void this.mapArray(t,e,r):t.mapItemFunction(t,e,n.prototype.createDestinationObject.call(this,t.destinationTypeClass),r)},e.prototype.mapArray=function(t,e,r){var o=0,p=n.prototype.handleArray.call(this,t,e,function(n,e){o++,t.mapItemFunction(t,n,e,function(t){o--})}),a=function(){0===o?r(p):setTimeout(function(){a()},10*o)};a()},e.prototype.mapItemUsingTypeConverter=function(t,n,e,r){var o={sourceValue:n,destinationValue:e};t.typeConverterFunction(o,r)},e.prototype.mapItem=function(t,e,r,o){var p=this,a=0;n.prototype.handleItem.call(this,t,e,r,function(n){a++,p.mapProperty(t,e,n,r,function(t){a--})});var i=function(){0===a?o(r):setTimeout(function(){i()},10*a)};i()},e.prototype.mapProperty=function(t,e,r,o,p){var a=this;n.prototype.handleProperty.call(this,t,e,r,o,function(e,r,i){a.handlePropertyMappings(r,i,function(r){for(var i=0,c=e;i any): string {\r\n // source: http://stackoverflow.com/a/13914278/702357\r\n if (classType && classType.constructor) {\r\n let className = classType.toString();\r\n if (className) {\r\n // classType.toString() is \"function classType (...) { ... }\"\r\n let matchParts = className.match(/function\\s*(\\w+)/);\r\n if (matchParts && matchParts.length === 2) {\r\n return matchParts[1];\r\n }\r\n }\r\n\r\n // for browsers which have name property in the constructor\r\n // of the object, such as chrome\r\n if ((classType.constructor).name) {\r\n return (classType.constructor).name;\r\n }\r\n\r\n if (classType.constructor.toString()) {\r\n var str = classType.constructor.toString();\r\n\r\n if (str.charAt(0) === '[') {\r\n // executed if the return of object.constructor.toString() is \"[object objectClass]\"\r\n var arr = str.match(/\\[\\w+\\s*(\\w+)\\]/);\r\n } else {\r\n // executed if the return of object.constructor.toString() is \"function objectClass () {}\"\r\n // (IE and Firefox)\r\n var arr = str.match(/function\\s*(\\w+)/);\r\n }\r\n\r\n if (arr && arr.length === 2) {\r\n return arr[1];\r\n }\r\n }\r\n }\r\n\r\n throw new Error(`Unable to extract class name from type '${classType}'`);\r\n }\r\n\r\n public static getFunctionParameters(func: Function): Array {\r\n const stripComments = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n const argumentNames = /([^\\s,]+)/g;\r\n\r\n var functionString = func.toString().replace(stripComments, '');\r\n var functionParameterNames = functionString.slice(functionString.indexOf('(') + 1, functionString.indexOf(')')).match(argumentNames);\r\n if (functionParameterNames === null) {\r\n functionParameterNames = new Array();\r\n }\r\n return functionParameterNames;\r\n }\r\n\r\n public static handleCurrying(func: Function, args: IArguments, closure: any): any {\r\n const argumentsStillToCome = func.length - args.length;\r\n\r\n // saved accumulator array\r\n // NOTE BL this does not deep copy array objects, only the array itself; should side effects occur, please report (or refactor).\r\n var argumentsCopy = Array.prototype.slice.apply(args);\r\n\r\n function accumulator(moreArgs: IArguments, alreadyProvidedArgs: Array, stillToCome: number): Function {\r\n var previousAlreadyProvidedArgs = alreadyProvidedArgs.slice(0); // to reset\r\n var previousStillToCome = stillToCome; // to reset\r\n\r\n for (let i = 0; i < moreArgs.length; i++, stillToCome--) {\r\n alreadyProvidedArgs[alreadyProvidedArgs.length] = moreArgs[i];\r\n }\r\n\r\n if (stillToCome - moreArgs.length <= 0) {\r\n var functionCallResult = func.apply(closure, alreadyProvidedArgs);\r\n\r\n // reset vars, so curried function can be applied to new params.\r\n alreadyProvidedArgs = previousAlreadyProvidedArgs;\r\n stillToCome = previousStillToCome;\r\n\r\n return functionCallResult;\r\n } else {\r\n return function(): Function {\r\n // arguments are params, so closure bussiness is avoided.\r\n return accumulator(arguments, alreadyProvidedArgs.slice(0), stillToCome);\r\n };\r\n }\r\n }\r\n\r\n return accumulator(([]), argumentsCopy, argumentsStillToCome);\r\n }\r\n\r\n public static getMappingMetadataFromConfigFunction(destination: string, func: any, sourceMapping: boolean): IMemberMappingMetaData {\r\n if (typeof func !== 'function') {\r\n return {\r\n destination: destination,\r\n source: destination,\r\n sourceMapping: sourceMapping,\r\n condition: null,\r\n ignore: false,\r\n async: false\r\n };\r\n }\r\n\r\n var funcStr = func.toString();\r\n\r\n var parameterNames = AutoMapperHelper.getFunctionParameters(func);\r\n var optsParamName = parameterNames.length >= 1 ? parameterNames[0] : '';\r\n\r\n var source = sourceMapping\r\n ? destination\r\n : AutoMapperHelper.getMapFromString(funcStr, destination, optsParamName);\r\n\r\n var metadata: IMemberMappingMetaData = {\r\n destination: destination,\r\n source: source,\r\n sourceMapping: sourceMapping,\r\n condition: null,\r\n ignore: AutoMapperHelper.getIgnoreFromString(funcStr, destination),\r\n async: parameterNames.length === 2\r\n };\r\n\r\n // calling the member options function when used asynchronous would be too 'dangerous'.\r\n if (!metadata.async && AutoMapperHelper.getFunctionCallIndex(funcStr, 'condition', optsParamName) >= 0) {\r\n metadata.condition = AutoMapperHelper.getConditionFromFunction(func, source);\r\n }\r\n\r\n return metadata;\r\n }\r\n\r\n private static getIgnoreFromString(functionString: string, optionsParameterName: string): boolean {\r\n var indexOfIgnore = AutoMapperHelper.getFunctionCallIndex(functionString, 'ignore', optionsParameterName);\r\n if (indexOfIgnore < 0) {\r\n return false;\r\n }\r\n\r\n var indexOfMapFromStart = functionString.indexOf('(', indexOfIgnore) + 1;\r\n var indexOfMapFromEnd = functionString.indexOf(')', indexOfMapFromStart);\r\n\r\n if (indexOfMapFromStart < 0 || indexOfMapFromEnd < 0) {\r\n return false;\r\n }\r\n\r\n var ignoreString = functionString.substring(indexOfMapFromStart, indexOfMapFromEnd).replace(/\\r/g, '').replace(/\\n/g, '').trim();\r\n return ignoreString === null || ignoreString === ''\r\n ? true // .ignore()\r\n : false; // .ignore( -> unexpected content)\r\n }\r\n\r\n private static getMapFromString(functionString: string, defaultValue: string, optionsParameterName: string): string {\r\n var indexOfMapFrom = AutoMapperHelper.getFunctionCallIndex(functionString, 'mapFrom', optionsParameterName);\r\n if (indexOfMapFrom < 0) {\r\n return defaultValue;\r\n }\r\n\r\n var indexOfMapFromStart = functionString.indexOf('(', indexOfMapFrom) + 1;\r\n var indexOfMapFromEnd = functionString.indexOf(')', indexOfMapFromStart);\r\n\r\n if (indexOfMapFromStart < 0 || indexOfMapFromEnd < 0) {\r\n return defaultValue;\r\n }\r\n\r\n var mapFromString = functionString.substring(indexOfMapFromStart, indexOfMapFromEnd).replace(/'/g, '').replace(/\"/g, '').trim();\r\n return mapFromString === null || mapFromString === ''\r\n ? defaultValue\r\n : mapFromString;\r\n }\r\n\r\n private static getFunctionCallIndex(functionString: string, functionToLookFor: string, optionsParameterName: string): number {\r\n var indexOfFunctionCall = functionString.indexOf(optionsParameterName + '.' + functionToLookFor);\r\n if (indexOfFunctionCall < 0) {\r\n indexOfFunctionCall = functionString.indexOf('.' + functionToLookFor);\r\n }\r\n\r\n return indexOfFunctionCall;\r\n }\r\n\r\n private static getConditionFromFunction(func: Function, sourceProperty: string): ((sourceObject: any) => boolean) {\r\n // Since we are calling the valueOrFunction function to determine whether to ignore or map from another property, we\r\n // want to prevent the call to be error prone when the end user uses the '(opts)=> opts.sourceObject.sourcePropertyName'\r\n // syntax. We don't actually have a source object when creating a mapping; therefore, we 'stub' a source object for the\r\n // function call.\r\n var sourceObject: any = {};\r\n sourceObject[sourceProperty] = {};\r\n\r\n var condition: (sourceObject: any) => boolean;\r\n\r\n // calling the function will result in calling our stubbed ignore() and mapFrom() functions if used inside the function.\r\n const configFuncOptions: IMemberConfigurationOptions = {\r\n ignore: (): void => {\r\n // do nothing\r\n },\r\n condition: (predicate: ((sourceObject: any) => boolean)): void => {\r\n condition = predicate;\r\n },\r\n mapFrom: (sourcePropertyName: string): void => {\r\n // do nothing\r\n },\r\n sourceObject: sourceObject,\r\n sourcePropertyName: sourceProperty,\r\n intermediatePropertyValue: {}\r\n };\r\n\r\n try {\r\n func(configFuncOptions);\r\n } catch (exc) {\r\n // do not handle by default.\r\n }\r\n\r\n return condition;\r\n }\r\n\t}\r\n}"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["AutoMapperHelper.ts"],"names":[],"mappings":"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","file":"AutoMapperHelper.js","sourcesContent":["module AutoMapperJs {\r\n 'use strict';\r\n\r\n /**\r\n * AutoMapper helper functions\r\n */\r\n export class AutoMapperHelper {\r\n public static getClassName(classType: new() => any): string {\r\n if (classType && (classType).name) {\r\n return (classType).name;\r\n }\r\n // source: http://stackoverflow.com/a/13914278/702357\r\n if (classType && classType.constructor) {\r\n let className = classType.toString();\r\n if (className) {\r\n // classType.toString() is \"function classType (...) { ... }\"\r\n let matchParts = className.match(/function\\s*(\\w+)/);\r\n if (matchParts && matchParts.length === 2) {\r\n return matchParts[1];\r\n }\r\n }\r\n\r\n // for browsers which have name property in the constructor\r\n // of the object, such as chrome\r\n if ((classType.constructor).name) {\r\n return (classType.constructor).name;\r\n }\r\n\r\n if (classType.constructor.toString()) {\r\n var str = classType.constructor.toString();\r\n\r\n if (str.charAt(0) === '[') {\r\n // executed if the return of object.constructor.toString() is \"[object objectClass]\"\r\n var arr = str.match(/\\[\\w+\\s*(\\w+)\\]/);\r\n } else {\r\n // executed if the return of object.constructor.toString() is \"function objectClass () {}\"\r\n // (IE and Firefox)\r\n var arr = str.match(/function\\s*(\\w+)/);\r\n }\r\n\r\n if (arr && arr.length === 2) {\r\n return arr[1];\r\n }\r\n }\r\n }\r\n\r\n throw new Error(`Unable to extract class name from type '${classType}'`);\r\n }\r\n\r\n public static getFunctionParameters(func: Function): Array {\r\n const stripComments = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n const argumentNames = /([^\\s,]+)/g;\r\n\r\n var functionString = func.toString().replace(stripComments, '');\r\n var functionParameterNames = functionString.slice(functionString.indexOf('(') + 1, functionString.indexOf(')')).match(argumentNames);\r\n if (functionParameterNames === null) {\r\n functionParameterNames = new Array();\r\n }\r\n return functionParameterNames;\r\n }\r\n\r\n public static handleCurrying(func: Function, args: IArguments, closure: any): any {\r\n const argumentsStillToCome = func.length - args.length;\r\n\r\n // saved accumulator array\r\n // NOTE BL this does not deep copy array objects, only the array itself; should side effects occur, please report (or refactor).\r\n var argumentsCopy = Array.prototype.slice.apply(args);\r\n\r\n function accumulator(moreArgs: IArguments, alreadyProvidedArgs: Array, stillToCome: number): Function {\r\n var previousAlreadyProvidedArgs = alreadyProvidedArgs.slice(0); // to reset\r\n var previousStillToCome = stillToCome; // to reset\r\n\r\n for (let i = 0; i < moreArgs.length; i++, stillToCome--) {\r\n alreadyProvidedArgs[alreadyProvidedArgs.length] = moreArgs[i];\r\n }\r\n\r\n if (stillToCome - moreArgs.length <= 0) {\r\n var functionCallResult = func.apply(closure, alreadyProvidedArgs);\r\n\r\n // reset vars, so curried function can be applied to new params.\r\n alreadyProvidedArgs = previousAlreadyProvidedArgs;\r\n stillToCome = previousStillToCome;\r\n\r\n return functionCallResult;\r\n } else {\r\n return function(): Function {\r\n // arguments are params, so closure bussiness is avoided.\r\n return accumulator(arguments, alreadyProvidedArgs.slice(0), stillToCome);\r\n };\r\n }\r\n }\r\n\r\n return accumulator(([]), argumentsCopy, argumentsStillToCome);\r\n }\r\n\r\n public static getMappingMetadataFromConfigFunction(destination: string, func: any, sourceMapping: boolean): IMemberMappingMetaData {\r\n if (typeof func !== 'function') {\r\n return {\r\n destination: destination,\r\n source: destination,\r\n sourceMapping: sourceMapping,\r\n condition: null,\r\n ignore: false,\r\n async: false\r\n };\r\n }\r\n\r\n var funcStr = func.toString();\r\n\r\n var parameterNames = AutoMapperHelper.getFunctionParameters(func);\r\n var optsParamName = parameterNames.length >= 1 ? parameterNames[0] : '';\r\n\r\n var source = sourceMapping\r\n ? destination\r\n : AutoMapperHelper.getMapFromString(funcStr, destination, optsParamName);\r\n\r\n var metadata: IMemberMappingMetaData = {\r\n destination: destination,\r\n source: source,\r\n sourceMapping: sourceMapping,\r\n condition: null,\r\n ignore: AutoMapperHelper.getIgnoreFromString(funcStr, destination),\r\n async: parameterNames.length === 2\r\n };\r\n\r\n // calling the member options function when used asynchronous would be too 'dangerous'.\r\n if (!metadata.async && AutoMapperHelper.getFunctionCallIndex(funcStr, 'condition', optsParamName) >= 0) {\r\n metadata.condition = AutoMapperHelper.getConditionFromFunction(func, source);\r\n }\r\n\r\n return metadata;\r\n }\r\n\r\n private static getIgnoreFromString(functionString: string, optionsParameterName: string): boolean {\r\n var indexOfIgnore = AutoMapperHelper.getFunctionCallIndex(functionString, 'ignore', optionsParameterName);\r\n if (indexOfIgnore < 0) {\r\n return false;\r\n }\r\n\r\n var indexOfMapFromStart = functionString.indexOf('(', indexOfIgnore) + 1;\r\n var indexOfMapFromEnd = functionString.indexOf(')', indexOfMapFromStart);\r\n\r\n if (indexOfMapFromStart < 0 || indexOfMapFromEnd < 0) {\r\n return false;\r\n }\r\n\r\n var ignoreString = functionString.substring(indexOfMapFromStart, indexOfMapFromEnd).replace(/\\r/g, '').replace(/\\n/g, '').trim();\r\n return ignoreString === null || ignoreString === ''\r\n ? true // .ignore()\r\n : false; // .ignore( -> unexpected content)\r\n }\r\n\r\n private static getMapFromString(functionString: string, defaultValue: string, optionsParameterName: string): string {\r\n var indexOfMapFrom = AutoMapperHelper.getFunctionCallIndex(functionString, 'mapFrom', optionsParameterName);\r\n if (indexOfMapFrom < 0) {\r\n return defaultValue;\r\n }\r\n\r\n var indexOfMapFromStart = functionString.indexOf('(', indexOfMapFrom) + 1;\r\n var indexOfMapFromEnd = functionString.indexOf(')', indexOfMapFromStart);\r\n\r\n if (indexOfMapFromStart < 0 || indexOfMapFromEnd < 0) {\r\n return defaultValue;\r\n }\r\n\r\n var mapFromString = functionString.substring(indexOfMapFromStart, indexOfMapFromEnd).replace(/'/g, '').replace(/\"/g, '').trim();\r\n return mapFromString === null || mapFromString === ''\r\n ? defaultValue\r\n : mapFromString;\r\n }\r\n\r\n private static getFunctionCallIndex(functionString: string, functionToLookFor: string, optionsParameterName: string): number {\r\n var indexOfFunctionCall = functionString.indexOf(optionsParameterName + '.' + functionToLookFor);\r\n if (indexOfFunctionCall < 0) {\r\n indexOfFunctionCall = functionString.indexOf('.' + functionToLookFor);\r\n }\r\n\r\n return indexOfFunctionCall;\r\n }\r\n\r\n private static getConditionFromFunction(func: Function, sourceProperty: string): ((sourceObject: any) => boolean) {\r\n // Since we are calling the valueOrFunction function to determine whether to ignore or map from another property, we\r\n // want to prevent the call to be error prone when the end user uses the '(opts)=> opts.sourceObject.sourcePropertyName'\r\n // syntax. We don't actually have a source object when creating a mapping; therefore, we 'stub' a source object for the\r\n // function call.\r\n var sourceObject: any = {};\r\n sourceObject[sourceProperty] = {};\r\n\r\n var condition: (sourceObject: any) => boolean;\r\n\r\n // calling the function will result in calling our stubbed ignore() and mapFrom() functions if used inside the function.\r\n const configFuncOptions: IMemberConfigurationOptions = {\r\n ignore: (): void => {\r\n // do nothing\r\n },\r\n condition: (predicate: ((sourceObject: any) => boolean)): void => {\r\n condition = predicate;\r\n },\r\n mapFrom: (sourcePropertyName: string): void => {\r\n // do nothing\r\n },\r\n sourceObject: sourceObject,\r\n sourcePropertyName: sourceProperty,\r\n intermediatePropertyValue: {}\r\n };\r\n\r\n try {\r\n func(configFuncOptions);\r\n } catch (exc) {\r\n // do not handle by default.\r\n }\r\n\r\n return condition;\r\n }\r\n\t}\r\n}\r\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/src/ts/AutoMapperHelper.ts b/src/ts/AutoMapperHelper.ts index 2f84c09..97d857b 100644 --- a/src/ts/AutoMapperHelper.ts +++ b/src/ts/AutoMapperHelper.ts @@ -6,6 +6,9 @@ module AutoMapperJs { */ export class AutoMapperHelper { public static getClassName(classType: new() => any): string { + if (classType && (classType).name) { + return (classType).name; + } // source: http://stackoverflow.com/a/13914278/702357 if (classType && classType.constructor) { let className = classType.toString();