Skip to content

Commit 544a1d3

Browse files
author
David Frank
committed
copy implementation from node-fetch
1 parent e5a76c5 commit 544a1d3

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

blob.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js
2+
// (MIT licensed)
3+
4+
import Stream from 'stream';
5+
6+
// fix for "Readable" isn't a named export issue
7+
const Readable = Stream.Readable;
8+
9+
export const BUFFER = Symbol('buffer');
10+
const TYPE = Symbol('type');
11+
12+
export default class Blob {
13+
constructor() {
14+
this[TYPE] = '';
15+
16+
const blobParts = arguments[0];
17+
const options = arguments[1];
18+
19+
const buffers = [];
20+
let size = 0;
21+
22+
if (blobParts) {
23+
const a = blobParts;
24+
const length = Number(a.length);
25+
for (let i = 0; i < length; i++) {
26+
const element = a[i];
27+
let buffer;
28+
if (element instanceof Buffer) {
29+
buffer = element;
30+
} else if (ArrayBuffer.isView(element)) {
31+
buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength);
32+
} else if (element instanceof ArrayBuffer) {
33+
buffer = Buffer.from(element);
34+
} else if (element instanceof Blob) {
35+
buffer = element[BUFFER];
36+
} else {
37+
buffer = Buffer.from(typeof element === 'string' ? element : String(element));
38+
}
39+
size += buffer.length;
40+
buffers.push(buffer);
41+
}
42+
}
43+
44+
this[BUFFER] = Buffer.concat(buffers);
45+
46+
let type = options && options.type !== undefined && String(options.type).toLowerCase();
47+
if (type && !/[^\u0020-\u007E]/.test(type)) {
48+
this[TYPE] = type;
49+
}
50+
}
51+
get size() {
52+
return this[BUFFER].length;
53+
}
54+
get type() {
55+
return this[TYPE];
56+
}
57+
text() {
58+
return Promise.resolve(this[BUFFER].toString())
59+
}
60+
arrayBuffer() {
61+
const buf = this[BUFFER];
62+
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
63+
return Promise.resolve(ab);
64+
}
65+
stream() {
66+
const readable = new Readable();
67+
readable._read = () => {};
68+
readable.push(this[BUFFER]);
69+
readable.push(null);
70+
return readable;
71+
}
72+
toString() {
73+
return '[object Blob]'
74+
}
75+
slice() {
76+
const size = this.size;
77+
78+
const start = arguments[0];
79+
const end = arguments[1];
80+
let relativeStart, relativeEnd;
81+
if (start === undefined) {
82+
relativeStart = 0;
83+
} else if (start < 0) {
84+
relativeStart = Math.max(size + start, 0);
85+
} else {
86+
relativeStart = Math.min(start, size);
87+
}
88+
if (end === undefined) {
89+
relativeEnd = size;
90+
} else if (end < 0) {
91+
relativeEnd = Math.max(size + end, 0);
92+
} else {
93+
relativeEnd = Math.min(end, size);
94+
}
95+
const span = Math.max(relativeEnd - relativeStart, 0);
96+
97+
const buffer = this[BUFFER];
98+
const slicedBuffer = buffer.slice(
99+
relativeStart,
100+
relativeStart + span
101+
);
102+
const blob = new Blob([], { type: arguments[2] });
103+
blob[BUFFER] = slicedBuffer;
104+
return blob;
105+
}
106+
}
107+
108+
Object.defineProperties(Blob.prototype, {
109+
size: { enumerable: true },
110+
type: { enumerable: true },
111+
slice: { enumerable: true }
112+
});
113+
114+
Object.defineProperty(Blob.prototype, Symbol.toStringTag, {
115+
value: 'Blob',
116+
writable: false,
117+
enumerable: false,
118+
configurable: true
119+
});

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "fetch-blob",
3+
"version": "1.0.0",
4+
"description": "A Blob implementation on node.js, originally from node-fetch",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/bitinn/fetch-blob.git"
12+
},
13+
"keywords": [
14+
"blob",
15+
"node-fetch"
16+
],
17+
"author": "David Frank",
18+
"license": "MIT",
19+
"bugs": {
20+
"url": "https://github.com/bitinn/fetch-blob/issues"
21+
},
22+
"homepage": "https://github.com/bitinn/fetch-blob#readme"
23+
}

0 commit comments

Comments
 (0)