Jelajahi Sumber

Make addFile() synchronous.

Renée Kooi 7 tahun lalu
induk
melakukan
acc819c2ed

+ 80 - 70
src/core/Core.js

@@ -1,6 +1,5 @@
 const Utils = require('../core/Utils')
 const Translator = require('../core/Translator')
-const PromiseWaiter = require('./PromiseWaiter')
 const ee = require('namespace-emitter')
 const cuid = require('cuid')
 const throttle = require('lodash.throttle')
@@ -48,7 +47,7 @@ class Uppy {
         allowedFileTypes: false
       },
       meta: {},
-      onBeforeFileAdded: (currentFile, files) => Promise.resolve(),
+      onBeforeFileAdded: (currentFile, files) => currentFile,
       onBeforeUpload: (files) => Promise.resolve(),
       locale: defaultLocale,
       store: new DefaultStore()
@@ -121,8 +120,6 @@ class Uppy {
       this.updateAll(nextState)
     })
 
-    this.addFilePromises = new PromiseWaiter()
-
     // for debugging and testing
     // this.updateNum = 0
     if (this.opts.debug) {
@@ -340,77 +337,90 @@ class Uppy {
   * @param {object} file object to add
   */
   addFile (file) {
-    const promise = Promise.resolve()
-      // Wrap this in a Promise `.then()` handler so errors will reject the Promise
-      // instead of throwing.
-      .then(() => this.opts.onBeforeFileAdded(file, this.getState().files))
-      .then(() => Utils.getFileType(file))
-      .then((fileType) => {
-        const updatedFiles = Object.assign({}, this.getState().files)
-        let fileName
-        if (file.name) {
-          fileName = file.name
-        } else if (fileType.split('/')[0] === 'image') {
-          fileName = fileType.split('/')[0] + '.' + fileType.split('/')[1]
-        } else {
-          fileName = 'noname'
-        }
-        const fileExtension = Utils.getFileNameAndExtension(fileName).extension
-        const isRemote = file.isRemote || false
-
-        const fileID = Utils.generateFileID(file)
-
-        const newFile = {
-          source: file.source || '',
-          id: fileID,
-          name: fileName,
-          extension: fileExtension || '',
-          meta: Object.assign({}, this.getState().meta, {
-            name: fileName,
-            type: fileType
-          }),
-          type: fileType,
-          data: file.data,
-          progress: {
-            percentage: 0,
-            bytesUploaded: 0,
-            bytesTotal: file.data.size || 0,
-            uploadComplete: false,
-            uploadStarted: false
-          },
-          size: file.data.size || 0,
-          isRemote: isRemote,
-          remote: file.remote || '',
-          preview: file.preview
-        }
+    const { files } = this.getState()
 
-        this._checkRestrictions(newFile)
+    const onError = (msg) => {
+      const err = typeof msg === 'object' ? msg : new Error(msg)
+      this.log(err.message)
+      this.info(err.message, 'error', 5000)
+      throw err
+    }
 
-        updatedFiles[fileID] = newFile
-        this.setState({files: updatedFiles})
+    let mappedFile
+    try {
+      mappedFile = this.opts.onBeforeFileAdded(file, files)
+    } catch (err) {
+      onError(err)
+    }
 
-        this.emit('file-added', newFile)
-        this.log(`Added file: ${fileName}, ${fileID}, mime type: ${fileType}`)
+    if (typeof mappedFile === 'object' && mappedFile) {
+      if (mappedFile.then) {
+        throw new TypeError('onBeforeFileAdded() returned a Promise, but this is no longer supported. It must be synchronous.')
+      }
+      file = mappedFile
+    }
 
-        if (this.opts.autoProceed && !this.scheduledAutoProceed) {
-          this.scheduledAutoProceed = setTimeout(() => {
-            this.scheduledAutoProceed = null
-            this.upload().catch((err) => {
-              console.error(err.stack || err.message || err)
-            })
-          }, 4)
-        }
-      })
-      .catch((err) => {
-        const message = typeof err === 'object' ? err.message : err
-        this.log(message)
-        this.info(message, 'error', 5000)
-        return Promise.reject(typeof err === 'object' ? err : new Error(err))
+    const fileType = Utils.getFileType(file)
+    let fileName
+    if (file.name) {
+      fileName = file.name
+    } else if (fileType.split('/')[0] === 'image') {
+      fileName = fileType.split('/')[0] + '.' + fileType.split('/')[1]
+    } else {
+      fileName = 'noname'
+    }
+    const fileExtension = Utils.getFileNameAndExtension(fileName).extension
+    const isRemote = file.isRemote || false
+
+    const fileID = Utils.generateFileID(file)
+
+    const newFile = {
+      source: file.source || '',
+      id: fileID,
+      name: fileName,
+      extension: fileExtension || '',
+      meta: Object.assign({}, this.getState().meta, {
+        name: fileName,
+        type: fileType
+      }),
+      type: fileType,
+      data: file.data,
+      progress: {
+        percentage: 0,
+        bytesUploaded: 0,
+        bytesTotal: file.data.size || 0,
+        uploadComplete: false,
+        uploadStarted: false
+      },
+      size: file.data.size || 0,
+      isRemote: isRemote,
+      remote: file.remote || '',
+      preview: file.preview
+    }
+
+    try {
+      this._checkRestrictions(newFile)
+    } catch (err) {
+      onError(err)
+    }
+
+    this.setState({
+      files: Object.assign({}, files, {
+        [fileID]: newFile
       })
+    })
 
-    this.addFilePromises.add(promise)
+    this.emit('file-added', newFile)
+    this.log(`Added file: ${fileName}, ${fileID}, mime type: ${fileType}`)
 
-    return promise
+    if (this.opts.autoProceed && !this.scheduledAutoProceed) {
+      this.scheduledAutoProceed = setTimeout(() => {
+        this.scheduledAutoProceed = null
+        this.upload().catch((err) => {
+          console.error(err.stack || err.message || err)
+        })
+      }, 4)
+    }
   }
 
   removeFile (fileID) {
@@ -1110,7 +1120,7 @@ class Uppy {
     })
   }
 
-    /**
+  /**
    * Start an upload for all the files that are not currently being uploaded.
    *
    * @return {Promise}
@@ -1120,7 +1130,7 @@ class Uppy {
       this.log('No uploader type plugins are used', 'warning')
     }
 
-    return this.addFilePromises.wait()
+    return Promise.resolve()
       .then(() => this.opts.onBeforeUpload(this.getState().files))
       .then(() => this._checkMinNumberOfFiles())
       .then(() => {

File diff ditekan karena terlalu besar
+ 2 - 1
src/core/Core.test.js


+ 11 - 30
src/core/Utils.js

@@ -1,8 +1,4 @@
 const throttle = require('lodash.throttle')
-// we inline file-type module, as opposed to using the NPM version,
-// because of this https://github.com/sindresorhus/file-type/issues/78
-// and https://github.com/sindresorhus/copy-text-to-clipboard/issues/5
-const fileType = require('../vendor/file-type')
 
 /**
  * A collection of small utility functions that help with dom manipulation, adding listeners,
@@ -133,36 +129,21 @@ function getFileType (file) {
 
   if (file.isRemote) {
     // some remote providers do not support file types
-    const mime = file.type ? file.type : extensionsToMime[fileExtension]
-    return Promise.resolve(mime)
+    return file.type ? file.type : extensionsToMime[fileExtension]
   }
 
-  // 1. try to determine file type from magic bytes with file-type module
-  // this should be the most trustworthy way
-  const chunk = file.data.slice(0, 4100)
-  return getArrayBuffer(chunk)
-    .then((buffer) => {
-      const type = fileType(buffer)
-      if (type && type.mime) {
-        return type.mime
-      }
-
-      // 2. if that’s no good, check if mime type is set in the file object
-      if (file.type) {
-        return file.type
-      }
+  // 2. if that’s no good, check if mime type is set in the file object
+  if (file.type) {
+    return file.type
+  }
 
-      // 3. if that’s no good, see if we can map extension to a mime type
-      if (fileExtension && extensionsToMime[fileExtension]) {
-        return extensionsToMime[fileExtension]
-      }
+  // 3. if that’s no good, see if we can map extension to a mime type
+  if (fileExtension && extensionsToMime[fileExtension]) {
+    return extensionsToMime[fileExtension]
+  }
 
-      // if all fails, well, return empty
-      return null
-    })
-    .catch(() => {
-      return null
-    })
+  // if all fails, well, return empty
+  return null
 }
 
 // TODO Check which types are actually supported in browsers. Chrome likes webm

+ 4 - 32
src/core/Utils.test.js

@@ -149,35 +149,13 @@ describe('core/utils', () => {
   })
 
   describe('getFileType', () => {
-    beforeEach(() => {
-      global.FileReader = class FileReader {
-        addEventListener (e, cb) {
-          if (e === 'load') {
-            this.loadCb = cb
-          }
-          if (e === 'error') {
-            this.errorCb = cb
-          }
-        }
-        readAsArrayBuffer (chunk) {
-          this.loadCb({ target: { result: new ArrayBuffer(8) } })
-        }
-      }
-    })
-
-    afterEach(() => {
-      global.FileReader = undefined
-    })
-
     it('should trust the filetype if the file comes from a remote source', () => {
       const file = {
         isRemote: true,
         type: 'audio/webm',
         name: 'foo.webm'
       }
-      return utils.getFileType(file).then(r => {
-        expect(r).toEqual('audio/webm')
-      })
+      expect(utils.getFileType(file)).toEqual('audio/webm')
     })
 
     it('should determine the filetype from the mimetype', () => {
@@ -186,9 +164,7 @@ describe('core/utils', () => {
         name: 'foo.webm',
         data: 'sdfsdfhq9efbicw'
       }
-      return utils.getFileType(file).then(r => {
-        expect(r).toEqual('audio/webm')
-      })
+      expect(utils.getFileType(file)).toEqual('audio/webm')
     })
 
     it('should determine the filetype from the extension', () => {
@@ -196,9 +172,7 @@ describe('core/utils', () => {
         name: 'foo.mp3',
         data: 'sdfsfhfh329fhwihs'
       }
-      return utils.getFileType(file).then(r => {
-        expect(r).toEqual('audio/mp3')
-      })
+      expect(utils.getFileType(file)).toEqual('audio/mp3')
     })
 
     it('should fail gracefully if unable to detect', () => {
@@ -206,9 +180,7 @@ describe('core/utils', () => {
         name: 'foobar',
         data: 'sdfsfhfh329fhwihs'
       }
-      return utils.getFileType(file).then(r => {
-        expect(r).toEqual(null)
-      })
+      expect(utils.getFileType(file)).toEqual(null)
     })
   })
 

+ 4 - 4
src/core/__snapshots__/Core.test.js.snap

@@ -26,7 +26,7 @@ Object {
       "isRemote": false,
       "meta": Object {
         "name": "foo.jpg",
-        "type": null,
+        "type": "image/jpeg",
       },
       "name": "foo.jpg",
       "preview": undefined,
@@ -40,7 +40,7 @@ Object {
       "remote": "",
       "size": 0,
       "source": "jest",
-      "type": null,
+      "type": "image/jpeg",
     },
     Object {
       "data": Uint8Array [],
@@ -49,7 +49,7 @@ Object {
       "isRemote": false,
       "meta": Object {
         "name": "bar.jpg",
-        "type": null,
+        "type": "image/jpeg",
       },
       "name": "bar.jpg",
       "preview": undefined,
@@ -63,7 +63,7 @@ Object {
       "remote": "",
       "size": 0,
       "source": "jest",
-      "type": null,
+      "type": "image/jpeg",
     },
   ],
   "uploadID": "cjd09qwxb000dlql4tp4doz8h",

+ 0 - 6
src/plugins/Dashboard/index.js

@@ -289,8 +289,6 @@ module.exports = class Dashboard extends Plugin {
         name: file.name,
         type: file.type,
         data: blob
-      }).catch(() => {
-        // Ignore
       })
     })
   }
@@ -305,8 +303,6 @@ module.exports = class Dashboard extends Plugin {
         name: file.name,
         type: file.type,
         data: file
-      }).catch(() => {
-        // Ignore
       })
     })
   }
@@ -373,8 +369,6 @@ module.exports = class Dashboard extends Plugin {
         name: file.name,
         type: file.type,
         data: file
-      }).catch(() => {
-        // Ignore
       })
     })
   }

+ 0 - 4
src/plugins/DragDrop/index.js

@@ -83,8 +83,6 @@ module.exports = class DragDrop extends Plugin {
         name: file.name,
         type: file.type,
         data: file
-      }).catch(() => {
-        // Ignore
       })
     })
   }
@@ -100,8 +98,6 @@ module.exports = class DragDrop extends Plugin {
         name: file.name,
         type: file.type,
         data: file
-      }).catch(() => {
-        // Ignore
       })
     })
   }

+ 1 - 3
src/plugins/Dummy.js

@@ -35,9 +35,7 @@ module.exports = class Dummy extends Plugin {
       data: blob
     }
     this.props.log('Adding fake file blob')
-    this.props.addFile(file).catch(() => {
-      // Ignore
-    })
+    this.props.addFile(file)
   }
 
   render (state) {

+ 0 - 2
src/plugins/FileInput.js

@@ -51,8 +51,6 @@ module.exports = class FileInput extends Plugin {
         name: file.name,
         type: file.type,
         data: file
-      }).catch(() => {
-        // Ignore
       })
     })
   }

+ 24 - 29
src/plugins/Transloadit/index.test.js

@@ -45,15 +45,14 @@ describe('Transloadit', () => {
 
     const data = Buffer.alloc(4000)
     data.size = data.byteLength
-    return uppy.addFile({
+    uppy.addFile({
       name: 'testfile',
       data
-    }).then(() => {
-      return uppy.upload().then(() => {
-        throw new Error('should have rejected')
-      }, (err) => {
-        expect(err.message).toMatch(/The `params\.auth\.key` option is required/)
-      })
+    })
+    return uppy.upload().then(() => {
+      throw new Error('should have rejected')
+    }, (err) => {
+      expect(err.message).toMatch(/The `params\.auth\.key` option is required/)
     })
   })
 
@@ -84,17 +83,15 @@ describe('Transloadit', () => {
     const data = Buffer.alloc(10)
     data.size = data.byteLength
 
-    return Promise.all([
-      uppy.addFile({ name: 'a.png', data }),
-      uppy.addFile({ name: 'b.png', data }),
-      uppy.addFile({ name: 'c.png', data }),
-      uppy.addFile({ name: 'd.png', data })
-    ]).then(() => {
-      return uppy.upload().then(() => {
-        throw new Error('upload should have been rejected')
-      }, () => {
-        expect(i).toBe(4)
-      })
+    uppy.addFile({ name: 'a.png', data })
+    uppy.addFile({ name: 'b.png', data })
+    uppy.addFile({ name: 'c.png', data })
+    uppy.addFile({ name: 'd.png', data })
+
+    return uppy.upload().then(() => {
+      throw new Error('upload should have been rejected')
+    }, () => {
+      expect(i).toBe(4)
     })
   })
 
@@ -131,17 +128,15 @@ describe('Transloadit', () => {
     const data2 = Buffer.alloc(20)
     data2.size = data2.byteLength
 
-    return Promise.all([
-      uppy.addFile({ name: 'a.png', data }),
-      uppy.addFile({ name: 'b.png', data }),
-      uppy.addFile({ name: 'c.png', data }),
-      uppy.addFile({ name: 'd.png', data: data2 })
-    ]).then(() => {
-      return uppy.upload().then(() => {
-        throw new Error('Upload should have been rejected')
-      }, () => {
-        expect(i).toBe(2)
-      })
+    uppy.addFile({ name: 'a.png', data })
+    uppy.addFile({ name: 'b.png', data })
+    uppy.addFile({ name: 'c.png', data })
+    uppy.addFile({ name: 'd.png', data: data2 })
+
+    return uppy.upload().then(() => {
+      throw new Error('Upload should have been rejected')
+    }, () => {
+      expect(i).toBe(2)
     })
   })
 

+ 0 - 559
src/vendor/file-type/index.js

@@ -1,559 +0,0 @@
-'use strict';
-
-module.exports = input => {
-	const buf = new Uint8Array(input);
-
-	if (!(buf && buf.length > 1)) {
-		return null;
-	}
-
-	const check = (header, opts) => {
-		opts = Object.assign({
-			offset: 0
-		}, opts);
-
-		for (let i = 0; i < header.length; i++) {
-			if (header[i] !== buf[i + opts.offset]) {
-				return false;
-			}
-		}
-
-		return true;
-	};
-
-	if (check([0xFF, 0xD8, 0xFF])) {
-		return {
-			ext: 'jpg',
-			mime: 'image/jpeg'
-		};
-	}
-
-	if (check([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) {
-		return {
-			ext: 'png',
-			mime: 'image/png'
-		};
-	}
-
-	if (check([0x47, 0x49, 0x46])) {
-		return {
-			ext: 'gif',
-			mime: 'image/gif'
-		};
-	}
-
-	if (check([0x57, 0x45, 0x42, 0x50], {offset: 8})) {
-		return {
-			ext: 'webp',
-			mime: 'image/webp'
-		};
-	}
-
-	if (check([0x46, 0x4C, 0x49, 0x46])) {
-		return {
-			ext: 'flif',
-			mime: 'image/flif'
-		};
-	}
-
-	// Needs to be before `tif` check
-	if (
-		(check([0x49, 0x49, 0x2A, 0x0]) || check([0x4D, 0x4D, 0x0, 0x2A])) &&
-		check([0x43, 0x52], {offset: 8})
-	) {
-		return {
-			ext: 'cr2',
-			mime: 'image/x-canon-cr2'
-		};
-	}
-
-	if (
-		check([0x49, 0x49, 0x2A, 0x0]) ||
-		check([0x4D, 0x4D, 0x0, 0x2A])
-	) {
-		return {
-			ext: 'tif',
-			mime: 'image/tiff'
-		};
-	}
-
-	if (check([0x42, 0x4D])) {
-		return {
-			ext: 'bmp',
-			mime: 'image/bmp'
-		};
-	}
-
-	if (check([0x49, 0x49, 0xBC])) {
-		return {
-			ext: 'jxr',
-			mime: 'image/vnd.ms-photo'
-		};
-	}
-
-	if (check([0x38, 0x42, 0x50, 0x53])) {
-		return {
-			ext: 'psd',
-			mime: 'image/vnd.adobe.photoshop'
-		};
-	}
-
-	// Needs to be before the `zip` check
-	if (
-		check([0x50, 0x4B, 0x3, 0x4]) &&
-		check([0x6D, 0x69, 0x6D, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x65, 0x70, 0x75, 0x62, 0x2B, 0x7A, 0x69, 0x70], {offset: 30})
-	) {
-		return {
-			ext: 'epub',
-			mime: 'application/epub+zip'
-		};
-	}
-
-	// Needs to be before `zip` check
-	// Assumes signed `.xpi` from addons.mozilla.org
-	if (
-		check([0x50, 0x4B, 0x3, 0x4]) &&
-		check([0x4D, 0x45, 0x54, 0x41, 0x2D, 0x49, 0x4E, 0x46, 0x2F, 0x6D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x2E, 0x72, 0x73, 0x61], {offset: 30})
-	) {
-		return {
-			ext: 'xpi',
-			mime: 'application/x-xpinstall'
-		};
-	}
-
-	if (
-		check([0x50, 0x4B]) &&
-		(buf[2] === 0x3 || buf[2] === 0x5 || buf[2] === 0x7) &&
-		(buf[3] === 0x4 || buf[3] === 0x6 || buf[3] === 0x8)
-	) {
-		return {
-			ext: 'zip',
-			mime: 'application/zip'
-		};
-	}
-
-	if (check([0x75, 0x73, 0x74, 0x61, 0x72], {offset: 257})) {
-		return {
-			ext: 'tar',
-			mime: 'application/x-tar'
-		};
-	}
-
-	if (
-		check([0x52, 0x61, 0x72, 0x21, 0x1A, 0x7]) &&
-		(buf[6] === 0x0 || buf[6] === 0x1)
-	) {
-		return {
-			ext: 'rar',
-			mime: 'application/x-rar-compressed'
-		};
-	}
-
-	if (check([0x1F, 0x8B, 0x8])) {
-		return {
-			ext: 'gz',
-			mime: 'application/gzip'
-		};
-	}
-
-	if (check([0x42, 0x5A, 0x68])) {
-		return {
-			ext: 'bz2',
-			mime: 'application/x-bzip2'
-		};
-	}
-
-	if (check([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])) {
-		return {
-			ext: '7z',
-			mime: 'application/x-7z-compressed'
-		};
-	}
-
-	if (check([0x78, 0x01])) {
-		return {
-			ext: 'dmg',
-			mime: 'application/x-apple-diskimage'
-		};
-	}
-
-	if (
-		(
-			check([0x0, 0x0, 0x0]) &&
-			(buf[3] === 0x18 || buf[3] === 0x20) &&
-			check([0x66, 0x74, 0x79, 0x70], {offset: 4})
-		) ||
-		check([0x33, 0x67, 0x70, 0x35]) ||
-		(
-			check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32]) &&
-			check([0x6D, 0x70, 0x34, 0x31, 0x6D, 0x70, 0x34, 0x32, 0x69, 0x73, 0x6F, 0x6D], {offset: 16})
-		) ||
-		check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D]) ||
-		check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32, 0x0, 0x0, 0x0, 0x0])
-	) {
-		return {
-			ext: 'mp4',
-			mime: 'video/mp4'
-		};
-	}
-
-	if (check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x56])) {
-		return {
-			ext: 'm4v',
-			mime: 'video/x-m4v'
-		};
-	}
-
-	if (check([0x4D, 0x54, 0x68, 0x64])) {
-		return {
-			ext: 'mid',
-			mime: 'audio/midi'
-		};
-	}
-
-	// https://github.com/threatstack/libmagic/blob/master/magic/Magdir/matroska
-	if (check([0x1A, 0x45, 0xDF, 0xA3])) {
-		const sliced = buf.subarray(4, 4 + 4096);
-		const idPos = sliced.findIndex((el, i, arr) => arr[i] === 0x42 && arr[i + 1] === 0x82);
-
-		if (idPos >= 0) {
-			const docTypePos = idPos + 3;
-			const findDocType = type => Array.from(type).every((c, i) => sliced[docTypePos + i] === c.charCodeAt(0));
-
-			if (findDocType('matroska')) {
-				return {
-					ext: 'mkv',
-					mime: 'video/x-matroska'
-				};
-			}
-
-			if (findDocType('webm')) {
-				return {
-					ext: 'webm',
-					mime: 'video/webm'
-				};
-			}
-		}
-	}
-
-	if (check([0x0, 0x0, 0x0, 0x14, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20]) ||
-		check([0x66, 0x72, 0x65, 0x65], {offset: 4}) ||
-		check([0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20], {offset: 4}) ||
-		check([0x6D, 0x64, 0x61, 0x74], {offset: 4}) || // MJPEG
-		check([0x77, 0x69, 0x64, 0x65], {offset: 4})) {
-		return {
-			ext: 'mov',
-			mime: 'video/quicktime'
-		};
-	}
-
-	if (
-		check([0x52, 0x49, 0x46, 0x46]) &&
-		check([0x41, 0x56, 0x49], {offset: 8})
-	) {
-		return {
-			ext: 'avi',
-			mime: 'video/x-msvideo'
-		};
-	}
-
-	if (check([0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9])) {
-		return {
-			ext: 'wmv',
-			mime: 'video/x-ms-wmv'
-		};
-	}
-
-	if (check([0x0, 0x0, 0x1, 0xBA])) {
-		return {
-			ext: 'mpg',
-			mime: 'video/mpeg'
-		};
-	}
-
-	if (
-		check([0x49, 0x44, 0x33]) ||
-		check([0xFF, 0xFB])
-	) {
-		return {
-			ext: 'mp3',
-			mime: 'audio/mpeg'
-		};
-	}
-
-	if (
-		check([0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41], {offset: 4}) ||
-		check([0x4D, 0x34, 0x41, 0x20])
-	) {
-		return {
-			ext: 'm4a',
-			mime: 'audio/m4a'
-		};
-	}
-
-	// Needs to be before `ogg` check
-	if (check([0x4F, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64], {offset: 28})) {
-		return {
-			ext: 'opus',
-			mime: 'audio/opus'
-		};
-	}
-
-	if (check([0x4F, 0x67, 0x67, 0x53])) {
-		return {
-			ext: 'ogg',
-			mime: 'audio/ogg'
-		};
-	}
-
-	if (check([0x66, 0x4C, 0x61, 0x43])) {
-		return {
-			ext: 'flac',
-			mime: 'audio/x-flac'
-		};
-	}
-
-	if (
-		check([0x52, 0x49, 0x46, 0x46]) &&
-		check([0x57, 0x41, 0x56, 0x45], {offset: 8})
-	) {
-		return {
-			ext: 'wav',
-			mime: 'audio/x-wav'
-		};
-	}
-
-	if (check([0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A])) {
-		return {
-			ext: 'amr',
-			mime: 'audio/amr'
-		};
-	}
-
-	if (check([0x25, 0x50, 0x44, 0x46])) {
-		return {
-			ext: 'pdf',
-			mime: 'application/pdf'
-		};
-	}
-
-	if (check([0x4D, 0x5A])) {
-		return {
-			ext: 'exe',
-			mime: 'application/x-msdownload'
-		};
-	}
-
-	if (
-		(buf[0] === 0x43 || buf[0] === 0x46) &&
-		check([0x57, 0x53], {offset: 1})
-	) {
-		return {
-			ext: 'swf',
-			mime: 'application/x-shockwave-flash'
-		};
-	}
-
-	if (check([0x7B, 0x5C, 0x72, 0x74, 0x66])) {
-		return {
-			ext: 'rtf',
-			mime: 'application/rtf'
-		};
-	}
-
-	if (check([0x00, 0x61, 0x73, 0x6D])) {
-		return {
-			ext: 'wasm',
-			mime: 'application/wasm'
-		};
-	}
-
-	if (
-		check([0x77, 0x4F, 0x46, 0x46]) &&
-		(
-			check([0x00, 0x01, 0x00, 0x00], {offset: 4}) ||
-			check([0x4F, 0x54, 0x54, 0x4F], {offset: 4})
-		)
-	) {
-		return {
-			ext: 'woff',
-			mime: 'font/woff'
-		};
-	}
-
-	if (
-		check([0x77, 0x4F, 0x46, 0x32]) &&
-		(
-			check([0x00, 0x01, 0x00, 0x00], {offset: 4}) ||
-			check([0x4F, 0x54, 0x54, 0x4F], {offset: 4})
-		)
-	) {
-		return {
-			ext: 'woff2',
-			mime: 'font/woff2'
-		};
-	}
-
-	if (
-		check([0x4C, 0x50], {offset: 34}) &&
-		(
-			check([0x00, 0x00, 0x01], {offset: 8}) ||
-			check([0x01, 0x00, 0x02], {offset: 8}) ||
-			check([0x02, 0x00, 0x02], {offset: 8})
-		)
-	) {
-		return {
-			ext: 'eot',
-			mime: 'application/octet-stream'
-		};
-	}
-
-	if (check([0x00, 0x01, 0x00, 0x00, 0x00])) {
-		return {
-			ext: 'ttf',
-			mime: 'font/ttf'
-		};
-	}
-
-	if (check([0x4F, 0x54, 0x54, 0x4F, 0x00])) {
-		return {
-			ext: 'otf',
-			mime: 'font/otf'
-		};
-	}
-
-	if (check([0x00, 0x00, 0x01, 0x00])) {
-		return {
-			ext: 'ico',
-			mime: 'image/x-icon'
-		};
-	}
-
-	if (check([0x46, 0x4C, 0x56, 0x01])) {
-		return {
-			ext: 'flv',
-			mime: 'video/x-flv'
-		};
-	}
-
-	if (check([0x25, 0x21])) {
-		return {
-			ext: 'ps',
-			mime: 'application/postscript'
-		};
-	}
-
-	if (check([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])) {
-		return {
-			ext: 'xz',
-			mime: 'application/x-xz'
-		};
-	}
-
-	if (check([0x53, 0x51, 0x4C, 0x69])) {
-		return {
-			ext: 'sqlite',
-			mime: 'application/x-sqlite3'
-		};
-	}
-
-	if (check([0x4E, 0x45, 0x53, 0x1A])) {
-		return {
-			ext: 'nes',
-			mime: 'application/x-nintendo-nes-rom'
-		};
-	}
-
-	if (check([0x43, 0x72, 0x32, 0x34])) {
-		return {
-			ext: 'crx',
-			mime: 'application/x-google-chrome-extension'
-		};
-	}
-
-	if (
-		check([0x4D, 0x53, 0x43, 0x46]) ||
-		check([0x49, 0x53, 0x63, 0x28])
-	) {
-		return {
-			ext: 'cab',
-			mime: 'application/vnd.ms-cab-compressed'
-		};
-	}
-
-	// Needs to be before `ar` check
-	if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A, 0x64, 0x65, 0x62, 0x69, 0x61, 0x6E, 0x2D, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79])) {
-		return {
-			ext: 'deb',
-			mime: 'application/x-deb'
-		};
-	}
-
-	if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E])) {
-		return {
-			ext: 'ar',
-			mime: 'application/x-unix-archive'
-		};
-	}
-
-	if (check([0xED, 0xAB, 0xEE, 0xDB])) {
-		return {
-			ext: 'rpm',
-			mime: 'application/x-rpm'
-		};
-	}
-
-	if (
-		check([0x1F, 0xA0]) ||
-		check([0x1F, 0x9D])
-	) {
-		return {
-			ext: 'Z',
-			mime: 'application/x-compress'
-		};
-	}
-
-	if (check([0x4C, 0x5A, 0x49, 0x50])) {
-		return {
-			ext: 'lz',
-			mime: 'application/x-lzip'
-		};
-	}
-
-	if (check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) {
-		return {
-			ext: 'msi',
-			mime: 'application/x-msi'
-		};
-	}
-
-	if (check([0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02])) {
-		return {
-			ext: 'mxf',
-			mime: 'application/mxf'
-		};
-	}
-
-	if (check([0x47], {offset: 4}) && (check([0x47], {offset: 192}) || check([0x47], {offset: 196}))) {
-		return {
-			ext: 'mts',
-			mime: 'video/mp2t'
-		};
-	}
-
-	if (check([0x42, 0x4C, 0x45, 0x4E, 0x44, 0x45, 0x52])) {
-		return {
-			ext: 'blend',
-			mime: 'application/x-blender'
-		};
-	}
-
-	if (check([0x42, 0x50, 0x47, 0xFB])) {
-		return {
-			ext: 'bpg',
-			mime: 'image/bpg'
-		};
-	}
-
-	return null;
-};

+ 0 - 21
src/vendor/file-type/license

@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.

+ 0 - 109
src/vendor/file-type/package.json

@@ -1,109 +0,0 @@
-{
-  "name": "file-type",
-  "version": "5.2.0",
-  "description": "Detect the file type of a Buffer/Uint8Array",
-  "license": "MIT",
-  "repository": "sindresorhus/file-type",
-  "author": {
-    "name": "Sindre Sorhus",
-    "email": "sindresorhus@gmail.com",
-    "url": "sindresorhus.com"
-  },
-  "engines": {
-    "node": ">=4"
-  },
-  "scripts": {
-    "test": "xo && ava"
-  },
-  "files": [
-    "index.js"
-  ],
-  "keywords": [
-    "mime",
-    "file",
-    "type",
-    "archive",
-    "image",
-    "img",
-    "pic",
-    "picture",
-    "flash",
-    "photo",
-    "video",
-    "type",
-    "detect",
-    "check",
-    "is",
-    "exif",
-    "exe",
-    "binary",
-    "buffer",
-    "uint8array",
-    "jpg",
-    "png",
-    "gif",
-    "webp",
-    "flif",
-    "cr2",
-    "tif",
-    "bmp",
-    "jxr",
-    "psd",
-    "zip",
-    "tar",
-    "rar",
-    "gz",
-    "bz2",
-    "7z",
-    "dmg",
-    "mp4",
-    "m4v",
-    "mid",
-    "mkv",
-    "webm",
-    "mov",
-    "avi",
-    "mpg",
-    "mp3",
-    "m4a",
-    "ogg",
-    "opus",
-    "flac",
-    "wav",
-    "amr",
-    "pdf",
-    "epub",
-    "exe",
-    "swf",
-    "rtf",
-    "woff",
-    "woff2",
-    "eot",
-    "ttf",
-    "otf",
-    "ico",
-    "flv",
-    "ps",
-    "xz",
-    "sqlite",
-    "xpi",
-    "cab",
-    "deb",
-    "ar",
-    "rpm",
-    "Z",
-    "lz",
-    "msi",
-    "mxf",
-    "mts",
-    "wasm",
-    "webassembly",
-    "blend",
-    "bpg"
-  ],
-  "devDependencies": {
-    "ava": "*",
-    "read-chunk": "^2.0.0",
-    "xo": "*"
-  }
-}

+ 10 - 12
src/views/ProviderView/index.js

@@ -167,18 +167,16 @@ module.exports = class ProviderView {
       }
     }
 
-    Utils.getFileType(tagFile).then(fileType => {
-      if (fileType && Utils.isPreviewSupported(fileType)) {
-        tagFile.preview = this.plugin.getItemThumbnailUrl(file)
-      }
-      this.plugin.uppy.log('Adding remote file')
-      this.plugin.uppy.addFile(tagFile).catch(() => {
-        // Ignore
-      })
-      if (!isCheckbox) {
-        this.donePicking()
-      }
-    })
+    const fileType = Utils.getFileType(tagFile)
+    // TODO Should we just always use the thumbnail URL if it exists?
+    if (fileType && Utils.isPreviewSupported(fileType)) {
+      tagFile.preview = this.plugin.getItemThumbnailUrl(file)
+    }
+    this.plugin.uppy.log('Adding remote file')
+    this.plugin.uppy.addFile(tagFile)
+    if (!isCheckbox) {
+      this.donePicking()
+    }
   }
 
   /**

TEMPAT SAMPAH
test/resources/image.jpg


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini