ccxt-look 1.81.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/.cache/eslintcache +1 -0
  2. package/.dockerignore +6 -0
  3. package/.eslintignore +1 -0
  4. package/.gitattributes +5 -0
  5. package/.readthedocs.yaml +16 -0
  6. package/CONTRIBUTING.md +1049 -0
  7. package/LICENSE.txt +21 -0
  8. package/README.md +537 -0
  9. package/SECURITY.md +5 -0
  10. package/build/cleanup-old-tags.js +94 -0
  11. package/build/countries.js +256 -0
  12. package/build/export-exchanges.js +520 -0
  13. package/build/fs.js +51 -0
  14. package/build/transpile.js +1772 -0
  15. package/build/vss.js +78 -0
  16. package/ccxt.browser.js +7 -0
  17. package/ccxt.d.ts +692 -0
  18. package/ccxt.js +171 -0
  19. package/cleanup.sh +2 -0
  20. package/composer-install.sh +20 -0
  21. package/dist/ccxt.browser.js +208383 -0
  22. package/gource.sh +3 -0
  23. package/index.html +7 -0
  24. package/js/.eslintrc +87 -0
  25. package/js/aax.js +2686 -0
  26. package/js/ascendex.js +2584 -0
  27. package/js/base/.eslintrc.js +43 -0
  28. package/js/base/Exchange.js +2371 -0
  29. package/js/base/Precise.js +283 -0
  30. package/js/base/errorHierarchy.js +47 -0
  31. package/js/base/errors.js +55 -0
  32. package/js/base/functions/crypto.js +158 -0
  33. package/js/base/functions/encode.js +118 -0
  34. package/js/base/functions/generic.js +270 -0
  35. package/js/base/functions/misc.js +138 -0
  36. package/js/base/functions/number.js +329 -0
  37. package/js/base/functions/platform.js +38 -0
  38. package/js/base/functions/string.js +21 -0
  39. package/js/base/functions/throttle.js +79 -0
  40. package/js/base/functions/time.js +210 -0
  41. package/js/base/functions/type.js +66 -0
  42. package/js/base/functions.js +28 -0
  43. package/js/bequant.js +32 -0
  44. package/js/bibox.js +1407 -0
  45. package/js/bigone.js +1366 -0
  46. package/js/binance.js +5652 -0
  47. package/js/binancecoinm.js +46 -0
  48. package/js/binanceus.js +46 -0
  49. package/js/binanceusdm.js +49 -0
  50. package/js/bit2c.js +535 -0
  51. package/js/bitbank.js +842 -0
  52. package/js/bitbay.js +16 -0
  53. package/js/bitbns.js +1073 -0
  54. package/js/bitcoincom.js +15 -0
  55. package/js/bitfinex.js +1433 -0
  56. package/js/bitfinex2.js +2025 -0
  57. package/js/bitflyer.js +840 -0
  58. package/js/bitforex.js +614 -0
  59. package/js/bitget.js +2397 -0
  60. package/js/bithumb.js +980 -0
  61. package/js/bitmart.js +2516 -0
  62. package/js/bitmex.js +1809 -0
  63. package/js/bitopro.js +1443 -0
  64. package/js/bitpanda.js +1782 -0
  65. package/js/bitrue.js +1747 -0
  66. package/js/bitso.js +1062 -0
  67. package/js/bitstamp.js +1757 -0
  68. package/js/bitstamp1.js +343 -0
  69. package/js/bittrex.js +1876 -0
  70. package/js/bitvavo.js +1579 -0
  71. package/js/bkex.js +1233 -0
  72. package/js/bl3p.js +346 -0
  73. package/js/blockchaincom.js +969 -0
  74. package/js/btcalpha.js +680 -0
  75. package/js/btcbox.js +477 -0
  76. package/js/btcmarkets.js +1022 -0
  77. package/js/btctradeua.js +466 -0
  78. package/js/btcturk.js +734 -0
  79. package/js/buda.js +946 -0
  80. package/js/bw.js +1265 -0
  81. package/js/bybit.js +3372 -0
  82. package/js/bytetrade.js +1336 -0
  83. package/js/cdax.js +1646 -0
  84. package/js/cex.js +1410 -0
  85. package/js/coinbase.js +1342 -0
  86. package/js/coinbaseprime.js +31 -0
  87. package/js/coinbasepro.js +1466 -0
  88. package/js/coincheck.js +755 -0
  89. package/js/coinex.js +3400 -0
  90. package/js/coinfalcon.js +880 -0
  91. package/js/coinmate.js +794 -0
  92. package/js/coinone.js +816 -0
  93. package/js/coinspot.js +345 -0
  94. package/js/crex24.js +1636 -0
  95. package/js/cryptocom.js +1832 -0
  96. package/js/currencycom.js +1748 -0
  97. package/js/delta.js +1547 -0
  98. package/js/deribit.js +2148 -0
  99. package/js/digifinex.js +1585 -0
  100. package/js/eqonex.js +1660 -0
  101. package/js/exmo.js +1670 -0
  102. package/js/fairdesk.js +1231 -0
  103. package/js/flowbtc.js +35 -0
  104. package/js/fmfwio.js +34 -0
  105. package/js/ftx.js +2751 -0
  106. package/js/ftxus.js +38 -0
  107. package/js/gateio.js +4174 -0
  108. package/js/gemini.js +1397 -0
  109. package/js/hitbtc.js +1343 -0
  110. package/js/hitbtc3.js +2329 -0
  111. package/js/hollaex.js +1486 -0
  112. package/js/huobi.js +5706 -0
  113. package/js/huobijp.js +1710 -0
  114. package/js/huobipro.js +18 -0
  115. package/js/idex.js +1439 -0
  116. package/js/independentreserve.js +649 -0
  117. package/js/indodax.js +742 -0
  118. package/js/itbit.js +722 -0
  119. package/js/kraken.js +2179 -0
  120. package/js/kucoin.js +2571 -0
  121. package/js/kucoinfutures.js +1771 -0
  122. package/js/kuna.js +809 -0
  123. package/js/latoken.js +1445 -0
  124. package/js/lbank.js +760 -0
  125. package/js/liquid.js +1432 -0
  126. package/js/luno.js +873 -0
  127. package/js/lykke.js +1147 -0
  128. package/js/mercado.js +771 -0
  129. package/js/mexc.js +3151 -0
  130. package/js/ndax.js +2233 -0
  131. package/js/novadax.js +1318 -0
  132. package/js/oceanex.js +816 -0
  133. package/js/okcoin.js +3841 -0
  134. package/js/okex.js +16 -0
  135. package/js/okex5.js +16 -0
  136. package/js/okx.js +4795 -0
  137. package/js/paymium.js +498 -0
  138. package/js/phemex.js +2957 -0
  139. package/js/poloniex.js +1674 -0
  140. package/js/probit.js +1346 -0
  141. package/js/qtrade.js +1588 -0
  142. package/js/ripio.js +1061 -0
  143. package/js/static_dependencies/BN/bn.js +3526 -0
  144. package/js/static_dependencies/README.md +1 -0
  145. package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
  146. package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
  147. package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
  148. package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
  149. package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
  150. package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
  151. package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
  152. package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
  153. package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
  154. package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
  155. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
  156. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
  157. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
  158. package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
  159. package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
  160. package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
  161. package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
  162. package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
  163. package/js/static_dependencies/node-fetch/index.js +1564 -0
  164. package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
  165. package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
  166. package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
  167. package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
  168. package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
  169. package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
  170. package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
  171. package/js/static_dependencies/node-rsa/formats/components.js +71 -0
  172. package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
  173. package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
  174. package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
  175. package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
  176. package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
  177. package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
  178. package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
  179. package/js/static_dependencies/node-rsa/utils.js +98 -0
  180. package/js/static_dependencies/qs/formats.js +18 -0
  181. package/js/static_dependencies/qs/index.js +11 -0
  182. package/js/static_dependencies/qs/parse.js +242 -0
  183. package/js/static_dependencies/qs/stringify.js +269 -0
  184. package/js/static_dependencies/qs/utils.js +230 -0
  185. package/js/stex.js +1925 -0
  186. package/js/test/.eslintrc.js +42 -0
  187. package/js/test/Exchange/test.balance.js +61 -0
  188. package/js/test/Exchange/test.borrowRate.js +32 -0
  189. package/js/test/Exchange/test.currency.js +52 -0
  190. package/js/test/Exchange/test.fetchBalance.js +23 -0
  191. package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
  192. package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
  193. package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
  194. package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
  195. package/js/test/Exchange/test.fetchCurrencies.js +35 -0
  196. package/js/test/Exchange/test.fetchDeposits.js +31 -0
  197. package/js/test/Exchange/test.fetchFundingFees.js +19 -0
  198. package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
  199. package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
  200. package/js/test/Exchange/test.fetchLedger.js +42 -0
  201. package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
  202. package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
  203. package/js/test/Exchange/test.fetchMarkets.js +33 -0
  204. package/js/test/Exchange/test.fetchMyTrades.js +42 -0
  205. package/js/test/Exchange/test.fetchOHLCV.js +46 -0
  206. package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
  207. package/js/test/Exchange/test.fetchOrderBook.js +25 -0
  208. package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
  209. package/js/test/Exchange/test.fetchOrders.js +41 -0
  210. package/js/test/Exchange/test.fetchPositions.js +47 -0
  211. package/js/test/Exchange/test.fetchStatus.js +35 -0
  212. package/js/test/Exchange/test.fetchTicker.js +38 -0
  213. package/js/test/Exchange/test.fetchTickers.js +49 -0
  214. package/js/test/Exchange/test.fetchTrades.js +39 -0
  215. package/js/test/Exchange/test.fetchTradingFee.js +18 -0
  216. package/js/test/Exchange/test.fetchTradingFees.js +22 -0
  217. package/js/test/Exchange/test.fetchTransactions.js +31 -0
  218. package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
  219. package/js/test/Exchange/test.ledgerItem.js +46 -0
  220. package/js/test/Exchange/test.leverageTier.js +33 -0
  221. package/js/test/Exchange/test.loadMarkets.js +35 -0
  222. package/js/test/Exchange/test.market.js +129 -0
  223. package/js/test/Exchange/test.ohlcv.js +33 -0
  224. package/js/test/Exchange/test.order.js +62 -0
  225. package/js/test/Exchange/test.orderbook.js +61 -0
  226. package/js/test/Exchange/test.position.js +21 -0
  227. package/js/test/Exchange/test.throttle.js +94 -0
  228. package/js/test/Exchange/test.ticker.js +95 -0
  229. package/js/test/Exchange/test.trade.js +68 -0
  230. package/js/test/Exchange/test.tradingFee.js +34 -0
  231. package/js/test/Exchange/test.transaction.js +35 -0
  232. package/js/test/base/.eslintrc +38 -0
  233. package/js/test/base/functions/test.crypto.js +110 -0
  234. package/js/test/base/functions/test.datetime.js +62 -0
  235. package/js/test/base/functions/test.generic.js +152 -0
  236. package/js/test/base/functions/test.number.js +362 -0
  237. package/js/test/base/functions/test.time.js +56 -0
  238. package/js/test/base/functions/test.type.js +53 -0
  239. package/js/test/base/test.base.js +193 -0
  240. package/js/test/errors/test.InsufficientFunds.js +86 -0
  241. package/js/test/errors/test.InvalidNonce.js +64 -0
  242. package/js/test/errors/test.InvalidOrder.js +35 -0
  243. package/js/test/errors/test.OrderNotFound.js +39 -0
  244. package/js/test/test.js +426 -0
  245. package/js/test/test.timeout_hang.js +12 -0
  246. package/js/therock.js +1431 -0
  247. package/js/tidebit.js +632 -0
  248. package/js/tidex.js +939 -0
  249. package/js/timex.js +1283 -0
  250. package/js/upbit.js +1622 -0
  251. package/js/vcc.js +1353 -0
  252. package/js/wavesexchange.js +2185 -0
  253. package/js/wazirx.js +732 -0
  254. package/js/whitebit.js +1352 -0
  255. package/js/woo.js +1577 -0
  256. package/js/xena.js +1948 -0
  257. package/js/yobit.js +1129 -0
  258. package/js/zaif.js +647 -0
  259. package/js/zb.js +4088 -0
  260. package/js/zipmex.js +40 -0
  261. package/js/zonda.js +1497 -0
  262. package/multilang.sh +159 -0
  263. package/package.json +591 -0
  264. package/postinstall.js +103 -0
@@ -0,0 +1,1564 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ // Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
6
+ // (MIT licensed)
7
+
8
+ const BUFFER = Symbol('buffer');
9
+ const TYPE = Symbol('type');
10
+
11
+ class Blob {
12
+ constructor() {
13
+ this[TYPE] = '';
14
+
15
+ const blobParts = arguments[0];
16
+ const options = arguments[1];
17
+
18
+ const buffers = [];
19
+
20
+ if (blobParts) {
21
+ const a = blobParts;
22
+ const length = Number(a.length);
23
+ for (let i = 0; i < length; i++) {
24
+ const element = a[i];
25
+ let buffer;
26
+ if (element instanceof Buffer) {
27
+ buffer = element;
28
+ } else if (ArrayBuffer.isView(element)) {
29
+ buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);
30
+ } else if (element instanceof ArrayBuffer) {
31
+ buffer = Buffer.from(element);
32
+ } else if (element instanceof Blob) {
33
+ buffer = element[BUFFER];
34
+ } else {
35
+ buffer = Buffer.from(typeof element === 'string' ? element : String(element));
36
+ }
37
+ buffers.push(buffer);
38
+ }
39
+ }
40
+
41
+ this[BUFFER] = Buffer.concat(buffers);
42
+
43
+ let type = options && options.type !== undefined && String(options.type).toLowerCase();
44
+ if (type && !/[^\u0020-\u007E]/.test(type)) {
45
+ this[TYPE] = type;
46
+ }
47
+ }
48
+ get size() {
49
+ return this[BUFFER].length;
50
+ }
51
+ get type() {
52
+ return this[TYPE];
53
+ }
54
+ slice() {
55
+ const size = this.size;
56
+
57
+ const start = arguments[0];
58
+ const end = arguments[1];
59
+ let relativeStart, relativeEnd;
60
+ if (start === undefined) {
61
+ relativeStart = 0;
62
+ } else if (start < 0) {
63
+ relativeStart = Math.max(size + start, 0);
64
+ } else {
65
+ relativeStart = Math.min(start, size);
66
+ }
67
+ if (end === undefined) {
68
+ relativeEnd = size;
69
+ } else if (end < 0) {
70
+ relativeEnd = Math.max(size + end, 0);
71
+ } else {
72
+ relativeEnd = Math.min(end, size);
73
+ }
74
+ const span = Math.max(relativeEnd - relativeStart, 0);
75
+
76
+ const buffer = this[BUFFER];
77
+ const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
78
+ const blob = new Blob([], { type: arguments[2] });
79
+ blob[BUFFER] = slicedBuffer;
80
+ return blob;
81
+ }
82
+ }
83
+
84
+ Object.defineProperties(Blob.prototype, {
85
+ size: { enumerable: true },
86
+ type: { enumerable: true },
87
+ slice: { enumerable: true }
88
+ });
89
+
90
+ Object.defineProperty(Blob.prototype, Symbol.toStringTag, {
91
+ value: 'Blob',
92
+ writable: false,
93
+ enumerable: false,
94
+ configurable: true
95
+ });
96
+
97
+ /**
98
+ * fetch-error.js
99
+ *
100
+ * FetchError interface for operational errors
101
+ */
102
+
103
+ /**
104
+ * Create FetchError instance
105
+ *
106
+ * @param String message Error message for human
107
+ * @param String type Error type for machine
108
+ * @param String systemError For Node.js system error
109
+ * @return FetchError
110
+ */
111
+ function FetchError(message, type, systemError) {
112
+ Error.call(this, message);
113
+
114
+ this.message = message;
115
+ this.type = type;
116
+
117
+ // when err.type is `system`, err.code contains system error code
118
+ if (systemError) {
119
+ this.code = this.errno = systemError.code;
120
+ }
121
+
122
+ // hide custom error implementation details from end-users
123
+ Error.captureStackTrace(this, this.constructor);
124
+ }
125
+
126
+ FetchError.prototype = Object.create(Error.prototype);
127
+ FetchError.prototype.constructor = FetchError;
128
+ FetchError.prototype.name = 'FetchError';
129
+
130
+ /**
131
+ * body.js
132
+ *
133
+ * Body interface provides common methods for Request and Response
134
+ */
135
+
136
+ const Stream = require('stream');
137
+
138
+ var _require = require('stream');
139
+
140
+ const PassThrough = _require.PassThrough;
141
+
142
+ /*
143
+ let convert;
144
+ try {
145
+ convert = require('encoding').convert;
146
+ } catch (e) {}
147
+ */
148
+
149
+ const INTERNALS = Symbol('Body internals');
150
+
151
+ /**
152
+ * Body mixin
153
+ *
154
+ * Ref: https://fetch.spec.whatwg.org/#body
155
+ *
156
+ * @param Stream body Readable stream
157
+ * @param Object opts Response options
158
+ * @return Void
159
+ */
160
+ function Body(body) {
161
+ var _this = this;
162
+
163
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
164
+ _ref$size = _ref.size;
165
+
166
+ let size = _ref$size === undefined ? 0 : _ref$size;
167
+ var _ref$timeout = _ref.timeout;
168
+ let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
169
+
170
+ if (body == null) {
171
+ // body is undefined or null
172
+ body = null;
173
+ } else if (typeof body === 'string') {
174
+ // body is string
175
+ } else if (isURLSearchParams(body)) {
176
+ // body is a URLSearchParams
177
+ } else if (body instanceof Blob) {
178
+ // body is blob
179
+ } else if (Buffer.isBuffer(body)) {
180
+ // body is buffer
181
+ } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
182
+ // body is array buffer
183
+ } else if (body instanceof Stream) {
184
+ // body is stream
185
+ } else {
186
+ // none of the above
187
+ // coerce to string
188
+ body = String(body);
189
+ }
190
+ this[INTERNALS] = {
191
+ body,
192
+ disturbed: false,
193
+ error: null
194
+ };
195
+ this.size = size;
196
+ this.timeout = timeout;
197
+
198
+ if (body instanceof Stream) {
199
+ body.on('error', function (err) {
200
+ _this[INTERNALS].error = new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err);
201
+ });
202
+ }
203
+ }
204
+
205
+ Body.prototype = {
206
+ get body() {
207
+ return this[INTERNALS].body;
208
+ },
209
+
210
+ get bodyUsed() {
211
+ return this[INTERNALS].disturbed;
212
+ },
213
+
214
+ /**
215
+ * Decode response as ArrayBuffer
216
+ *
217
+ * @return Promise
218
+ */
219
+ arrayBuffer() {
220
+ return consumeBody.call(this).then(function (buf) {
221
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
222
+ });
223
+ },
224
+
225
+ /**
226
+ * Return raw response as Blob
227
+ *
228
+ * @return Promise
229
+ */
230
+ blob() {
231
+ let ct = this.headers && this.headers.get('content-type') || '';
232
+ return consumeBody.call(this).then(function (buf) {
233
+ return Object.assign(
234
+ // Prevent copying
235
+ new Blob([], {
236
+ type: ct.toLowerCase()
237
+ }), {
238
+ [BUFFER]: buf
239
+ });
240
+ });
241
+ },
242
+
243
+ /**
244
+ * Decode response as json
245
+ *
246
+ * @return Promise
247
+ */
248
+ json() {
249
+ var _this2 = this;
250
+
251
+ return consumeBody.call(this).then(function (buffer) {
252
+ try {
253
+ return JSON.parse(buffer.toString());
254
+ } catch (err) {
255
+ return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json'));
256
+ }
257
+ });
258
+ },
259
+
260
+ /**
261
+ * Decode response as text
262
+ *
263
+ * @return Promise
264
+ */
265
+ text() {
266
+ return consumeBody.call(this).then(function (buffer) {
267
+ return buffer.toString();
268
+ });
269
+ },
270
+
271
+ /**
272
+ * Decode response as buffer (non-spec api)
273
+ *
274
+ * @return Promise
275
+ */
276
+ buffer() {
277
+ return consumeBody.call(this);
278
+ },
279
+
280
+ /**
281
+ * Decode response as text, while automatically detecting the encoding and
282
+ * trying to decode to UTF-8 (non-spec api)
283
+ *
284
+ * @return Promise
285
+ */
286
+ textConverted() {
287
+ var _this3 = this;
288
+
289
+ return consumeBody.call(this).then(function (buffer) {
290
+ return convertBody(buffer, _this3.headers);
291
+ });
292
+ }
293
+
294
+ };
295
+
296
+ // In browsers, all properties are enumerable.
297
+ Object.defineProperties(Body.prototype, {
298
+ body: { enumerable: true },
299
+ bodyUsed: { enumerable: true },
300
+ arrayBuffer: { enumerable: true },
301
+ blob: { enumerable: true },
302
+ json: { enumerable: true },
303
+ text: { enumerable: true }
304
+ });
305
+
306
+ Body.mixIn = function (proto) {
307
+ for (const name of Object.getOwnPropertyNames(Body.prototype)) {
308
+ // istanbul ignore else: future proof
309
+ if (!(name in proto)) {
310
+ const desc = Object.getOwnPropertyDescriptor(Body.prototype, name);
311
+ Object.defineProperty(proto, name, desc);
312
+ }
313
+ }
314
+ };
315
+
316
+ /**
317
+ * Consume and convert an entire Body to a Buffer.
318
+ *
319
+ * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body
320
+ *
321
+ * @return Promise
322
+ */
323
+ function consumeBody() {
324
+ var _this4 = this;
325
+
326
+ if (this[INTERNALS].disturbed) {
327
+ return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`));
328
+ }
329
+
330
+ this[INTERNALS].disturbed = true;
331
+
332
+ if (this[INTERNALS].error) {
333
+ return Body.Promise.reject(this[INTERNALS].error);
334
+ }
335
+
336
+ // body is null
337
+ if (this.body === null) {
338
+ return Body.Promise.resolve(Buffer.alloc(0));
339
+ }
340
+
341
+ // body is string
342
+ if (typeof this.body === 'string') {
343
+ return Body.Promise.resolve(Buffer.from(this.body));
344
+ }
345
+
346
+ // body is blob
347
+ if (this.body instanceof Blob) {
348
+ return Body.Promise.resolve(this.body[BUFFER]);
349
+ }
350
+
351
+ // body is buffer
352
+ if (Buffer.isBuffer(this.body)) {
353
+ return Body.Promise.resolve(this.body);
354
+ }
355
+
356
+ // body is buffer
357
+ if (Object.prototype.toString.call(this.body) === '[object ArrayBuffer]') {
358
+ return Body.Promise.resolve(Buffer.from(this.body));
359
+ }
360
+
361
+ // istanbul ignore if: should never happen
362
+ if (!(this.body instanceof Stream)) {
363
+ return Body.Promise.resolve(Buffer.alloc(0));
364
+ }
365
+
366
+ // body is stream
367
+ // get ready to actually consume the body
368
+ let accum = [];
369
+ let accumBytes = 0;
370
+ let abort = false;
371
+
372
+ return new Body.Promise(function (resolve, reject) {
373
+ let resTimeout;
374
+
375
+ // allow timeout on slow response body
376
+ if (_this4.timeout) {
377
+ resTimeout = setTimeout(function () {
378
+ abort = true;
379
+ reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout'));
380
+ }, _this4.timeout);
381
+ }
382
+
383
+ // handle stream error, such as incorrect content-encoding
384
+ _this4.body.on('error', function (err) {
385
+ reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err));
386
+ });
387
+
388
+ _this4.body.on('data', function (chunk) {
389
+ if (abort || chunk === null) {
390
+ return;
391
+ }
392
+
393
+ if (_this4.size && accumBytes + chunk.length > _this4.size) {
394
+ abort = true;
395
+ reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size'));
396
+ return;
397
+ }
398
+
399
+ accumBytes += chunk.length;
400
+ accum.push(chunk);
401
+ });
402
+
403
+ _this4.body.on('end', function () {
404
+ if (abort) {
405
+ return;
406
+ }
407
+
408
+ clearTimeout(resTimeout);
409
+
410
+ try {
411
+ resolve(Buffer.concat(accum));
412
+ } catch (err) {
413
+ // handle streams that have accumulated too much data (issue #414)
414
+ reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err));
415
+ }
416
+ });
417
+ });
418
+ }
419
+
420
+ /**
421
+ * Detect buffer encoding and convert to target encoding
422
+ * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding
423
+ *
424
+ * @param Buffer buffer Incoming buffer
425
+ * @param String encoding Target encoding
426
+ * @return String
427
+ */
428
+ function convertBody(buffer, headers) {
429
+ if (typeof convert !== 'function') {
430
+ throw new Error('The package `encoding` must be installed to use the textConverted() function');
431
+ }
432
+
433
+ const ct = headers.get('content-type');
434
+ let charset = 'utf-8';
435
+ let res, str;
436
+
437
+ // header
438
+ if (ct) {
439
+ res = /charset=([^;]*)/i.exec(ct);
440
+ }
441
+
442
+ // no charset in content type, peek at response body for at most 1024 bytes
443
+ str = buffer.slice(0, 1024).toString();
444
+
445
+ // html5
446
+ if (!res && str) {
447
+ res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
448
+ }
449
+
450
+ // html4
451
+ if (!res && str) {
452
+ res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);
453
+
454
+ if (res) {
455
+ res = /charset=(.*)/i.exec(res.pop());
456
+ }
457
+ }
458
+
459
+ // xml
460
+ if (!res && str) {
461
+ res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
462
+ }
463
+
464
+ // found charset
465
+ if (res) {
466
+ charset = res.pop();
467
+
468
+ // prevent decode issues when sites use incorrect encoding
469
+ // ref: https://hsivonen.fi/encoding-menu/
470
+ if (charset === 'gb2312' || charset === 'gbk') {
471
+ charset = 'gb18030';
472
+ }
473
+ }
474
+
475
+ // turn raw buffers into a single utf-8 buffer
476
+ return convert(buffer, 'UTF-8', charset).toString();
477
+ }
478
+
479
+ /**
480
+ * Detect a URLSearchParams object
481
+ * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143
482
+ *
483
+ * @param Object obj Object to detect by type or brand
484
+ * @return String
485
+ */
486
+ function isURLSearchParams(obj) {
487
+ // Duck-typing as a necessary condition.
488
+ if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') {
489
+ return false;
490
+ }
491
+
492
+ // Brand-checking and more duck-typing as optional condition.
493
+ return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';
494
+ }
495
+
496
+ /**
497
+ * Clone body given Res/Req instance
498
+ *
499
+ * @param Mixed instance Response or Request instance
500
+ * @return Mixed
501
+ */
502
+ function clone(instance) {
503
+ let p1, p2;
504
+ let body = instance.body;
505
+
506
+ // don't allow cloning a used body
507
+ if (instance.bodyUsed) {
508
+ throw new Error('cannot clone body after it is used');
509
+ }
510
+
511
+ // check that body is a stream and not form-data object
512
+ // note: we can't clone the form-data object without having it as a dependency
513
+ if (body instanceof Stream && typeof body.getBoundary !== 'function') {
514
+ // tee instance body
515
+ p1 = new PassThrough();
516
+ p2 = new PassThrough();
517
+ body.pipe(p1);
518
+ body.pipe(p2);
519
+ // set instance body to teed body and return the other teed body
520
+ instance[INTERNALS].body = p1;
521
+ body = p2;
522
+ }
523
+
524
+ return body;
525
+ }
526
+
527
+ /**
528
+ * Performs the operation "extract a `Content-Type` value from |object|" as
529
+ * specified in the specification:
530
+ * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
531
+ *
532
+ * This function assumes that instance.body is present.
533
+ *
534
+ * @param Mixed instance Response or Request instance
535
+ */
536
+ function extractContentType(instance) {
537
+ const body = instance.body;
538
+
539
+ // istanbul ignore if: Currently, because of a guard in Request, body
540
+ // can never be null. Included here for completeness.
541
+
542
+ if (body === null) {
543
+ // body is null
544
+ return null;
545
+ } else if (typeof body === 'string') {
546
+ // body is string
547
+ return 'text/plain;charset=UTF-8';
548
+ } else if (isURLSearchParams(body)) {
549
+ // body is a URLSearchParams
550
+ return 'application/x-www-form-urlencoded;charset=UTF-8';
551
+ } else if (body instanceof Blob) {
552
+ // body is blob
553
+ return body.type || null;
554
+ } else if (Buffer.isBuffer(body)) {
555
+ // body is buffer
556
+ return null;
557
+ } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
558
+ // body is array buffer
559
+ return null;
560
+ } else if (typeof body.getBoundary === 'function') {
561
+ // detect form data input from form-data module
562
+ return `multipart/form-data;boundary=${body.getBoundary()}`;
563
+ } else {
564
+ // body is stream
565
+ // can't really do much about this
566
+ return null;
567
+ }
568
+ }
569
+
570
+ /**
571
+ * The Fetch Standard treats this as if "total bytes" is a property on the body.
572
+ * For us, we have to explicitly get it with a function.
573
+ *
574
+ * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes
575
+ *
576
+ * @param Body instance Instance of Body
577
+ * @return Number? Number of bytes, or null if not possible
578
+ */
579
+ function getTotalBytes(instance) {
580
+ const body = instance.body;
581
+
582
+ // istanbul ignore if: included for completion
583
+
584
+ if (body === null) {
585
+ // body is null
586
+ return 0;
587
+ } else if (typeof body === 'string') {
588
+ // body is string
589
+ return Buffer.byteLength(body);
590
+ } else if (isURLSearchParams(body)) {
591
+ // body is URLSearchParams
592
+ return Buffer.byteLength(String(body));
593
+ } else if (body instanceof Blob) {
594
+ // body is blob
595
+ return body.size;
596
+ } else if (Buffer.isBuffer(body)) {
597
+ // body is buffer
598
+ return body.length;
599
+ } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
600
+ // body is array buffer
601
+ return body.byteLength;
602
+ } else if (body && typeof body.getLengthSync === 'function') {
603
+ // detect form data input from form-data module
604
+ if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x
605
+ body.hasKnownLength && body.hasKnownLength()) {
606
+ // 2.x
607
+ return body.getLengthSync();
608
+ }
609
+ return null;
610
+ } else {
611
+ // body is stream
612
+ // can't really do much about this
613
+ return null;
614
+ }
615
+ }
616
+
617
+ /**
618
+ * Write a Body to a Node.js WritableStream (e.g. http.Request) object.
619
+ *
620
+ * @param Body instance Instance of Body
621
+ * @return Void
622
+ */
623
+ function writeToStream(dest, instance) {
624
+ const body = instance.body;
625
+
626
+
627
+ if (body === null) {
628
+ // body is null
629
+ dest.end();
630
+ } else if (typeof body === 'string') {
631
+ // body is string
632
+ dest.write(body);
633
+ dest.end();
634
+ } else if (isURLSearchParams(body)) {
635
+ // body is URLSearchParams
636
+ dest.write(Buffer.from(String(body)));
637
+ dest.end();
638
+ } else if (body instanceof Blob) {
639
+ // body is blob
640
+ dest.write(body[BUFFER]);
641
+ dest.end();
642
+ } else if (Buffer.isBuffer(body)) {
643
+ // body is buffer
644
+ dest.write(body);
645
+ dest.end();
646
+ } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
647
+ // body is array buffer
648
+ dest.write(Buffer.from(body));
649
+ dest.end();
650
+ } else {
651
+ // body is stream
652
+ body.pipe(dest);
653
+ }
654
+ }
655
+
656
+ // expose Promise
657
+ Body.Promise = global.Promise;
658
+
659
+ /**
660
+ * headers.js
661
+ *
662
+ * Headers class offers convenient helpers
663
+ */
664
+
665
+ const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/;
666
+ const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/;
667
+
668
+ function validateName(name) {
669
+ name = `${name}`;
670
+ if (invalidTokenRegex.test(name)) {
671
+ throw new TypeError(`${name} is not a legal HTTP header name`);
672
+ }
673
+ }
674
+
675
+ function validateValue(value) {
676
+ value = `${value}`;
677
+ if (invalidHeaderCharRegex.test(value)) {
678
+ throw new TypeError(`${value} is not a legal HTTP header value`);
679
+ }
680
+ }
681
+
682
+ /**
683
+ * Find the key in the map object given a header name.
684
+ *
685
+ * Returns undefined if not found.
686
+ *
687
+ * @param String name Header name
688
+ * @return String|Undefined
689
+ */
690
+ function find(map, name) {
691
+ name = name.toLowerCase();
692
+ for (const key in map) {
693
+ if (key.toLowerCase() === name) {
694
+ return key;
695
+ }
696
+ }
697
+ return undefined;
698
+ }
699
+
700
+ const MAP = Symbol('map');
701
+ class Headers {
702
+ /**
703
+ * Headers class
704
+ *
705
+ * @param Object headers Response headers
706
+ * @return Void
707
+ */
708
+ constructor() {
709
+ let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
710
+
711
+ this[MAP] = Object.create(null);
712
+
713
+ if (init instanceof Headers) {
714
+ const rawHeaders = init.raw();
715
+ const headerNames = Object.keys(rawHeaders);
716
+
717
+ for (const headerName of headerNames) {
718
+ for (const value of rawHeaders[headerName]) {
719
+ this.append(headerName, value);
720
+ }
721
+ }
722
+
723
+ return;
724
+ }
725
+
726
+ // We don't worry about converting prop to ByteString here as append()
727
+ // will handle it.
728
+ if (init == null) {
729
+ // no op
730
+ } else if (typeof init === 'object') {
731
+ const method = init[Symbol.iterator];
732
+ if (method != null) {
733
+ if (typeof method !== 'function') {
734
+ throw new TypeError('Header pairs must be iterable');
735
+ }
736
+
737
+ // sequence<sequence<ByteString>>
738
+ // Note: per spec we have to first exhaust the lists then process them
739
+ const pairs = [];
740
+ for (const pair of init) {
741
+ if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
742
+ throw new TypeError('Each header pair must be iterable');
743
+ }
744
+ pairs.push(Array.from(pair));
745
+ }
746
+
747
+ for (const pair of pairs) {
748
+ if (pair.length !== 2) {
749
+ throw new TypeError('Each header pair must be a name/value tuple');
750
+ }
751
+ this.append(pair[0], pair[1]);
752
+ }
753
+ } else {
754
+ // record<ByteString, ByteString>
755
+ for (const key of Object.keys(init)) {
756
+ const value = init[key];
757
+ this.append(key, value);
758
+ }
759
+ }
760
+ } else {
761
+ throw new TypeError('Provided initializer must be an object');
762
+ }
763
+ }
764
+
765
+ /**
766
+ * Return combined header value given name
767
+ *
768
+ * @param String name Header name
769
+ * @return Mixed
770
+ */
771
+ get(name) {
772
+ name = `${name}`;
773
+ validateName(name);
774
+ const key = find(this[MAP], name);
775
+ if (key === undefined) {
776
+ return null;
777
+ }
778
+
779
+ return this[MAP][key].join(', ');
780
+ }
781
+
782
+ /**
783
+ * Iterate over all headers
784
+ *
785
+ * @param Function callback Executed for each item with parameters (value, name, thisArg)
786
+ * @param Boolean thisArg `this` context for callback function
787
+ * @return Void
788
+ */
789
+ forEach(callback) {
790
+ let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
791
+
792
+ let pairs = getHeaders(this);
793
+ let i = 0;
794
+ while (i < pairs.length) {
795
+ var _pairs$i = pairs[i];
796
+ const name = _pairs$i[0],
797
+ value = _pairs$i[1];
798
+
799
+ callback.call(thisArg, value, name, this);
800
+ pairs = getHeaders(this);
801
+ i++;
802
+ }
803
+ }
804
+
805
+ /**
806
+ * Overwrite header values given name
807
+ *
808
+ * @param String name Header name
809
+ * @param String value Header value
810
+ * @return Void
811
+ */
812
+ set(name, value) {
813
+ name = `${name}`;
814
+ value = `${value}`;
815
+ validateName(name);
816
+ validateValue(value);
817
+ const key = find(this[MAP], name);
818
+ this[MAP][key !== undefined ? key : name] = [value];
819
+ }
820
+
821
+ /**
822
+ * Append a value onto existing header
823
+ *
824
+ * @param String name Header name
825
+ * @param String value Header value
826
+ * @return Void
827
+ */
828
+ append(name, value) {
829
+ name = `${name}`;
830
+ value = `${value}`;
831
+ validateName(name);
832
+ validateValue(value);
833
+ const key = find(this[MAP], name);
834
+ if (key !== undefined) {
835
+ this[MAP][key].push(value);
836
+ } else {
837
+ this[MAP][name] = [value];
838
+ }
839
+ }
840
+
841
+ /**
842
+ * Check for header name existence
843
+ *
844
+ * @param String name Header name
845
+ * @return Boolean
846
+ */
847
+ has(name) {
848
+ name = `${name}`;
849
+ validateName(name);
850
+ return find(this[MAP], name) !== undefined;
851
+ }
852
+
853
+ /**
854
+ * Delete all header values given name
855
+ *
856
+ * @param String name Header name
857
+ * @return Void
858
+ */
859
+ delete(name) {
860
+ name = `${name}`;
861
+ validateName(name);
862
+ const key = find(this[MAP], name);
863
+ if (key !== undefined) {
864
+ delete this[MAP][key];
865
+ }
866
+ }
867
+
868
+ /**
869
+ * Return raw headers (non-spec api)
870
+ *
871
+ * @return Object
872
+ */
873
+ raw() {
874
+ return this[MAP];
875
+ }
876
+
877
+ /**
878
+ * Get an iterator on keys.
879
+ *
880
+ * @return Iterator
881
+ */
882
+ keys() {
883
+ return createHeadersIterator(this, 'key');
884
+ }
885
+
886
+ /**
887
+ * Get an iterator on values.
888
+ *
889
+ * @return Iterator
890
+ */
891
+ values() {
892
+ return createHeadersIterator(this, 'value');
893
+ }
894
+
895
+ /**
896
+ * Get an iterator on entries.
897
+ *
898
+ * This is the default iterator of the Headers object.
899
+ *
900
+ * @return Iterator
901
+ */
902
+ [Symbol.iterator]() {
903
+ return createHeadersIterator(this, 'key+value');
904
+ }
905
+ }
906
+ Headers.prototype.entries = Headers.prototype[Symbol.iterator];
907
+
908
+ Object.defineProperty(Headers.prototype, Symbol.toStringTag, {
909
+ value: 'Headers',
910
+ writable: false,
911
+ enumerable: false,
912
+ configurable: true
913
+ });
914
+
915
+ Object.defineProperties(Headers.prototype, {
916
+ get: { enumerable: true },
917
+ forEach: { enumerable: true },
918
+ set: { enumerable: true },
919
+ append: { enumerable: true },
920
+ has: { enumerable: true },
921
+ delete: { enumerable: true },
922
+ keys: { enumerable: true },
923
+ values: { enumerable: true },
924
+ entries: { enumerable: true }
925
+ });
926
+
927
+ function getHeaders(headers) {
928
+ let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value';
929
+
930
+ const keys = Object.keys(headers[MAP]).sort();
931
+ return keys.map(kind === 'key' ? function (k) {
932
+ return k.toLowerCase();
933
+ } : kind === 'value' ? function (k) {
934
+ return headers[MAP][k].join(', ');
935
+ } : function (k) {
936
+ return [k.toLowerCase(), headers[MAP][k].join(', ')];
937
+ });
938
+ }
939
+
940
+ const INTERNAL = Symbol('internal');
941
+
942
+ function createHeadersIterator(target, kind) {
943
+ const iterator = Object.create(HeadersIteratorPrototype);
944
+ iterator[INTERNAL] = {
945
+ target,
946
+ kind,
947
+ index: 0
948
+ };
949
+ return iterator;
950
+ }
951
+
952
+ const HeadersIteratorPrototype = Object.setPrototypeOf({
953
+ next() {
954
+ // istanbul ignore if
955
+ if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {
956
+ throw new TypeError('Value of `this` is not a HeadersIterator');
957
+ }
958
+
959
+ var _INTERNAL = this[INTERNAL];
960
+ const target = _INTERNAL.target,
961
+ kind = _INTERNAL.kind,
962
+ index = _INTERNAL.index;
963
+
964
+ const values = getHeaders(target, kind);
965
+ const len = values.length;
966
+ if (index >= len) {
967
+ return {
968
+ value: undefined,
969
+ done: true
970
+ };
971
+ }
972
+
973
+ this[INTERNAL].index = index + 1;
974
+
975
+ return {
976
+ value: values[index],
977
+ done: false
978
+ };
979
+ }
980
+ }, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
981
+
982
+ Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {
983
+ value: 'HeadersIterator',
984
+ writable: false,
985
+ enumerable: false,
986
+ configurable: true
987
+ });
988
+
989
+ /**
990
+ * Export the Headers object in a form that Node.js can consume.
991
+ *
992
+ * @param Headers headers
993
+ * @return Object
994
+ */
995
+ function exportNodeCompatibleHeaders(headers) {
996
+ const obj = Object.assign({ __proto__: null }, headers[MAP]);
997
+
998
+ // http.request() only supports string as Host header. This hack makes
999
+ // specifying custom Host header possible.
1000
+ const hostHeaderKey = find(headers[MAP], 'Host');
1001
+ if (hostHeaderKey !== undefined) {
1002
+ obj[hostHeaderKey] = obj[hostHeaderKey][0];
1003
+ }
1004
+
1005
+ return obj;
1006
+ }
1007
+
1008
+ /**
1009
+ * Create a Headers object from an object of headers, ignoring those that do
1010
+ * not conform to HTTP grammar productions.
1011
+ *
1012
+ * @param Object obj Object of headers
1013
+ * @return Headers
1014
+ */
1015
+ function createHeadersLenient(obj) {
1016
+ const headers = new Headers();
1017
+ for (const name of Object.keys(obj)) {
1018
+ if (invalidTokenRegex.test(name)) {
1019
+ continue;
1020
+ }
1021
+ if (Array.isArray(obj[name])) {
1022
+ for (const val of obj[name]) {
1023
+ if (invalidHeaderCharRegex.test(val)) {
1024
+ continue;
1025
+ }
1026
+ if (headers[MAP][name] === undefined) {
1027
+ headers[MAP][name] = [val];
1028
+ } else {
1029
+ headers[MAP][name].push(val);
1030
+ }
1031
+ }
1032
+ } else if (!invalidHeaderCharRegex.test(obj[name])) {
1033
+ headers[MAP][name] = [obj[name]];
1034
+ }
1035
+ }
1036
+ return headers;
1037
+ }
1038
+
1039
+ /**
1040
+ * response.js
1041
+ *
1042
+ * Response class provides content decoding
1043
+ */
1044
+
1045
+ var _require$1 = require('http');
1046
+
1047
+ const STATUS_CODES = _require$1.STATUS_CODES;
1048
+
1049
+
1050
+ const INTERNALS$1 = Symbol('Response internals');
1051
+
1052
+ /**
1053
+ * Response class
1054
+ *
1055
+ * @param Stream body Readable stream
1056
+ * @param Object opts Response options
1057
+ * @return Void
1058
+ */
1059
+ class Response {
1060
+ constructor() {
1061
+ let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1062
+ let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1063
+
1064
+ Body.call(this, body, opts);
1065
+
1066
+ const status = opts.status || 200;
1067
+
1068
+ this[INTERNALS$1] = {
1069
+ url: opts.url,
1070
+ status,
1071
+ statusText: opts.statusText || STATUS_CODES[status],
1072
+ headers: new Headers(opts.headers)
1073
+ };
1074
+ }
1075
+
1076
+ get url() {
1077
+ return this[INTERNALS$1].url;
1078
+ }
1079
+
1080
+ get status() {
1081
+ return this[INTERNALS$1].status;
1082
+ }
1083
+
1084
+ /**
1085
+ * Convenience property representing if the request ended normally
1086
+ */
1087
+ get ok() {
1088
+ return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300;
1089
+ }
1090
+
1091
+ get statusText() {
1092
+ return this[INTERNALS$1].statusText;
1093
+ }
1094
+
1095
+ get headers() {
1096
+ return this[INTERNALS$1].headers;
1097
+ }
1098
+
1099
+ /**
1100
+ * Clone this response
1101
+ *
1102
+ * @return Response
1103
+ */
1104
+ clone() {
1105
+ return new Response(clone(this), {
1106
+ url: this.url,
1107
+ status: this.status,
1108
+ statusText: this.statusText,
1109
+ headers: this.headers,
1110
+ ok: this.ok
1111
+ });
1112
+ }
1113
+ }
1114
+
1115
+ Body.mixIn(Response.prototype);
1116
+
1117
+ Object.defineProperties(Response.prototype, {
1118
+ url: { enumerable: true },
1119
+ status: { enumerable: true },
1120
+ ok: { enumerable: true },
1121
+ statusText: { enumerable: true },
1122
+ headers: { enumerable: true },
1123
+ clone: { enumerable: true }
1124
+ });
1125
+
1126
+ Object.defineProperty(Response.prototype, Symbol.toStringTag, {
1127
+ value: 'Response',
1128
+ writable: false,
1129
+ enumerable: false,
1130
+ configurable: true
1131
+ });
1132
+
1133
+ /**
1134
+ * request.js
1135
+ *
1136
+ * Request class contains server only options
1137
+ *
1138
+ * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
1139
+ */
1140
+
1141
+ var _require$2 = require('url');
1142
+
1143
+ const format_url = _require$2.format;
1144
+ const parse_url = _require$2.parse;
1145
+
1146
+
1147
+ const INTERNALS$2 = Symbol('Request internals');
1148
+
1149
+ /**
1150
+ * Check if a value is an instance of Request.
1151
+ *
1152
+ * @param Mixed input
1153
+ * @return Boolean
1154
+ */
1155
+ function isRequest(input) {
1156
+ return typeof input === 'object' && typeof input[INTERNALS$2] === 'object';
1157
+ }
1158
+
1159
+ /**
1160
+ * Request class
1161
+ *
1162
+ * @param Mixed input Url or Request instance
1163
+ * @param Object init Custom options
1164
+ * @return Void
1165
+ */
1166
+ class Request {
1167
+ constructor(input) {
1168
+ let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1169
+
1170
+ let parsedURL;
1171
+
1172
+ // normalize input
1173
+ if (!isRequest(input)) {
1174
+ if (input && input.href) {
1175
+ // in order to support Node.js' Url objects; though WHATWG's URL objects
1176
+ // will fall into this branch also (since their `toString()` will return
1177
+ // `href` property anyway)
1178
+ parsedURL = parse_url(input.href);
1179
+ } else {
1180
+ // coerce input to a string before attempting to parse
1181
+ parsedURL = parse_url(`${input}`);
1182
+ }
1183
+ input = {};
1184
+ } else {
1185
+ parsedURL = parse_url(input.url);
1186
+ }
1187
+
1188
+ let method = init.method || input.method || 'GET';
1189
+ method = method.toUpperCase();
1190
+
1191
+ if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) {
1192
+ throw new TypeError('Request with GET/HEAD method cannot have body');
1193
+ }
1194
+
1195
+ let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null;
1196
+
1197
+ Body.call(this, inputBody, {
1198
+ timeout: init.timeout || input.timeout || 0,
1199
+ size: init.size || input.size || 0
1200
+ });
1201
+
1202
+ const headers = new Headers(init.headers || input.headers || {});
1203
+
1204
+ if (init.body != null) {
1205
+ const contentType = extractContentType(this);
1206
+ if (contentType !== null && !headers.has('Content-Type')) {
1207
+ headers.append('Content-Type', contentType);
1208
+ }
1209
+ }
1210
+
1211
+ this[INTERNALS$2] = {
1212
+ method,
1213
+ redirect: init.redirect || input.redirect || 'follow',
1214
+ headers,
1215
+ parsedURL
1216
+ };
1217
+
1218
+ // node-fetch-only options
1219
+ this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
1220
+ this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
1221
+ this.counter = init.counter || input.counter || 0;
1222
+ this.agent = init.agent || input.agent;
1223
+ }
1224
+
1225
+ get method() {
1226
+ return this[INTERNALS$2].method;
1227
+ }
1228
+
1229
+ get url() {
1230
+ return format_url(this[INTERNALS$2].parsedURL);
1231
+ }
1232
+
1233
+ get headers() {
1234
+ return this[INTERNALS$2].headers;
1235
+ }
1236
+
1237
+ get redirect() {
1238
+ return this[INTERNALS$2].redirect;
1239
+ }
1240
+
1241
+ /**
1242
+ * Clone this request
1243
+ *
1244
+ * @return Request
1245
+ */
1246
+ clone() {
1247
+ return new Request(this);
1248
+ }
1249
+ }
1250
+
1251
+ Body.mixIn(Request.prototype);
1252
+
1253
+ Object.defineProperty(Request.prototype, Symbol.toStringTag, {
1254
+ value: 'Request',
1255
+ writable: false,
1256
+ enumerable: false,
1257
+ configurable: true
1258
+ });
1259
+
1260
+ Object.defineProperties(Request.prototype, {
1261
+ method: { enumerable: true },
1262
+ url: { enumerable: true },
1263
+ headers: { enumerable: true },
1264
+ redirect: { enumerable: true },
1265
+ clone: { enumerable: true }
1266
+ });
1267
+
1268
+ /**
1269
+ * Convert a Request to Node.js http request options.
1270
+ *
1271
+ * @param Request A Request instance
1272
+ * @return Object The options object to be passed to http.request
1273
+ */
1274
+ function getNodeRequestOptions(request) {
1275
+ const parsedURL = request[INTERNALS$2].parsedURL;
1276
+ const headers = new Headers(request[INTERNALS$2].headers);
1277
+
1278
+ // fetch step 1.3
1279
+ if (!headers.has('Accept')) {
1280
+ headers.set('Accept', '*/*');
1281
+ }
1282
+
1283
+ // Basic fetch
1284
+ if (!parsedURL.protocol || !parsedURL.hostname) {
1285
+ throw new TypeError('Only absolute URLs are supported');
1286
+ }
1287
+
1288
+ if (!/^https?:$/.test(parsedURL.protocol)) {
1289
+ throw new TypeError('Only HTTP(S) protocols are supported');
1290
+ }
1291
+
1292
+ // HTTP-network-or-cache fetch steps 2.4-2.7
1293
+ let contentLengthValue = null;
1294
+ if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
1295
+ contentLengthValue = '0';
1296
+ }
1297
+ if (request.body != null) {
1298
+ const totalBytes = getTotalBytes(request);
1299
+ if (typeof totalBytes === 'number') {
1300
+ contentLengthValue = String(totalBytes);
1301
+ }
1302
+ }
1303
+ if (contentLengthValue) {
1304
+ headers.set('Content-Length', contentLengthValue);
1305
+ }
1306
+
1307
+ // HTTP-network-or-cache fetch step 2.11
1308
+ if (!headers.has('User-Agent')) {
1309
+ headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');
1310
+ }
1311
+
1312
+ // HTTP-network-or-cache fetch step 2.15
1313
+ if (request.compress) {
1314
+ headers.set('Accept-Encoding', 'gzip,deflate');
1315
+ }
1316
+ if (!headers.has('Connection') && !request.agent) {
1317
+ headers.set('Connection', 'close');
1318
+ }
1319
+
1320
+ // HTTP-network fetch step 4.2
1321
+ // chunked encoding is handled by Node.js
1322
+
1323
+ return Object.assign({}, parsedURL, {
1324
+ method: request.method,
1325
+ headers: exportNodeCompatibleHeaders(headers),
1326
+ agent: request.agent
1327
+ });
1328
+ }
1329
+
1330
+ /**
1331
+ * index.js
1332
+ *
1333
+ * a request API compatible with window.fetch
1334
+ *
1335
+ * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/.
1336
+ */
1337
+
1338
+ const http = require('http');
1339
+ const https = require('https');
1340
+
1341
+ var _require$3 = require('stream');
1342
+
1343
+ const PassThrough$1 = _require$3.PassThrough;
1344
+
1345
+ var _require2 = require('url');
1346
+
1347
+ const resolve_url = _require2.resolve;
1348
+
1349
+ const zlib = require('zlib');
1350
+
1351
+ /**
1352
+ * Fetch function
1353
+ *
1354
+ * @param Mixed url Absolute url or Request instance
1355
+ * @param Object opts Fetch options
1356
+ * @return Promise
1357
+ */
1358
+ function fetch(url, opts) {
1359
+
1360
+ // allow custom promise
1361
+ if (!fetch.Promise) {
1362
+ throw new Error('native promise missing, set fetch.Promise to your favorite alternative');
1363
+ }
1364
+
1365
+ Body.Promise = fetch.Promise;
1366
+
1367
+ // wrap http.request into fetch
1368
+ return new fetch.Promise(function (resolve, reject) {
1369
+ // build request object
1370
+ const request = new Request(url, opts);
1371
+ const options = getNodeRequestOptions(request);
1372
+
1373
+ const send = (options.protocol === 'https:' ? https : http).request;
1374
+
1375
+ // send request
1376
+ const req = send(options);
1377
+ let reqTimeout;
1378
+
1379
+ function finalize() {
1380
+ req.abort();
1381
+ clearTimeout(reqTimeout);
1382
+ }
1383
+
1384
+ if (request.timeout) {
1385
+ req.once('socket', function (socket) {
1386
+ reqTimeout = setTimeout(function () {
1387
+ reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
1388
+ finalize();
1389
+ }, request.timeout);
1390
+ });
1391
+ }
1392
+
1393
+ req.on('error', function (err) {
1394
+ reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
1395
+ finalize();
1396
+ });
1397
+
1398
+ req.on('response', function (res) {
1399
+ clearTimeout(reqTimeout);
1400
+
1401
+ const headers = createHeadersLenient(res.headers);
1402
+
1403
+ // HTTP fetch step 5
1404
+ if (fetch.isRedirect(res.statusCode)) {
1405
+ // HTTP fetch step 5.2
1406
+ const location = headers.get('Location');
1407
+
1408
+ // HTTP fetch step 5.3
1409
+ const locationURL = location === null ? null : resolve_url(request.url, location);
1410
+
1411
+ // HTTP fetch step 5.5
1412
+ switch (request.redirect) {
1413
+ case 'error':
1414
+ reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect'));
1415
+ finalize();
1416
+ return;
1417
+ case 'manual':
1418
+ // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL.
1419
+ if (locationURL !== null) {
1420
+ headers.set('Location', locationURL);
1421
+ }
1422
+ break;
1423
+ case 'follow':
1424
+ // HTTP-redirect fetch step 2
1425
+ if (locationURL === null) {
1426
+ break;
1427
+ }
1428
+
1429
+ // HTTP-redirect fetch step 5
1430
+ if (request.counter >= request.follow) {
1431
+ reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
1432
+ finalize();
1433
+ return;
1434
+ }
1435
+
1436
+ // HTTP-redirect fetch step 6 (counter increment)
1437
+ // Create a new Request object.
1438
+ const requestOpts = {
1439
+ headers: new Headers(request.headers),
1440
+ follow: request.follow,
1441
+ counter: request.counter + 1,
1442
+ agent: request.agent,
1443
+ compress: request.compress,
1444
+ method: request.method,
1445
+ body: request.body
1446
+ };
1447
+
1448
+ // HTTP-redirect fetch step 9
1449
+ if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) {
1450
+ reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect'));
1451
+ finalize();
1452
+ return;
1453
+ }
1454
+
1455
+ // HTTP-redirect fetch step 11
1456
+ if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
1457
+ requestOpts.method = 'GET';
1458
+ requestOpts.body = undefined;
1459
+ requestOpts.headers.delete('content-length');
1460
+ }
1461
+
1462
+ // HTTP-redirect fetch step 15
1463
+ resolve(fetch(new Request(locationURL, requestOpts)));
1464
+ finalize();
1465
+ return;
1466
+ }
1467
+ }
1468
+
1469
+ // prepare response
1470
+ let body = res.pipe(new PassThrough$1());
1471
+ const response_options = {
1472
+ url: request.url,
1473
+ status: res.statusCode,
1474
+ statusText: res.statusMessage,
1475
+ headers: headers,
1476
+ size: request.size,
1477
+ timeout: request.timeout
1478
+ };
1479
+
1480
+ // HTTP-network fetch step 12.1.1.3
1481
+ const codings = headers.get('Content-Encoding');
1482
+
1483
+ // HTTP-network fetch step 12.1.1.4: handle content codings
1484
+
1485
+ // in following scenarios we ignore compression support
1486
+ // 1. compression support is disabled
1487
+ // 2. HEAD request
1488
+ // 3. no Content-Encoding header
1489
+ // 4. no content response (204)
1490
+ // 5. content not modified response (304)
1491
+ if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {
1492
+ resolve(new Response(body, response_options));
1493
+ return;
1494
+ }
1495
+
1496
+ // For Node v6+
1497
+ // Be less strict when decoding compressed responses, since sometimes
1498
+ // servers send slightly invalid responses that are still accepted
1499
+ // by common browsers.
1500
+ // Always using Z_SYNC_FLUSH is what cURL does.
1501
+ const zlibOptions = {
1502
+ flush: zlib.Z_SYNC_FLUSH,
1503
+ finishFlush: zlib.Z_SYNC_FLUSH
1504
+ };
1505
+
1506
+ // for gzip
1507
+ if (codings == 'gzip' || codings == 'x-gzip') {
1508
+ body = body.pipe(zlib.createGunzip(zlibOptions));
1509
+ resolve(new Response(body, response_options));
1510
+ return;
1511
+ }
1512
+
1513
+ // for deflate
1514
+ if (codings == 'deflate' || codings == 'x-deflate') {
1515
+ // handle the infamous raw deflate response from old servers
1516
+ // a hack for old IIS and Apache servers
1517
+ const raw = res.pipe(new PassThrough$1());
1518
+ raw.once('data', function (chunk) {
1519
+ // see http://stackoverflow.com/questions/37519828
1520
+ if ((chunk[0] & 0x0F) === 0x08) {
1521
+ body = body.pipe(zlib.createInflate());
1522
+ } else {
1523
+ body = body.pipe(zlib.createInflateRaw());
1524
+ }
1525
+ resolve(new Response(body, response_options));
1526
+ });
1527
+ return;
1528
+ }
1529
+
1530
+ // otherwise, use response as-is
1531
+ resolve(new Response(body, response_options));
1532
+ });
1533
+
1534
+ writeToStream(req, request);
1535
+ });
1536
+ }
1537
+
1538
+ /**
1539
+ * Redirect code matching
1540
+ *
1541
+ * @param Number code Status code
1542
+ * @return Boolean
1543
+ */
1544
+ fetch.isRedirect = function (code) {
1545
+ return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
1546
+ };
1547
+
1548
+ // Needed for TypeScript.
1549
+ fetch.default = fetch;
1550
+
1551
+ // expose Promise
1552
+ fetch.Promise = global.Promise;
1553
+
1554
+ // Igor Kroitor 2019 Dec 30
1555
+ // expose http and https
1556
+ // https://github.com/ccxt/ccxt/issues/6327
1557
+ fetch.http = http
1558
+ fetch.https = https
1559
+
1560
+ module.exports = exports = fetch;
1561
+ exports.Headers = Headers;
1562
+ exports.Request = Request;
1563
+ exports.Response = Response;
1564
+ exports.FetchError = FetchError;