1'use strict' 2const { Minipass } = require('minipass') 3const TYPE = Symbol('type') 4const BUFFER = Symbol('buffer') 5 6class Blob { 7 constructor (blobParts, options) { 8 this[TYPE] = '' 9 10 const buffers = [] 11 let size = 0 12 13 if (blobParts) { 14 const a = blobParts 15 const length = Number(a.length) 16 for (let i = 0; i < length; i++) { 17 const element = a[i] 18 const buffer = element instanceof Buffer ? element 19 : ArrayBuffer.isView(element) 20 ? Buffer.from(element.buffer, element.byteOffset, element.byteLength) 21 : element instanceof ArrayBuffer ? Buffer.from(element) 22 : element instanceof Blob ? element[BUFFER] 23 : typeof element === 'string' ? Buffer.from(element) 24 : Buffer.from(String(element)) 25 size += buffer.length 26 buffers.push(buffer) 27 } 28 } 29 30 this[BUFFER] = Buffer.concat(buffers, size) 31 32 const type = options && options.type !== undefined 33 && String(options.type).toLowerCase() 34 if (type && !/[^\u0020-\u007E]/.test(type)) { 35 this[TYPE] = type 36 } 37 } 38 39 get size () { 40 return this[BUFFER].length 41 } 42 43 get type () { 44 return this[TYPE] 45 } 46 47 text () { 48 return Promise.resolve(this[BUFFER].toString()) 49 } 50 51 arrayBuffer () { 52 const buf = this[BUFFER] 53 const off = buf.byteOffset 54 const len = buf.byteLength 55 const ab = buf.buffer.slice(off, off + len) 56 return Promise.resolve(ab) 57 } 58 59 stream () { 60 return new Minipass().end(this[BUFFER]) 61 } 62 63 slice (start, end, type) { 64 const size = this.size 65 const relativeStart = start === undefined ? 0 66 : start < 0 ? Math.max(size + start, 0) 67 : Math.min(start, size) 68 const relativeEnd = end === undefined ? size 69 : end < 0 ? Math.max(size + end, 0) 70 : Math.min(end, size) 71 const span = Math.max(relativeEnd - relativeStart, 0) 72 73 const buffer = this[BUFFER] 74 const slicedBuffer = buffer.slice( 75 relativeStart, 76 relativeStart + span 77 ) 78 const blob = new Blob([], { type }) 79 blob[BUFFER] = slicedBuffer 80 return blob 81 } 82 83 get [Symbol.toStringTag] () { 84 return 'Blob' 85 } 86 87 static get BUFFER () { 88 return BUFFER 89 } 90} 91 92Object.defineProperties(Blob.prototype, { 93 size: { enumerable: true }, 94 type: { enumerable: true }, 95}) 96 97module.exports = Blob 98