├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── dist ├── index.js ├── index.js.map └── types │ ├── index.d.ts │ ├── types.d.ts │ └── util.d.ts ├── package.json ├── src ├── index.ts ├── types.ts ├── util.ts └── weex.d.ts ├── test └── http.test.js ├── tsconfig.json └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | coverage 40 | yarn.lock 41 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 'node' 4 | 5 | script: npm run test-cov 6 | after_success: cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # weex-http 2 | weex simple http lib 3 | 4 | [![Build Status](https://img.shields.io/travis/MMF-FE/weex-http.svg?style=flat-square)](https://travis-ci.org/MMF-FE/weex-http) 5 | [![Coverage Status](https://img.shields.io/coveralls/MMF-FE/weex-http.svg?style=flat-square)](https://coveralls.io/r/MMF-FE/weex-http?branch=master) 6 | 7 | ## Installing 8 | 9 | ``` 10 | npm i weex-http --save-dev 11 | # or 12 | yarn add weex-http --dev 13 | ``` 14 | 15 | ## Example 16 | 17 | Performing a GET request 18 | 19 | ```js 20 | import weexHttp from 'weex-http' 21 | 22 | weexHttp.get('/user', { 23 | ID: 12345 24 | }) 25 | .then(function (response) { 26 | console.log(response) 27 | }) 28 | .catch(function (error) { 29 | console.log(error) 30 | }) 31 | ``` 32 | 33 | Performing a POST request 34 | 35 | ```js 36 | weexHttp.post('/user', { 37 | firstName: 'Fred', 38 | lastName: 'Flintstone' 39 | }) 40 | .then(function (response) { 41 | console.log(response); 42 | }) 43 | .catch(function (error) { 44 | console.log(error); 45 | }) 46 | ``` 47 | 48 | ## Creating an instance 49 | 50 | You can create a new instance of axios with a custom config. 51 | 52 | weexHttp.create([config]) 53 | 54 | ```js 55 | var instance = weexHttp.create({ 56 | baseURL: 'https://some-domain.com/api/', 57 | timeout: 1000, 58 | headers: {'X-Custom-Header': 'foobar'} 59 | }) 60 | ``` 61 | 62 | ## Options 63 | 64 | - timeout number `default: 10000` ms 65 | - headers any `default: {}` 66 | - transformRequest Function[] `default: []` 67 | - transformHeaders Function[] `default: []` 68 | - transformResponse Function[] `default: []` 69 | 70 | ## Instance methods 71 | 72 | The available instance methods are listed below. The specified config will be merged with the instance config. 73 | 74 | weexHttp#get(url[, data[, config]]) 75 | 76 | weexHttp#delete(url[, data[, config]]) 77 | 78 | weexHttp#head(url[, data[, config]]) 79 | 80 | weexHttp#post(url[, data[, config]]) 81 | 82 | weexHttp#put(url[, data[, config]]) 83 | 84 | weexHttp#patch(url[, data[, config]]) 85 | 86 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | module.exports = 2 | /******/ (function(modules) { // webpackBootstrap 3 | /******/ // The module cache 4 | /******/ var installedModules = {}; 5 | /******/ 6 | /******/ // The require function 7 | /******/ function __webpack_require__(moduleId) { 8 | /******/ 9 | /******/ // Check if module is in cache 10 | /******/ if(installedModules[moduleId]) 11 | /******/ return installedModules[moduleId].exports; 12 | /******/ 13 | /******/ // Create a new module (and put it into the cache) 14 | /******/ var module = installedModules[moduleId] = { 15 | /******/ exports: {}, 16 | /******/ id: moduleId, 17 | /******/ loaded: false 18 | /******/ }; 19 | /******/ 20 | /******/ // Execute the module function 21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 22 | /******/ 23 | /******/ // Flag the module as loaded 24 | /******/ module.loaded = true; 25 | /******/ 26 | /******/ // Return the exports of the module 27 | /******/ return module.exports; 28 | /******/ } 29 | /******/ 30 | /******/ 31 | /******/ // expose the modules object (__webpack_modules__) 32 | /******/ __webpack_require__.m = modules; 33 | /******/ 34 | /******/ // expose the module cache 35 | /******/ __webpack_require__.c = installedModules; 36 | /******/ 37 | /******/ // __webpack_public_path__ 38 | /******/ __webpack_require__.p = ""; 39 | /******/ 40 | /******/ // Load entry module and return exports 41 | /******/ return __webpack_require__(0); 42 | /******/ }) 43 | /************************************************************************/ 44 | /******/ ([ 45 | /* 0 */ 46 | /***/ (function(module, exports, __webpack_require__) { 47 | 48 | /** 49 | * http lib 50 | * @author vfasky 51 | * 52 | **/ 53 | 'use strict'; 54 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 55 | return new (P || (P = Promise))(function (resolve, reject) { 56 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 57 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 58 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 59 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 60 | }); 61 | }; 62 | var __generator = (this && this.__generator) || function (thisArg, body) { 63 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 64 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 65 | function verb(n) { return function (v) { return step([n, v]); }; } 66 | function step(op) { 67 | if (f) throw new TypeError("Generator is already executing."); 68 | while (_) try { 69 | if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; 70 | if (y = 0, t) op = [0, t.value]; 71 | switch (op[0]) { 72 | case 0: case 1: t = op; break; 73 | case 4: _.label++; return { value: op[1], done: false }; 74 | case 5: _.label++; y = op[1]; op = [0]; continue; 75 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 76 | default: 77 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 78 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 79 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 80 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 81 | if (t[2]) _.ops.pop(); 82 | _.trys.pop(); continue; 83 | } 84 | op = body.call(thisArg, _); 85 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 86 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 87 | } 88 | }; 89 | Object.defineProperty(exports, "__esModule", { value: true }); 90 | var util_1 = __webpack_require__(1); 91 | var stream = weex.requireModule('stream'); 92 | var methods = ['GET', 'DELETE', 'HEAD', 'POST', 'PUT', 'PATCH']; 93 | var buildUrlMemthods = ['POST', 'PUT', 'PATCH']; 94 | var platform = weex.config.env.platform.toLocaleLowerCase(); 95 | var is = { 96 | web: platform === 'web', 97 | android: platform === 'android', 98 | iOS: platform === 'ios', 99 | ios: platform === 'ios', 100 | wechat: platform === 'web' && (/micromessenger/i).test(navigator.userAgent) 101 | }; 102 | var Http = (function () { 103 | function Http(options) { 104 | this.options = util_1.setOptonsDefault(options, { 105 | timeout: 10000, 106 | headers: {}, 107 | baseURL: '', 108 | method: 'GET', 109 | data: {}, 110 | url: '/', 111 | progress: function () { }, 112 | transformRequest: [], 113 | transformResponse: [], 114 | transformHeaders: [] 115 | }); 116 | } 117 | Http.prototype.getHeaders = function () { 118 | return this.clone(util_1.setOptonsDefault(this.options.headers, { 119 | 'Content-Type': 'application/x-www-form-urlencoded' 120 | })); 121 | }; 122 | Http.prototype.getMethod = function (options) { 123 | var method = String(options.method).trim().toLocaleUpperCase(); 124 | if (methods.indexOf(method) === -1) { 125 | throw new Error(method + " not in " + methods.join(', ')); 126 | } 127 | return method; 128 | }; 129 | Http.prototype.buildUrl = function (options) { 130 | return (options.hasOwnProperty('baseURL') ? options.baseURL : this.options.baseURL) + 131 | options.url; 132 | }; 133 | Http.prototype.clone = function (data) { 134 | return JSON.parse(JSON.stringify(data)); 135 | }; 136 | Http.prototype.buildData = function (options) { 137 | return __awaiter(this, void 0, void 0, function () { 138 | var data, sendData; 139 | return __generator(this, function (_a) { 140 | switch (_a.label) { 141 | case 0: 142 | data = this.clone(options.data); 143 | return [4 /*yield*/, this.callPromise('transformRequest', options, data)]; 144 | case 1: 145 | _a.sent(); 146 | sendData = util_1.param(data); 147 | return [2 /*return*/, sendData]; 148 | } 149 | }); 150 | }); 151 | }; 152 | Http.prototype.callPromise = function (funStr, options, data) { 153 | return __awaiter(this, void 0, void 0, function () { 154 | return __generator(this, function (_a) { 155 | switch (_a.label) { 156 | case 0: 157 | if (!Array.isArray(this.options[funStr])) return [3 /*break*/, 2]; 158 | return [4 /*yield*/, Promise.all(this.options[funStr].map(function (promise) { 159 | return promise(data); 160 | }))]; 161 | case 1: 162 | _a.sent(); 163 | _a.label = 2; 164 | case 2: 165 | if (!Array.isArray(options[funStr])) return [3 /*break*/, 4]; 166 | return [4 /*yield*/, Promise.all(options[funStr].map(function (promise) { 167 | return promise(data); 168 | }))]; 169 | case 3: 170 | _a.sent(); 171 | _a.label = 4; 172 | case 4: return [2 /*return*/, data]; 173 | } 174 | }); 175 | }); 176 | }; 177 | Http.prototype.send = function (options) { 178 | return __awaiter(this, void 0, void 0, function () { 179 | var _this = this; 180 | var timeout, method, body, url, headers, isSend, link; 181 | return __generator(this, function (_a) { 182 | switch (_a.label) { 183 | case 0: 184 | timeout = options.hasOwnProperty('timeout') ? options.timeout : this.options.timeout; 185 | method = this.getMethod(options); 186 | return [4 /*yield*/, this.buildData(options)]; 187 | case 1: 188 | body = _a.sent(); 189 | url = this.buildUrl(options); 190 | headers = this.getHeaders(); 191 | if (options.headers) { 192 | Object.keys(options.headers).forEach(function (key) { 193 | headers[key] = options.headers[key]; 194 | }); 195 | } 196 | return [4 /*yield*/, this.callPromise('transformHeaders', options, headers)]; 197 | case 2: 198 | _a.sent(); 199 | isSend = true; 200 | if (buildUrlMemthods.indexOf(method.toLocaleUpperCase()) === -1) { 201 | link = url.indexOf('?') === -1 ? '?' : '&'; 202 | url += link + body; 203 | body = ''; 204 | isSend = false; 205 | } 206 | return [2 /*return*/, new Promise(function (resolve, reject) { 207 | var isReturn = false; 208 | var timeoutId = setTimeout(function () { 209 | isReturn = true; 210 | reject({ 211 | status: 0, 212 | ok: false, 213 | statusText: 'TIMEOUT', 214 | data: 'TIMEOUT', 215 | headers: {} 216 | }); 217 | }, timeout); 218 | // ios8 wechat back bug 219 | if (is.wechat) { 220 | var deviceAgent = navigator.userAgent.toLowerCase(); 221 | var isIos8_1 = /(iphone|ipod|ipad).* os 8_/.test(deviceAgent); 222 | var xhr_1 = new XMLHttpRequest(); 223 | var xhrDone_1 = function () { 224 | clearTimeout(timeoutId); 225 | if (isReturn) 226 | return; 227 | if (xhr_1.status >= 200 && xhr_1.status < 300) { 228 | resolve({ 229 | status: xhr_1.status, 230 | ok: true, 231 | statusText: xhr_1.statusText, 232 | data: xhr_1.responseText, 233 | headers: {} 234 | }); 235 | } 236 | }; 237 | var xhrOnChange = function () { 238 | if (xhr_1.readyState == 4) { 239 | // 微信你大爷 240 | if (!xhr_1.status && isIos8_1) { 241 | var key = '__weex_http'; 242 | var lastReloadDate = localStorage.getItem(key); 243 | var now = Date.now(); 244 | if (lastReloadDate == null || now - Number(lastReloadDate) > 5000) { 245 | localStorage.setItem(key, String(now)); 246 | window.location.reload(); 247 | } 248 | return; 249 | } 250 | xhrDone_1(); 251 | } 252 | }; 253 | xhr_1.onreadystatechange = xhrOnChange; 254 | xhr_1.open(method, url, true); 255 | Object.keys(headers).forEach(function (key) { 256 | xhr_1.setRequestHeader(key, headers[key]); 257 | }); 258 | xhr_1.send(body); 259 | } 260 | else { 261 | stream.fetch({ 262 | method: method, 263 | body: body, 264 | url: url, 265 | headers: headers, 266 | type: 'text' 267 | }, function (response) { 268 | clearTimeout(timeoutId); 269 | if (isReturn) 270 | return; 271 | if (response.ok) { 272 | resolve(response); 273 | } 274 | else { 275 | reject(response); 276 | } 277 | }, function (args) { 278 | _this.options.progress(args); 279 | }); 280 | } 281 | }).then(function (response) { return __awaiter(_this, void 0, void 0, function () { 282 | return __generator(this, function (_a) { 283 | switch (_a.label) { 284 | case 0: return [4 /*yield*/, this.callPromise('transformResponse', options, response)]; 285 | case 1: 286 | _a.sent(); 287 | return [2 /*return*/, response]; 288 | } 289 | }); 290 | }); })]; 291 | } 292 | }); 293 | }); 294 | }; 295 | Object.defineProperty(Http, "config", { 296 | get: function () { 297 | return this._config; 298 | }, 299 | set: function (options) { 300 | var _this = this; 301 | Object.keys(options).forEach(function (key) { 302 | _this._config[key] = options[key]; 303 | if (_this._instance) { 304 | _this._instance.options[key] = options[key]; 305 | } 306 | }); 307 | }, 308 | enumerable: true, 309 | configurable: true 310 | }); 311 | Http.buildMethod = function (method, url, data, options, instance) { 312 | if (data === void 0) { data = {}; } 313 | if (options === void 0) { options = {}; } 314 | if (!instance) { 315 | if (!this._instance) { 316 | this._instance = new this(this.config); 317 | } 318 | instance = this._instance; 319 | } 320 | options.method = method; 321 | options.data = data; 322 | options.url = url; 323 | return instance.send(options); 324 | }; 325 | Http.create = function (options) { 326 | var _this = this; 327 | if (options === void 0) { options = {}; } 328 | var instance = new this(options); 329 | var func = { 330 | instance: instance 331 | }; 332 | methods.forEach(function (method) { 333 | func[method.toLocaleLowerCase()] = function (url, data, options) { 334 | if (data === void 0) { data = {}; } 335 | return _this.buildMethod(method, url, data, options, instance); 336 | }; 337 | }); 338 | return func; 339 | }; 340 | Http.get = function (url, data, options) { 341 | if (data === void 0) { data = {}; } 342 | return this.buildMethod('GET', url, data, options); 343 | }; 344 | Http.post = function (url, data, options) { 345 | if (data === void 0) { data = {}; } 346 | return this.buildMethod('POST', url, data, options); 347 | }; 348 | Http.delete = function (url, data, options) { 349 | if (data === void 0) { data = {}; } 350 | return this.buildMethod('DELETE', url, data, options); 351 | }; 352 | Http.head = function (url, data, options) { 353 | if (data === void 0) { data = {}; } 354 | return this.buildMethod('HEAD', url, data, options); 355 | }; 356 | Http.put = function (url, data, options) { 357 | if (data === void 0) { data = {}; } 358 | return this.buildMethod('PUT', url, data, options); 359 | }; 360 | Http.patch = function (url, data, options) { 361 | if (data === void 0) { data = {}; } 362 | return this.buildMethod('PATCH', url, data, options); 363 | }; 364 | return Http; 365 | }()); 366 | Http._config = { 367 | timeout: 10000, 368 | baseURL: '', 369 | headers: {} 370 | }; 371 | exports.default = Http; 372 | 373 | 374 | /***/ }), 375 | /* 1 */ 376 | /***/ (function(module, exports) { 377 | 378 | /** 379 | * util 380 | * @author vfasky 381 | * 382 | **/ 383 | 'use strict'; 384 | Object.defineProperty(exports, "__esModule", { value: true }); 385 | var rbracket = /\[\]$/; 386 | function buildParams(prefix, obj, add) { 387 | var name; 388 | if (Array.isArray(obj)) { 389 | // Serialize array item. 390 | obj.forEach(function (v, i) { 391 | if (rbracket.test(prefix)) { 392 | // Treat each array item as a scalar. 393 | add(prefix, v); 394 | } 395 | else { 396 | // Item is non-scalar (array or object), encode its numeric index. 397 | buildParams(prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", v, add); 398 | } 399 | }); 400 | } 401 | else if (typeof obj === "object") { 402 | // Serialize object item. 403 | for (name in obj) { 404 | buildParams(prefix + "[" + name + "]", obj[name], add); 405 | } 406 | } 407 | else { 408 | // Serialize scalar item. 409 | add(prefix, obj); 410 | } 411 | } 412 | function setOptonsDefault(options, defaultVals) { 413 | if (options === void 0) { options = {}; } 414 | if (defaultVals === void 0) { defaultVals = {}; } 415 | Object.keys(defaultVals).forEach(function (key) { 416 | if (!options.hasOwnProperty(key)) { 417 | options[key] = defaultVals[key]; 418 | } 419 | }); 420 | return options; 421 | } 422 | exports.setOptonsDefault = setOptonsDefault; 423 | function isFunction(obj) { 424 | return !!(obj && obj.constructor && obj.call && obj.apply); 425 | } 426 | exports.isFunction = isFunction; 427 | function param(a) { 428 | if (a === void 0) { a = {}; } 429 | var prefix; 430 | var s = []; 431 | var add = function (key, valueOrFunction) { 432 | // If value is a function, invoke it and use its return value 433 | var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction; 434 | s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value); 435 | }; 436 | for (prefix in a) { 437 | buildParams(prefix, a[prefix], add); 438 | } 439 | // Return the resulting serialization 440 | return s.join("&"); 441 | } 442 | exports.param = param; 443 | 444 | 445 | /***/ }) 446 | /******/ ]); 447 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack:///webpack/bootstrap dbde85f69d52f0c4f30c","webpack:///./src/index.ts","webpack:///./src/util.ts"],"names":[],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAmC,MAAM,6BAA6B,EAAE,YAAY,WAAW,EAAE;AACjG,mCAAkC,MAAM,iCAAiC,EAAE,YAAY,WAAW,EAAE;AACpG,gCAA+B,iEAAiE,uBAAuB,EAAE,4BAA4B;AACrJ;AACA,MAAK;AACL;AACA;AACA,cAAa,6BAA6B,0BAA0B,aAAa,EAAE,qBAAqB;AACxG,iBAAgB,qDAAqD,oEAAoE,aAAa,EAAE;AACxJ,uBAAsB,sBAAsB,qBAAqB,GAAG;AACpE;AACA;AACA;AACA;AACA;AACA;AACA,wCAAuC;AACvC,mCAAkC,SAAS;AAC3C,mCAAkC,WAAW,UAAU;AACvD,0CAAyC,cAAc;AACvD;AACA,8GAA6G,OAAO,UAAU;AAC9H,iFAAgF,iBAAiB,OAAO;AACxG,yDAAwD,gBAAgB,QAAQ,OAAO;AACvF,+CAA8C,gBAAgB,gBAAgB,OAAO;AACrF;AACA,kCAAiC;AACjC;AACA;AACA,UAAS,YAAY,aAAa,OAAO,EAAE,UAAU,WAAW;AAChE,oCAAmC,SAAS;AAC5C;AACA;AACA,+CAA8C,cAAc;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB;AACvB;AACA;AACA,qBAAoB;AACpB;AACA,oCAAmC,EAAE;AACrC;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC;AACrC,kCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC;AACrC;AACA,sCAAqC;AACrC;AACA,8BAA6B,4BAA4B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC;AACjC,8BAA6B,EAAE,EAAE;AACjC;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAa;AACb,UAAS;AACT;AACA;AACA,MAAK;AACL;AACA,+BAA8B,WAAW;AACzC,kCAAiC,cAAc;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAiC,cAAc;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA,uCAAsC,WAAW;AACjD;AACA;AACA,UAAS;AACT;AACA;AACA;AACA,+BAA8B,WAAW;AACzC;AACA;AACA;AACA,+BAA8B,WAAW;AACzC;AACA;AACA;AACA,+BAA8B,WAAW;AACzC;AACA;AACA;AACA,+BAA8B,WAAW;AACzC;AACA;AACA;AACA,+BAA8B,WAAW;AACzC;AACA;AACA;AACA,+BAA8B,WAAW;AACzC;AACA;AACA;AACA,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;;;;;;;ACnUA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA8C,cAAc;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA6B,cAAc;AAC3C,kCAAiC,kBAAkB;AACnD;AACA;AACA;AACA;AACA,MAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap dbde85f69d52f0c4f30c","/**\n * http lib\n * @author vfasky\n *\n **/\n'use strict';\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (this && this.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [0, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar util_1 = require(\"./util\");\nvar stream = weex.requireModule('stream');\nvar methods = ['GET', 'DELETE', 'HEAD', 'POST', 'PUT', 'PATCH'];\nvar buildUrlMemthods = ['POST', 'PUT', 'PATCH'];\nvar platform = weex.config.env.platform.toLocaleLowerCase();\nvar is = {\n web: platform === 'web',\n android: platform === 'android',\n iOS: platform === 'ios',\n ios: platform === 'ios',\n wechat: platform === 'web' && (/micromessenger/i).test(navigator.userAgent)\n};\nvar Http = (function () {\n function Http(options) {\n this.options = util_1.setOptonsDefault(options, {\n timeout: 10000,\n headers: {},\n baseURL: '',\n method: 'GET',\n data: {},\n url: '/',\n progress: function () { },\n transformRequest: [],\n transformResponse: [],\n transformHeaders: []\n });\n }\n Http.prototype.getHeaders = function () {\n return this.clone(util_1.setOptonsDefault(this.options.headers, {\n 'Content-Type': 'application/x-www-form-urlencoded'\n }));\n };\n Http.prototype.getMethod = function (options) {\n var method = String(options.method).trim().toLocaleUpperCase();\n if (methods.indexOf(method) === -1) {\n throw new Error(method + \" not in \" + methods.join(', '));\n }\n return method;\n };\n Http.prototype.buildUrl = function (options) {\n return (options.hasOwnProperty('baseURL') ? options.baseURL : this.options.baseURL) +\n options.url;\n };\n Http.prototype.clone = function (data) {\n return JSON.parse(JSON.stringify(data));\n };\n Http.prototype.buildData = function (options) {\n return __awaiter(this, void 0, void 0, function () {\n var data, sendData;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n data = this.clone(options.data);\n return [4 /*yield*/, this.callPromise('transformRequest', options, data)];\n case 1:\n _a.sent();\n sendData = util_1.param(data);\n return [2 /*return*/, sendData];\n }\n });\n });\n };\n Http.prototype.callPromise = function (funStr, options, data) {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n if (!Array.isArray(this.options[funStr])) return [3 /*break*/, 2];\n return [4 /*yield*/, Promise.all(this.options[funStr].map(function (promise) {\n return promise(data);\n }))];\n case 1:\n _a.sent();\n _a.label = 2;\n case 2:\n if (!Array.isArray(options[funStr])) return [3 /*break*/, 4];\n return [4 /*yield*/, Promise.all(options[funStr].map(function (promise) {\n return promise(data);\n }))];\n case 3:\n _a.sent();\n _a.label = 4;\n case 4: return [2 /*return*/, data];\n }\n });\n });\n };\n Http.prototype.send = function (options) {\n return __awaiter(this, void 0, void 0, function () {\n var _this = this;\n var timeout, method, body, url, headers, isSend, link;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n timeout = options.hasOwnProperty('timeout') ? options.timeout : this.options.timeout;\n method = this.getMethod(options);\n return [4 /*yield*/, this.buildData(options)];\n case 1:\n body = _a.sent();\n url = this.buildUrl(options);\n headers = this.getHeaders();\n if (options.headers) {\n Object.keys(options.headers).forEach(function (key) {\n headers[key] = options.headers[key];\n });\n }\n return [4 /*yield*/, this.callPromise('transformHeaders', options, headers)];\n case 2:\n _a.sent();\n isSend = true;\n if (buildUrlMemthods.indexOf(method.toLocaleUpperCase()) === -1) {\n link = url.indexOf('?') === -1 ? '?' : '&';\n url += link + body;\n body = '';\n isSend = false;\n }\n return [2 /*return*/, new Promise(function (resolve, reject) {\n var isReturn = false;\n var timeoutId = setTimeout(function () {\n isReturn = true;\n reject({\n status: 0,\n ok: false,\n statusText: 'TIMEOUT',\n data: 'TIMEOUT',\n headers: {}\n });\n }, timeout);\n // ios8 wechat back bug\n if (is.wechat) {\n var deviceAgent = navigator.userAgent.toLowerCase();\n var isIos8_1 = /(iphone|ipod|ipad).* os 8_/.test(deviceAgent);\n var xhr_1 = new XMLHttpRequest();\n var xhrDone_1 = function () {\n clearTimeout(timeoutId);\n if (isReturn)\n return;\n if (xhr_1.status >= 200 && xhr_1.status < 300) {\n resolve({\n status: xhr_1.status,\n ok: true,\n statusText: xhr_1.statusText,\n data: xhr_1.responseText,\n headers: {}\n });\n }\n };\n var xhrOnChange = function () {\n if (xhr_1.readyState == 4) {\n // 微信你大爷\n if (!xhr_1.status && isIos8_1) {\n var key = '__weex_http';\n var lastReloadDate = localStorage.getItem(key);\n var now = Date.now();\n if (lastReloadDate == null || now - Number(lastReloadDate) > 5000) {\n localStorage.setItem(key, String(now));\n window.location.reload();\n }\n return;\n }\n xhrDone_1();\n }\n };\n xhr_1.onreadystatechange = xhrOnChange;\n xhr_1.open(method, url, true);\n Object.keys(headers).forEach(function (key) {\n xhr_1.setRequestHeader(key, headers[key]);\n });\n xhr_1.send(body);\n }\n else {\n stream.fetch({\n method: method,\n body: body,\n url: url,\n headers: headers,\n type: 'text'\n }, function (response) {\n clearTimeout(timeoutId);\n if (isReturn)\n return;\n if (response.ok) {\n resolve(response);\n }\n else {\n reject(response);\n }\n }, function (args) {\n _this.options.progress(args);\n });\n }\n }).then(function (response) { return __awaiter(_this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.callPromise('transformResponse', options, response)];\n case 1:\n _a.sent();\n return [2 /*return*/, response];\n }\n });\n }); })];\n }\n });\n });\n };\n Object.defineProperty(Http, \"config\", {\n get: function () {\n return this._config;\n },\n set: function (options) {\n var _this = this;\n Object.keys(options).forEach(function (key) {\n _this._config[key] = options[key];\n if (_this._instance) {\n _this._instance.options[key] = options[key];\n }\n });\n },\n enumerable: true,\n configurable: true\n });\n Http.buildMethod = function (method, url, data, options, instance) {\n if (data === void 0) { data = {}; }\n if (options === void 0) { options = {}; }\n if (!instance) {\n if (!this._instance) {\n this._instance = new this(this.config);\n }\n instance = this._instance;\n }\n options.method = method;\n options.data = data;\n options.url = url;\n return instance.send(options);\n };\n Http.create = function (options) {\n var _this = this;\n if (options === void 0) { options = {}; }\n var instance = new this(options);\n var func = {\n instance: instance\n };\n methods.forEach(function (method) {\n func[method.toLocaleLowerCase()] = function (url, data, options) {\n if (data === void 0) { data = {}; }\n return _this.buildMethod(method, url, data, options, instance);\n };\n });\n return func;\n };\n Http.get = function (url, data, options) {\n if (data === void 0) { data = {}; }\n return this.buildMethod('GET', url, data, options);\n };\n Http.post = function (url, data, options) {\n if (data === void 0) { data = {}; }\n return this.buildMethod('POST', url, data, options);\n };\n Http.delete = function (url, data, options) {\n if (data === void 0) { data = {}; }\n return this.buildMethod('DELETE', url, data, options);\n };\n Http.head = function (url, data, options) {\n if (data === void 0) { data = {}; }\n return this.buildMethod('HEAD', url, data, options);\n };\n Http.put = function (url, data, options) {\n if (data === void 0) { data = {}; }\n return this.buildMethod('PUT', url, data, options);\n };\n Http.patch = function (url, data, options) {\n if (data === void 0) { data = {}; }\n return this.buildMethod('PATCH', url, data, options);\n };\n return Http;\n}());\nHttp._config = {\n timeout: 10000,\n baseURL: '',\n headers: {}\n};\nexports.default = Http;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/index.ts\n// module id = 0\n// module chunks = 0","/**\n * util\n * @author vfasky\n *\n **/\n'use strict';\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar rbracket = /\\[\\]$/;\nfunction buildParams(prefix, obj, add) {\n var name;\n if (Array.isArray(obj)) {\n // Serialize array item.\n obj.forEach(function (v, i) {\n if (rbracket.test(prefix)) {\n // Treat each array item as a scalar.\n add(prefix, v);\n }\n else {\n // Item is non-scalar (array or object), encode its numeric index.\n buildParams(prefix + \"[\" + (typeof v === \"object\" && v != null ? i : \"\") + \"]\", v, add);\n }\n });\n }\n else if (typeof obj === \"object\") {\n // Serialize object item.\n for (name in obj) {\n buildParams(prefix + \"[\" + name + \"]\", obj[name], add);\n }\n }\n else {\n // Serialize scalar item.\n add(prefix, obj);\n }\n}\nfunction setOptonsDefault(options, defaultVals) {\n if (options === void 0) { options = {}; }\n if (defaultVals === void 0) { defaultVals = {}; }\n Object.keys(defaultVals).forEach(function (key) {\n if (!options.hasOwnProperty(key)) {\n options[key] = defaultVals[key];\n }\n });\n return options;\n}\nexports.setOptonsDefault = setOptonsDefault;\nfunction isFunction(obj) {\n return !!(obj && obj.constructor && obj.call && obj.apply);\n}\nexports.isFunction = isFunction;\nfunction param(a) {\n if (a === void 0) { a = {}; }\n var prefix;\n var s = [];\n var add = function (key, valueOrFunction) {\n // If value is a function, invoke it and use its return value\n var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction;\n s[s.length] = encodeURIComponent(key) + \"=\" + encodeURIComponent(value == null ? \"\" : value);\n };\n for (prefix in a) {\n buildParams(prefix, a[prefix], add);\n }\n // Return the resulting serialization\n return s.join(\"&\");\n}\nexports.param = param;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./src/util.ts\n// module id = 1\n// module chunks = 0"],"sourceRoot":""} -------------------------------------------------------------------------------- /dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { HttpOptions, Response, HttpConfig } from './types'; 2 | export default class Http { 3 | options: HttpOptions; 4 | headers: { 5 | [key: string]: string; 6 | }; 7 | method: string; 8 | url: string; 9 | constructor(options: HttpOptions); 10 | getHeaders(): any; 11 | getMethod(options: any): string; 12 | buildUrl(options: any): any; 13 | clone(data: any): any; 14 | buildData(options: any): Promise; 15 | callPromise(funStr: string, options: HttpOptions, data: any): Promise; 16 | send(options: HttpConfig): Promise; 17 | static _config: HttpConfig; 18 | static config: HttpConfig; 19 | static _instance: Http; 20 | static buildMethod(method: any, url: any, data?: {}, options?: HttpOptions, instance?: Http): Promise; 21 | static create(options?: HttpOptions): { 22 | get(url, data?, options?: HttpOptions): Promise; 23 | post(url, data?, options?: HttpOptions): Promise; 24 | put(url, data?, options?: HttpOptions): Promise; 25 | path(url, data?, options?: HttpOptions): Promise; 26 | delete(url, data?, options?: HttpOptions): Promise; 27 | head(url, data?, options?: HttpOptions): Promise; 28 | instance: Http; 29 | }; 30 | static get(url: any, data?: {}, options?: HttpOptions): Promise; 31 | static post(url: any, data?: {}, options?: HttpOptions): Promise; 32 | static delete(url: any, data?: {}, options?: HttpOptions): Promise; 33 | static head(url: any, data?: {}, options?: HttpOptions): Promise; 34 | static put(url: any, data?: {}, options?: HttpOptions): Promise; 35 | static patch(url: any, data?: {}, options?: HttpOptions): Promise; 36 | } 37 | -------------------------------------------------------------------------------- /dist/types/types.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * types 3 | * @author vfasky 4 | * 5 | **/ 6 | export interface HttpOptions { 7 | timeout?: number; 8 | headers?: { 9 | [key: string]: string; 10 | }; 11 | baseURL?: string; 12 | method?: string; 13 | data?: { 14 | [key: string]: any; 15 | }; 16 | url?: string; 17 | transformRequest?: Function[]; 18 | transformHeaders?: Function[]; 19 | transformResponse?: Function[]; 20 | progress?: Function; 21 | } 22 | export interface HttpConfig { 23 | timeout?: number; 24 | headers?: { 25 | [key: string]: string; 26 | }; 27 | method?: string; 28 | data?: { 29 | [key: string]: any; 30 | }; 31 | url?: string; 32 | transformRequest?: Function[]; 33 | transformHeaders?: Function[]; 34 | transformResponse?: Function[]; 35 | baseURL?: string; 36 | } 37 | export interface Response { 38 | status: number; 39 | ok: boolean; 40 | statusText: string; 41 | data: string; 42 | headers: { 43 | [key: string]: string; 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /dist/types/util.d.ts: -------------------------------------------------------------------------------- 1 | export declare function setOptonsDefault(options?: { 2 | [key: string]: any; 3 | }, defaultVals?: { 4 | [key: string]: any; 5 | }): { 6 | [key: string]: any; 7 | }; 8 | export declare function isFunction(obj: any): boolean; 9 | export declare function param(a?: { 10 | [key: string]: any; 11 | }): string; 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weex-http", 3 | "version": "1.0.8", 4 | "description": "simple http lib for weex", 5 | "devDependencies": { 6 | "coveralls": "^2.11.16", 7 | "istanbul": "^0.4.5", 8 | "jsdom": "^9.11.0", 9 | "mocha": "^3.2.0", 10 | "mocha-jsdom": "^1.1.0", 11 | "ts-loader": "^2.0.1", 12 | "typescript": "^2.2.1", 13 | "vue": "^2.2.1", 14 | "vue-loader": "^11.1.2", 15 | "vue-typescript-import-dts": "^3.0.1", 16 | "webpack": "1.x", 17 | "weex-vue-render": "0.2.0" 18 | }, 19 | "main": "dist/index.js", 20 | "typings": "dist/types/index.d.ts", 21 | "scripts": { 22 | "test": "mocha -t 10000 test/*.test.js", 23 | "test-cov": "istanbul cover --preserve-comments _mocha -- --reporter spec -t 10000 test/*.test.js --bail" 24 | }, 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/MMF-FE/weex-http.git" 28 | }, 29 | "keywords": [ 30 | "weex", 31 | "http" 32 | ], 33 | "author": "vfasky@gmail.com", 34 | "license": "Apache-2.0", 35 | "bugs": { 36 | "url": "https://github.com/MMF-FE/weex-http/issues" 37 | }, 38 | "homepage": "https://github.com/MMF-FE/weex-http#readme" 39 | } 40 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * http lib 3 | * @author vfasky 4 | * 5 | **/ 6 | 'use strict' 7 | 8 | import { setOptonsDefault, param } from './util' 9 | import { HttpOptions, Response, HttpConfig } from './types' 10 | var stream = weex.requireModule('stream') 11 | 12 | const methods = ['GET', 'DELETE', 'HEAD', 'POST', 'PUT', 'PATCH'] 13 | const buildUrlMemthods = ['POST', 'PUT', 'PATCH'] 14 | const platform = weex.config.env.platform.toLocaleLowerCase() 15 | const is = { 16 | web: platform === 'web', 17 | android: platform === 'android', 18 | iOS: platform === 'ios', 19 | ios: platform === 'ios', 20 | wechat: platform === 'web' && (/micromessenger/i).test(navigator.userAgent) 21 | } 22 | 23 | export default class Http { 24 | options: HttpOptions 25 | headers: { 26 | [key: string]: string 27 | } 28 | method: string 29 | url: string 30 | 31 | constructor(options: HttpOptions) { 32 | this.options = setOptonsDefault(options, { 33 | timeout: 10000, 34 | headers: {}, 35 | baseURL: '', 36 | method: 'GET', 37 | data: {}, 38 | url: '/', 39 | progress: function () { }, 40 | transformRequest: [], 41 | transformResponse: [], 42 | transformHeaders: [] 43 | }) 44 | 45 | } 46 | 47 | getHeaders() { 48 | return this.clone(setOptonsDefault(this.options.headers, { 49 | 'Content-Type': 'application/x-www-form-urlencoded' 50 | })) 51 | } 52 | 53 | getMethod(options) { 54 | let method = String(options.method).trim().toLocaleUpperCase() 55 | if (methods.indexOf(method) === -1) { 56 | throw new Error(`${method} not in ${methods.join(', ')}`) 57 | } 58 | return method 59 | } 60 | 61 | buildUrl(options) { 62 | return (options.hasOwnProperty('baseURL') ? options.baseURL : this.options.baseURL) + 63 | options.url 64 | } 65 | 66 | clone(data) { 67 | return JSON.parse(JSON.stringify(data)) 68 | } 69 | 70 | async buildData(options) { 71 | let data = this.clone(options.data) 72 | await this.callPromise('transformRequest', options, data) 73 | 74 | let sendData = param(data) 75 | 76 | return sendData 77 | } 78 | 79 | async callPromise(funStr: string, options: HttpOptions, data) { 80 | if (Array.isArray(this.options[funStr])) { 81 | await Promise.all(this.options[funStr].map((promise) => { 82 | return promise(data) 83 | })) 84 | } 85 | 86 | if (Array.isArray(options[funStr])) { 87 | await Promise.all(options[funStr].map((promise) => { 88 | return promise(data) 89 | })) 90 | } 91 | 92 | return data 93 | } 94 | 95 | async send(options: HttpConfig) { 96 | 97 | let timeout = options.hasOwnProperty('timeout') ? options.timeout : this.options.timeout 98 | let method = this.getMethod(options) 99 | let body = await this.buildData(options) 100 | let url = this.buildUrl(options) 101 | let headers = this.getHeaders() 102 | 103 | if (options.headers) { 104 | Object.keys(options.headers).forEach((key) => { 105 | headers[key] = options.headers[key] 106 | }) 107 | } 108 | await this.callPromise('transformHeaders', options, headers) 109 | let isSend = true 110 | if (buildUrlMemthods.indexOf(method.toLocaleUpperCase()) === -1) { 111 | let link = url.indexOf('?') === -1 ? '?' : '&' 112 | url += link + body 113 | body = '' 114 | isSend = false 115 | } 116 | return new Promise((resolve: Function, reject: Function) => { 117 | let isReturn = false 118 | let timeoutId = setTimeout(() => { 119 | isReturn = true 120 | reject({ 121 | status: 0, 122 | ok: false, 123 | statusText: 'TIMEOUT', 124 | data: 'TIMEOUT', 125 | headers: {} 126 | }) 127 | }, timeout) 128 | 129 | // ios8 wechat back bug 130 | if (is.wechat) { 131 | let deviceAgent = navigator.userAgent.toLowerCase() 132 | let isIos8 = /(iphone|ipod|ipad).* os 8_/.test(deviceAgent) 133 | 134 | let xhr = new XMLHttpRequest() 135 | 136 | let xhrDone = function () { 137 | clearTimeout(timeoutId) 138 | if (isReturn) return 139 | if (xhr.status >= 200 && xhr.status < 300) { 140 | resolve({ 141 | status: xhr.status, 142 | ok: true, 143 | statusText: xhr.statusText, 144 | data: xhr.responseText, 145 | headers: {} 146 | }) 147 | } 148 | } 149 | 150 | let xhrOnChange = function () { 151 | if (xhr.readyState == 4) { 152 | // 微信你大爷 153 | if (!xhr.status && isIos8) { 154 | let key = '__weex_http' 155 | let lastReloadDate = localStorage.getItem(key) 156 | let now = Date.now() 157 | if (lastReloadDate == null || now - Number(lastReloadDate) > 5000) { 158 | localStorage.setItem(key, String(now)) 159 | window.location.reload() 160 | } 161 | 162 | return 163 | } 164 | xhrDone() 165 | } 166 | } 167 | xhr.onreadystatechange = xhrOnChange 168 | xhr.open(method, url, true) 169 | Object.keys(headers).forEach((key) => { 170 | xhr.setRequestHeader(key, headers[key]) 171 | }) 172 | 173 | xhr.send(body) 174 | } else { 175 | stream.fetch({ 176 | method, 177 | body, 178 | url, 179 | headers, 180 | type: 'text' 181 | }, (response: Response) => { 182 | clearTimeout(timeoutId) 183 | if (isReturn) return 184 | 185 | if (response.ok) { 186 | resolve(response) 187 | } else { 188 | reject(response) 189 | } 190 | 191 | }, (args) => { 192 | this.options.progress(args) 193 | }) 194 | } 195 | }).then(async (response: Response) => { 196 | await this.callPromise('transformResponse', options, response) 197 | 198 | return response 199 | }) 200 | } 201 | 202 | static _config: HttpConfig = { 203 | timeout: 10000, 204 | baseURL: '', 205 | headers: {} 206 | } 207 | 208 | static get config() { 209 | return this._config 210 | } 211 | 212 | static set config(options: HttpConfig) { 213 | Object.keys(options).forEach((key) => { 214 | this._config[key] = options[key] 215 | if (this._instance) { 216 | this._instance.options[key] = options[key] 217 | } 218 | }) 219 | } 220 | 221 | static _instance: Http 222 | 223 | static buildMethod(method, url, data = {}, options: HttpOptions = {}, instance?: Http) { 224 | 225 | if (!instance) { 226 | if (!this._instance) { 227 | this._instance = new this(this.config) 228 | } 229 | instance = this._instance 230 | 231 | } 232 | 233 | options.method = method 234 | options.data = data 235 | options.url = url 236 | 237 | return instance.send(options) 238 | 239 | } 240 | 241 | static create(options: HttpOptions = {}): { 242 | get(url, data?, options?: HttpOptions): Promise 243 | post(url, data?, options?: HttpOptions): Promise 244 | put(url, data?, options?: HttpOptions): Promise 245 | path(url, data?, options?: HttpOptions): Promise 246 | delete(url, data?, options?: HttpOptions): Promise 247 | head(url, data?, options?: HttpOptions): Promise 248 | instance: Http 249 | } { 250 | let instance = new this(options) 251 | let func: any = { 252 | instance 253 | } 254 | 255 | methods.forEach((method) => { 256 | func[method.toLocaleLowerCase()] = (url, data = {}, options?: HttpOptions) => { 257 | return this.buildMethod(method, url, data, options, instance) 258 | } 259 | }) 260 | 261 | return func 262 | } 263 | 264 | static get(url, data = {}, options?: HttpOptions) { 265 | return this.buildMethod('GET', url, data, options) 266 | } 267 | 268 | static post(url, data = {}, options?: HttpOptions) { 269 | return this.buildMethod('POST', url, data, options) 270 | } 271 | 272 | static delete(url, data = {}, options?: HttpOptions) { 273 | return this.buildMethod('DELETE', url, data, options) 274 | } 275 | 276 | static head(url, data = {}, options?: HttpOptions) { 277 | return this.buildMethod('HEAD', url, data, options) 278 | } 279 | 280 | static put(url, data = {}, options?: HttpOptions) { 281 | return this.buildMethod('PUT', url, data, options) 282 | } 283 | 284 | static patch(url, data = {}, options?: HttpOptions) { 285 | return this.buildMethod('PATCH', url, data, options) 286 | } 287 | } -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * types 3 | * @author vfasky 4 | * 5 | **/ 6 | 7 | export interface HttpOptions { 8 | timeout?: number 9 | headers?: { 10 | [key: string]: string 11 | } 12 | baseURL?: string 13 | method?: string 14 | data?: { 15 | [key:string]: any 16 | }, 17 | url?: string, 18 | transformRequest?: Function[] 19 | transformHeaders?: Function[] 20 | transformResponse?: Function[] 21 | progress?: Function 22 | } 23 | 24 | export interface HttpConfig { 25 | timeout?: number 26 | headers?: { 27 | [key: string]: string 28 | } 29 | method?: string 30 | data?: { 31 | [key:string]: any 32 | }, 33 | url?: string, 34 | transformRequest?: Function[] 35 | transformHeaders?: Function[] 36 | transformResponse?: Function[] 37 | baseURL?: string 38 | } 39 | 40 | export interface Response { 41 | status: number, 42 | ok: boolean, 43 | statusText: string, 44 | data: string, 45 | headers: { 46 | [key: string]: string 47 | } 48 | } -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * util 3 | * @author vfasky 4 | * 5 | **/ 6 | 'use strict' 7 | 8 | const rbracket = /\[\]$/ 9 | 10 | function buildParams(prefix: string, obj, add: Function) { 11 | let name 12 | 13 | if (Array.isArray(obj)) { 14 | 15 | // Serialize array item. 16 | obj.forEach((v, i) => { 17 | 18 | if (rbracket.test(prefix)) { 19 | // Treat each array item as a scalar. 20 | add(prefix, v) 21 | 22 | } else { 23 | 24 | // Item is non-scalar (array or object), encode its numeric index. 25 | buildParams( 26 | prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", 27 | v, 28 | add 29 | ) 30 | } 31 | }) 32 | 33 | } else if (typeof obj === "object") { 34 | 35 | // Serialize object item. 36 | for (name in obj) { 37 | buildParams(prefix + "[" + name + "]", obj[name], add) 38 | } 39 | 40 | } else { 41 | 42 | // Serialize scalar item. 43 | add(prefix, obj) 44 | } 45 | } 46 | 47 | export function setOptonsDefault(options: { [key: string]: any } = {}, defaultVals: { [key: string]: any } = {}) { 48 | Object.keys(defaultVals).forEach((key) => { 49 | if (!options.hasOwnProperty(key)) { 50 | options[key] = defaultVals[key] 51 | } 52 | }) 53 | 54 | return options 55 | } 56 | 57 | export function isFunction(obj) { 58 | return !!(obj && obj.constructor && obj.call && obj.apply) 59 | } 60 | 61 | 62 | export function param(a: { [key: string]: any } = {}) { 63 | let prefix 64 | let s = [] 65 | let add = function (key, valueOrFunction) { 66 | // If value is a function, invoke it and use its return value 67 | var value = isFunction(valueOrFunction) ? valueOrFunction() : valueOrFunction 68 | 69 | s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value == null ? "" : value) 70 | } 71 | 72 | for (prefix in a) { 73 | buildParams(prefix, a[prefix], add) 74 | } 75 | // Return the resulting serialization 76 | return s.join("&"); 77 | } 78 | -------------------------------------------------------------------------------- /src/weex.d.ts: -------------------------------------------------------------------------------- 1 | interface Weex { 2 | requireModule(module: string): any, 3 | registerModule(name: string, methods: { 4 | [name: string]: Function 5 | }): void, 6 | config: { 7 | bundleUrl: string, 8 | env: { 9 | weexVersion: string 10 | appName: string 11 | appVersion: string 12 | platform: string 13 | osVersion: string 14 | deviceModel?: string 15 | deviceWidth: number 16 | deviceHeight: number 17 | } 18 | } 19 | } 20 | declare var weex: Weex -------------------------------------------------------------------------------- /test/http.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Test case 3 | * @author vfasky 4 | * 5 | **/ 6 | 'use strict' 7 | 8 | const Vue = require('vue') 9 | const jsdom = require('mocha-jsdom') 10 | const assert = require('assert') 11 | let methods = ['GET', 'PUT', 'POST', 'PATCH', 'DELETE'] 12 | let weexHttp 13 | 14 | describe('weex-http Test', () => { 15 | jsdom() 16 | 17 | before(() => { 18 | var weexRender = require('weex-vue-render') 19 | Vue.use(weexRender) 20 | global.weex = window.weex 21 | weexHttp = require('../dist').default 22 | }) 23 | 24 | describe('Static methods', () => { 25 | 26 | it('Set config', () => { 27 | weexHttp.config = { baseURL: 'http://httpbin.org' } 28 | }) 29 | 30 | methods.forEach((method) => { 31 | let httpMethod = String(method).toLocaleLowerCase() 32 | 33 | it(method, (done) => { 34 | let args = { test: 'weex-http' } 35 | weexHttp[httpMethod]('/' + httpMethod, args).then((res) => { 36 | let data = JSON.parse(res.data) 37 | 38 | let resData = data.args 39 | 40 | if(['POST', 'PUT', 'PATCH'].indexOf(method) !== -1) { 41 | resData = data.form 42 | } 43 | 44 | assert.equal(args.test, resData.test) 45 | done() 46 | }).catch(done) 47 | }) 48 | 49 | 50 | it(method + ' Array', (done) => { 51 | let args = { test: ['weex-http', 'weex', 'vue'] } 52 | weexHttp[httpMethod]('/' + httpMethod, args).then((res) => { 53 | let data = JSON.parse(res.data) 54 | 55 | let resData = data.args 56 | 57 | if(['POST', 'PUT', 'PATCH'].indexOf(method) !== -1) { 58 | resData = data.form 59 | } 60 | 61 | assert.equal(args.test[2], resData['test[]'][2]) 62 | done() 63 | }).catch(done) 64 | }) 65 | 66 | it(method + ' Object', (done) => { 67 | let args = { 68 | test: { 69 | obj: ['weex-http', 'weex', 'vue'] 70 | } 71 | } 72 | weexHttp[httpMethod]('/' + httpMethod, args).then((res) => { 73 | let data = JSON.parse(res.data) 74 | 75 | let resData = data.args 76 | 77 | if(['POST', 'PUT', 'PATCH'].indexOf(method) !== -1) { 78 | resData = data.form 79 | } 80 | assert.equal(args.test.obj[2], resData['test[obj][]'][2]) 81 | done() 82 | }).catch(done) 83 | }) 84 | }) 85 | 86 | it('transform Response', (done) => { 87 | weexHttp.get('/get', {}, { 88 | transformResponse: [function(response){ 89 | done() 90 | }] 91 | }) 92 | }) 93 | 94 | }) 95 | 96 | describe('Create instance', () => { 97 | let http 98 | 99 | before(() => { 100 | http = weexHttp.create({ 101 | baseURL: 'https://httpbin.org/', 102 | timeout: 2000 103 | }) 104 | }) 105 | 106 | methods.forEach((method) => { 107 | let httpMethod = String(method).toLocaleLowerCase() 108 | 109 | it(method, (done) => { 110 | let args = { test: 'weex-http' } 111 | http[httpMethod](httpMethod, args).then((res) => { 112 | 113 | let data = JSON.parse(res.data) 114 | 115 | let resData = data.args 116 | 117 | if(['POST', 'PUT', 'PATCH'].indexOf(method) !== -1) { 118 | resData = data.form 119 | } 120 | 121 | assert.equal(args.test, resData.test) 122 | done() 123 | }).catch(done) 124 | }) 125 | 126 | 127 | it(method + ' Array', (done) => { 128 | let args = { test: ['weex-http', 'weex', 'vue'] } 129 | http[httpMethod](httpMethod, args).then((res) => { 130 | let data = JSON.parse(res.data) 131 | 132 | let resData = data.args 133 | 134 | if(['POST', 'PUT', 'PATCH'].indexOf(method) !== -1) { 135 | resData = data.form 136 | } 137 | 138 | assert.equal(args.test[2], resData['test[]'][2]) 139 | done() 140 | }).catch(done) 141 | }) 142 | 143 | it(method + ' Object', (done) => { 144 | let args = { 145 | test: { 146 | obj: ['weex-http', 'weex', 'vue'] 147 | } 148 | } 149 | http[httpMethod](httpMethod, args).then((res) => { 150 | let data = JSON.parse(res.data) 151 | 152 | let resData = data.args 153 | 154 | if(['POST', 'PUT', 'PATCH'].indexOf(method) !== -1) { 155 | resData = data.form 156 | } 157 | assert.equal(args.test.obj[2], resData['test[obj][]'][2]) 158 | done() 159 | }).catch(done) 160 | }) 161 | }) 162 | }) 163 | }) -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "noImplicitAny": false, 6 | "sourceMap": false, 7 | "types": ["vue-typescript-import-dts"], 8 | "declaration": true, 9 | "alwaysStrict": true, 10 | "outDir": "types", 11 | "lib": [ 12 | "dom", 13 | "es2015.promise", 14 | "es5" 15 | ] 16 | }, 17 | "filesGlob": [ 18 | "./**/*.ts" 19 | ], 20 | "include": [ 21 | "./src/**/*.ts" 22 | ] 23 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: './src/index.ts', 6 | devtool: false, 7 | output: { 8 | path: path.resolve('./dist'), 9 | filename: 'index.js', 10 | libraryTarget: 'commonjs2' 11 | }, 12 | devtool: 'source-map', 13 | resolve: { 14 | modulesDirectories: [ 15 | path.resolve('./node_modules'), 16 | path.resolve('./src') 17 | ], 18 | extensions: ['', '.js', '.ts', '.vue', '.css'] 19 | }, 20 | module: { 21 | loaders: [ 22 | { 23 | test: /\.vue$/, 24 | loader: 'vue-loader' 25 | }, 26 | { 27 | test: /\.ts$/, 28 | loader: 'ts', 29 | exclude: /node_modules/ 30 | } 31 | ] 32 | }, 33 | vue: { 34 | loaders: { 35 | ts: 'ts-loader' 36 | } 37 | }, 38 | externals: { 39 | vue: 'vue', 40 | 'vue-router': 'vue-router' 41 | }, 42 | plugins: [ 43 | new webpack.DefinePlugin({ 44 | 'process.env': 'production' 45 | }), 46 | // minify with dead-code elimination 47 | // new webpack.optimize.UglifyJsPlugin({ 48 | // compress: { 49 | // warnings: false 50 | // } 51 | // }), 52 | // optimize module ids by occurrence count 53 | new webpack.optimize.OccurrenceOrderPlugin() 54 | ] 55 | } 56 | --------------------------------------------------------------------------------