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
|
append(name, value, filename = '') {
const {
data, dashDash, boundary, CRLF, indices,
} = this;
data.splice(...(data.length ? [-2, 1] : [0, 0, dashDash, boundary, CRLF]));
indices.push([name, data.push(...this.formed(name, value, filename)) - 1]);
data.push(CRLF, dashDash, boundary, dashDash, CRLF);
return this;
}
formed(name, value, filename = '') {
const { mimeTypes, CRLF, EMPTY } = this;
const isBufferOrStream = Buffer.isBuffer(value) || (value instanceof ReadStream);
return [
Buffer.from(`Content-Disposition: form-data; name="${name}"${filename && isBufferOrStream ? `; filename="${filename}"` : ''}`),
CRLF,
...(
filename || isBufferOrStream
? [Buffer.from(`Content-Type: ${mimeTypes[extname(filename).substring(1).toLowerCase()] || 'application/octet-stream'}`), CRLF]
: [EMPTY, EMPTY]
),
CRLF,
isBufferOrStream ? value : Buffer.from(String(value)),
];
}
set(name, value, filename = '') {
if (this.has(name)) {
this.indices.filter(([field]) => field === name).forEach(([field, index]) => {
this.data.splice(index - 5, 6, ...this.formed(field, value, filename));
});
} else {
this.append(name, value, filename);
}
return this;
}
delete(name) {
this.indices = Object.values(this.indices.filter(([field]) => field === name).reduceRight((mapper, [, index]) => {
this.data.splice(index - 8, 10);
Reflect.deleteProperty(mapper, `${index}`);
Object.entries(mapper).filter(([fixed]) => +fixed > index).forEach(([fixed, [field, idx]]) => {
Reflect.set(mapper, `${fixed}`, [field, idx - 10]);
});
return mapper;
}, this.indices.reduce((des, [field, value]) => {
Reflect.set(des, value, [field, value]);
return des;
}, {})));
if (!this.indices.length) {
this.data.splice(0, this.data.length);
}
return this;
}
|