Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8fed4e338 | ||
|
|
483973cf25 | ||
|
|
cc929f3714 | ||
|
|
5584886f0f | ||
|
|
0d2cd8b9b7 | ||
|
|
149030ddbe | ||
|
|
f08e6a6773 | ||
|
|
eed6a1dddd | ||
|
|
3b12a39ea2 | ||
|
|
591a28ed94 | ||
|
|
40f4568c95 | ||
|
|
a74fb90d95 | ||
|
|
689bee122b | ||
|
|
50b89fcdce | ||
|
|
40c6ff45df |
@@ -14,7 +14,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
node: ["14", "12", engines]
|
||||
node: ["15", "14", "12", engines]
|
||||
exclude:
|
||||
# On Windows, run tests with only the LTS environments.
|
||||
- os: windows-latest
|
||||
@@ -47,7 +47,6 @@ jobs:
|
||||
node-version: ${{steps.get-version.outputs.node}}
|
||||
|
||||
- run: npm install
|
||||
- run: npm install domexception
|
||||
|
||||
- run: npm run report -- --colors
|
||||
|
||||
|
||||
@@ -63,3 +63,4 @@ typings/
|
||||
.env
|
||||
|
||||
index.d.ts
|
||||
from.d.ts
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
## next
|
||||
- Fixed a bug where in BlobDataItem when the file was empty (#86)
|
||||
|
||||
## v2.1.2
|
||||
- Fixed a bug where `start` in BlobDataItem was undefined (#85)
|
||||
|
||||
## v2.1.1
|
||||
- Add nullish values checking in Symbol.hasInstance (#82)
|
||||
- Add generated typings for from.js file (#80)
|
||||
- Updated dev dependencies
|
||||
|
||||
## v2.1.0
|
||||
- Fix: .slice has an implementation bug (#54).
|
||||
- Added blob backed up by filesystem (#55)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const {statSync, createReadStream} = require('fs');
|
||||
const Blob = require('.');
|
||||
const Blob = require('./index.js');
|
||||
const DOMException = require('domexception');
|
||||
|
||||
/**
|
||||
@@ -23,12 +23,12 @@ class BlobDataItem {
|
||||
constructor(options) {
|
||||
this.size = options.size;
|
||||
this.path = options.path;
|
||||
this.start = options.start;
|
||||
this.start = options.start || 0;
|
||||
this.mtime = options.mtime;
|
||||
}
|
||||
|
||||
// Slicing arguments is validated and formated
|
||||
// by Blob.prototype.slice
|
||||
// Slicing arguments is first validated and formated
|
||||
// to not be out of range by Blob.prototype.slice
|
||||
slice(start, end) {
|
||||
return new BlobDataItem({
|
||||
path: this.path,
|
||||
@@ -43,6 +43,10 @@ class BlobDataItem {
|
||||
throw new DOMException('The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.', 'NotReadableError');
|
||||
}
|
||||
|
||||
if (!this.size) {
|
||||
return new Blob().stream();
|
||||
}
|
||||
|
||||
return createReadStream(this.path, {
|
||||
start: this.start,
|
||||
end: this.start + this.size - 1
|
||||
|
||||
@@ -24,7 +24,7 @@ class Blob {
|
||||
* @param {(ArrayBufferLike | ArrayBufferView | Blob | Buffer | string)[]} blobParts
|
||||
* @param {{ type?: string }} [options]
|
||||
*/
|
||||
constructor(blobParts = [], options = {type: ''}) {
|
||||
constructor(blobParts = [], options = {}) {
|
||||
let size = 0;
|
||||
|
||||
const parts = blobParts.map(element => {
|
||||
@@ -41,6 +41,7 @@ class Blob {
|
||||
buffer = Buffer.from(typeof element === 'string' ? element : String(element));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line unicorn/explicit-length-check
|
||||
size += buffer.length || buffer.size || 0;
|
||||
return buffer;
|
||||
});
|
||||
@@ -148,7 +149,7 @@ class Blob {
|
||||
}
|
||||
}
|
||||
|
||||
const blob = new Blob([], {type});
|
||||
const blob = new Blob([], {type: String(type).toLowerCase()});
|
||||
Object.assign(wm.get(blob), {size: span, parts: blobParts});
|
||||
|
||||
return blob;
|
||||
@@ -160,6 +161,7 @@ class Blob {
|
||||
|
||||
static [Symbol.hasInstance](object) {
|
||||
return (
|
||||
object &&
|
||||
typeof object === 'object' &&
|
||||
typeof object.stream === 'function' &&
|
||||
object.stream.length === 0 &&
|
||||
|
||||
+28
-14
@@ -1,19 +1,20 @@
|
||||
{
|
||||
"name": "fetch-blob",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.2",
|
||||
"description": "A Blob implementation in Node.js, originally from node-fetch.",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"from.js",
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
"index.d.ts",
|
||||
"from.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "xo",
|
||||
"test": "xo && ava",
|
||||
"report": "c8 --reporter json --reporter text ava",
|
||||
"coverage": "c8 --reporter json --reporter text ava && codecov -f coverage/coverage-final.json",
|
||||
"prepublishOnly": "tsc --declaration --emitDeclarationOnly --allowJs index.js"
|
||||
"prepublishOnly": "tsc --declaration --emitDeclarationOnly --allowJs index.js from.js"
|
||||
},
|
||||
"repository": "https://github.com/node-fetch/fetch-blob.git",
|
||||
"keywords": [
|
||||
@@ -29,16 +30,17 @@
|
||||
"url": "https://github.com/node-fetch/fetch-blob/issues"
|
||||
},
|
||||
"homepage": "https://github.com/node-fetch/fetch-blob#readme",
|
||||
"devDependencies": {
|
||||
"ava": "^3.8.2",
|
||||
"c8": "^7.2.0",
|
||||
"codecov": "^3.7.0",
|
||||
"get-stream": "^5.1.0",
|
||||
"node-fetch": "^2.6.0",
|
||||
"typescript": "^3.9.5",
|
||||
"xo": "^0.32.0"
|
||||
},
|
||||
"xo": {
|
||||
"rules": {
|
||||
"unicorn/import-index": "off",
|
||||
"import/extensions": [
|
||||
"error",
|
||||
"always",
|
||||
{
|
||||
"ignorePackages": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": "test.js",
|
||||
@@ -49,7 +51,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"peerDependencies": {
|
||||
"domexception": "^2.0.1"
|
||||
"peerDependenciesMeta": {
|
||||
"domexception": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "^3.15.0",
|
||||
"c8": "^7.7.1",
|
||||
"codecov": "^3.8.1",
|
||||
"domexception": "^2.0.1",
|
||||
"get-stream": "^6.0.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"typescript": "^4.2.4",
|
||||
"xo": "^0.38.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const fs = require('fs');
|
||||
const test = require('ava');
|
||||
const Blob = require('.');
|
||||
const blobFrom = require('./from');
|
||||
const getStream = require('get-stream');
|
||||
const {Response} = require('node-fetch');
|
||||
const {TextDecoder} = require('util');
|
||||
const Blob = require('./index.js');
|
||||
const blobFrom = require('./from.js');
|
||||
|
||||
test('new Blob()', t => {
|
||||
const blob = new Blob(); // eslint-disable-line no-unused-vars
|
||||
@@ -153,10 +153,43 @@ test('blob part backed up by filesystem', async t => {
|
||||
|
||||
test('Reading after modified should fail', async t => {
|
||||
const blob = blobFrom('./LICENSE');
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await new Promise(resolve => {
|
||||
setTimeout(resolve, 100);
|
||||
});
|
||||
const now = new Date();
|
||||
// Change modified time
|
||||
fs.utimesSync('./LICENSE', now, now);
|
||||
const error = await blob.text().catch(error => error);
|
||||
t.is(error.name, 'NotReadableError');
|
||||
});
|
||||
|
||||
test('Reading from the stream created by blobFrom', async t => {
|
||||
const blob = blobFrom('./LICENSE');
|
||||
const expected = await fs.promises.readFile('./LICENSE', 'utf-8');
|
||||
|
||||
const actual = await getStream(blob.stream());
|
||||
|
||||
t.is(actual, expected);
|
||||
});
|
||||
|
||||
test('Reading empty blobs', async t => {
|
||||
const blob = blobFrom('./LICENSE').slice(0, 0);
|
||||
const actual = await blob.text();
|
||||
t.is(actual, '');
|
||||
});
|
||||
|
||||
test('Blob-ish class is an instance of Blob', t => {
|
||||
class File {
|
||||
stream() {}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return 'File';
|
||||
}
|
||||
}
|
||||
|
||||
t.true(new File() instanceof Blob);
|
||||
});
|
||||
|
||||
test('Instanceof check returns false for nullish values', t => {
|
||||
t.false(null instanceof Blob);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user