-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstream.js
87 lines (76 loc) · 2.13 KB
/
stream.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use strict';
const {Duplex, PassThrough} = require('stream');
const io = require('./main');
const requestHasNoBody = {GET: 1, HEAD: 1, OPTIONS: 1, DELETE: 1},
responseHasNoBody = {HEAD: 1, OPTIONS: 1};
class IO extends Duplex {
constructor(options, streamOptions) {
super(streamOptions);
this.meta = null;
if (typeof options == 'string') {
options = {url: options, method: 'GET'};
} else {
options = Object.create(options);
options.method = (options.method && options.method.toUpperCase()) || 'GET';
}
options.responseType = '$tream';
options.returnXHR = true;
if (requestHasNoBody[options.method] === 1 || 'data' in options) {
this._write = (_1, _2, callback) => callback(null);
this._final = callback => callback(null); // unavailable in Node 6
} else {
this.input = options.data = new PassThrough();
// this.on('finish', () => this.input.end(null, null)); // for Node 6
}
io(options)
.then(xhr => {
this.meta = xhr;
this.output = xhr.response;
this.output.on('data', chunk => !this.push(chunk) && this.output.pause());
this.output.on('end', () => this.push(null));
if (responseHasNoBody[options.method] === 1) {
this.resume();
}
})
.catch(e => this.emit('error', e));
}
getData() {
return io.getData(this.meta);
}
getHeaders() {
return io.getHeaders(this.meta);
}
_write(chunk, encoding, callback) {
let error = null;
try {
this.input.write(chunk, encoding, e => callback(e || error));
} catch (e) {
error = e;
}
}
_final(callback) { // unavailable in Node 6
let error = null;
try {
this.input.end(null, null, e => callback(e || error));
} catch (e) {
error = e;
}
}
_read() {
this.output && this.output.resume();
}
}
const mod = {IO};
const makeVerb = verb => (url, data) => {
const options = typeof url == 'string' ? {url: url} : Object.create(url);
options.method = verb;
if (data) {
options.data = data;
}
return new IO(options);
};
['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].forEach(verb => {
mod[verb.toLowerCase()] = makeVerb(verb);
});
mod.del = mod.remove = mod['delete']; // alias for simplicity
module.exports = mod;