[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 4\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n    \"env\": {\n        \"browser\": true,\n        \"es2021\": true,\n        \"node\": true,\n    },\n    globals : {\n        wx:true,\n    },\n    \"extends\": \"eslint:recommended\",\n    \"parserOptions\": {\n        \"ecmaVersion\": 12,\n        \"sourceType\": \"module\"\n    },\n    \"rules\": {\n        semi: [2, \"always\"],\n        quotes: [2, \"double\"],\n        indent: [\"error\", 4],\n        \"no-mixed-spaces-and-tabs\": [\"error\", \"smart-tabs\"],\n        camelcase: 0,\n        \"no-irregular-whitespace\": [\"error\", { \"skipComments\": true }],\n        \"no-tabs\" : 0\n    }\n};\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules/\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Editor directories and files\n.idea\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n/dist\n*.tgz\n"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"tabWidth\": 4,\n  \"singleQuote\": false,\n  \"printWidth\": 100,\n  \"semi\": true,\n  \"useTabs\": false\n}"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "\n\n\n\n# wechat-request\n\n<p align=\"center\">\n    <img src=\"https://img.shields.io/npm/dm/wechat-request.svg?style=flat-square\" />\n    <img src=\"https://img.shields.io/npm/v/wechat-request.svg?style=flat-square\" />\n    <img src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square\" />\n</p>\n\n> 基于Promise微信小程序http请求，轻便，小巧，api友好，功能丰富\n\n\n## 特别之处\n- 支持Promise API\n- 拦截请求和响应\n- 转换请求和响应数据\n- 取消请求\n- 自动转换为JSON数据\n- 超时请求\n- 告别callback\n- 支持默认请求前缀\n- 支持并发请求\n\n## 使用方式\n\n```yarn add wechat-request``` <br />\n```npm install wechat-request --save ```<br />\n```import wxRequest from 'wechat-request';```<br />\n\n\n\n## 一步上手\n\n首先来一个简单的```get```请求\n```js\n// 向具有给定ID的用户发出请求\nwxRequest.get('/user?id=12345')\n.then(function (response) {\n\tconsole.log(response);\n})\n.catch(function (error) {\n\tconsole.log(error);\n});\n\n// 可选地，上面的请求也可以按照\nwxRequest.get('/user', {\n\tparams: {\n\t\t\tid: 'number'\n\t}\n}).then(function (response) {\n    console.log(response);\n}).catch(function (error) {\n    console.log(error);\n});\n\n// 想要使用 async/await？ 将`async`关键字添加到外部函数/method\nasync function getUser() {\n\ttry {\n\t\tconst response = await wxRequest.get('/user?ID=12345');\n\t\tconsole.log(response);\n\t} catch (error) {\n\t\tconsole.error(error);\n\t}\n}\n```\n> 多种方法使用async/waait，开启代码便捷、畅快之旅\n\n接着再来一个```post```请求\n\n```js\nwxRequest.post('/user', {\n\tfirstname : 'firstname',\n\tlastname : 'lastname'\n}).then(function (response) {\n  console.log(response);\n}).catch(function (error) {\n  console.log(error);\n});\n```\n\n执行多并发请求例子\n\n```js\nfunction getUserAccount() {\n  return wxRequest.get('/user/12345');\n}\n\nfunction getUserPermissions() {\n  return wxRequest.get('/user/12345/permissions');\n}\n\nwxRequest.all([getUserAccount(), getUserPermissions()])\n\t.then(response =>{\n\t\t\t// dosoming ...\n\t});\n```\n\n## 请求方法别名\n当然除了常见的```get```,```post```其他的请求也统一封装\n\n- ```wxRequest.request(config)```\n- ```wxRequest.get(url[, config])```\n- ```wxRequest.delete(url[, config])```\n- ```wxRequest.head(url[, config])```\n- ```wxRequest.options(url[, config])```\n- ```wxRequest.post(url[, data[, config]])```\n- ```wxRequest.put(url[, data[, config]])```\n- ```wxRequest.patch(url[, data[, config]])```\n\n> note: 当使用别名方法`url`时，`method`和`data`属性不需要在config中指定。\n\n\n### 全局配置\n\n使用场景用户请求需要token,或者地址前缀，一次配置，省时省心。\n\n```js\nwxRequest.defaults.baseURL = 'https://api.example.com';\nwxRequest.defaults.headers['Authorization'] = AUTH_TOKEN;\nwxRequest.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';\n```\n\n## 致谢 && 参考\n* [axios](https://github.com/axios/axios)\n\n\n## License\n\nMIT\n"
  },
  {
    "path": "example/defaultConfig/request.js",
    "content": "\n\nimport wxRequest from 'wechat-request';\n\n\n// 针对post请求增加token\nwxRequest.interceptors.request.use(\n    config => {\n        if (config.method === 'post') {\n            config.headers.common['Authorization'] = AUTH_TOKEN;\n        }\n        return config;\n    },\n    err => {\n        return Promise.reject(err);\n    });\n\n\n\nexport default wxRequest;\n\n\n\n"
  },
  {
    "path": "index.d.ts",
    "content": "export interface BaseData {\n    [key: string]: any;\n}\n\nexport interface RequestPromise<T = any> extends Promise<Response<T>> {\n\n}\n\nexport type Method =\n    | 'get' | 'GET'\n    | 'delete' | 'DELETE'\n    | 'head' | 'HEAD'\n    | 'options' | 'OPTIONS'\n    | 'post' | 'POST'\n    | 'put' | 'PUT'\n    | 'patch' | 'PATCH'\n    | 'link' | 'LINK'\n    | 'unlink' | 'UNLINK'\n\nexport interface RequestConfig {\n    url?: string;\n    method?: Method;\n    baseURL?: string;\n    headers?: BaseData;\n    params?: BaseData;\n    data?: BaseData;\n    timeout?: number;\n}\n\nexport interface InterceptorManager<V> {\n    use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: any) => any): number;\n    eject(id: number): void;\n}\n\nexport interface Response<T = BaseData> {\n    data: T,\n    status: number,\n    statusText: string,\n    headers: T,\n    config: RequestConfig\n}\n\nexport interface RequestError<T = any> extends Error {\n\n}\n\nexport interface Instance {\n    (config: RequestConfig): RequestPromise;\n    (url: string, config?: RequestConfig): RequestPromise;\n    interceptors: {\n        request: InterceptorManager<RequestConfig>;\n        response: InterceptorManager<Response>;\n    };\n    request<T = any, R = Response<T>>(config: RequestConfig): Promise<R>;\n    get<T = any, R = Response<T>>(url: string, config?: RequestConfig): Promise<R>;\n    delete<T = any, R = Response<T>>(url: string, config?: RequestConfig): Promise<R>;\n    head<T = any, R = Response<T>>(url: string, config?: RequestConfig): Promise<R>;\n    post<T = any, R = Response<T>>(url: string, data?: any, config?: RequestConfig): Promise<R>;\n    put<T = any, R = Response<T>>(url: string, data?: any, config?: RequestConfig): Promise<R>;\n    patch<T = any, R = Response<T>>(url: string, data?: any, config?: RequestConfig): Promise<R>;\n}\nexport interface RequestStatic extends Instance {\n    create(config?: RequestConfig): Instance;\n    all<T>(values: (T | Promise<T>)[]): Promise<T[]>;\n}\n\ndeclare const wechatRequest: RequestStatic\nexport default wechatRequest;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"wechat-request\",\n  \"version\": \"2.7.0\",\n  \"description\": \"基于Promise微信小程序http请求，轻便，小巧，api友好，功能丰富\",\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"dev\": \"rollup -c -w\",\n    \"build\": \"rollup -c\",\n    \"lint\": \"eslint -c ./.eslintrc.js --ext .js src/ --fix\",\n    \"lint-prettire\": \"prettier --write src/**/*.{vue,js,jsx,less}\"\n  },\n  \"keywords\": [\n    \"request\",\n    \"wechat\",\n    \"promise\",\n    \"http\",\n    \"微信小程序\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/hatedMe/wechat-request.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/hatedMe/wechat-request/issues\"\n  },\n  \"license\": \"ISC\",\n  \"author\": \"Atom <7548764@qq.com>\",\n  \"files\": [\n    \"dist\",\n    \"index.d.ts\"\n  ],\n  \"types\": \"index.d.ts\",\n  \"devDependencies\": {}\n}"
  },
  {
    "path": "rollup.config.js",
    "content": "export default {\n    input: \"src/index.js\",\n    output: {\n        file: \"dist/index.js\",\n        format: \"umd\",\n        name: \"wechatRequest\",\n    },\n    watch: {\n        include: \"src/**\",\n    },\n};\n"
  },
  {
    "path": "src/InterceptorManager.js",
    "content": "export default class InterceptorManager {\n    constructor() {\n        this.handlers = [];\n    }\n\n    use(fulfilled, rejected) {\n        this.handlers.push({\n            fulfilled,\n            rejected,\n        });\n        return this.handlers.length - 1;\n    }\n\n    eject(id) {\n        if (this.handlers[id]) {\n            this.handlers[id] = null;\n        }\n    }\n\n    forEach(fn) {\n        this.handlers.forEach((e) => {\n            if (e !== null) {\n                fn(e);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "src/class.js",
    "content": "import * as util from \"./helpers/util\";\nimport InterceptorManager from \"./InterceptorManager\";\nimport { dispatchRequest } from \"./core/dispatchRequest\";\n\nclass Request {\n    constructor(config) {\n        this.defaults = config;\n        this.interceptors = {\n            request: new InterceptorManager(),\n            response: new InterceptorManager(),\n        };\n    }\n    request(config) {\n        if (typeof config === \"string\") {\n            config = util.merge({ url: arguments[0] }, arguments[1]);\n        }\n\n        config = util.deepMerge(this.defaults, config);\n        config.method = config.method ? config.method.toLowerCase() : \"get\";\n\n        let chain = [dispatchRequest, undefined];\n        let promise = Promise.resolve(config);\n\n        this.interceptors.request.forEach(function (interceptor) {\n            chain.unshift(interceptor.fulfilled, interceptor.rejected);\n        });\n\n        this.interceptors.response.forEach(function (interceptor) {\n            chain.push(interceptor.fulfilled, interceptor.rejected);\n        });\n\n        while (chain.length) {\n            promise = promise.then(chain.shift(), chain.shift());\n        }\n\n        return promise;\n    }\n    all(promises) {\n        return Promise.all(promises);\n    }\n}\n\n[\"delete\", \"get\", \"head\", \"options\", \"trace\"].forEach((method) => {\n    Request.prototype[method] = function (url, config) {\n        return this.request(\n            util.merge(config || {}, {\n                method,\n                url,\n            })\n        );\n    };\n});\n\n[\"post\", \"put\", \"patch\"].forEach((method) => {\n    Request.prototype[method] = function (url, data, config) {\n        return this.request(\n            util.merge(config || {}, {\n                method,\n                url,\n                data,\n            })\n        );\n    };\n});\n\nexport default Request;\n"
  },
  {
    "path": "src/core/dispatchRequest.js",
    "content": "import * as util from \"../helpers/util\";\nexport const dispatchRequest = function (config) {\n    if (config.baseURL && !util.isAbsoluteURL(config.url)) {\n        config.url = util.combineURLs(config.baseURL, config.url);\n    }\n\n    config.url = util.buildURL(config.url, config.params);\n\n    config.data = util.merge(config.data, config.transformRequest(config.data));\n\n    config.headers = util.merge(\n        config.headers.common || {},\n        config.headers[config.method] || {},\n        config.headers || {}\n    );\n\n    let methods = [\"delete\", \"get\", \"head\", \"post\", \"put\", \"patch\", \"common\"];\n    methods.forEach((method) => {\n        delete config.headers[method];\n    });\n\n    let promise = Promise.resolve(config);\n    promise = promise.then((config) => {\n        return new Promise(function (resolve, reject) {\n            let requestTask = wx.request({\n                url: config.url,\n                data: util.buildData(config.data),\n                header: config.headers,\n                method: config.method,\n                dataType: config.dataType,\n                success: function (res) {\n                    resolve({\n                        data: res.data,\n                        headers: res.header,\n                        status: res.statusCode,\n                        statusText: \"ok\",\n                    });\n                },\n                fail: function (err) {\n                    reject(err);\n                },\n                complete: function () {\n                    config.complete && config.complete();\n                },\n            });\n\n            if (config.timeout && typeof config.timeout === \"number\" && config.timeout > 1000) {\n                setTimeout(() => {\n                    requestTask.abort();\n                    resolve({\n                        status: \"canceled\",\n                    });\n                }, config.timeout);\n            }\n        });\n    });\n\n    return promise;\n};\n"
  },
  {
    "path": "src/defaults.js",
    "content": "import * as util from \"./helpers/util\";\n\nlet DEFAULT_CONTENT_TYPE = {\n    \"Content-Type\": \"application/x-www-form-urlencoded\",\n};\n\nconst defaults = {\n    method: \"get\", // default\n    // baseURL: '',\n    dataType: \"json\",\n    responseType: \"text\",\n    // timeout: 0,\n    headers: {},\n\n    // params : {},\n\n    transformRequest(data) {\n        return data;\n    },\n\n    // transformResponse (data) {\n    //     return data;\n    // },\n\n    // validateStatus ( status ) {\n    //     return status >= 200 && status < 300\n    // }\n};\n\ndefaults.headers = {\n    common: {\n        Accept: \"application/json, text/plain, */*\",\n    },\n};\n\n[\"delete\", \"get\", \"head\", \"post\", \"put\", \"patch\"].map((e) => {\n    defaults.headers[e] = util.merge(defaults.headers, DEFAULT_CONTENT_TYPE);\n});\n\nexport default defaults;\n"
  },
  {
    "path": "src/helpers/util.js",
    "content": "export const bind = function (fn, thisArg) {\n    return function warp() {\n        return fn.apply(thisArg, Array.from(arguments));\n    };\n};\n\nexport const extend = function (a, b, thisArg) {\n    let o = Object.getOwnPropertyNames(b);\n    o.forEach((attr) => {\n        if (thisArg && typeof b[attr] === \"function\") {\n            a[attr] = bind(b[attr], thisArg);\n        } else {\n            a[attr] = b[attr];\n        }\n    });\n    return a;\n};\n\nexport const copyobj = function (a, b) {\n    return Object.assign({}, a, b);\n};\n\nexport const merge = function () {\n    var result = {};\n    Array.from(arguments).forEach((e) => {\n        for (let key in e) {\n            if (e[key] && typeof e[key] === \"object\" && !isEmptyObject(e[key])) {\n                merge(result[key], e[key]);\n            }\n            result[key] = e[key];\n        }\n    });\n    return result;\n};\n\nexport const deepMerge = function () {\n    let result = {};\n    Array.from(arguments).forEach((e) => {\n        if (e && typeof e === \"object\" && !isEmptyObject(e)) {\n            Object.keys(e).forEach((key) => {\n                if (e[key] && typeof e[key] === \"object\") {\n                    result[key] = deepMerge(result[key], e[key]);\n                }\n                result[key] = e[key];\n            });\n        }\n    });\n    return result;\n};\n\nexport const isEmptyObject = (obj) => {\n    return Object.getOwnPropertyNames(obj).length === 0;\n};\n\nexport const isObject = (obj) => {\n    return obj !== null && typeof obj === \"object\";\n};\n\nexport const combineURLs = function (baseURL, relativeURL) {\n    return relativeURL\n        ? baseURL.replace(/\\/+$/, \"\") + \"/\" + relativeURL.replace(/^\\/+/, \"\")\n        : baseURL;\n};\n\nfunction encode(val) {\n    return encodeURIComponent(val)\n        .replace(/%40/gi, \"@\")\n        .replace(/%3A/gi, \":\")\n        .replace(/%24/g, \"$\")\n        .replace(/%2C/gi, \",\")\n        .replace(/%20/g, \"+\")\n        .replace(/%5B/gi, \"[\")\n        .replace(/%5D/gi, \"]\");\n}\nexport const buildURL = function (url, paramsObject) {\n    if (!paramsObject || isEmptyObject(paramsObject)) return url;\n    let parts = [];\n    Object.keys(paramsObject).forEach((key) => {\n        parts.push(encode(key) + \"=\" + encode(paramsObject[key]));\n    });\n    return (url += (url.indexOf(\"?\") === -1 ? \"?\" : \"&\") + parts.join(\"&\"));\n};\n\nexport const isAbsoluteURL = function (url) {\n    return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n};\n\nexport const buildData = (data) => {\n    if (!isObject(data) || isEmptyObject(data)) return {};\n    const result = {};\n    Object.keys(data).forEach((key) => {\n        if (data[key] !== null && typeof data[key] !== \"undefined\") {\n            result[key] = data[key];\n        }\n    });\n    return result;\n};\n"
  },
  {
    "path": "src/index.js",
    "content": "import request from \"./request\";\nexport default request;\n"
  },
  {
    "path": "src/request.js",
    "content": "import Request from \"./class\";\nimport * as util from \"./helpers/util\";\nimport defaults from \"./defaults\";\n\nfunction createInstance(config) {\n    let context = new Request(config);\n    let instance = util.bind(Request.prototype.request, context);\n    util.extend(instance, Request.prototype, context);\n    util.extend(instance, context);\n    // 用于创建多个实例\n    instance.create = function (config) {\n        return createInstance(util.merge(defaults, config));\n    };\n    return instance;\n}\n\nconst request = createInstance(defaults);\n// 并发请求数据处理\nrequest.spread = function (callback) {\n    return function (...arg) {\n        return callback.apply(null, [...arg]);\n    };\n};\n\nexport default request;\n"
  }
]