From a320b4545e48cc8ad60a283aac31cd7934333c1a Mon Sep 17 00:00:00 2001 From: Konstantin Vyatkin Date: Sun, 7 Jun 2020 01:07:52 -0400 Subject: [PATCH] refactor in sync with node-fetch --- index.d.ts | 4 -- index.js | 152 ++++++++++++++++++++++++++------------------------- package.json | 13 +++-- 3 files changed, 87 insertions(+), 82 deletions(-) delete mode 100644 index.d.ts diff --git a/index.d.ts b/index.d.ts deleted file mode 100644 index 841e665..0000000 --- a/index.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/// - -/* global Blob */ -export = Blob; diff --git a/index.js b/index.js index 6dd75a0..f2e36d7 100644 --- a/index.js +++ b/index.js @@ -1,107 +1,120 @@ // Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js // (MIT licensed) -const {Readable: ReadableStream} = require('stream'); +const {Readable} = require('stream'); +const {types} = require('util'); +/** + * @type {WeakMap { - let buffer; - if (element instanceof Buffer) { - buffer = element; - } else if (ArrayBuffer.isView(element)) { - buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); - } else if (element instanceof ArrayBuffer) { - buffer = Buffer.from(element); - } else if (element instanceof Blob) { - buffer = wm.get(element).buffer; - } else { - buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + const buffers = blobParts.map(element => { + if (Buffer.isBuffer(element)) { + return element; } - size += buffer.length; - buffers.push(buffer); + if (ArrayBuffer.isView(element)) { + return Buffer.from( + element.buffer, + element.byteOffset, + element.byteLength + ); + } + + if (types.isAnyArrayBuffer(element)) { + return Buffer.from(element); + } + + if (wm.has(element)) { + return wm.get(element).buffer; + } + + return Buffer.from( + typeof element === 'string' ? element : String(element) + ); }); - const buffer = Buffer.concat(buffers, size); + const buffer = Buffer.concat(buffers); - const type = options.type === undefined ? '' : String(options.type).toLowerCase(); + const type = + options.type === undefined ? '' : String(options.type).toLowerCase(); wm.set(this, { type: /[^\u0020-\u007E]/.test(type) ? '' : type, - size, buffer }); } + /** + * The Blob interface's size property returns the size of the Blob in bytes. + */ get size() { - return wm.get(this).size; + return wm.get(this).buffer.byteLength; } + /** + * The type property of a Blob object returns the MIME type of the file. + */ get type() { return wm.get(this).type; } - text() { - return Promise.resolve(wm.get(this).buffer.toString()); + /** + * The text() method in the Blob interface returns a Promise that resolves with a string containing the contents of the blob, interpreted as UTF-8. + */ + async text() { + return wm.get(this).buffer.toString(); } - arrayBuffer() { + /** + * The arrayBuffer() method in the Blob interface returns a Promise that resolves with the contents of the blob as binary data contained in an ArrayBuffer. + */ + async arrayBuffer() { const buf = wm.get(this).buffer; - const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); - return Promise.resolve(ab); + const ab = buf.buffer.slice( + buf.byteOffset, + buf.byteOffset + buf.byteLength + ); + return ab; } + /** + * The Blob interface's stream() method returns a ReadableStream which upon reading returns the data contained within the Blob. + */ stream() { - const readable = new ReadableStream(); - readable._read = () => { }; - readable.push(wm.get(this).buffer); - readable.push(null); - return readable; + return Readable.from(wm.get(this).buffer); + } + + get [Symbol.toStringTag]() { + return 'Blob'; } + /** + * @returns {string} + */ toString() { - return '[object Blob]'; + return Object.prototype.toString.call(this); } - slice(...args) { - const {size} = this; - - const start = args[0]; - const end = args[1]; - let relativeStart; - let relativeEnd; - - if (start === undefined) { - relativeStart = 0; // - } else if (start < 0) { - relativeStart = Math.max(size + start, 0); // - } else { - relativeStart = Math.min(start, size); - } - - if (end === undefined) { - relativeEnd = size; // - } else if (end < 0) { - relativeEnd = Math.max(size + end, 0); // - } else { - relativeEnd = Math.min(end, size); - } - - const span = Math.max(relativeEnd - relativeStart, 0); - const slicedBuffer = wm.get(this).buffer.slice( - relativeStart, - relativeStart + span - ); - const blob = new Blob([], {type: args[2]}); - const _ = wm.get(blob); - _.buffer = slicedBuffer; - return blob; + /** + * The Blob interface's slice() method creates and returns a new Blob object which contains data from a subset of the blob on which it's called. + * + * @param {number} [start] + * @param {number} [end] + * @param {string} [contentType] + */ + slice(start, end, contentType) { + return new Blob([wm + .get(this) + .buffer.subarray(start, end)], {type: contentType}); } } @@ -111,11 +124,4 @@ Object.defineProperties(Blob.prototype, { slice: {enumerable: true} }); -Object.defineProperty(Blob.prototype, Symbol.toStringTag, { - value: 'Blob', - writable: false, - enumerable: false, - configurable: true -}); - module.exports = Blob; diff --git a/package.json b/package.json index cb0f11d..c897d2b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "lint": "xo", "test": "xo && ava", "report": "nyc ava", - "coverage": "nyc --reporter json --reporter text ava && codecov -f coverage/coverage-final.json" + "coverage": "nyc --reporter json --reporter text ava && codecov -f coverage/coverage-final.json", + "prepublishOnly": "npx typescript --declaration --emitDeclarationOnly --allowJs index.js" }, "repository": "https://github.com/node-fetch/fetch-blob.git", "keywords": [ @@ -19,7 +20,7 @@ "node-fetch" ], "engines": { - "node": ">=6" + "node": ">=10.17" }, "author": "David Frank", "license": "MIT", @@ -36,14 +37,16 @@ "xo": "^0.30.0" }, "xo": { + "rules": { + "node/no-unsupported-features/node-builtins": 0 + }, "overrides": [ { "files": "test.js", "rules": { - "node/no-unsupported-features/es-syntax": 0, - "node/no-unsupported-features/node-builtins": 0 + "node/no-unsupported-features/es-syntax": 0 } } ] } -} +} \ No newline at end of file