├── .babelrc ├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── dist ├── filepond-plugin-file-validate-size.esm.js ├── filepond-plugin-file-validate-size.esm.min.js ├── filepond-plugin-file-validate-size.js └── filepond-plugin-file-validate-size.min.js ├── index.html ├── package-lock.json ├── package.json ├── rollup.config.js ├── rollup.scripts.js ├── src └── js │ └── index.js └── types └── index.d.ts /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "retainLines": true, 3 | "presets": [ 4 | ["@babel/preset-env", { 5 | "exclude": ["transform-typeof-symbol"], 6 | "modules": false 7 | }] 8 | ], 9 | "plugins": [ 10 | ["@babel/plugin-proposal-object-rest-spread", { 11 | "loose": true, 12 | "useBuiltIns": true 13 | }] 14 | ] 15 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | dist/* linguist-vendored=false 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules/ -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist/* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "svelteSortOrder": "scripts-markup-styles", 3 | "trailingComma": "es5", 4 | "tabWidth": 4, 5 | "printWidth": 100, 6 | "singleQuote": true, 7 | "semi": true 8 | } 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 PQINA | Rik Schennink 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # File Size Validation plugin for FilePond 2 | 3 | [![npm version](https://badge.fury.io/js/filepond-plugin-file-validate-size.svg)](https://badge.fury.io/js/filepond) 4 | 5 | https://pqina.nl/filepond/docs/patterns/plugins/file-validate-size/ 6 | 7 | The File Size Validation plugin is used to block files that are too large to upload. Set a maximum size for single files and a maximum size for all files. 8 | 9 | [Demo](https://pqina.github.io/filepond-plugin-file-validate-size/) -------------------------------------------------------------------------------- /dist/filepond-plugin-file-validate-size.esm.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePondPluginFileValidateSize 2.2.8 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | 9 | const plugin = ({ addFilter, utils }) => { 10 | // get quick reference to Type utils 11 | const { Type, replaceInString, toNaturalFileSize } = utils; 12 | 13 | // filtering if an item is allowed in hopper 14 | addFilter('ALLOW_HOPPER_ITEM', (file, { query }) => { 15 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 16 | return true; 17 | } 18 | 19 | const sizeMax = query('GET_MAX_FILE_SIZE'); 20 | if (sizeMax !== null && file.size > sizeMax) { 21 | return false; 22 | } 23 | 24 | const sizeMin = query('GET_MIN_FILE_SIZE'); 25 | if (sizeMin !== null && file.size < sizeMin) { 26 | return false; 27 | } 28 | 29 | return true; 30 | }); 31 | 32 | // called for each file that is loaded 33 | // right before it is set to the item state 34 | // should return a promise 35 | addFilter( 36 | 'LOAD_FILE', 37 | (file, { query }) => 38 | new Promise((resolve, reject) => { 39 | // if not allowed, all fine, exit 40 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 41 | return resolve(file); 42 | } 43 | 44 | // check if file should be filtered 45 | const fileFilter = query('GET_FILE_VALIDATE_SIZE_FILTER'); 46 | if (fileFilter && !fileFilter(file)) { 47 | return resolve(file); 48 | } 49 | 50 | // reject or resolve based on file size 51 | const sizeMax = query('GET_MAX_FILE_SIZE'); 52 | if (sizeMax !== null && file.size > sizeMax) { 53 | reject({ 54 | status: { 55 | main: query('GET_LABEL_MAX_FILE_SIZE_EXCEEDED'), 56 | sub: replaceInString(query('GET_LABEL_MAX_FILE_SIZE'), { 57 | filesize: toNaturalFileSize( 58 | sizeMax, 59 | '.', 60 | query('GET_FILE_SIZE_BASE'), 61 | query('GET_FILE_SIZE_LABELS', query) 62 | ), 63 | }), 64 | }, 65 | }); 66 | return; 67 | } 68 | 69 | // reject or resolve based on file size 70 | const sizeMin = query('GET_MIN_FILE_SIZE'); 71 | if (sizeMin !== null && file.size < sizeMin) { 72 | reject({ 73 | status: { 74 | main: query('GET_LABEL_MIN_FILE_SIZE_EXCEEDED'), 75 | sub: replaceInString(query('GET_LABEL_MIN_FILE_SIZE'), { 76 | filesize: toNaturalFileSize( 77 | sizeMin, 78 | '.', 79 | query('GET_FILE_SIZE_BASE'), 80 | query('GET_FILE_SIZE_LABELS', query) 81 | ), 82 | }), 83 | }, 84 | }); 85 | return; 86 | } 87 | 88 | // returns the current option value 89 | const totalSizeMax = query('GET_MAX_TOTAL_FILE_SIZE'); 90 | if (totalSizeMax !== null) { 91 | // get the current total file size 92 | const currentTotalSize = query('GET_ACTIVE_ITEMS').reduce((total, item) => { 93 | return total + item.fileSize; 94 | }, 0); 95 | 96 | // get the size of the new file 97 | if (currentTotalSize > totalSizeMax) { 98 | reject({ 99 | status: { 100 | main: query('GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED'), 101 | sub: replaceInString(query('GET_LABEL_MAX_TOTAL_FILE_SIZE'), { 102 | filesize: toNaturalFileSize( 103 | totalSizeMax, 104 | '.', 105 | query('GET_FILE_SIZE_BASE'), 106 | query('GET_FILE_SIZE_LABELS', query) 107 | ), 108 | }), 109 | }, 110 | }); 111 | return; 112 | } 113 | } 114 | 115 | // file is fine, let's pass it back 116 | resolve(file); 117 | }) 118 | ); 119 | 120 | return { 121 | options: { 122 | // Enable or disable file type validation 123 | allowFileSizeValidation: [true, Type.BOOLEAN], 124 | 125 | // Max individual file size in bytes 126 | maxFileSize: [null, Type.INT], 127 | 128 | // Min individual file size in bytes 129 | minFileSize: [null, Type.INT], 130 | 131 | // Max total file size in bytes 132 | maxTotalFileSize: [null, Type.INT], 133 | 134 | // Filter the files that need to be validated for size 135 | fileValidateSizeFilter: [null, Type.FUNCTION], 136 | 137 | // error labels 138 | labelMinFileSizeExceeded: ['File is too small', Type.STRING], 139 | labelMinFileSize: ['Minimum file size is {filesize}', Type.STRING], 140 | 141 | labelMaxFileSizeExceeded: ['File is too large', Type.STRING], 142 | labelMaxFileSize: ['Maximum file size is {filesize}', Type.STRING], 143 | 144 | labelMaxTotalFileSizeExceeded: ['Maximum total size exceeded', Type.STRING], 145 | labelMaxTotalFileSize: ['Maximum total file size is {filesize}', Type.STRING], 146 | }, 147 | }; 148 | }; 149 | 150 | // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags 151 | const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'; 152 | if (isBrowser) { 153 | document.dispatchEvent(new CustomEvent('FilePond:pluginloaded', { detail: plugin })); 154 | } 155 | 156 | export default plugin; 157 | -------------------------------------------------------------------------------- /dist/filepond-plugin-file-validate-size.esm.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePondPluginFileValidateSize 2.2.8 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | 9 | const e=({addFilter:e,utils:E})=>{const{Type:i,replaceInString:_,toNaturalFileSize:l}=E;return e("ALLOW_HOPPER_ITEM",(e,{query:E})=>{if(!E("GET_ALLOW_FILE_SIZE_VALIDATION"))return!0;const i=E("GET_MAX_FILE_SIZE");if(null!==i&&e.size>i)return!1;const _=E("GET_MIN_FILE_SIZE");return!(null!==_&&e.size<_)}),e("LOAD_FILE",(e,{query:E})=>new Promise((i,I)=>{if(!E("GET_ALLOW_FILE_SIZE_VALIDATION"))return i(e);const L=E("GET_FILE_VALIDATE_SIZE_FILTER");if(L&&!L(e))return i(e);const t=E("GET_MAX_FILE_SIZE");if(null!==t&&e.size>t)return void I({status:{main:E("GET_LABEL_MAX_FILE_SIZE_EXCEEDED"),sub:_(E("GET_LABEL_MAX_FILE_SIZE"),{filesize:l(t,".",E("GET_FILE_SIZE_BASE"),E("GET_FILE_SIZE_LABELS",E))})}});const n=E("GET_MIN_FILE_SIZE");if(null!==n&&e.sizee+E.fileSize,0)>T)return void I({status:{main:E("GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED"),sub:_(E("GET_LABEL_MAX_TOTAL_FILE_SIZE"),{filesize:l(T,".",E("GET_FILE_SIZE_BASE"),E("GET_FILE_SIZE_LABELS",E))})}})}i(e)})),{options:{allowFileSizeValidation:[!0,i.BOOLEAN],maxFileSize:[null,i.INT],minFileSize:[null,i.INT],maxTotalFileSize:[null,i.INT],fileValidateSizeFilter:[null,i.FUNCTION],labelMinFileSizeExceeded:["File is too small",i.STRING],labelMinFileSize:["Minimum file size is {filesize}",i.STRING],labelMaxFileSizeExceeded:["File is too large",i.STRING],labelMaxFileSize:["Maximum file size is {filesize}",i.STRING],labelMaxTotalFileSizeExceeded:["Maximum total size exceeded",i.STRING],labelMaxTotalFileSize:["Maximum total file size is {filesize}",i.STRING]}}};"undefined"!=typeof window&&void 0!==window.document&&document.dispatchEvent(new CustomEvent("FilePond:pluginloaded",{detail:e}));export default e; 10 | -------------------------------------------------------------------------------- /dist/filepond-plugin-file-validate-size.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePondPluginFileValidateSize 2.2.8 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | 9 | (function(global, factory) { 10 | typeof exports === 'object' && typeof module !== 'undefined' 11 | ? (module.exports = factory()) 12 | : typeof define === 'function' && define.amd 13 | ? define(factory) 14 | : ((global = global || self), (global.FilePondPluginFileValidateSize = factory())); 15 | })(this, function() { 16 | 'use strict'; 17 | 18 | var plugin = function plugin(_ref) { 19 | var addFilter = _ref.addFilter, 20 | utils = _ref.utils; 21 | // get quick reference to Type utils 22 | var Type = utils.Type, 23 | replaceInString = utils.replaceInString, 24 | toNaturalFileSize = utils.toNaturalFileSize; 25 | 26 | // filtering if an item is allowed in hopper 27 | addFilter('ALLOW_HOPPER_ITEM', function(file, _ref2) { 28 | var query = _ref2.query; 29 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 30 | return true; 31 | } 32 | 33 | var sizeMax = query('GET_MAX_FILE_SIZE'); 34 | if (sizeMax !== null && file.size > sizeMax) { 35 | return false; 36 | } 37 | 38 | var sizeMin = query('GET_MIN_FILE_SIZE'); 39 | if (sizeMin !== null && file.size < sizeMin) { 40 | return false; 41 | } 42 | 43 | return true; 44 | }); 45 | 46 | // called for each file that is loaded 47 | // right before it is set to the item state 48 | // should return a promise 49 | addFilter('LOAD_FILE', function(file, _ref3) { 50 | var query = _ref3.query; 51 | return new Promise(function(resolve, reject) { 52 | // if not allowed, all fine, exit 53 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 54 | return resolve(file); 55 | } 56 | 57 | // check if file should be filtered 58 | var fileFilter = query('GET_FILE_VALIDATE_SIZE_FILTER'); 59 | if (fileFilter && !fileFilter(file)) { 60 | return resolve(file); 61 | } 62 | 63 | // reject or resolve based on file size 64 | var sizeMax = query('GET_MAX_FILE_SIZE'); 65 | if (sizeMax !== null && file.size > sizeMax) { 66 | reject({ 67 | status: { 68 | main: query('GET_LABEL_MAX_FILE_SIZE_EXCEEDED'), 69 | sub: replaceInString(query('GET_LABEL_MAX_FILE_SIZE'), { 70 | filesize: toNaturalFileSize( 71 | sizeMax, 72 | '.', 73 | query('GET_FILE_SIZE_BASE'), 74 | query('GET_FILE_SIZE_LABELS', query) 75 | ), 76 | }), 77 | }, 78 | }); 79 | 80 | return; 81 | } 82 | 83 | // reject or resolve based on file size 84 | var sizeMin = query('GET_MIN_FILE_SIZE'); 85 | if (sizeMin !== null && file.size < sizeMin) { 86 | reject({ 87 | status: { 88 | main: query('GET_LABEL_MIN_FILE_SIZE_EXCEEDED'), 89 | sub: replaceInString(query('GET_LABEL_MIN_FILE_SIZE'), { 90 | filesize: toNaturalFileSize( 91 | sizeMin, 92 | '.', 93 | query('GET_FILE_SIZE_BASE'), 94 | query('GET_FILE_SIZE_LABELS', query) 95 | ), 96 | }), 97 | }, 98 | }); 99 | 100 | return; 101 | } 102 | 103 | // returns the current option value 104 | var totalSizeMax = query('GET_MAX_TOTAL_FILE_SIZE'); 105 | if (totalSizeMax !== null) { 106 | // get the current total file size 107 | var currentTotalSize = query('GET_ACTIVE_ITEMS').reduce(function(total, item) { 108 | return total + item.fileSize; 109 | }, 0); 110 | 111 | // get the size of the new file 112 | if (currentTotalSize > totalSizeMax) { 113 | reject({ 114 | status: { 115 | main: query('GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED'), 116 | sub: replaceInString(query('GET_LABEL_MAX_TOTAL_FILE_SIZE'), { 117 | filesize: toNaturalFileSize( 118 | totalSizeMax, 119 | '.', 120 | query('GET_FILE_SIZE_BASE'), 121 | query('GET_FILE_SIZE_LABELS', query) 122 | ), 123 | }), 124 | }, 125 | }); 126 | 127 | return; 128 | } 129 | } 130 | 131 | // file is fine, let's pass it back 132 | resolve(file); 133 | }); 134 | }); 135 | 136 | return { 137 | options: { 138 | // Enable or disable file type validation 139 | allowFileSizeValidation: [true, Type.BOOLEAN], 140 | 141 | // Max individual file size in bytes 142 | maxFileSize: [null, Type.INT], 143 | 144 | // Min individual file size in bytes 145 | minFileSize: [null, Type.INT], 146 | 147 | // Max total file size in bytes 148 | maxTotalFileSize: [null, Type.INT], 149 | 150 | // Filter the files that need to be validated for size 151 | fileValidateSizeFilter: [null, Type.FUNCTION], 152 | 153 | // error labels 154 | labelMinFileSizeExceeded: ['File is too small', Type.STRING], 155 | labelMinFileSize: ['Minimum file size is {filesize}', Type.STRING], 156 | 157 | labelMaxFileSizeExceeded: ['File is too large', Type.STRING], 158 | labelMaxFileSize: ['Maximum file size is {filesize}', Type.STRING], 159 | 160 | labelMaxTotalFileSizeExceeded: ['Maximum total size exceeded', Type.STRING], 161 | labelMaxTotalFileSize: ['Maximum total file size is {filesize}', Type.STRING], 162 | }, 163 | }; 164 | }; 165 | 166 | // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags 167 | var isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'; 168 | if (isBrowser) { 169 | document.dispatchEvent(new CustomEvent('FilePond:pluginloaded', { detail: plugin })); 170 | } 171 | 172 | return plugin; 173 | }); 174 | -------------------------------------------------------------------------------- /dist/filepond-plugin-file-validate-size.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FilePondPluginFileValidateSize 2.2.8 3 | * Licensed under MIT, https://opensource.org/licenses/MIT/ 4 | * Please visit https://pqina.nl/filepond/ for details. 5 | */ 6 | 7 | /* eslint-disable */ 8 | 9 | !function(e,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(e=e||self).FilePondPluginFileValidateSize=i()}(this,function(){"use strict";var e=function(e){var i=e.addFilter,E=e.utils,l=E.Type,_=E.replaceInString,n=E.toNaturalFileSize;return i("ALLOW_HOPPER_ITEM",function(e,i){var E=i.query;if(!E("GET_ALLOW_FILE_SIZE_VALIDATION"))return!0;var l=E("GET_MAX_FILE_SIZE");if(null!==l&&e.size>l)return!1;var _=E("GET_MIN_FILE_SIZE");return!(null!==_&&e.size<_)}),i("LOAD_FILE",function(e,i){var E=i.query;return new Promise(function(i,l){if(!E("GET_ALLOW_FILE_SIZE_VALIDATION"))return i(e);var I=E("GET_FILE_VALIDATE_SIZE_FILTER");if(I&&!I(e))return i(e);var t=E("GET_MAX_FILE_SIZE");if(null!==t&&e.size>t)l({status:{main:E("GET_LABEL_MAX_FILE_SIZE_EXCEEDED"),sub:_(E("GET_LABEL_MAX_FILE_SIZE"),{filesize:n(t,".",E("GET_FILE_SIZE_BASE"),E("GET_FILE_SIZE_LABELS",E))})}});else{var L=E("GET_MIN_FILE_SIZE");if(null!==L&&e.sizea)return void l({status:{main:E("GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED"),sub:_(E("GET_LABEL_MAX_TOTAL_FILE_SIZE"),{filesize:n(a,".",E("GET_FILE_SIZE_BASE"),E("GET_FILE_SIZE_LABELS",E))})}});i(e)}}})}),{options:{allowFileSizeValidation:[!0,l.BOOLEAN],maxFileSize:[null,l.INT],minFileSize:[null,l.INT],maxTotalFileSize:[null,l.INT],fileValidateSizeFilter:[null,l.FUNCTION],labelMinFileSizeExceeded:["File is too small",l.STRING],labelMinFileSize:["Minimum file size is {filesize}",l.STRING],labelMaxFileSizeExceeded:["File is too large",l.STRING],labelMaxFileSize:["Maximum file size is {filesize}",l.STRING],labelMaxTotalFileSizeExceeded:["Maximum total size exceeded",l.STRING],labelMaxTotalFileSize:["Maximum total file size is {filesize}",l.STRING]}}};return"undefined"!=typeof window&&void 0!==window.document&&document.dispatchEvent(new CustomEvent("FilePond:pluginloaded",{detail:e})),e}); 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | FilePond Plugin File Validate Size Demo 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "filepond-plugin-file-validate-size", 3 | "version": "2.2.8", 4 | "description": "File Size Validation Plugin for FilePond", 5 | "license": "MIT", 6 | "author": { 7 | "name": "PQINA", 8 | "url": "https://pqina.nl/" 9 | }, 10 | "homepage": "https://pqina.nl/filepond/", 11 | "repository": "pqina/filepond-plugin-file-validate-size", 12 | "main": "dist/filepond-plugin-file-validate-size.js", 13 | "browser": "dist/filepond-plugin-file-validate-size.js", 14 | "module": "dist/filepond-plugin-file-validate-size.esm.js", 15 | "browserslist": [ 16 | "last 1 version and not Explorer 10", 17 | "Explorer 11", 18 | "iOS >= 9", 19 | "Android >= 4.4" 20 | ], 21 | "files": [ 22 | "dist", 23 | "types/*.d.ts" 24 | ], 25 | "types": "types/index.d.ts", 26 | "scripts": { 27 | "start": "npx rollup -c -w", 28 | "build": "npx rollup -c" 29 | }, 30 | "peerDependencies": { 31 | "filepond": ">=3.1.2 <5.x" 32 | }, 33 | "devDependencies": { 34 | "@babel/core": "^7.4.0", 35 | "@babel/preset-env": "^7.4.2", 36 | "rollup": "^1.7.0", 37 | "rollup-plugin-babel": "^4.3.2", 38 | "rollup-plugin-commonjs": "^9.2.1", 39 | "rollup-plugin-license": "^0.8.1", 40 | "rollup-plugin-node-resolve": "^4.0.1", 41 | "rollup-plugin-prettier": "^0.6.0", 42 | "rollup-plugin-terser": "^4.0.4" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import * as pkg from './package.json'; 2 | import build from './rollup.scripts'; 3 | 4 | export default build( 5 | { 6 | id: 'FilePondPluginFileValidateSize', 7 | ...pkg 8 | }, 9 | [ 10 | { 11 | format: 'umd', 12 | transpile: true 13 | }, 14 | { 15 | format: 'umd', 16 | transpile: true, 17 | minify: true 18 | }, 19 | { 20 | format: 'es' 21 | }, 22 | { 23 | format: 'es', 24 | minify: true 25 | } 26 | ] 27 | ); -------------------------------------------------------------------------------- /rollup.scripts.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel'; 2 | import license from 'rollup-plugin-license'; 3 | import { terser } from 'rollup-plugin-terser'; 4 | import prettier from 'rollup-plugin-prettier'; 5 | 6 | const createBanner = ({ id, version, license, homepage }) => ({banner:`/*! 7 | * ${ id } ${ version } 8 | * Licensed under ${ license }, https://opensource.org/licenses/${ license }/ 9 | * Please visit ${ homepage } for details. 10 | */ 11 | 12 | /* eslint-disable */ 13 | `}); 14 | 15 | const createBuild = (options) => { 16 | const { format, id, name, minify = false, transpile = false } = options; 17 | 18 | // get filename 19 | const filename = ['dist/', name]; 20 | if (format === 'es') { 21 | filename.push('.esm'); 22 | } 23 | if (minify) { 24 | filename.push('.min'); 25 | } 26 | filename.push('.js'); 27 | 28 | // collect plugins 29 | const plugins = []; 30 | if (transpile) { 31 | plugins.push(babel({ 32 | exclude: ['node_modules/**'] 33 | })) 34 | } 35 | if (minify) { 36 | plugins.push(terser()) 37 | } 38 | else { 39 | plugins.push(prettier({ 40 | singleQuote: true, 41 | parser: 'babel' 42 | })) 43 | } 44 | plugins.push(license(createBanner(options))) 45 | 46 | // return Rollup config 47 | return { 48 | input: 'src/js/index.js', 49 | treeshake: false, 50 | output: [ 51 | { 52 | format, 53 | name: id, 54 | file: filename.join('') 55 | } 56 | ], 57 | plugins 58 | } 59 | }; 60 | 61 | export default (metadata, configs) => configs.map(config => createBuild({ ...metadata, ...config })); -------------------------------------------------------------------------------- /src/js/index.js: -------------------------------------------------------------------------------- 1 | const plugin = ({ addFilter, utils }) => { 2 | // get quick reference to Type utils 3 | const { Type, replaceInString, toNaturalFileSize } = utils; 4 | 5 | // filtering if an item is allowed in hopper 6 | addFilter('ALLOW_HOPPER_ITEM', (file, { query }) => { 7 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 8 | return true; 9 | } 10 | 11 | const sizeMax = query('GET_MAX_FILE_SIZE'); 12 | if (sizeMax !== null && file.size > sizeMax) { 13 | return false; 14 | } 15 | 16 | const sizeMin = query('GET_MIN_FILE_SIZE'); 17 | if (sizeMin !== null && file.size < sizeMin) { 18 | return false; 19 | } 20 | 21 | return true; 22 | }); 23 | 24 | // called for each file that is loaded 25 | // right before it is set to the item state 26 | // should return a promise 27 | addFilter( 28 | 'LOAD_FILE', 29 | (file, { query }) => 30 | new Promise((resolve, reject) => { 31 | // if not allowed, all fine, exit 32 | if (!query('GET_ALLOW_FILE_SIZE_VALIDATION')) { 33 | return resolve(file); 34 | } 35 | 36 | // check if file should be filtered 37 | const fileFilter = query('GET_FILE_VALIDATE_SIZE_FILTER'); 38 | if (fileFilter && !fileFilter(file)) { 39 | return resolve(file); 40 | } 41 | 42 | // reject or resolve based on file size 43 | const sizeMax = query('GET_MAX_FILE_SIZE'); 44 | if (sizeMax !== null && file.size > sizeMax) { 45 | reject({ 46 | status: { 47 | main: query('GET_LABEL_MAX_FILE_SIZE_EXCEEDED'), 48 | sub: replaceInString(query('GET_LABEL_MAX_FILE_SIZE'), { 49 | filesize: toNaturalFileSize( 50 | sizeMax, 51 | '.', 52 | query('GET_FILE_SIZE_BASE'), 53 | query('GET_FILE_SIZE_LABELS', query) 54 | ), 55 | }), 56 | }, 57 | }); 58 | return; 59 | } 60 | 61 | // reject or resolve based on file size 62 | const sizeMin = query('GET_MIN_FILE_SIZE'); 63 | if (sizeMin !== null && file.size < sizeMin) { 64 | reject({ 65 | status: { 66 | main: query('GET_LABEL_MIN_FILE_SIZE_EXCEEDED'), 67 | sub: replaceInString(query('GET_LABEL_MIN_FILE_SIZE'), { 68 | filesize: toNaturalFileSize( 69 | sizeMin, 70 | '.', 71 | query('GET_FILE_SIZE_BASE'), 72 | query('GET_FILE_SIZE_LABELS', query) 73 | ), 74 | }), 75 | }, 76 | }); 77 | return; 78 | } 79 | 80 | // returns the current option value 81 | const totalSizeMax = query('GET_MAX_TOTAL_FILE_SIZE'); 82 | if (totalSizeMax !== null) { 83 | // get the current total file size 84 | const currentTotalSize = query('GET_ACTIVE_ITEMS').reduce((total, item) => { 85 | return total + item.fileSize; 86 | }, 0); 87 | 88 | // get the size of the new file 89 | if (currentTotalSize > totalSizeMax) { 90 | reject({ 91 | status: { 92 | main: query('GET_LABEL_MAX_TOTAL_FILE_SIZE_EXCEEDED'), 93 | sub: replaceInString(query('GET_LABEL_MAX_TOTAL_FILE_SIZE'), { 94 | filesize: toNaturalFileSize( 95 | totalSizeMax, 96 | '.', 97 | query('GET_FILE_SIZE_BASE'), 98 | query('GET_FILE_SIZE_LABELS', query) 99 | ), 100 | }), 101 | }, 102 | }); 103 | return; 104 | } 105 | } 106 | 107 | // file is fine, let's pass it back 108 | resolve(file); 109 | }) 110 | ); 111 | 112 | return { 113 | options: { 114 | // Enable or disable file type validation 115 | allowFileSizeValidation: [true, Type.BOOLEAN], 116 | 117 | // Max individual file size in bytes 118 | maxFileSize: [null, Type.INT], 119 | 120 | // Min individual file size in bytes 121 | minFileSize: [null, Type.INT], 122 | 123 | // Max total file size in bytes 124 | maxTotalFileSize: [null, Type.INT], 125 | 126 | // Filter the files that need to be validated for size 127 | fileValidateSizeFilter: [null, Type.FUNCTION], 128 | 129 | // error labels 130 | labelMinFileSizeExceeded: ['File is too small', Type.STRING], 131 | labelMinFileSize: ['Minimum file size is {filesize}', Type.STRING], 132 | 133 | labelMaxFileSizeExceeded: ['File is too large', Type.STRING], 134 | labelMaxFileSize: ['Maximum file size is {filesize}', Type.STRING], 135 | 136 | labelMaxTotalFileSizeExceeded: ['Maximum total size exceeded', Type.STRING], 137 | labelMaxTotalFileSize: ['Maximum total file size is {filesize}', Type.STRING], 138 | }, 139 | }; 140 | }; 141 | 142 | // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags 143 | const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'; 144 | if (isBrowser) { 145 | document.dispatchEvent(new CustomEvent('FilePond:pluginloaded', { detail: plugin })); 146 | } 147 | 148 | export default plugin; 149 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import { FilePondOptions } from "filepond"; 3 | 4 | declare module "filepond" { 5 | export interface FilePondOptions { 6 | /** Enable or disable file size validation. */ 7 | allowFileSizeValidation?: boolean; 8 | /** The minimum size of a file, for instance 5MB or 750KB. */ 9 | minFileSize?: string | null; 10 | /** Message shown when a small file is dropped. */ 11 | labelMinFileSizeExceeded?: string; 12 | /** Message shown when the file size is lower than the {filesize}. {filesize} is replaced with the value of the minFileSize property */ 13 | labelMinFileSize?: string; 14 | /** The maximum size of a file, for instance 5MB or 750KB. */ 15 | maxFileSize?: string | null; 16 | /** Maximum size of all files in list, same format as maxFileSize. */ 17 | maxTotalFileSize?: string | null; 18 | /** Message shown when a large file is dropped. */ 19 | labelMaxFileSizeExceeded?: string; 20 | /** Message shown when max file size was exceeded. {filesize} is replaced with the value of the maxFileSize property. */ 21 | labelMaxFileSize?: string; 22 | /** Message shown when total file size exceeds maximum. */ 23 | labelMaxTotalFileSizeExceeded?: string; 24 | /** Message shown then total file size exceeds maximum. */ 25 | labelMaxTotalFileSize?: string; 26 | } 27 | } 28 | --------------------------------------------------------------------------------