Ver Fonte

Restrictions: add maxTotalFileSize (#2594)

* add maxTotalFileSize restriction and tests

* docs and types

* use file.data.size and expect.toThrowError in tests
Artur Paikin há 4 anos atrás
pai
commit
9b5d3ec9a7

+ 17 - 1
packages/@uppy/core/src/index.js

@@ -97,6 +97,7 @@ class Uppy {
       restrictions: {
         maxFileSize: null,
         minFileSize: null,
+        maxTotalFileSize: null,
         maxNumberOfFiles: null,
         minNumberOfFiles: null,
         allowedFileTypes: null
@@ -444,7 +445,7 @@ class Uppy {
    * @private
    */
   _checkRestrictions (files, file) {
-    const { maxFileSize, minFileSize, maxNumberOfFiles, allowedFileTypes } = this.opts.restrictions
+    const { maxFileSize, minFileSize, maxTotalFileSize, maxNumberOfFiles, allowedFileTypes } = this.opts.restrictions
 
     if (maxNumberOfFiles) {
       if (Object.keys(files).length + 1 > maxNumberOfFiles) {
@@ -473,6 +474,21 @@ class Uppy {
       }
     }
 
+    // We can't check maxTotalFileSize if the size is unknown.
+    if (maxTotalFileSize && file.data.size != null) {
+      let totalFilesSize = 0
+      totalFilesSize += file.data.size
+      Object.keys(files).forEach((file) => {
+        totalFilesSize += files[file].data.size
+      })
+      if (totalFilesSize > maxTotalFileSize) {
+        throw new RestrictionError(this.i18n('exceedsSize2', {
+          backwardsCompat: this.i18n('exceedsSize'),
+          size: prettierBytes(maxTotalFileSize)
+        }))
+      }
+    }
+
     // We can't check maxFileSize if the size is unknown.
     if (maxFileSize && file.data.size != null) {
       if (file.data.size > maxFileSize) {

+ 26 - 0
packages/@uppy/core/src/index.test.js

@@ -1604,6 +1604,32 @@ describe('src/Core', () => {
       }
     })
 
+    it('should enforce the maxTotalFileSize rule', () => {
+      const core = new Core({
+        restrictions: {
+          maxTotalFileSize: 34000
+        }
+      })
+
+      core.addFile({
+        source: 'jest',
+        name: 'foo.jpg',
+        type: 'image/jpeg',
+        data: new File([sampleImage], { type: 'image/jpeg' })
+      })
+
+      expect(() => {
+        core.addFile({
+          source: 'jest',
+          name: 'foo1.jpg',
+          type: 'image/jpeg',
+          data: new File([sampleImage], { type: 'image/jpeg' })
+        })
+      }).toThrowError(
+        new Error('This file exceeds maximum allowed size of 33 KB')
+      )
+    })
+
     it('should emit `restriction-failed` event when some rule is violated', () => {
       const maxFileSize = 100
       const core = new Core({

+ 1 - 0
packages/@uppy/core/types/index.d.ts

@@ -76,6 +76,7 @@ declare module Uppy {
   interface Restrictions {
     maxFileSize?: number | null
     minFileSize?: number | null
+    maxTotalFileSize?: number | null
     maxNumberOfFiles?: number | null
     minNumberOfFiles?: number | null
     allowedFileTypes?: string[] | null

+ 4 - 0
website/src/docs/robodog-dashboard.md

@@ -53,6 +53,10 @@ Maximum file size in bytes for each individual file.
 
 Minimum file size in bytes for each individual file.
 
+### `restrictions.maxTotalFileSize`
+
+Maximum file size in bytes for all the files together.
+
 ### `restrictions.maxNumberOfFiles`
 
 The total number of files that can be selected. If this is larger than 1, the `multiple` attribute will be added to `<input type="file">` fields.

+ 4 - 0
website/src/docs/robodog-form.md

@@ -61,6 +61,10 @@ Maximum file size in bytes for each individual file.
 
 Minimum file size in bytes for each individual file.
 
+### `restrictions.maxTotalFileSize`
+
+Maximum file size in bytes for all the files together.
+
 ### `restrictions.maxNumberOfFiles`
 
 The total number of files that can be selected. If this is larger than 1, the `multiple` attribute will be added to `<input type="file">` fields.

+ 4 - 0
website/src/docs/robodog-picker.md

@@ -51,6 +51,10 @@ Maximum file size in bytes for each individual file.
 
 Minimum file size in bytes for each individual file.
 
+### `restrictions.maxTotalFileSize`
+
+Maximum file size in bytes for all the files together.
+
 ### `restrictions.maxNumberOfFiles`
 
 The total number of files that can be selected. If this is equal to 1, users can only select a single file in system dialogs; else they can select multiple.

+ 5 - 3
website/src/docs/uppy.md

@@ -76,6 +76,7 @@ const uppy = new Uppy({
   restrictions: {
     maxFileSize: null,
     minFileSize: null,
+    maxTotalFileSize: null,
     maxNumberOfFiles: null,
     minNumberOfFiles: null,
     allowedFileTypes: null
@@ -164,6 +165,7 @@ Optionally, provide rules and conditions to limit the type and/or number of file
 
 - `maxFileSize` *null | number* — maximum file size in bytes for each individual file (total max size [has been requested, and is planned](https://github.com/transloadit/uppy/issues/514))
 - `minFileSize` *null | number* — minimum file size in bytes for each individual file
+- `maxTotalFileSize` *null | number* — maximum file size in bytes for all the files that can be selected for upload
 - `maxNumberOfFiles` *null | number* — total number of files that can be selected
 - `minNumberOfFiles` *null | number* — minimum number of files that must be selected before the upload
 - `allowedFileTypes` *null | array* of wildcards `image/*`, exact mime types `image/jpeg`, or file extensions `.jpg`: `['image/*', '.jpg', '.jpeg', '.png', '.gif']`
@@ -688,9 +690,9 @@ this.info('Oh my, something good happened!', 'success', 3000)
 
 ```js
 this.info({
-    message: 'Oh no, something bad happened!',
-    details: 'File couldn’t be uploaded because there is no internet connection',
-  }, 'error', 5000)
+  message: 'Oh no, something bad happened!',
+  details: 'File couldn’t be uploaded because there is no internet connection',
+}, 'error', 5000)
 ```
 
 `info-visible` and `info-hidden` events are emitted when this info message should be visible or hidden.