@graphprotocol/graph-cli 0.24.1 → 0.25.3

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 (105) hide show
  1. package/examples/basic-event-handlers/node_modules/chalk/node_modules/supports-color/index.js +50 -0
  2. package/examples/basic-event-handlers/node_modules/chalk/node_modules/supports-color/license +21 -0
  3. package/examples/basic-event-handlers/node_modules/chalk/node_modules/supports-color/package.json +49 -0
  4. package/examples/basic-event-handlers/node_modules/chalk/node_modules/supports-color/readme.md +36 -0
  5. package/examples/basic-event-handlers/node_modules/cliui/node_modules/ansi-regex/index.js +10 -0
  6. package/examples/basic-event-handlers/node_modules/cliui/node_modules/ansi-regex/license +9 -0
  7. package/examples/basic-event-handlers/node_modules/cliui/node_modules/ansi-regex/package.json +53 -0
  8. package/examples/basic-event-handlers/node_modules/cliui/node_modules/ansi-regex/readme.md +46 -0
  9. package/examples/basic-event-handlers/node_modules/cliui/node_modules/strip-ansi/index.js +4 -0
  10. package/examples/basic-event-handlers/node_modules/cliui/node_modules/strip-ansi/license +9 -0
  11. package/examples/basic-event-handlers/node_modules/cliui/node_modules/strip-ansi/package.json +52 -0
  12. package/examples/basic-event-handlers/node_modules/cliui/node_modules/strip-ansi/readme.md +39 -0
  13. package/examples/basic-event-handlers/node_modules/keccak/build/Makefile +342 -0
  14. package/examples/basic-event-handlers/node_modules/keccak/build/Release/.deps/Release/obj.target/keccak/src/addon.o.d.raw +27 -0
  15. package/examples/basic-event-handlers/node_modules/keccak/build/binding.Makefile +6 -0
  16. package/examples/basic-event-handlers/node_modules/keccak/build/config.gypi +207 -0
  17. package/examples/basic-event-handlers/node_modules/keccak/build/gyp-mac-tool +615 -0
  18. package/examples/basic-event-handlers/node_modules/keccak/build/keccak.target.mk +209 -0
  19. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/.coveralls.yml +1 -0
  20. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/.eslintrc +14 -0
  21. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/.travis.yml +20 -0
  22. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/CHANGELOG.md +395 -0
  23. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/LICENSE +19 -0
  24. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/Makefile +58 -0
  25. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/README.md +368 -0
  26. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/karma.conf.js +70 -0
  27. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/node.js +1 -0
  28. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/package.json +43 -0
  29. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/src/browser.js +195 -0
  30. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/src/debug.js +225 -0
  31. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/src/index.js +10 -0
  32. package/examples/basic-event-handlers/node_modules/mocha/node_modules/debug/src/node.js +186 -0
  33. package/examples/basic-event-handlers/node_modules/rimraf/node_modules/glob/LICENSE +15 -0
  34. package/examples/basic-event-handlers/node_modules/rimraf/node_modules/glob/README.md +368 -0
  35. package/examples/basic-event-handlers/node_modules/rimraf/node_modules/glob/changelog.md +67 -0
  36. package/examples/basic-event-handlers/node_modules/rimraf/node_modules/glob/common.js +240 -0
  37. package/examples/basic-event-handlers/node_modules/rimraf/node_modules/glob/glob.js +790 -0
  38. package/examples/basic-event-handlers/node_modules/rimraf/node_modules/glob/package.json +43 -0
  39. package/examples/basic-event-handlers/node_modules/rimraf/node_modules/glob/sync.js +486 -0
  40. package/examples/basic-event-handlers/node_modules/string-width/node_modules/ansi-regex/index.js +10 -0
  41. package/examples/basic-event-handlers/node_modules/string-width/node_modules/ansi-regex/license +9 -0
  42. package/examples/basic-event-handlers/node_modules/string-width/node_modules/ansi-regex/package.json +53 -0
  43. package/examples/basic-event-handlers/node_modules/string-width/node_modules/ansi-regex/readme.md +46 -0
  44. package/examples/basic-event-handlers/node_modules/string-width/node_modules/strip-ansi/index.js +4 -0
  45. package/examples/basic-event-handlers/node_modules/string-width/node_modules/strip-ansi/license +9 -0
  46. package/examples/basic-event-handlers/node_modules/string-width/node_modules/strip-ansi/package.json +52 -0
  47. package/examples/basic-event-handlers/node_modules/string-width/node_modules/strip-ansi/readme.md +39 -0
  48. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point/index.js +46 -0
  49. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point/license +21 -0
  50. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point/package.json +45 -0
  51. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/is-fullwidth-code-point/readme.md +39 -0
  52. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/string-width/index.js +37 -0
  53. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/string-width/license +21 -0
  54. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/string-width/package.json +56 -0
  55. package/examples/basic-event-handlers/node_modules/wrap-ansi/node_modules/string-width/readme.md +42 -0
  56. package/package.json +2 -2
  57. package/src/codegen/schema.js +15 -5
  58. package/src/codegen/schema.test.js +368 -0
  59. package/src/codegen/types/defaults.js +34 -0
  60. package/src/codegen/types/index.js +8 -1
  61. package/src/codegen/typescript.js +7 -11
  62. package/src/command-helpers/scaffold.js +66 -0
  63. package/src/command-helpers/version.js +1 -1
  64. package/src/command-helpers/version.test.js +1 -1
  65. package/src/commands/init.js +129 -92
  66. package/src/commands/test.js +210 -27
  67. package/src/protocols/ethereum/contract.js +22 -0
  68. package/src/protocols/ethereum/scaffold/manifest.js +32 -0
  69. package/src/protocols/ethereum/scaffold/mapping.js +76 -0
  70. package/src/protocols/ethereum/subgraph.js +0 -14
  71. package/src/protocols/index.js +94 -12
  72. package/src/protocols/near/contract.js +46 -0
  73. package/src/protocols/near/scaffold/manifest.js +16 -0
  74. package/src/protocols/near/scaffold/mapping.js +39 -0
  75. package/src/protocols/near/subgraph.js +1 -23
  76. package/src/{scaffold.test.js → scaffold/ethereum.test.js} +27 -19
  77. package/src/scaffold/index.js +149 -0
  78. package/src/scaffold/mapping.js +49 -0
  79. package/src/scaffold/near.test.js +89 -0
  80. package/src/scaffold/schema.js +62 -0
  81. package/src/subgraph.js +8 -0
  82. package/src/validation/contract.js +56 -0
  83. package/src/validation/index.js +2 -1
  84. package/src/validation/manifest.js +0 -29
  85. package/tests/cli/init/{abis → ethereum/abis}/Marketplace.json +0 -0
  86. package/tests/cli/init/{abis → ethereum/abis}/OverloadedElements.json +0 -0
  87. package/tests/cli/init/{abis → ethereum/abis}/SoloMargin.json +0 -0
  88. package/tests/cli/init/{from-contract-with-abi-and-structs.stderr → ethereum/from-contract-with-abi-and-structs.stderr} +1 -1
  89. package/tests/cli/init/{from-contract-with-abi-and-structs.stdout → ethereum/from-contract-with-abi-and-structs.stdout} +0 -0
  90. package/tests/cli/init/{from-contract-with-abi.stderr → ethereum/from-contract-with-abi.stderr} +1 -1
  91. package/tests/cli/init/{from-contract-with-abi.stdout → ethereum/from-contract-with-abi.stdout} +0 -0
  92. package/tests/cli/init/{from-contract-with-overloaded-elements.stderr → ethereum/from-contract-with-overloaded-elements.stderr} +1 -1
  93. package/tests/cli/init/{from-contract-with-overloaded-elements.stdout → ethereum/from-contract-with-overloaded-elements.stdout} +0 -0
  94. package/tests/cli/init/{from-contract.stderr → ethereum/from-contract.stderr} +1 -1
  95. package/tests/cli/init/{from-contract.stdout → ethereum/from-contract.stdout} +0 -0
  96. package/tests/cli/init/{from-example.stderr → ethereum/from-example.stderr} +0 -0
  97. package/tests/cli/init/{from-example.stdout → ethereum/from-example.stdout} +0 -0
  98. package/tests/cli/init/near/from-contract.stderr +12 -0
  99. package/tests/cli/init/near/from-contract.stdout +12 -0
  100. package/tests/cli/init.test.js +143 -112
  101. package/tests/cli/util.js +56 -41
  102. package/tests/cli/validation/near-is-valid/subgraph.yaml +1 -0
  103. package/examples/basic-event-handlers/node_modules/mocha/lib/reporters/base.js.orig +0 -498
  104. package/examples/basic-event-handlers/node_modules/node-fetch/lib/index.js +0 -1416
  105. package/src/scaffold.js +0 -364
@@ -1,1416 +0,0 @@
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
- const CLOSED = Symbol('closed');
11
-
12
- class Blob {
13
- constructor() {
14
- Object.defineProperty(this, Symbol.toStringTag, {
15
- value: 'Blob',
16
- writable: false,
17
- enumerable: false,
18
- configurable: true
19
- });
20
-
21
- this[CLOSED] = false;
22
- this[TYPE] = '';
23
-
24
- const blobParts = arguments[0];
25
- const options = arguments[1];
26
-
27
- const buffers = [];
28
-
29
- if (blobParts) {
30
- const a = blobParts;
31
- const length = Number(a.length);
32
- for (let i = 0; i < length; i++) {
33
- const element = a[i];
34
- let buffer;
35
- if (element instanceof Buffer) {
36
- buffer = element;
37
- } else if (ArrayBuffer.isView(element)) {
38
- buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);
39
- } else if (element instanceof ArrayBuffer) {
40
- buffer = Buffer.from(element);
41
- } else if (element instanceof Blob) {
42
- buffer = element[BUFFER];
43
- } else {
44
- buffer = Buffer.from(typeof element === 'string' ? element : String(element));
45
- }
46
- buffers.push(buffer);
47
- }
48
- }
49
-
50
- this[BUFFER] = Buffer.concat(buffers);
51
-
52
- let type = options && options.type !== undefined && String(options.type).toLowerCase();
53
- if (type && !/[^\u0020-\u007E]/.test(type)) {
54
- this[TYPE] = type;
55
- }
56
- }
57
- get size() {
58
- return this[CLOSED] ? 0 : this[BUFFER].length;
59
- }
60
- get type() {
61
- return this[TYPE];
62
- }
63
- get isClosed() {
64
- return this[CLOSED];
65
- }
66
- slice() {
67
- const size = this.size;
68
-
69
- const start = arguments[0];
70
- const end = arguments[1];
71
- let relativeStart, relativeEnd;
72
- if (start === undefined) {
73
- relativeStart = 0;
74
- } else if (start < 0) {
75
- relativeStart = Math.max(size + start, 0);
76
- } else {
77
- relativeStart = Math.min(start, size);
78
- }
79
- if (end === undefined) {
80
- relativeEnd = size;
81
- } else if (end < 0) {
82
- relativeEnd = Math.max(size + end, 0);
83
- } else {
84
- relativeEnd = Math.min(end, size);
85
- }
86
- const span = Math.max(relativeEnd - relativeStart, 0);
87
-
88
- const buffer = this[BUFFER];
89
- const slicedBuffer = buffer.slice(relativeStart, relativeStart + span);
90
- const blob = new Blob([], { type: arguments[2] });
91
- blob[BUFFER] = slicedBuffer;
92
- blob[CLOSED] = this[CLOSED];
93
- return blob;
94
- }
95
- close() {
96
- this[CLOSED] = true;
97
- }
98
- }
99
-
100
- Object.defineProperty(Blob.prototype, Symbol.toStringTag, {
101
- value: 'BlobPrototype',
102
- writable: false,
103
- enumerable: false,
104
- configurable: true
105
- });
106
-
107
- /**
108
- * fetch-error.js
109
- *
110
- * FetchError interface for operational errors
111
- */
112
-
113
- /**
114
- * Create FetchError instance
115
- *
116
- * @param String message Error message for human
117
- * @param String type Error type for machine
118
- * @param String systemError For Node.js system error
119
- * @return FetchError
120
- */
121
- function FetchError(message, type, systemError) {
122
- Error.call(this, message);
123
-
124
- this.message = message;
125
- this.type = type;
126
-
127
- // when err.type is `system`, err.code contains system error code
128
- if (systemError) {
129
- this.code = this.errno = systemError.code;
130
- }
131
-
132
- // hide custom error implementation details from end-users
133
- Error.captureStackTrace(this, this.constructor);
134
- }
135
-
136
- FetchError.prototype = Object.create(Error.prototype);
137
- FetchError.prototype.constructor = FetchError;
138
- FetchError.prototype.name = 'FetchError';
139
-
140
- /**
141
- * body.js
142
- *
143
- * Body interface provides common methods for Request and Response
144
- */
145
-
146
- const Stream = require('stream');
147
-
148
- var _require$1 = require('stream');
149
-
150
- const PassThrough$1 = _require$1.PassThrough;
151
-
152
-
153
- const DISTURBED = Symbol('disturbed');
154
-
155
- let convert;
156
- try {
157
- convert = require('encoding').convert;
158
- } catch (e) {}
159
-
160
- /**
161
- * Body class
162
- *
163
- * Cannot use ES6 class because Body must be called with .call().
164
- *
165
- * @param Stream body Readable stream
166
- * @param Object opts Response options
167
- * @return Void
168
- */
169
- function Body(body) {
170
- var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
171
- _ref$size = _ref.size;
172
-
173
- let size = _ref$size === undefined ? 0 : _ref$size;
174
- var _ref$timeout = _ref.timeout;
175
- let timeout = _ref$timeout === undefined ? 0 : _ref$timeout;
176
-
177
- if (body == null) {
178
- // body is undefined or null
179
- body = null;
180
- } else if (typeof body === 'string') {
181
- // body is string
182
- } else if (isURLSearchParams(body)) {
183
- // body is a URLSearchParams
184
- } else if (body instanceof Blob) {
185
- // body is blob
186
- } else if (Buffer.isBuffer(body)) {
187
- // body is buffer
188
- } else if (body instanceof Stream) {
189
- // body is stream
190
- } else {
191
- // none of the above
192
- // coerce to string
193
- body = String(body);
194
- }
195
- this.body = body;
196
- this[DISTURBED] = false;
197
- this.size = size;
198
- this.timeout = timeout;
199
- }
200
-
201
- Body.prototype = {
202
- get bodyUsed() {
203
- return this[DISTURBED];
204
- },
205
-
206
- /**
207
- * Decode response as ArrayBuffer
208
- *
209
- * @return Promise
210
- */
211
- arrayBuffer() {
212
- return consumeBody.call(this).then(function (buf) {
213
- return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
214
- });
215
- },
216
-
217
- /**
218
- * Return raw response as Blob
219
- *
220
- * @return Promise
221
- */
222
- blob() {
223
- let ct = this.headers && this.headers.get('content-type') || '';
224
- return consumeBody.call(this).then(function (buf) {
225
- return Object.assign(
226
- // Prevent copying
227
- new Blob([], {
228
- type: ct.toLowerCase()
229
- }), {
230
- [BUFFER]: buf
231
- });
232
- });
233
- },
234
-
235
- /**
236
- * Decode response as json
237
- *
238
- * @return Promise
239
- */
240
- json() {
241
- var _this = this;
242
-
243
- return consumeBody.call(this).then(function (buffer) {
244
- try {
245
- return JSON.parse(buffer.toString());
246
- } catch (err) {
247
- return Body.Promise.reject(new FetchError(`invalid json response body at ${_this.url} reason: ${err.message}`, 'invalid-json'));
248
- }
249
- });
250
- },
251
-
252
- /**
253
- * Decode response as text
254
- *
255
- * @return Promise
256
- */
257
- text() {
258
- return consumeBody.call(this).then(function (buffer) {
259
- return buffer.toString();
260
- });
261
- },
262
-
263
- /**
264
- * Decode response as buffer (non-spec api)
265
- *
266
- * @return Promise
267
- */
268
- buffer() {
269
- return consumeBody.call(this);
270
- },
271
-
272
- /**
273
- * Decode response as text, while automatically detecting the encoding and
274
- * trying to decode to UTF-8 (non-spec api)
275
- *
276
- * @return Promise
277
- */
278
- textConverted() {
279
- var _this2 = this;
280
-
281
- return consumeBody.call(this).then(function (buffer) {
282
- return convertBody(buffer, _this2.headers);
283
- });
284
- }
285
-
286
- };
287
-
288
- Body.mixIn = function (proto) {
289
- for (const name of Object.getOwnPropertyNames(Body.prototype)) {
290
- // istanbul ignore else: future proof
291
- if (!(name in proto)) {
292
- const desc = Object.getOwnPropertyDescriptor(Body.prototype, name);
293
- Object.defineProperty(proto, name, desc);
294
- }
295
- }
296
- };
297
-
298
- /**
299
- * Decode buffers into utf-8 string
300
- *
301
- * @return Promise
302
- */
303
- function consumeBody(body) {
304
- var _this3 = this;
305
-
306
- if (this[DISTURBED]) {
307
- return Body.Promise.reject(new Error(`body used already for: ${this.url}`));
308
- }
309
-
310
- this[DISTURBED] = true;
311
-
312
- // body is null
313
- if (this.body === null) {
314
- return Body.Promise.resolve(Buffer.alloc(0));
315
- }
316
-
317
- // body is string
318
- if (typeof this.body === 'string') {
319
- return Body.Promise.resolve(Buffer.from(this.body));
320
- }
321
-
322
- // body is blob
323
- if (this.body instanceof Blob) {
324
- return Body.Promise.resolve(this.body[BUFFER]);
325
- }
326
-
327
- // body is buffer
328
- if (Buffer.isBuffer(this.body)) {
329
- return Body.Promise.resolve(this.body);
330
- }
331
-
332
- // istanbul ignore if: should never happen
333
- if (!(this.body instanceof Stream)) {
334
- return Body.Promise.resolve(Buffer.alloc(0));
335
- }
336
-
337
- // body is stream
338
- // get ready to actually consume the body
339
- let accum = [];
340
- let accumBytes = 0;
341
- let abort = false;
342
-
343
- return new Body.Promise(function (resolve, reject) {
344
- let resTimeout;
345
-
346
- // allow timeout on slow response body
347
- if (_this3.timeout) {
348
- resTimeout = setTimeout(function () {
349
- abort = true;
350
- reject(new FetchError(`Response timeout while trying to fetch ${_this3.url} (over ${_this3.timeout}ms)`, 'body-timeout'));
351
- }, _this3.timeout);
352
- }
353
-
354
- // handle stream error, such as incorrect content-encoding
355
- _this3.body.on('error', function (err) {
356
- reject(new FetchError(`Invalid response body while trying to fetch ${_this3.url}: ${err.message}`, 'system', err));
357
- });
358
-
359
- _this3.body.on('data', function (chunk) {
360
- if (abort || chunk === null) {
361
- return;
362
- }
363
-
364
- if (_this3.size && accumBytes + chunk.length > _this3.size) {
365
- abort = true;
366
- reject(new FetchError(`content size at ${_this3.url} over limit: ${_this3.size}`, 'max-size'));
367
- return;
368
- }
369
-
370
- accumBytes += chunk.length;
371
- accum.push(chunk);
372
- });
373
-
374
- _this3.body.on('end', function () {
375
- if (abort) {
376
- return;
377
- }
378
-
379
- clearTimeout(resTimeout);
380
- resolve(Buffer.concat(accum));
381
- });
382
- });
383
- }
384
-
385
- /**
386
- * Detect buffer encoding and convert to target encoding
387
- * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding
388
- *
389
- * @param Buffer buffer Incoming buffer
390
- * @param String encoding Target encoding
391
- * @return String
392
- */
393
- function convertBody(buffer, headers) {
394
- if (typeof convert !== 'function') {
395
- throw new Error('The package `encoding` must be installed to use the textConverted() function');
396
- }
397
-
398
- const ct = headers.get('content-type');
399
- let charset = 'utf-8';
400
- let res, str;
401
-
402
- // header
403
- if (ct) {
404
- res = /charset=([^;]*)/i.exec(ct);
405
- }
406
-
407
- // no charset in content type, peek at response body for at most 1024 bytes
408
- str = buffer.slice(0, 1024).toString();
409
-
410
- // html5
411
- if (!res && str) {
412
- res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str);
413
- }
414
-
415
- // html4
416
- if (!res && str) {
417
- res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str);
418
-
419
- if (res) {
420
- res = /charset=(.*)/i.exec(res.pop());
421
- }
422
- }
423
-
424
- // xml
425
- if (!res && str) {
426
- res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str);
427
- }
428
-
429
- // found charset
430
- if (res) {
431
- charset = res.pop();
432
-
433
- // prevent decode issues when sites use incorrect encoding
434
- // ref: https://hsivonen.fi/encoding-menu/
435
- if (charset === 'gb2312' || charset === 'gbk') {
436
- charset = 'gb18030';
437
- }
438
- }
439
-
440
- // turn raw buffers into a single utf-8 buffer
441
- return convert(buffer, 'UTF-8', charset).toString();
442
- }
443
-
444
- /**
445
- * Detect a URLSearchParams object
446
- * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143
447
- *
448
- * @param Object obj Object to detect by type or brand
449
- * @return String
450
- */
451
- function isURLSearchParams(obj) {
452
- // Duck-typing as a necessary condition.
453
- 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') {
454
- return false;
455
- }
456
-
457
- // Brand-checking and more duck-typing as optional condition.
458
- return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function';
459
- }
460
-
461
- /**
462
- * Clone body given Res/Req instance
463
- *
464
- * @param Mixed instance Response or Request instance
465
- * @return Mixed
466
- */
467
- function clone(instance) {
468
- let p1, p2;
469
- let body = instance.body;
470
-
471
- // don't allow cloning a used body
472
- if (instance.bodyUsed) {
473
- throw new Error('cannot clone body after it is used');
474
- }
475
-
476
- // check that body is a stream and not form-data object
477
- // note: we can't clone the form-data object without having it as a dependency
478
- if (body instanceof Stream && typeof body.getBoundary !== 'function') {
479
- // tee instance body
480
- p1 = new PassThrough$1();
481
- p2 = new PassThrough$1();
482
- body.pipe(p1);
483
- body.pipe(p2);
484
- // set instance body to teed body and return the other teed body
485
- instance.body = p1;
486
- body = p2;
487
- }
488
-
489
- return body;
490
- }
491
-
492
- /**
493
- * Performs the operation "extract a `Content-Type` value from |object|" as
494
- * specified in the specification:
495
- * https://fetch.spec.whatwg.org/#concept-bodyinit-extract
496
- *
497
- * This function assumes that instance.body is present and non-null.
498
- *
499
- * @param Mixed instance Response or Request instance
500
- */
501
- function extractContentType(instance) {
502
- const body = instance.body;
503
-
504
- // istanbul ignore if: Currently, because of a guard in Request, body
505
- // can never be null. Included here for completeness.
506
-
507
- if (body === null) {
508
- // body is null
509
- return null;
510
- } else if (typeof body === 'string') {
511
- // body is string
512
- return 'text/plain;charset=UTF-8';
513
- } else if (isURLSearchParams(body)) {
514
- // body is a URLSearchParams
515
- return 'application/x-www-form-urlencoded;charset=UTF-8';
516
- } else if (body instanceof Blob) {
517
- // body is blob
518
- return body.type || null;
519
- } else if (Buffer.isBuffer(body)) {
520
- // body is buffer
521
- return null;
522
- } else if (typeof body.getBoundary === 'function') {
523
- // detect form data input from form-data module
524
- return `multipart/form-data;boundary=${body.getBoundary()}`;
525
- } else {
526
- // body is stream
527
- // can't really do much about this
528
- return null;
529
- }
530
- }
531
-
532
- function getTotalBytes(instance) {
533
- const body = instance.body;
534
-
535
- // istanbul ignore if: included for completion
536
-
537
- if (body === null) {
538
- // body is null
539
- return 0;
540
- } else if (typeof body === 'string') {
541
- // body is string
542
- return Buffer.byteLength(body);
543
- } else if (isURLSearchParams(body)) {
544
- // body is URLSearchParams
545
- return Buffer.byteLength(String(body));
546
- } else if (body instanceof Blob) {
547
- // body is blob
548
- return body.size;
549
- } else if (Buffer.isBuffer(body)) {
550
- // body is buffer
551
- return body.length;
552
- } else if (body && typeof body.getLengthSync === 'function') {
553
- // detect form data input from form-data module
554
- if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x
555
- body.hasKnownLength && body.hasKnownLength()) {
556
- // 2.x
557
- return body.getLengthSync();
558
- }
559
- return null;
560
- } else {
561
- // body is stream
562
- // can't really do much about this
563
- return null;
564
- }
565
- }
566
-
567
- function writeToStream(dest, instance) {
568
- const body = instance.body;
569
-
570
-
571
- if (body === null) {
572
- // body is null
573
- dest.end();
574
- } else if (typeof body === 'string') {
575
- // body is string
576
- dest.write(body);
577
- dest.end();
578
- } else if (isURLSearchParams(body)) {
579
- // body is URLSearchParams
580
- dest.write(Buffer.from(String(body)));
581
- dest.end();
582
- } else if (body instanceof Blob) {
583
- // body is blob
584
- dest.write(body[BUFFER]);
585
- dest.end();
586
- } else if (Buffer.isBuffer(body)) {
587
- // body is buffer
588
- dest.write(body);
589
- dest.end();
590
- } else {
591
- // body is stream
592
- body.pipe(dest);
593
- }
594
- }
595
-
596
- // expose Promise
597
- Body.Promise = global.Promise;
598
-
599
- /**
600
- * A set of utilities borrowed from Node.js' _http_common.js
601
- */
602
-
603
- /**
604
- * Verifies that the given val is a valid HTTP token
605
- * per the rules defined in RFC 7230
606
- * See https://tools.ietf.org/html/rfc7230#section-3.2.6
607
- *
608
- * Allowed characters in an HTTP token:
609
- * ^_`a-z 94-122
610
- * A-Z 65-90
611
- * - 45
612
- * 0-9 48-57
613
- * ! 33
614
- * #$%&' 35-39
615
- * *+ 42-43
616
- * . 46
617
- * | 124
618
- * ~ 126
619
- *
620
- * This implementation of checkIsHttpToken() loops over the string instead of
621
- * using a regular expression since the former is up to 180% faster with v8 4.9
622
- * depending on the string length (the shorter the string, the larger the
623
- * performance difference)
624
- *
625
- * Additionally, checkIsHttpToken() is currently designed to be inlinable by v8,
626
- * so take care when making changes to the implementation so that the source
627
- * code size does not exceed v8's default max_inlined_source_size setting.
628
- **/
629
- /* istanbul ignore next */
630
- function isValidTokenChar(ch) {
631
- if (ch >= 94 && ch <= 122) return true;
632
- if (ch >= 65 && ch <= 90) return true;
633
- if (ch === 45) return true;
634
- if (ch >= 48 && ch <= 57) return true;
635
- if (ch === 34 || ch === 40 || ch === 41 || ch === 44) return false;
636
- if (ch >= 33 && ch <= 46) return true;
637
- if (ch === 124 || ch === 126) return true;
638
- return false;
639
- }
640
- /* istanbul ignore next */
641
- function checkIsHttpToken(val) {
642
- if (typeof val !== 'string' || val.length === 0) return false;
643
- if (!isValidTokenChar(val.charCodeAt(0))) return false;
644
- const len = val.length;
645
- if (len > 1) {
646
- if (!isValidTokenChar(val.charCodeAt(1))) return false;
647
- if (len > 2) {
648
- if (!isValidTokenChar(val.charCodeAt(2))) return false;
649
- if (len > 3) {
650
- if (!isValidTokenChar(val.charCodeAt(3))) return false;
651
- for (var i = 4; i < len; i++) {
652
- if (!isValidTokenChar(val.charCodeAt(i))) return false;
653
- }
654
- }
655
- }
656
- }
657
- return true;
658
- }
659
- /**
660
- * True if val contains an invalid field-vchar
661
- * field-value = *( field-content / obs-fold )
662
- * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
663
- * field-vchar = VCHAR / obs-text
664
- *
665
- * checkInvalidHeaderChar() is currently designed to be inlinable by v8,
666
- * so take care when making changes to the implementation so that the source
667
- * code size does not exceed v8's default max_inlined_source_size setting.
668
- **/
669
- /* istanbul ignore next */
670
- function checkInvalidHeaderChar(val) {
671
- val += '';
672
- if (val.length < 1) return false;
673
- var c = val.charCodeAt(0);
674
- if (c <= 31 && c !== 9 || c > 255 || c === 127) return true;
675
- if (val.length < 2) return false;
676
- c = val.charCodeAt(1);
677
- if (c <= 31 && c !== 9 || c > 255 || c === 127) return true;
678
- if (val.length < 3) return false;
679
- c = val.charCodeAt(2);
680
- if (c <= 31 && c !== 9 || c > 255 || c === 127) return true;
681
- for (var i = 3; i < val.length; ++i) {
682
- c = val.charCodeAt(i);
683
- if (c <= 31 && c !== 9 || c > 255 || c === 127) return true;
684
- }
685
- return false;
686
- }
687
-
688
- /**
689
- * headers.js
690
- *
691
- * Headers class offers convenient helpers
692
- */
693
-
694
- function sanitizeName(name) {
695
- name += '';
696
- if (!checkIsHttpToken(name)) {
697
- throw new TypeError(`${name} is not a legal HTTP header name`);
698
- }
699
- return name.toLowerCase();
700
- }
701
-
702
- function sanitizeValue(value) {
703
- value += '';
704
- if (checkInvalidHeaderChar(value)) {
705
- throw new TypeError(`${value} is not a legal HTTP header value`);
706
- }
707
- return value;
708
- }
709
-
710
- const MAP = Symbol('map');
711
- class Headers {
712
- /**
713
- * Headers class
714
- *
715
- * @param Object headers Response headers
716
- * @return Void
717
- */
718
- constructor() {
719
- let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
720
-
721
- this[MAP] = Object.create(null);
722
-
723
- if (init instanceof Headers) {
724
- const rawHeaders = init.raw();
725
- const headerNames = Object.keys(rawHeaders);
726
-
727
- for (const headerName of headerNames) {
728
- for (const value of rawHeaders[headerName]) {
729
- this.append(headerName, value);
730
- }
731
- }
732
-
733
- return;
734
- }
735
-
736
- // We don't worry about converting prop to ByteString here as append()
737
- // will handle it.
738
- if (init == null) {
739
- // no op
740
- } else if (typeof init === 'object') {
741
- const method = init[Symbol.iterator];
742
- if (method != null) {
743
- if (typeof method !== 'function') {
744
- throw new TypeError('Header pairs must be iterable');
745
- }
746
-
747
- // sequence<sequence<ByteString>>
748
- // Note: per spec we have to first exhaust the lists then process them
749
- const pairs = [];
750
- for (const pair of init) {
751
- if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') {
752
- throw new TypeError('Each header pair must be iterable');
753
- }
754
- pairs.push(Array.from(pair));
755
- }
756
-
757
- for (const pair of pairs) {
758
- if (pair.length !== 2) {
759
- throw new TypeError('Each header pair must be a name/value tuple');
760
- }
761
- this.append(pair[0], pair[1]);
762
- }
763
- } else {
764
- // record<ByteString, ByteString>
765
- for (const key of Object.keys(init)) {
766
- const value = init[key];
767
- this.append(key, value);
768
- }
769
- }
770
- } else {
771
- throw new TypeError('Provided initializer must be an object');
772
- }
773
-
774
- Object.defineProperty(this, Symbol.toStringTag, {
775
- value: 'Headers',
776
- writable: false,
777
- enumerable: false,
778
- configurable: true
779
- });
780
- }
781
-
782
- /**
783
- * Return first header value given name
784
- *
785
- * @param String name Header name
786
- * @return Mixed
787
- */
788
- get(name) {
789
- const list = this[MAP][sanitizeName(name)];
790
- if (!list) {
791
- return null;
792
- }
793
-
794
- return list.join(', ');
795
- }
796
-
797
- /**
798
- * Iterate over all headers
799
- *
800
- * @param Function callback Executed for each item with parameters (value, name, thisArg)
801
- * @param Boolean thisArg `this` context for callback function
802
- * @return Void
803
- */
804
- forEach(callback) {
805
- let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
806
-
807
- let pairs = getHeaderPairs(this);
808
- let i = 0;
809
- while (i < pairs.length) {
810
- var _pairs$i = pairs[i];
811
- const name = _pairs$i[0],
812
- value = _pairs$i[1];
813
-
814
- callback.call(thisArg, value, name, this);
815
- pairs = getHeaderPairs(this);
816
- i++;
817
- }
818
- }
819
-
820
- /**
821
- * Overwrite header values given name
822
- *
823
- * @param String name Header name
824
- * @param String value Header value
825
- * @return Void
826
- */
827
- set(name, value) {
828
- this[MAP][sanitizeName(name)] = [sanitizeValue(value)];
829
- }
830
-
831
- /**
832
- * Append a value onto existing header
833
- *
834
- * @param String name Header name
835
- * @param String value Header value
836
- * @return Void
837
- */
838
- append(name, value) {
839
- if (!this.has(name)) {
840
- this.set(name, value);
841
- return;
842
- }
843
-
844
- this[MAP][sanitizeName(name)].push(sanitizeValue(value));
845
- }
846
-
847
- /**
848
- * Check for header name existence
849
- *
850
- * @param String name Header name
851
- * @return Boolean
852
- */
853
- has(name) {
854
- return !!this[MAP][sanitizeName(name)];
855
- }
856
-
857
- /**
858
- * Delete all header values given name
859
- *
860
- * @param String name Header name
861
- * @return Void
862
- */
863
- delete(name) {
864
- delete this[MAP][sanitizeName(name)];
865
- }
866
-
867
- /**
868
- * Return raw headers (non-spec api)
869
- *
870
- * @return Object
871
- */
872
- raw() {
873
- return this[MAP];
874
- }
875
-
876
- /**
877
- * Get an iterator on keys.
878
- *
879
- * @return Iterator
880
- */
881
- keys() {
882
- return createHeadersIterator(this, 'key');
883
- }
884
-
885
- /**
886
- * Get an iterator on values.
887
- *
888
- * @return Iterator
889
- */
890
- values() {
891
- return createHeadersIterator(this, 'value');
892
- }
893
-
894
- /**
895
- * Get an iterator on entries.
896
- *
897
- * This is the default iterator of the Headers object.
898
- *
899
- * @return Iterator
900
- */
901
- [Symbol.iterator]() {
902
- return createHeadersIterator(this, 'key+value');
903
- }
904
- }
905
- Headers.prototype.entries = Headers.prototype[Symbol.iterator];
906
-
907
- Object.defineProperty(Headers.prototype, Symbol.toStringTag, {
908
- value: 'HeadersPrototype',
909
- writable: false,
910
- enumerable: false,
911
- configurable: true
912
- });
913
-
914
- function getHeaderPairs(headers, kind) {
915
- const keys = Object.keys(headers[MAP]).sort();
916
- return keys.map(kind === 'key' ? function (k) {
917
- return [k];
918
- } : function (k) {
919
- return [k, headers.get(k)];
920
- });
921
- }
922
-
923
- const INTERNAL = Symbol('internal');
924
-
925
- function createHeadersIterator(target, kind) {
926
- const iterator = Object.create(HeadersIteratorPrototype);
927
- iterator[INTERNAL] = {
928
- target,
929
- kind,
930
- index: 0
931
- };
932
- return iterator;
933
- }
934
-
935
- const HeadersIteratorPrototype = Object.setPrototypeOf({
936
- next() {
937
- // istanbul ignore if
938
- if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) {
939
- throw new TypeError('Value of `this` is not a HeadersIterator');
940
- }
941
-
942
- var _INTERNAL = this[INTERNAL];
943
- const target = _INTERNAL.target,
944
- kind = _INTERNAL.kind,
945
- index = _INTERNAL.index;
946
-
947
- const values = getHeaderPairs(target, kind);
948
- const len = values.length;
949
- if (index >= len) {
950
- return {
951
- value: undefined,
952
- done: true
953
- };
954
- }
955
-
956
- const pair = values[index];
957
- this[INTERNAL].index = index + 1;
958
-
959
- let result;
960
- if (kind === 'key') {
961
- result = pair[0];
962
- } else if (kind === 'value') {
963
- result = pair[1];
964
- } else {
965
- result = pair;
966
- }
967
-
968
- return {
969
- value: result,
970
- done: false
971
- };
972
- }
973
- }, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())));
974
-
975
- Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, {
976
- value: 'HeadersIterator',
977
- writable: false,
978
- enumerable: false,
979
- configurable: true
980
- });
981
-
982
- /**
983
- * response.js
984
- *
985
- * Response class provides content decoding
986
- */
987
-
988
- var _require$2 = require('http');
989
-
990
- const STATUS_CODES = _require$2.STATUS_CODES;
991
-
992
- /**
993
- * Response class
994
- *
995
- * @param Stream body Readable stream
996
- * @param Object opts Response options
997
- * @return Void
998
- */
999
-
1000
- class Response {
1001
- constructor() {
1002
- let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1003
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1004
-
1005
- Body.call(this, body, opts);
1006
-
1007
- this.url = opts.url;
1008
- this.status = opts.status || 200;
1009
- this.statusText = opts.statusText || STATUS_CODES[this.status];
1010
-
1011
- this.headers = new Headers(opts.headers);
1012
-
1013
- Object.defineProperty(this, Symbol.toStringTag, {
1014
- value: 'Response',
1015
- writable: false,
1016
- enumerable: false,
1017
- configurable: true
1018
- });
1019
- }
1020
-
1021
- /**
1022
- * Convenience property representing if the request ended normally
1023
- */
1024
- get ok() {
1025
- return this.status >= 200 && this.status < 300;
1026
- }
1027
-
1028
- /**
1029
- * Clone this response
1030
- *
1031
- * @return Response
1032
- */
1033
- clone() {
1034
-
1035
- return new Response(clone(this), {
1036
- url: this.url,
1037
- status: this.status,
1038
- statusText: this.statusText,
1039
- headers: this.headers,
1040
- ok: this.ok
1041
- });
1042
- }
1043
- }
1044
-
1045
- Body.mixIn(Response.prototype);
1046
-
1047
- Object.defineProperty(Response.prototype, Symbol.toStringTag, {
1048
- value: 'ResponsePrototype',
1049
- writable: false,
1050
- enumerable: false,
1051
- configurable: true
1052
- });
1053
-
1054
- /**
1055
- * request.js
1056
- *
1057
- * Request class contains server only options
1058
- */
1059
-
1060
- var _require$3 = require('url');
1061
-
1062
- const format_url = _require$3.format;
1063
- const parse_url = _require$3.parse;
1064
-
1065
-
1066
- const PARSED_URL = Symbol('url');
1067
-
1068
- /**
1069
- * Request class
1070
- *
1071
- * @param Mixed input Url or Request instance
1072
- * @param Object init Custom options
1073
- * @return Void
1074
- */
1075
- class Request {
1076
- constructor(input) {
1077
- let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1078
-
1079
- let parsedURL;
1080
-
1081
- // normalize input
1082
- if (!(input instanceof Request)) {
1083
- if (input && input.href) {
1084
- // in order to support Node.js' Url objects; though WHATWG's URL objects
1085
- // will fall into this branch also (since their `toString()` will return
1086
- // `href` property anyway)
1087
- parsedURL = parse_url(input.href);
1088
- } else {
1089
- // coerce input to a string before attempting to parse
1090
- parsedURL = parse_url(`${input}`);
1091
- }
1092
- input = {};
1093
- } else {
1094
- parsedURL = parse_url(input.url);
1095
- }
1096
-
1097
- let method = init.method || input.method || 'GET';
1098
-
1099
- if ((init.body != null || input instanceof Request && input.body !== null) && (method === 'GET' || method === 'HEAD')) {
1100
- throw new TypeError('Request with GET/HEAD method cannot have body');
1101
- }
1102
-
1103
- let inputBody = init.body != null ? init.body : input instanceof Request && input.body !== null ? clone(input) : null;
1104
-
1105
- Body.call(this, inputBody, {
1106
- timeout: init.timeout || input.timeout || 0,
1107
- size: init.size || input.size || 0
1108
- });
1109
-
1110
- // fetch spec options
1111
- this.method = method.toUpperCase();
1112
- this.redirect = init.redirect || input.redirect || 'follow';
1113
- this.headers = new Headers(init.headers || input.headers || {});
1114
-
1115
- if (init.body != null) {
1116
- const contentType = extractContentType(this);
1117
- if (contentType !== null && !this.headers.has('Content-Type')) {
1118
- this.headers.append('Content-Type', contentType);
1119
- }
1120
- }
1121
-
1122
- // server only options
1123
- this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20;
1124
- this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true;
1125
- this.counter = init.counter || input.counter || 0;
1126
- this.agent = init.agent || input.agent;
1127
-
1128
- this[PARSED_URL] = parsedURL;
1129
- Object.defineProperty(this, Symbol.toStringTag, {
1130
- value: 'Request',
1131
- writable: false,
1132
- enumerable: false,
1133
- configurable: true
1134
- });
1135
- }
1136
-
1137
- get url() {
1138
- return format_url(this[PARSED_URL]);
1139
- }
1140
-
1141
- /**
1142
- * Clone this request
1143
- *
1144
- * @return Request
1145
- */
1146
- clone() {
1147
- return new Request(this);
1148
- }
1149
- }
1150
-
1151
- Body.mixIn(Request.prototype);
1152
-
1153
- Object.defineProperty(Request.prototype, Symbol.toStringTag, {
1154
- value: 'RequestPrototype',
1155
- writable: false,
1156
- enumerable: false,
1157
- configurable: true
1158
- });
1159
-
1160
- function getNodeRequestOptions(request) {
1161
- const parsedURL = request[PARSED_URL];
1162
- const headers = new Headers(request.headers);
1163
-
1164
- // fetch step 3
1165
- if (!headers.has('Accept')) {
1166
- headers.set('Accept', '*/*');
1167
- }
1168
-
1169
- // Basic fetch
1170
- if (!parsedURL.protocol || !parsedURL.hostname) {
1171
- throw new TypeError('Only absolute URLs are supported');
1172
- }
1173
-
1174
- if (!/^https?:$/.test(parsedURL.protocol)) {
1175
- throw new TypeError('Only HTTP(S) protocols are supported');
1176
- }
1177
-
1178
- // HTTP-network-or-cache fetch steps 5-9
1179
- let contentLengthValue = null;
1180
- if (request.body == null && /^(POST|PUT)$/i.test(request.method)) {
1181
- contentLengthValue = '0';
1182
- }
1183
- if (request.body != null) {
1184
- const totalBytes = getTotalBytes(request);
1185
- if (typeof totalBytes === 'number') {
1186
- contentLengthValue = String(totalBytes);
1187
- }
1188
- }
1189
- if (contentLengthValue) {
1190
- headers.set('Content-Length', contentLengthValue);
1191
- }
1192
-
1193
- // HTTP-network-or-cache fetch step 12
1194
- if (!headers.has('User-Agent')) {
1195
- headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)');
1196
- }
1197
-
1198
- // HTTP-network-or-cache fetch step 16
1199
- if (request.compress) {
1200
- headers.set('Accept-Encoding', 'gzip,deflate');
1201
- }
1202
- if (!headers.has('Connection') && !request.agent) {
1203
- headers.set('Connection', 'close');
1204
- }
1205
-
1206
- // HTTP-network fetch step 4
1207
- // chunked encoding is handled by Node.js
1208
-
1209
- return Object.assign({}, parsedURL, {
1210
- method: request.method,
1211
- headers: headers.raw(),
1212
- agent: request.agent
1213
- });
1214
- }
1215
-
1216
- /**
1217
- * index.js
1218
- *
1219
- * a request API compatible with window.fetch
1220
- */
1221
-
1222
- const http = require('http');
1223
- const https = require('https');
1224
-
1225
- var _require = require('stream');
1226
-
1227
- const PassThrough = _require.PassThrough;
1228
-
1229
- var _require2 = require('url');
1230
-
1231
- const resolve_url = _require2.resolve;
1232
-
1233
- const zlib = require('zlib');
1234
-
1235
- /**
1236
- * Fetch function
1237
- *
1238
- * @param Mixed url Absolute url or Request instance
1239
- * @param Object opts Fetch options
1240
- * @return Promise
1241
- */
1242
- function fetch(url, opts) {
1243
-
1244
- // allow custom promise
1245
- if (!fetch.Promise) {
1246
- throw new Error('native promise missing, set fetch.Promise to your favorite alternative');
1247
- }
1248
-
1249
- Body.Promise = fetch.Promise;
1250
-
1251
- // wrap http.request into fetch
1252
- return new fetch.Promise(function (resolve, reject) {
1253
- // build request object
1254
- const request = new Request(url, opts);
1255
- const options = getNodeRequestOptions(request);
1256
-
1257
- const send = (options.protocol === 'https:' ? https : http).request;
1258
-
1259
- // http.request only support string as host header, this hack make custom host header possible
1260
- if (options.headers.host) {
1261
- options.headers.host = options.headers.host[0];
1262
- }
1263
-
1264
- // send request
1265
- const req = send(options);
1266
- let reqTimeout;
1267
-
1268
- if (request.timeout) {
1269
- req.once('socket', function (socket) {
1270
- reqTimeout = setTimeout(function () {
1271
- req.abort();
1272
- reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout'));
1273
- }, request.timeout);
1274
- });
1275
- }
1276
-
1277
- req.on('error', function (err) {
1278
- clearTimeout(reqTimeout);
1279
- reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err));
1280
- });
1281
-
1282
- req.on('response', function (res) {
1283
- clearTimeout(reqTimeout);
1284
-
1285
- // handle redirect
1286
- if (fetch.isRedirect(res.statusCode) && request.redirect !== 'manual') {
1287
- if (request.redirect === 'error') {
1288
- reject(new FetchError(`redirect mode is set to error: ${request.url}`, 'no-redirect'));
1289
- return;
1290
- }
1291
-
1292
- if (request.counter >= request.follow) {
1293
- reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect'));
1294
- return;
1295
- }
1296
-
1297
- if (!res.headers.location) {
1298
- reject(new FetchError(`redirect location header missing at: ${request.url}`, 'invalid-redirect'));
1299
- return;
1300
- }
1301
-
1302
- // per fetch spec, for POST request with 301/302 response, or any request with 303 response, use GET when following redirect
1303
- if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') {
1304
- request.method = 'GET';
1305
- request.body = null;
1306
- request.headers.delete('content-length');
1307
- }
1308
-
1309
- request.counter++;
1310
-
1311
- resolve(fetch(resolve_url(request.url, res.headers.location), request));
1312
- return;
1313
- }
1314
-
1315
- // normalize location header for manual redirect mode
1316
- const headers = new Headers();
1317
- for (const name of Object.keys(res.headers)) {
1318
- if (Array.isArray(res.headers[name])) {
1319
- for (const val of res.headers[name]) {
1320
- headers.append(name, val);
1321
- }
1322
- } else {
1323
- headers.append(name, res.headers[name]);
1324
- }
1325
- }
1326
- if (request.redirect === 'manual' && headers.has('location')) {
1327
- headers.set('location', resolve_url(request.url, headers.get('location')));
1328
- }
1329
-
1330
- // prepare response
1331
- let body = res.pipe(new PassThrough());
1332
- const response_options = {
1333
- url: request.url,
1334
- status: res.statusCode,
1335
- statusText: res.statusMessage,
1336
- headers: headers,
1337
- size: request.size,
1338
- timeout: request.timeout
1339
- };
1340
-
1341
- // HTTP-network fetch step 16.1.2
1342
- const codings = headers.get('Content-Encoding');
1343
-
1344
- // HTTP-network fetch step 16.1.3: handle content codings
1345
-
1346
- // in following scenarios we ignore compression support
1347
- // 1. compression support is disabled
1348
- // 2. HEAD request
1349
- // 3. no Content-Encoding header
1350
- // 4. no content response (204)
1351
- // 5. content not modified response (304)
1352
- if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) {
1353
- resolve(new Response(body, response_options));
1354
- return;
1355
- }
1356
-
1357
- // For Node v6+
1358
- // Be less strict when decoding compressed responses, since sometimes
1359
- // servers send slightly invalid responses that are still accepted
1360
- // by common browsers.
1361
- // Always using Z_SYNC_FLUSH is what cURL does.
1362
- const zlibOptions = {
1363
- flush: zlib.Z_SYNC_FLUSH,
1364
- finishFlush: zlib.Z_SYNC_FLUSH
1365
- };
1366
-
1367
- // for gzip
1368
- if (codings == 'gzip' || codings == 'x-gzip') {
1369
- body = body.pipe(zlib.createGunzip(zlibOptions));
1370
- resolve(new Response(body, response_options));
1371
- return;
1372
- }
1373
-
1374
- // for deflate
1375
- if (codings == 'deflate' || codings == 'x-deflate') {
1376
- // handle the infamous raw deflate response from old servers
1377
- // a hack for old IIS and Apache servers
1378
- const raw = res.pipe(new PassThrough());
1379
- raw.once('data', function (chunk) {
1380
- // see http://stackoverflow.com/questions/37519828
1381
- if ((chunk[0] & 0x0F) === 0x08) {
1382
- body = body.pipe(zlib.createInflate());
1383
- } else {
1384
- body = body.pipe(zlib.createInflateRaw());
1385
- }
1386
- resolve(new Response(body, response_options));
1387
- });
1388
- return;
1389
- }
1390
-
1391
- // otherwise, use response as-is
1392
- resolve(new Response(body, response_options));
1393
- });
1394
-
1395
- writeToStream(req, request);
1396
- });
1397
- }
1398
-
1399
- /**
1400
- * Redirect code matching
1401
- *
1402
- * @param Number code Status code
1403
- * @return Boolean
1404
- */
1405
- fetch.isRedirect = function (code) {
1406
- return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
1407
- };
1408
-
1409
- // expose Promise
1410
- fetch.Promise = global.Promise;
1411
-
1412
- module.exports = exports = fetch;
1413
- exports.Headers = Headers;
1414
- exports.Request = Request;
1415
- exports.Response = Response;
1416
- exports.FetchError = FetchError;