react-resource源码

react-resource.js发送请求,返回promise,不像jquery那样可以自由设置contentType,数据预处理等

/* ==========================================================================
   [COMPONENT] React-Resource
   --------------------------------------------------------------------------
   Component for creating http restful requests by using Promises.
   Written to symbiose with RefluxJs async actions.
   ========================================================================== */

'use strict';

Object.defineProperty(exports, '__esModule', {
    value: true
});

// _createClass(Constructor,protoProps,staticProps) 创建构造函数,定义静态方法、原型属性和方法
// protoProps用以定义Constructor.prototype 各属性、方法的访问器属性
// staticProps用以定义Constructor 各属性、方法的访问器属性,[{key,enumerable,configurable,value}]形式
var _createClass = (function () {// 利用自执行匿名函数优化defineProperties书写
    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; 
    }; 
})();

exports['default'] = ReactResource;

function _interopRequireDefault(obj) { 
    return obj && obj.__esModule ? obj : { 'default': obj }; 
}

// 构造函数只能通过new关键字调用
function _classCallCheck(instance, Constructor) { 
    if (!(instance instanceof Constructor)) { 
        throw new TypeError('Cannot call a class as a function'); 
    }
}

var _promise = require('promise');
var _promise2 = _interopRequireDefault(_promise);

var _superagent = require('superagent');
var _superagent2 = _interopRequireDefault(_superagent);

// lodash工具函数集,类似underscore
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);

// ------------------------------------------------------------------------------
// Resource class creator
// url用于给actionsConfig中未设置url的action赋值
// mapping为{key:string};后续url中用"{"、"}"括起的string,将被替换成actionname方法解析参数获得的source.key
// actionsConfig为{actionname:{url,params,method,isArray}}形式,actionname为添加给Resource的静态方法名
// 使用:
//      ReactResource(url, mappings, actionsConfig)[actionname]([source],[queryParams],[bodyData],[resolveFn],[rejectFn])
//      或者 new ReactResource(url, mappings, actionsConfig)()["$"+actionname]([source],[queryParams],[bodyData],[resolveFn],[rejectFn])
function ReactResource(url, mappings, actionsConfig) {
    // 实例含url、mapping、actionsConfig属性,this.actionsConfig是默认actions和用户配置actions复合后的结果
    var resourceConfig = new ResourceConfig(url, mappings, actionsConfig);

    function Resource(initObject) {
        // HelpersAndParsers.copyPureAttributes拷贝对象输出,"$"起始的键不拷贝
        HelpersAndParsers.copyPureAttributes(initObject, this);
        ActionsBuilder.createInstanceActions(resourceConfig, this);
    }
    ActionsBuilder.createClassActions(resourceConfig, Resource);

    return Resource;
}

// 拦截器{response:function(res){},rejection:function(err,res)},引用对象形式处理响应
ReactResource.interceptors = [];
ReactResource.add_interceptor = function (interceptorObj) {
    if (typeof interceptorObj == 'object' && (typeof interceptorObj.response == 'function' || typeof interceptorObj.rejection == 'function')) {
        ReactResource.interceptors.push(interceptorObj);
    }
};

var ActionsBuilder = (function () {
    function ActionsBuilder() {
        _classCallCheck(this, ActionsBuilder);
    }

    // 添加静态方法
    // ActionsBuilder.createClassActions创建resourceClass.query|get|update|delete|create|[customMethodName]方法,用于发送请求,返回promise
    //     其中,customMethodName来自用户传入ReactResource的actionsConfig参数{customMethodName:{url,query,method,isArray}}
    //     resourceClass是ReactResource构造函数中的Resource构造函数,即用户调用ReactResource(url,mapping,actionsConfig)返回值
    _createClass(ActionsBuilder, null, [{
        key: 'createClassActions',
        value: function createClassActions(resourceConfig, resourceClass) {
            _lodash2['default'].forEach(Object.keys(resourceConfig.actionsConfig), function (actionName) {
                resourceClass[actionName] = ActionsBuilder.buildActionFromConfig(actionName, resourceConfig, {});
            });
        }
    }, {
        key: 'createInstanceActions',
        // resourceClass实例添加方法$query|$get|$update|$delete|$create|["$"+customMethodName][actionName],用于发送请求,返回promise
        value: function createInstanceActions(resourceConfig, resourceInstance) {
            _lodash2['default'].forEach(Object.keys(resourceConfig.actionsConfig), function (actionName) {
                resourceInstance["$" + actionName] = ActionsBuilder.buildActionFromConfig(actionName, resourceConfig, resourceInstance);
            });
        }
    }, {
        key: 'buildActionFromConfig',

        // 构建resourceClass[actionName]函数内容体
        value: function buildActionFromConfig(actionName, resourceConfig) {
            var ModelInstance = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

            // 构建resourceClass[actionName]函数内容体
            return function () {
                // 接收resourceClass[actionName]方法传参
                for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
                    args[_key] = arguments[_key];
                }

                // HelpersAndParsers.parseArgs获取本次请求的promiseConfig,形为{url,source,queryParams,bodyData,resolveFn,rejectFn}
                // 请求由resourceClass[actionName]发起
                // resourceClass[actionName]即ReactResource(url,mapping,actionsConfig)[actionName]
                // 或new ReactResource(url,mapping,actionsConfig)["$"+actionName]
                var promiseConfig = HelpersAndParsers.parseArgs.apply(HelpersAndParsers, [actionName, resourceConfig, ModelInstance].concat(args));
                

                return ActionsBuilder.buildPromiseFromAction(actionName, resourceConfig, promiseConfig);
            };
        }
    }, {
        key: 'buildPromiseFromAction',

        // 发送请求,返回promise
        value: function buildPromiseFromAction(actionName, resourceConfig, promiseConfig) {
            var actionConfig = resourceConfig.actionsConfig[actionName];
            return new _promise2['default'](function (resolvePromiseFn, rejectPromiseFn) {
                var newRequest = _superagent2['default'],
                    actionMethod = actionConfig.method.toUpperCase();
                switch (actionMethod) {
                    case 'GET':
                        newRequest = newRequest.get(promiseConfig.url);
                        break;
                    case 'POST':
                        newRequest = newRequest.post(promiseConfig.url);
                        break;
                    case 'PUT':
                    case 'PATCH':
                        newRequest = newRequest.put(promiseConfig.url);
                        break;
                    case 'DELETE':
                        newRequest = newRequest.del(promiseConfig.url);
                        break;
                }

                // JSON
                newRequest.set('Accept', 'application/json');

                // 添加url携带参数,get、post请求都有
                newRequest.query(_lodash2['default'].merge(_lodash2['default'].cloneDeep(actionConfig.params), promiseConfig.queryParams));

                // 添加json格式数据,post请求独有
                if (!_lodash2['default'].isEmpty(promiseConfig.bodyData) && ACTIONS_WITH_BODY.indexOf(actionMethod) > -1) {
                    newRequest.send(promiseConfig.bodyData);
                }

                newRequest.end(function (err, res) {
                    if (err === null) {
                        _lodash2['default'].forEach(ReactResource.interceptors, function (interceptor) {
                            if (typeof interceptor.response == 'function') interceptor.response(res);
                        });

                        resolvePromiseFn(res && res.body);
                        if (promiseConfig.resolveFn && typeof promiseConfig.resolveFn == 'function') {
                            promiseConfig.resolveFn(res && res.body);
                        }
                    } else {
                        _lodash2['default'].forEach(ReactResource.interceptors, function (interceptor) {
                            if (typeof interceptor.rejection == 'function') interceptor.rejection(err, res);
                        });

                        rejectPromiseFn(res && res.body || err);
                        if (promiseConfig.rejectFn && typeof promiseConfig.rejectFn == 'function') {
                            promiseConfig.rejectFn(res && res.body || err);
                        }
                    }
                  });
            });
        }
    }]);

    return ActionsBuilder;
})();

// 实例含url、mapping、actionsConfig属性,this.actionsConfig是默认actions和用户配置actions复合后的结果
var ResourceConfig = (function () {// 利用自调用匿名函数,构造函数的静态方法和原型方法赋值
    function ResourceConfig(url) {
        var mappings = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
        var extraActionsConfig = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

        _classCallCheck(this, ResourceConfig);

        if (!url) throw Error("Cant create resource config without url");
        this.url = url;
        this.mappings = mappings;
        this.extraActionsConfig = extraActionsConfig;// 默认actions
        this.defaultActionsConfig = _lodash2['default'].cloneDeep(DEFAULT_ACTIONS_CONFIG);// 用户配置actions
        this.actionsConfig = {};// 存储复合actions
        this.buildActionsConfig();// 获取复合actions并存储
    }

    // 添加ResourceConfig.prototype.buildActionsConfig原型方法,this.actionsConfig添加默认及用户配置的actions
    // 添加ResourceConfig.checkActionConfig静态方法,校验action的{url,params,method,isArray}配置
    //     如无url|method,赋值为_this.extraActionsConfig.url|method
    //     如无params,从_this.extraActionsConfig.url中解析得到
    //     如isArray为undfined或null,赋值为false
    _createClass(ResourceConfig, [{
        key: 'buildActionsConfig',
        value: function buildActionsConfig() {
            var _this = this;

            // HelpersAndParsers.uniqueArray数组项去重
            var mergedConfigKeys = HelpersAndParsers.uniqueArray(
                Object.keys(this.defaultActionsConfig).concat(Object.keys(this.extraActionsConfig))
            );
            _lodash2['default'].forEach(mergedConfigKeys, function (actionName) {
                // 默认及用户定义的action,{url,params,method,isArray}形式
                var defaultActionConfig = _this.defaultActionsConfig[actionName],
                    extraActionConfig = _this.extraActionsConfig[actionName];

                if (defaultActionConfig) _this.actionsConfig[actionName] = defaultActionConfig;

                if (extraActionConfig) {
                    _lodash2['default'].forEach(Object.keys(extraActionConfig), function (extraActionConfigKey) {
                        if (!_this.actionsConfig[actionName]) _this.actionsConfig[actionName] = {};
                        _this.actionsConfig[actionName][extraActionConfigKey] = extraActionConfig[extraActionConfigKey];
                    });
                }

                _this.checkActionConfig(actionName);
            });
        }
    }, {
        key: 'checkActionConfig',
        value: function checkActionConfig(actionName) {
            var actionConfig = this.actionsConfig[actionName];
            if (_lodash2['default'].isEmpty(actionConfig.url)) {
                this.actionsConfig[actionName].url = this.url;
            }
            if (_lodash2['default'].isEmpty(actionConfig.params)) {
                // HelpersAndParsers.extractQueryParams解析url中的查询字符串,对象形式输出
                this.actionsConfig[actionName].params = HelpersAndParsers.extractQueryParams(this.actionsConfig[actionName].url);
            }
            if (_lodash2['default'].isEmpty(actionConfig.method)) {
                this.actionsConfig[actionName].method = 'GET';
            }
            if (_lodash2['default'].isNull(actionConfig.isArray) || _lodash2['default'].isUndefined(actionConfig.isArray)) {
                this.actionsConfig[actionName].isArray = false;
            }
        }
    }]);

    return ResourceConfig;
})();

// 工具函数
var HelpersAndParsers = (function () {
    function HelpersAndParsers() {
        _classCallCheck(this, HelpersAndParsers);
    }

    // 添加静态方法
    // HelpersAndParsers.parseArgs获取本次请求的promiseConfig,形为{url,source,queryParams,bodyData,resolveFn,rejectFn}
    //      请求由resourceClass[actionName]发起
    // HelpersAndParsers.WithBodyData处理resourceClass[actionName]传参([source],[queryParams],[bodyData],[resolveFn],[rejectFn])
    //      ajax请求为类put形式,通过bodyData传输数据
    // HelpersAndParsers.NoBodyData处理resourceClass[actionName]传参([source],[queryParams],[resolveFn],[rejectFn])
    //      ajax请求为get形式,不通过bodyData传输数据
    //   resourceClass[actionName]即ReactResource(url,mapping,actionsConfig)[actionName]
    //   或new ReactResource(url,mapping,actionsConfig)["$"+actionName]
    // HelpersAndParsers.parseUrlWithMapping将首参actionConfig.url中变量{:id}替换为实际值或空
    // HelpersAndParsers.copyPureAttributes拷贝对象输出,"$"起始的键不拷贝
    // HelpersAndParsers.extractQueryParams解析url中的查询字符串,对象形式输出
    // HelpersAndParsers.uniqueArray数组项去重
    _createClass(HelpersAndParsers, null, [{
        key: 'parseArgs',

        // 获取本次请求的promiseConfig,形为{url,source,queryParams,bodyData,resolveFn,rejectFn}
        // 参数actionName是resourceConfig.actionsConfig中的键,参数resourceConfig即ResourceConfig实例
        // resourceConfig含url、mapping、actionsConfig属性,actionsConfig是默认及用户配置actions复合后的结果
        value: function parseArgs(actionName, resourceConfig) {
            var ModelInstance = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];

            var promiseConfig = _lodash2['default'].cloneDeep(HelpersAndParsers.getDefaultPromiseConfig()),
                actionConfig = resourceConfig.actionsConfig && resourceConfig.actionsConfig[actionName],
                actionMethod = actionConfig && actionConfig.method.toUpperCase();

            // args接收从arguments第三项后的所有内容,不含第三项,即resourceClass[actionName]方法传参
            for (var _len2 = arguments.length, args = Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
                args[_key2 - 3] = arguments[_key2];
            }

            // actionname为'POST','PUT','PATCH','DELETE'及其小写形式
            if (ACTIONS_WITH_BODY.indexOf(actionMethod) > -1) {
                // HelpersAndParsers.WithBodyData处理resourceClass[actionName]传参args
                // 赋值给promiseConfig
                HelpersAndParsers.WithBodyData.apply(HelpersAndParsers, 
                    [actionName, resourceConfig, promiseConfig, ModelInstance].concat(args));

                // promiseConfig.source为空,promiseConfig.bodyData非空,promiseConfig.source和promiseConfig.bodyData等值
                if (!_lodash2['default'].isEmpty(promiseConfig.source) && _lodash2['default'].isEmpty(promiseConfig.bodyData)) {
                    HelpersAndParsers.copyPureAttributes(promiseConfig.source, promiseConfig.bodyData);
                }

            // actionname为'GET'及其小写形式
            } else if (ACTIONS_WITHOUT_BODY.indexOf(actionMethod) > -1) {
                // HelpersAndParsers.NoBodyData处理resourceClass[actionName]传参args
                // 赋值给promiseConfig
                HelpersAndParsers.NoBodyData.apply(HelpersAndParsers, [actionName, resourceConfig, promiseConfig, ModelInstance].concat(args));
            } else {
                throw Error("Dont know how to build HTTP request.", actionName, actionMethod);
            }

            // HelpersAndParsers.parseUrlWithMapping将首参actionConfig.url中变量{:id}替换为实际值或空
            promiseConfig.url = HelpersAndParsers.parseUrlWithMapping(actionConfig, resourceConfig, promiseConfig);
            return promiseConfig;
        }

    }, {
        key: 'WithBodyData',

        // resourceClass[actionName]传参处理([source],[queryParams],[bodyData],[resolveFn],[rejectFn])
        //      针对put形式的ajax,数据通过bodyData传递
        // 参数actionName是resourceConfig.actionsConfig中的键,参数resourceConfig即ResourceConfig实例
        // resourceConfig含url、mapping、actionsConfig属性,actionsConfig是默认及用户配置actions复合后的结果
        // 参数promiseConfigh是HelpersAndParsers.getDefaultPromiseConfig获取的默认promiseConfig
        value: function WithBodyData(actionName, resourceConfig, promiseConfig, ModelInstance) {
            // 用户调用形式为ReactResource(url,mapping,actionsConfig).get(...)为否,构造函数的静态方法
            // 用户调用形式为new ReactResource(url,mapping,actionsConfig).$get(...)为真,实例的原型链方法
            var isClassMethod = _lodash2['default'].isEmpty(ModelInstance);
            if (!isClassMethod) {
                promiseConfig.source = ModelInstance;
            }

            // args接收从arguments第四项后的所有内容,不含第四项,即resourceClass[actionName]方法传参
            for (var _len3 = arguments.length, args = Array(_len3 > 4 ? _len3 - 4 : 0), _key3 = 4; _key3 < _len3; _key3++) {
                args[_key3 - 4] = arguments[_key3];
            }

            switch (args.length) {
                case 5:
                    if (!isClassMethod) throw Error("Instance method can't have 5 arguments");
                    if (typeof args[0] == 'object' && typeof args[1] == 'object' && typeof args[2] == 'object' && typeof args[3] == 'function' && typeof args[4] == 'function') {
                        promiseConfig.source = args[0];
                        promiseConfig.queryParams = args[1];
                        promiseConfig.bodyData = args[2];
                        promiseConfig.resolveFn = args[3];
                        promiseConfig.rejectFn = args[4];
                    } else {
                        throw Error("Arguments types mismatch!");
                    }
                    break;
                case 4:
                    if (typeof args[0] == 'object' && typeof args[1] == 'object' && typeof args[2] == 'function' && typeof args[3] == 'function') {
                        if (isClassMethod) {
                            promiseConfig.source = args[0];
                            promiseConfig.queryParams = args[1];
                        } else {
                            promiseConfig.queryParams = args[0];
                            promiseConfig.bodyData = args[1];
                        }
                        promiseConfig.resolveFn = args[2];
                        promiseConfig.rejectFn = args[3];
                    } else if (typeof args[0] == 'object' && typeof args[1] == 'object' && typeof args[2] == 'object' && typeof args[3] == 'function') {
                        if (isClassMethod) {
                            promiseConfig.source = args[0];
                            promiseConfig.queryParams = args[1];
                            promiseConfig.bodyData = args[3];
                            promiseConfig.resolveFn = args[4];
                        } else {
                            throw Error("Arguments types mismatch!");
                        }
                    } else {
                        throw Error("Arguments types mismatch!");
                    }
                    break;
                case 3:
                    if (isClassMethod) {
                        promiseConfig.source = args[0];
                        if (typeof args[1] == 'function' && typeof args[2] == 'function') {
                            promiseConfig.resolveFn = args[1];
                            promiseConfig.rejectFn = args[2];
                        } else if (typeof args[1] == 'object' && typeof args[2] == 'function') {
                            promiseConfig.queryParams = args[1];
                            promiseConfig.rejectFn = args[2];
                        } else if (typeof args[1] == 'object' && typeof args[2] == 'object') {
                            promiseConfig.queryParams = args[1];
                            promiseConfig.bodyData = args[2];
                        } else {
                            throw Error("Arguments types mismatch!");
                        }
                    } else {
                        promiseConfig.queryParams = args[0];

                        if (typeof args[1] == 'object' && typeof args[2] == 'function') {
                          promiseConfig.bodyData = args[1];
                          promiseConfig.resolveFn = args[2];
                        } else if (typeof args[1] == 'function' && typeof args[2] == 'function') {
                            promiseConfig.resolveFn = args[1];
                            promiseConfig.rejectFn = args[2];
                        } else {
                            throw Error("Arguments types mismatch!");
                        }
                    }
                    break;
                case 2:
                    if (typeof args[0] == 'function' && typeof args[1] == 'function') {
                        promiseConfig.resolveFn = args[0];
                        promiseConfig.rejectFn = args[1];
                    } else {
                        if (isClassMethod) {
                            if (typeof args[0] == 'object' && typeof args[1] == 'function') {
                                promiseConfig.source = args[0];
                                promiseConfig.resolveFn = args[1];
                            } else if (typeof args[0] == 'object' && typeof args[1] == 'object') {
                                promiseConfig.source = args[0];
                                promiseConfig.queryParams = args[1];
                            } else {
                                throw Error("Arguments types mismatch!");
                            }
                        } else {
                            if (typeof args[0] == 'object' && typeof args[1] == 'function') {
                                promiseConfig.queryParams = args[0];
                                promiseConfig.resolveFn = args[1];
                            } else if (typeof args[0] == 'object' && typeof args[1] == 'object') {
                                promiseConfig.queryParams = args[0];
                                promiseConfig.bodyData = args[1];
                            } else {
                                throw Error("Arguments types mismatch!");
                            }
                        }
                    }
                    break;

                // resourceClass[actionName]传入单参数
                // 类层面调用时作为promiseConfig.source???,或promiseConfig.resolveFn成功时回调
                // 实例层面调用时作为promiseConfig.queryParams携带的查询数据,或promiseConfig.resolveFn成功时回调
                case 1:
                    if (typeof args[0] == 'object') {
                        if (isClassMethod) {
                            promiseConfig.source = args[0];
                        }else {
                            promiseConfig.queryParams = args[0];
                        }
                    } else {
                      if (typeof args[0] == 'function') {
                          promiseConfig.resolveFn = args[0];
                      } else {
                          throw Error("Arguments types mismatch!");
                      }
                    }
                    break;
            }
        }

    }, {
        key: 'NoBodyData',

        // resourceClass[actionName]传参处理([source],[queryParams],[resolveFn],[rejectFn])
        //      针对get形式的ajax,数据不通过bodyData传递
        // 参数actionName是resourceConfig.actionsConfig中的键,参数resourceConfig即ResourceConfig实例
        // resourceConfig含url、mapping、actionsConfig属性,actionsConfig是默认及用户配置actions复合后的结果
        // 参数promiseConfigh是HelpersAndParsers.getDefaultPromiseConfig获取的默认promiseConfig
        value: function NoBodyData(actionName, resourceConfig, promiseConfig, ModelInstance) {
            var isClassMethod = _lodash2['default'].isEmpty(ModelInstance),
                actionConfig = resourceConfig.actionsConfig[actionName];

            if (!isClassMethod) {
                promiseConfig.source = ModelInstance;
            }

            // args接收从arguments第四项后的所有内容,不含第四项,即resourceClass[actionName]方法传参
            for (var _len4 = arguments.length, args = Array(_len4 > 4 ? _len4 - 4 : 0), _key4 = 4; _key4 < _len4; _key4++) {
                args[_key4 - 4] = arguments[_key4];
            }

            switch (args.length) {
                case 4:
                    if (!isClassMethod) throw Error("Instance method can't have 4 arguments");
                    if (typeof args[0] == 'object' && typeof args[1] == 'object' && typeof args[2] == 'function' && typeof args[3] == 'function') {
                        promiseConfig.source = args[0];
                        promiseConfig.queryParams = args[1];
                        promiseConfig.resolveFn = args[2];
                        promiseConfig.rejectFn = args[3];
                    } else {
                        throw Error("Arguments types mismatch!");
                    }
                    break;
                case 3:
                    if (isClassMethod) {
                        if (typeof args[0] == 'object' && typeof args[1] == 'object' && typeof args[2] == 'function') {
                            promiseConfig.source = args[0];
                            promiseConfig.queryParams = args[1];
                            promiseConfig.resolveFn = args[2];
                        } else if (typeof args[0] == 'object' && typeof args[1] == 'function' && typeof args[2] == 'function') {
                            promiseConfig.source = args[0];
                            promiseConfig.resolveFn = args[1];
                            promiseConfig.rejectFn = args[2];
                        } else {
                            throw Error("Arguments types mismatch!");
                        }
                    } else {
                        if (typeof args[0] == 'object' && typeof args[1] == 'function' && typeof args[2] == 'function') {
                            promiseConfig.queryParams = args[0];
                            promiseConfig.resolveFn = args[1];
                            promiseConfig.rejectFn = args[2];
                        } else {
                            throw Error("Arguments types mismatch!");
                        }
                    }
                    break;
                case 2:
                    if (typeof args[0] == 'function' && typeof args[1] == 'function') {
                        promiseConfig.resolveFn = args[0];
                        promiseConfig.rejectFn = args[1];
                    } else {
                        if (isClassMethod) {
                            if (typeof args[0] == 'object' && typeof args[1] == 'object') {
                                promiseConfig.source = args[0];
                                promiseConfig.queryParams = args[1];
                            } else if (typeof args[0] == 'object' && typeof args[1] == 'function') {
                                promiseConfig.source = args[0];
                                promiseConfig.resolveFn = args[1];
                            } else {
                                throw Error("Arguments types mismatch!");
                            }
                        } else {
                            if (typeof args[0] == 'object' && typeof args[1] == 'function') {
                                promiseConfig.queryParams = args[0];
                                promiseConfig.resolveFn = args[1];
                            } else {
                                throw Error("Arguments types mismatch!");
                            }
                        }
                    }
                    break;
                case 1:
                    if (typeof args[0] == 'object') {
                        if (isClassMethod) {
                            if (actionConfig.isArray == false) {
                              promiseConfig.source = args[0];
                            } else {
                              promiseConfig.queryParams = args[0];
                            }
                        } else {
                            promiseConfig.queryParams = args[0];
                        }
                    } else if (typeof args[0] == 'function') {
                        promiseConfig.resolveFn = args[0];
                    } else {
                        throw Error("Arguments types mismatch!");
                    }
                    break;
            }
        }

    // actionConfig.url中变量{:id}替换为实际值或空
    }, {
      key: 'parseUrlWithMapping',
      value: function parseUrlWithMapping(actionConfig, resourceConfig, promiseConfig) {
          var outputUrl = _lodash2['default'].clone(actionConfig.url);
          for (var object_key in resourceConfig.mappings) {
              var sourceValue = promiseConfig.source[object_key];
              if (sourceValue) {
                  outputUrl = outputUrl.replace(new RegExp('{' + resourceConfig.mappings[object_key] + '}', 'g'), sourceValue);
              } else {
                  outputUrl = outputUrl.replace(new RegExp('/?{' + resourceConfig.mappings[object_key] + '}', 'g'), "");
              }
          }
          outputUrl = outputUrl.replace(/\/?\{\:.+\}/i, "");
          return outputUrl;
      }

    // 默认的promiseConfig,设置成功和失败时的回调函数
    // resourceClass[actionName]传参处理后将赋值给该promiseConfig拷贝,作为resourceClass[actionName]的promiseConfig
    }, {
      key: 'getDefaultPromiseConfig',
      value: function getDefaultPromiseConfig() {
          return {
              url: undefined,
              source: {},
              queryParams: {},
              bodyData: {},
              resolveFn: function resolveFn() {},
              rejectFn: function rejectFn() {}
          };
      }

    // 拷贝对象输出,"$"起始的键不拷贝
    }, {
      key: 'copyPureAttributes',
      value: function copyPureAttributes(sourceObject) {
          var targetObject = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

          if (typeof sourceObject == 'object') {
              _lodash2['default'].forEach(Object.keys(sourceObject), function (sourceAttribute) {
                  // lodash.startsWith(str1,str2)校验str1是否以str2起始
                  if (_lodash2['default'].startsWith(sourceAttribute, '$') == false) {
                      targetObject[sourceAttribute] = sourceObject[sourceAttribute];
                  }
              });
          }
          return targetObject;
      }

    // 解析url中的查询字符串,对象形式输出
    }, {
      key: 'extractQueryParams',
      value: function extractQueryParams() {
          var inputUrl = arguments.length <= 0 || arguments[0] === undefined ? "" : arguments[0];

          var regex = /[?&]([^=#]+)=([^&#]*)/g,
              params = {},
              match = undefined;
          while (match = regex.exec(inputUrl)) {
              params[match[1]] = match[2];
          }
          return params;
      }

    // 数组项去重
    }, {
        key: 'uniqueArray',
        value: function uniqueArray() {
            var array = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];

            var a = array.concat();
            for (var i = 0; i < a.length; ++i) {
                for (var j = i + 1; j < a.length; ++j) {
                    if (a[i] === a[j]) a.splice(j--, 1);
                }
            }
            return a;
        }
    }]);

    return HelpersAndParsers;
})();

// 默认actions
var DEFAULT_ACTIONS_CONFIG = {
    'query': { url: null, params: {}, method: 'GET', isArray: true },
    'get': { url: null, params: {}, method: 'GET', isArray: false },
    'create': { url: null, params: {}, method: 'POST', isArray: false },
    'update': { url: null, params: {}, method: 'PUT', isArray: false },
    'delete': { url: null, params: {}, method: 'DELETE', isArray: false }
};

var ACTIONS_WITH_BODY = ['POST', 'PUT', 'PATCH', 'DELETE'];

var ACTIONS_WITHOUT_BODY = ['GET'];

module.exports = exports['default'];

猜你喜欢

转载自schifred.iteye.com/blog/2349033
今日推荐