diff --git a/app/assets/javascripts/discourse-shims.js b/app/assets/javascripts/discourse-shims.js index 71ce8478e37..e93da4e080a 100644 --- a/app/assets/javascripts/discourse-shims.js +++ b/app/assets/javascripts/discourse-shims.js @@ -32,7 +32,7 @@ define("@popperjs/core", ["exports"], function (__exports__) { define("@uppy/core", ["exports"], function (__exports__) { __exports__.default = window.Uppy.Core; - __exports__.Plugin = window.Uppy.Plugin; + __exports__.BasePlugin = window.Uppy.Core.BasePlugin; }); define("@uppy/aws-s3", ["exports"], function (__exports__) { diff --git a/app/assets/javascripts/discourse/app/lib/uppy-checksum-plugin.js b/app/assets/javascripts/discourse/app/lib/uppy-checksum-plugin.js index 4cd0cea0476..3e74b36252f 100644 --- a/app/assets/javascripts/discourse/app/lib/uppy-checksum-plugin.js +++ b/app/assets/javascripts/discourse/app/lib/uppy-checksum-plugin.js @@ -1,8 +1,8 @@ -import { Plugin } from "@uppy/core"; +import { BasePlugin } from "@uppy/core"; import { warn } from "@ember/debug"; import { Promise } from "rsvp"; -export default class UppyChecksum extends Plugin { +export default class UppyChecksum extends BasePlugin { constructor(uppy, opts) { super(uppy, opts); this.id = opts.id || "uppy-checksum"; diff --git a/app/assets/javascripts/discourse/app/lib/uppy-media-optimization-plugin.js b/app/assets/javascripts/discourse/app/lib/uppy-media-optimization-plugin.js index 862a55a34d8..dcf3c3121ba 100644 --- a/app/assets/javascripts/discourse/app/lib/uppy-media-optimization-plugin.js +++ b/app/assets/javascripts/discourse/app/lib/uppy-media-optimization-plugin.js @@ -1,8 +1,8 @@ -import { Plugin } from "@uppy/core"; +import { BasePlugin } from "@uppy/core"; import { warn } from "@ember/debug"; import { Promise } from "rsvp"; -export default class UppyMediaOptimization extends Plugin { +export default class UppyMediaOptimization extends BasePlugin { constructor(uppy, opts) { super(uppy, opts); this.id = opts.id || "uppy-media-optimization"; diff --git a/app/assets/javascripts/discourse/package.json b/app/assets/javascripts/discourse/package.json index 932954cb96e..07da58e6c9f 100644 --- a/app/assets/javascripts/discourse/package.json +++ b/app/assets/javascripts/discourse/package.json @@ -21,11 +21,11 @@ "@ember/test-helpers": "^2.2.0", "@glimmer/component": "^1.0.0", "@popperjs/core": "2.9.3", - "@uppy/aws-s3": "^1.7.12", - "@uppy/aws-s3-multipart": "^1.8.18", - "@uppy/core": "^1.19.2", - "@uppy/drop-target": "^0.2.4", - "@uppy/xhr-upload": "^1.7.5", + "@uppy/core": "^2.0.1", + "@uppy/aws-s3": "^2.0.1", + "@uppy/aws-s3-multipart": "^2.0.2", + "@uppy/drop-target": "^1.0.1", + "@uppy/xhr-upload": "^2.0.1", "admin": "^1.0.0", "bent": "^7.3.12", "broccoli-asset-rev": "^3.0.0", diff --git a/app/assets/javascripts/yarn.lock b/app/assets/javascripts/yarn.lock index fcc1bad4348..1110338971b 100644 --- a/app/assets/javascripts/yarn.lock +++ b/app/assets/javascripts/yarn.lock @@ -1382,78 +1382,73 @@ resolved "https://registry.yarnpkg.com/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz#4151a81b4052c80bc2becbae09f3a9ec010a9c7a" integrity sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg== -"@uppy/aws-s3-multipart@^1.8.18": - version "1.8.18" - resolved "https://registry.yarnpkg.com/@uppy/aws-s3-multipart/-/aws-s3-multipart-1.8.18.tgz#d0b3ede025d06b615ad3df90c3771eed38f68d87" - integrity sha512-m+IJSsDF253igTlQb2vgCTetqd+qgNIBX48i8HGnLj4rBfRd4FjpBpcV7DgfAn7QVOfrQOgOJoz9cGtXdaZ3lA== +"@uppy/aws-s3-multipart@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@uppy/aws-s3-multipart/-/aws-s3-multipart-2.0.2.tgz#b12f0938fad61532f20a9aa1aa017a484d310c83" + integrity sha512-+PaYGP8/XbMnWAEEAcdh9AF1TzXXazHdHDJf+QEN2eH7UBEDpieY2P7c4t/yhZXY25ifOQjKryGt8inoAaHJDA== dependencies: - "@uppy/companion-client" "^1.10.2" - "@uppy/utils" "^3.6.2" + "@uppy/companion-client" "^2.0.0" + "@uppy/utils" "^4.0.0" -"@uppy/aws-s3@^1.7.12": - version "1.7.12" - resolved "https://registry.yarnpkg.com/@uppy/aws-s3/-/aws-s3-1.7.12.tgz#5fd3259afc06feb745129ee224f93b618934be63" - integrity sha512-9Q8EMg1vQlDrmhaLs5UUQn4kAszLa8E2c1c4mD2urkpS/jHofdF4geRRtp4g4/xvBwwtnhzGqPX4dIylvoZICQ== +"@uppy/aws-s3@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@uppy/aws-s3/-/aws-s3-2.0.1.tgz#d59058f606044f258a9df763dfe1b6a2f7363feb" + integrity sha512-mgdRiXYeX7+yOyXXb28M+j/AzCCmkOyaiXsyFfoKtkCP+ALw2HHCWO4dycl0xaghSFIALBIoLN8ZGQ8zR6P9Pg== dependencies: - "@uppy/companion-client" "^1.10.2" - "@uppy/utils" "^3.6.2" - "@uppy/xhr-upload" "^1.7.5" - cuid "^2.1.1" - qs-stringify "^1.1.0" - url-parse "^1.4.7" + "@uppy/companion-client" "^2.0.0" + "@uppy/utils" "^4.0.0" + "@uppy/xhr-upload" "^2.0.1" + nanoid "^3.1.25" -"@uppy/companion-client@^1.10.2": - version "1.10.2" - resolved "https://registry.yarnpkg.com/@uppy/companion-client/-/companion-client-1.10.2.tgz#a640b3ef90b91751c49bf4b6a7a63c2ebac294f6" - integrity sha512-5RmsNF9UBvUqmqQz48SoiLvkpGmvQTgwNM4bJX8xwVozv/6goRpFrsMJGLwqFcHS/9xj6STKOqrM582g8exVwQ== +"@uppy/companion-client@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@uppy/companion-client/-/companion-client-2.0.0.tgz#60980d949d1ed15fe88bc8358171a938289b917c" + integrity sha512-TH/uw6aVeDKHcoepM9QAbSMMoi4MqUEG+loOEDwkB0CPkJGRYLqwvpnaO9pnELE7k1ZHfGGvRw0lxbkq5olGAg== dependencies: - "@uppy/utils" "^3.6.2" + "@uppy/utils" "^4.0.0" namespace-emitter "^2.0.1" - qs-stringify "^1.1.0" - url-parse "^1.4.7" -"@uppy/core@^1.19.2": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@uppy/core/-/core-1.19.2.tgz#0db125586bc663921066d9098a4c9b39355b8135" - integrity sha512-2aHvUMdH8fs2eFn30LzNZDHCKoUNAyC+MXwM2NQeO858o0gj2R4axZbrheXnpXrI9dB6RGELGIGkS+ZhnjQAmA== +"@uppy/core@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@uppy/core/-/core-2.0.1.tgz#e9686ce3e5560593d249c455a9b3c542509e2289" + integrity sha512-MdSvc3ngVebfSBHYLKzFFSUxAatSqH/vYP6v4R3uU/zFaZ0cW9A/Xm52S6rGLKf1d5ZNOvZjesdkre6d61m2Eg== dependencies: "@transloadit/prettier-bytes" "0.0.7" - "@uppy/store-default" "^1.2.7" - "@uppy/utils" "^3.6.2" - cuid "^2.1.1" + "@uppy/store-default" "^2.0.0" + "@uppy/utils" "^4.0.0" lodash.throttle "^4.1.1" mime-match "^1.0.2" namespace-emitter "^2.0.1" - preact "8.2.9" + nanoid "^3.1.25" + preact "^10.5.13" -"@uppy/drop-target@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@uppy/drop-target/-/drop-target-0.2.4.tgz#92e4ffa0d34781a37760e98850262c14b8718c2d" - integrity sha512-aRACD7f5jznt7NhLAtw/Nyi94XVjgYnqO3LN2mIbBQrsoQ+mINMzIu4rdVBhpGvk7qNM6961d5jPmPYSUBNiUw== +"@uppy/drop-target@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@uppy/drop-target/-/drop-target-1.0.1.tgz#9126fc52c1f36b30a3dff91219c7a0a45865bd2d" + integrity sha512-BAX/T9p6qySmty8i3MglPi3Ica722RctY2BE9PwhwvQ5konyH4WlhH/jDAaGzzVZE9plc2sfoLntzH1yZoajEA== dependencies: - "@uppy/utils" "^3.6.2" + "@uppy/utils" "^4.0.0" -"@uppy/store-default@^1.2.7": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-1.2.7.tgz#41a0b1579f4d5b86c236e7f5e52fdc01960bb011" - integrity sha512-58IG9yk/i/kYQ9uEwAwMFl1H2V3syOoODrYoFfVHlxaqv+9MkXBg2tHE2gk40iaAIxcCErcPxZkBOvkqzO1SQA== +"@uppy/store-default@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@uppy/store-default/-/store-default-2.0.0.tgz#c446a89d07a6df7f980a15eeb880d169baa14d7f" + integrity sha512-5HXTR2Qn20rpPUCUFBuNBfYDIa20oyUV14+FAnklgv2P32/zIyk79eFYloDRg8H7mOosVpovlysfDkI4iJh8Ag== -"@uppy/utils@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@uppy/utils/-/utils-3.6.2.tgz#78b02455b9c469d927d22736be5b68cda2600826" - integrity sha512-wGTZma7eywIojfuE1vXlT0fxPSpmCRMkfgFWYc+6TL2FfGqWInmePoB+yal6/M2AnjeKHz6XYMhIpZkjOxFvcw== +"@uppy/utils@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@uppy/utils/-/utils-4.0.0.tgz#337ffe668843a393171c8e9ff885d70af3a57417" + integrity sha512-sQOIM0cZOuV63l8JxgpRxAJiD/sJChKdEb1c5clRoxs4oafgtD9pl/BcBrOarMwk3r7kVZHt2apOL3V4BvD2Zw== dependencies: - abortcontroller-polyfill "^1.4.0" lodash.throttle "^4.1.1" -"@uppy/xhr-upload@^1.7.5": - version "1.7.5" - resolved "https://registry.yarnpkg.com/@uppy/xhr-upload/-/xhr-upload-1.7.5.tgz#990ba3e698503bd51534a59fd426096e37ef942b" - integrity sha512-Itnc9j9k/PemcmT5KrZ1BEw3pTc6WJg0yyyOcE+hLO8Hjv60Fm7c/I2ZknarOroIjT1WiTSyuxTBPp+9UGkxNA== +"@uppy/xhr-upload@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@uppy/xhr-upload/-/xhr-upload-2.0.1.tgz#751f00c30bd00004aa38d0e0eda653dee0e42206" + integrity sha512-7LMZL1+MdpUT1v3+JTs23Zhw+vZ1XL0a3r6cH0+1/JeN4Kx0AnSUouXF2tamdA5OOZpSqseY4lfFO3pJqCXOOA== dependencies: - "@uppy/companion-client" "^1.10.2" - "@uppy/utils" "^3.6.2" - cuid "^2.1.1" + "@uppy/companion-client" "^2.0.0" + "@uppy/utils" "^4.0.0" + nanoid "^3.1.25" "@webassemblyjs/ast@1.9.0": version "1.9.0" @@ -1620,11 +1615,6 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -abortcontroller-polyfill@^1.4.0: - version "1.7.3" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" - integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -4362,11 +4352,6 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -cuid@^2.1.1: - version "2.1.8" - resolved "https://registry.yarnpkg.com/cuid/-/cuid-2.1.8.tgz#cbb88f954171e0d5747606c0139fb65c5101eac0" - integrity sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg== - cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -8619,6 +8604,11 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nanoid@^3.1.25: + version "3.1.25" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.25.tgz#09ca32747c0e543f0e1814b7d3793477f9c8e152" + integrity sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -9322,10 +9312,10 @@ posix-character-classes@^0.1.0: resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= -preact@8.2.9: - version "8.2.9" - resolved "https://registry.yarnpkg.com/preact/-/preact-8.2.9.tgz#813ba9dd45e5d97c5ea0d6c86d375b3be711cc40" - integrity sha512-ThuGXBmJS3VsT+jIP+eQufD3L8pRw/PY3FoCys6O9Pu6aF12Pn9zAJDX99TfwRAFOCEKm/P0lwiPTbqKMJp0fA== +preact@^10.5.13: + version "10.5.14" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.5.14.tgz#0b14a2eefba3c10a57116b90d1a65f5f00cd2701" + integrity sha512-KojoltCrshZ099ksUZ2OQKfbH66uquFoxHSbnwKbTJHeQNvx42EmC7wQVWNuDt6vC5s3nudRHFtKbpY4ijKlaQ== prelude-ls@^1.2.1: version "1.2.1" @@ -9479,11 +9469,6 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs-stringify@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/qs-stringify/-/qs-stringify-1.2.1.tgz#9b39ef6b816bd83309628fc9dad435fc0eccc28b" - integrity sha512-2N5xGLGZUxpgAYq1fD1LmBSCbxQVsXYt5JU0nU3FuPWO8PlCnKNFQwXkZgyB6mrTdg7IbexX4wxIR403dJw9pw== - qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -9520,11 +9505,6 @@ querystring@0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -11416,14 +11396,6 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@^1.4.7: - version "1.5.1" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" - integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" diff --git a/package.json b/package.json index ed1a496921a..64fb5f33264 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,11 @@ "@highlightjs/cdn-assets": "^10.6.0", "@json-editor/json-editor": "^2.5.2", "@popperjs/core": "v2.9.3", - "@uppy/aws-s3": "^1.7.12", - "@uppy/aws-s3-multipart": "^1.8.18", - "@uppy/core": "^1.19.2", - "@uppy/drop-target": "^0.2.4", - "@uppy/xhr-upload": "^1.7.5", + "@uppy/core": "^2.0.1", + "@uppy/aws-s3": "^2.0.1", + "@uppy/aws-s3-multipart": "^2.0.2", + "@uppy/drop-target": "^1.0.1", + "@uppy/xhr-upload": "^2.0.1", "ace-builds": "1.4.12", "blueimp-file-upload": "10.13.0", "bootbox": "3.2.0", diff --git a/vendor/assets/javascripts/custom-uppy.js b/vendor/assets/javascripts/custom-uppy.js index bf13103841e..e146b136628 100644 --- a/vendor/assets/javascripts/custom-uppy.js +++ b/vendor/assets/javascripts/custom-uppy.js @@ -5,7 +5,6 @@ // use the plugins we actually want. window.Uppy = {} Uppy.Core = require('@uppy/core') -Uppy.Plugin = Uppy.Core.Plugin Uppy.XHRUpload = require('@uppy/xhr-upload') Uppy.AwsS3 = require('@uppy/aws-s3') Uppy.AwsS3Multipart = require('@uppy/aws-s3-multipart') diff --git a/vendor/assets/javascripts/uppy.js b/vendor/assets/javascripts/uppy.js index 36cf75c3923..d34c794d815 100644 --- a/vendor/assets/javascripts/uppy.js +++ b/vendor/assets/javascripts/uppy.js @@ -32,28 +32,42 @@ module.exports = function prettierBytes (num) { } },{}],2:[function(require,module,exports){ -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +"use strict"; -var _require = require('@uppy/utils/lib/AbortController'), - AbortController = _require.AbortController, - createAbortError = _require.createAbortError; +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } -var delay = require('@uppy/utils/lib/delay'); +var id = 0; -var MB = 1024 * 1024; -var defaultOptions = { +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +const { + AbortController, + createAbortError +} = require('@uppy/utils/lib/AbortController'); + +const delay = require('@uppy/utils/lib/delay'); + +const MB = 1024 * 1024; +const defaultOptions = { limit: 1, retryDelays: [0, 1000, 3000, 5000], - getChunkSize: function getChunkSize(file) { + + getChunkSize(file) { return Math.ceil(file.size / 10000); }, - onStart: function onStart() {}, - onProgress: function onProgress() {}, - onPartComplete: function onPartComplete() {}, - onSuccess: function onSuccess() {}, - onError: function onError(err) { + + onStart() {}, + + onProgress() {}, + + onPartComplete() {}, + + onSuccess() {}, + + onError(err) { throw err; } + }; function ensureInt(value) { @@ -68,9 +82,86 @@ function ensureInt(value) { throw new TypeError('Expected a number'); } -var MultipartUploader = /*#__PURE__*/function () { - function MultipartUploader(file, options) { - this.options = _extends({}, defaultOptions, options); // Use default `getChunkSize` if it was null or something +var _aborted = /*#__PURE__*/_classPrivateFieldLooseKey("aborted"); + +var _initChunks = /*#__PURE__*/_classPrivateFieldLooseKey("initChunks"); + +var _createUpload = /*#__PURE__*/_classPrivateFieldLooseKey("createUpload"); + +var _resumeUpload = /*#__PURE__*/_classPrivateFieldLooseKey("resumeUpload"); + +var _uploadParts = /*#__PURE__*/_classPrivateFieldLooseKey("uploadParts"); + +var _retryable = /*#__PURE__*/_classPrivateFieldLooseKey("retryable"); + +var _prepareUploadParts = /*#__PURE__*/_classPrivateFieldLooseKey("prepareUploadParts"); + +var _uploadPartRetryable = /*#__PURE__*/_classPrivateFieldLooseKey("uploadPartRetryable"); + +var _uploadPart = /*#__PURE__*/_classPrivateFieldLooseKey("uploadPart"); + +var _onPartProgress = /*#__PURE__*/_classPrivateFieldLooseKey("onPartProgress"); + +var _onPartComplete = /*#__PURE__*/_classPrivateFieldLooseKey("onPartComplete"); + +var _uploadPartBytes = /*#__PURE__*/_classPrivateFieldLooseKey("uploadPartBytes"); + +var _completeUpload = /*#__PURE__*/_classPrivateFieldLooseKey("completeUpload"); + +var _abortUpload = /*#__PURE__*/_classPrivateFieldLooseKey("abortUpload"); + +var _onError = /*#__PURE__*/_classPrivateFieldLooseKey("onError"); + +class MultipartUploader { + constructor(file, options) { + Object.defineProperty(this, _onError, { + value: _onError2 + }); + Object.defineProperty(this, _abortUpload, { + value: _abortUpload2 + }); + Object.defineProperty(this, _completeUpload, { + value: _completeUpload2 + }); + Object.defineProperty(this, _uploadPartBytes, { + value: _uploadPartBytes2 + }); + Object.defineProperty(this, _onPartComplete, { + value: _onPartComplete2 + }); + Object.defineProperty(this, _onPartProgress, { + value: _onPartProgress2 + }); + Object.defineProperty(this, _uploadPart, { + value: _uploadPart2 + }); + Object.defineProperty(this, _uploadPartRetryable, { + value: _uploadPartRetryable2 + }); + Object.defineProperty(this, _prepareUploadParts, { + value: _prepareUploadParts2 + }); + Object.defineProperty(this, _retryable, { + value: _retryable2 + }); + Object.defineProperty(this, _uploadParts, { + value: _uploadParts2 + }); + Object.defineProperty(this, _resumeUpload, { + value: _resumeUpload2 + }); + Object.defineProperty(this, _createUpload, { + value: _createUpload2 + }); + Object.defineProperty(this, _initChunks, { + value: _initChunks2 + }); + Object.defineProperty(this, _aborted, { + value: _aborted2 + }); + this.options = { ...defaultOptions, + ...options + }; // Use default `getChunkSize` if it was null or something if (!this.options.getChunkSize) { this.options.getChunkSize = defaultOptions.getChunkSize; @@ -84,7 +175,7 @@ var MultipartUploader = /*#__PURE__*/function () { // upload was created already. That also ensures that the sequencing is right // (so the `OP` definitely happens if the upload is created). // - // This mostly exists to make `_abortUpload` work well: only sending the abort request if + // This mostly exists to make `#abortUpload` work well: only sending the abort request if // the upload was already created, and if the createMultipartUpload request is still in flight, // aborting it immediately after it finishes. @@ -94,10 +185,11 @@ var MultipartUploader = /*#__PURE__*/function () { this.partsInProgress = 0; this.chunks = null; this.chunkState = null; + this.lockedCandidatesForBatch = []; - this._initChunks(); + _classPrivateFieldLooseBase(this, _initChunks)[_initChunks](); - this.createdPromise.catch(function () {}); // silence uncaught rejection warning + this.createdPromise.catch(() => {}); // silence uncaught rejection warning } /** * Was this upload aborted? @@ -108,467 +200,457 @@ var MultipartUploader = /*#__PURE__*/function () { */ - var _proto = MultipartUploader.prototype; - - _proto._aborted = function _aborted() { - return this.abortController.signal.aborted; - }; - - _proto._initChunks = function _initChunks() { - var chunks = []; - var desiredChunkSize = this.options.getChunkSize(this.file); // at least 5MB per request, at most 10k requests - - var minChunkSize = Math.max(5 * MB, Math.ceil(this.file.size / 10000)); - var chunkSize = Math.max(desiredChunkSize, minChunkSize); // Upload zero-sized files in one zero-sized chunk - - if (this.file.size === 0) { - chunks.push(this.file); - } else { - for (var i = 0; i < this.file.size; i += chunkSize) { - var end = Math.min(this.file.size, i + chunkSize); - chunks.push(this.file.slice(i, end)); - } - } - - this.chunks = chunks; - this.chunkState = chunks.map(function () { - return { - uploaded: 0, - busy: false, - done: false - }; - }); - }; - - _proto._createUpload = function _createUpload() { - var _this = this; - - this.createdPromise = Promise.resolve().then(function () { - return _this.options.createMultipartUpload(); - }); - return this.createdPromise.then(function (result) { - if (_this._aborted()) throw createAbortError(); - var valid = typeof result === 'object' && result && typeof result.uploadId === 'string' && typeof result.key === 'string'; - - if (!valid) { - throw new TypeError('AwsS3/Multipart: Got incorrect result from `createMultipartUpload()`, expected an object `{ uploadId, key }`.'); - } - - _this.key = result.key; - _this.uploadId = result.uploadId; - - _this.options.onStart(result); - - _this._uploadParts(); - }).catch(function (err) { - _this._onError(err); - }); - }; - - _proto._resumeUpload = function _resumeUpload() { - var _this2 = this; - - return Promise.resolve().then(function () { - return _this2.options.listParts({ - uploadId: _this2.uploadId, - key: _this2.key - }); - }).then(function (parts) { - if (_this2._aborted()) throw createAbortError(); - parts.forEach(function (part) { - var i = part.PartNumber - 1; - _this2.chunkState[i] = { - uploaded: ensureInt(part.Size), - etag: part.ETag, - done: true - }; // Only add if we did not yet know about this part. - - if (!_this2.parts.some(function (p) { - return p.PartNumber === part.PartNumber; - })) { - _this2.parts.push({ - PartNumber: part.PartNumber, - ETag: part.ETag - }); - } - }); - - _this2._uploadParts(); - }).catch(function (err) { - _this2._onError(err); - }); - }; - - _proto._uploadParts = function _uploadParts() { - var _this3 = this; - - if (this.isPaused) return; - var need = this.options.limit - this.partsInProgress; - if (need === 0) return; // All parts are uploaded. - - if (this.chunkState.every(function (state) { - return state.done; - })) { - this._completeUpload(); - - return; - } - - var candidates = []; - - for (var i = 0; i < this.chunkState.length; i++) { - var state = this.chunkState[i]; - if (state.done || state.busy) continue; - candidates.push(i); - - if (candidates.length >= need) { - break; - } - } - - candidates.forEach(function (index) { - _this3._uploadPartRetryable(index).then(function () { - // Continue uploading parts - _this3._uploadParts(); - }, function (err) { - _this3._onError(err); - }); - }); - }; - - _proto._retryable = function _retryable(_ref) { - var _this4 = this; - - var before = _ref.before, - attempt = _ref.attempt, - after = _ref.after; - var retryDelays = this.options.retryDelays; - var signal = this.abortController.signal; - if (before) before(); - - function shouldRetry(err) { - if (err.source && typeof err.source.status === 'number') { - var status = err.source.status; // 0 probably indicates network failure - - return status === 0 || status === 409 || status === 423 || status >= 500 && status < 600; - } - - return false; - } - - var doAttempt = function doAttempt(retryAttempt) { - return attempt().catch(function (err) { - if (_this4._aborted()) throw createAbortError(); - - if (shouldRetry(err) && retryAttempt < retryDelays.length) { - return delay(retryDelays[retryAttempt], { - signal: signal - }).then(function () { - return doAttempt(retryAttempt + 1); - }); - } - - throw err; - }); - }; - - return doAttempt(0).then(function (result) { - if (after) after(); - return result; - }, function (err) { - if (after) after(); - throw err; - }); - }; - - _proto._uploadPartRetryable = function _uploadPartRetryable(index) { - var _this5 = this; - - return this._retryable({ - before: function before() { - _this5.partsInProgress += 1; - }, - attempt: function attempt() { - return _this5._uploadPart(index); - }, - after: function after() { - _this5.partsInProgress -= 1; - } - }); - }; - - _proto._uploadPart = function _uploadPart(index) { - var _this6 = this; - - var body = this.chunks[index]; - this.chunkState[index].busy = true; - return Promise.resolve().then(function () { - return _this6.options.prepareUploadPart({ - key: _this6.key, - uploadId: _this6.uploadId, - body: body, - number: index + 1 - }); - }).then(function (result) { - var valid = typeof result === 'object' && result && typeof result.url === 'string'; - - if (!valid) { - throw new TypeError('AwsS3/Multipart: Got incorrect result from `prepareUploadPart()`, expected an object `{ url }`.'); - } - - return result; - }).then(function (_ref2) { - var url = _ref2.url, - headers = _ref2.headers; - - if (_this6._aborted()) { - _this6.chunkState[index].busy = false; - throw createAbortError(); - } - - return _this6._uploadPartBytes(index, url, headers); - }); - }; - - _proto._onPartProgress = function _onPartProgress(index, sent, total) { - this.chunkState[index].uploaded = ensureInt(sent); - var totalUploaded = this.chunkState.reduce(function (n, c) { - return n + c.uploaded; - }, 0); - this.options.onProgress(totalUploaded, this.file.size); - }; - - _proto._onPartComplete = function _onPartComplete(index, etag) { - this.chunkState[index].etag = etag; - this.chunkState[index].done = true; - var part = { - PartNumber: index + 1, - ETag: etag - }; - this.parts.push(part); - this.options.onPartComplete(part); - }; - - _proto._uploadPartBytes = function _uploadPartBytes(index, url, headers) { - var _this7 = this; - - var body = this.chunks[index]; - var signal = this.abortController.signal; - var defer; - var promise = new Promise(function (resolve, reject) { - defer = { - resolve: resolve, - reject: reject - }; - }); - var xhr = new XMLHttpRequest(); - xhr.open('PUT', url, true); - - if (headers) { - Object.keys(headers).map(function (key) { - xhr.setRequestHeader(key, headers[key]); - }); - } - - xhr.responseType = 'text'; - - function cleanup() { - signal.removeEventListener('abort', onabort); - } - - function onabort() { - xhr.abort(); - } - - signal.addEventListener('abort', onabort); - xhr.upload.addEventListener('progress', function (ev) { - if (!ev.lengthComputable) return; - - _this7._onPartProgress(index, ev.loaded, ev.total); - }); - xhr.addEventListener('abort', function (ev) { - cleanup(); - _this7.chunkState[index].busy = false; - defer.reject(createAbortError()); - }); - xhr.addEventListener('load', function (ev) { - cleanup(); - _this7.chunkState[index].busy = false; - - if (ev.target.status < 200 || ev.target.status >= 300) { - var error = new Error('Non 2xx'); - error.source = ev.target; - defer.reject(error); - return; - } - - _this7._onPartProgress(index, body.size, body.size); // NOTE This must be allowed by CORS. - - - var etag = ev.target.getResponseHeader('ETag'); - - if (etag === null) { - defer.reject(new Error('AwsS3/Multipart: Could not read the ETag header. This likely means CORS is not configured correctly on the S3 Bucket. See https://uppy.io/docs/aws-s3-multipart#S3-Bucket-Configuration for instructions.')); - return; - } - - _this7._onPartComplete(index, etag); - - defer.resolve(); - }); - xhr.addEventListener('error', function (ev) { - cleanup(); - _this7.chunkState[index].busy = false; - var error = new Error('Unknown error'); - error.source = ev.target; - defer.reject(error); - }); - xhr.send(body); - return promise; - }; - - _proto._completeUpload = function _completeUpload() { - var _this8 = this; - - // Parts may not have completed uploading in sorted order, if limit > 1. - this.parts.sort(function (a, b) { - return a.PartNumber - b.PartNumber; - }); - return Promise.resolve().then(function () { - return _this8.options.completeMultipartUpload({ - key: _this8.key, - uploadId: _this8.uploadId, - parts: _this8.parts - }); - }).then(function (result) { - _this8.options.onSuccess(result); - }, function (err) { - _this8._onError(err); - }); - }; - - _proto._abortUpload = function _abortUpload() { - var _this9 = this; - - this.abortController.abort(); - this.createdPromise.then(function () { - _this9.options.abortMultipartUpload({ - key: _this9.key, - uploadId: _this9.uploadId - }); - }, function () {// if the creation failed we do not need to abort - }); - }; - - _proto._onError = function _onError(err) { - if (err && err.name === 'AbortError') { - return; - } - - this.options.onError(err); - }; - - _proto.start = function start() { + start() { this.isPaused = false; if (this.uploadId) { - this._resumeUpload(); + _classPrivateFieldLooseBase(this, _resumeUpload)[_resumeUpload](); } else { - this._createUpload(); + _classPrivateFieldLooseBase(this, _createUpload)[_createUpload](); } - }; + } - _proto.pause = function pause() { + pause() { this.abortController.abort(); // Swap it out for a new controller, because this instance may be resumed later. this.abortController = new AbortController(); this.isPaused = true; - }; + } - _proto.abort = function abort(opts) { - if (opts === void 0) { - opts = {}; - } - - var really = opts.really || false; + abort(opts = {}) { + const really = opts.really || false; if (!really) return this.pause(); - this._abortUpload(); - }; + _classPrivateFieldLooseBase(this, _abortUpload)[_abortUpload](); + } - return MultipartUploader; -}(); +} + +function _aborted2() { + return this.abortController.signal.aborted; +} + +function _initChunks2() { + const chunks = []; + const desiredChunkSize = this.options.getChunkSize(this.file); // at least 5MB per request, at most 10k requests + + const minChunkSize = Math.max(5 * MB, Math.ceil(this.file.size / 10000)); + const chunkSize = Math.max(desiredChunkSize, minChunkSize); // Upload zero-sized files in one zero-sized chunk + + if (this.file.size === 0) { + chunks.push(this.file); + } else { + for (let i = 0; i < this.file.size; i += chunkSize) { + const end = Math.min(this.file.size, i + chunkSize); + chunks.push(this.file.slice(i, end)); + } + } + + this.chunks = chunks; + this.chunkState = chunks.map(() => ({ + uploaded: 0, + busy: false, + done: false + })); +} + +function _createUpload2() { + this.createdPromise = Promise.resolve().then(() => this.options.createMultipartUpload()); + return this.createdPromise.then(result => { + if (_classPrivateFieldLooseBase(this, _aborted)[_aborted]()) throw createAbortError(); + const valid = typeof result === 'object' && result && typeof result.uploadId === 'string' && typeof result.key === 'string'; + + if (!valid) { + throw new TypeError('AwsS3/Multipart: Got incorrect result from `createMultipartUpload()`, expected an object `{ uploadId, key }`.'); + } + + this.key = result.key; + this.uploadId = result.uploadId; + this.options.onStart(result); + + _classPrivateFieldLooseBase(this, _uploadParts)[_uploadParts](); + }).catch(err => { + _classPrivateFieldLooseBase(this, _onError)[_onError](err); + }); +} + +async function _resumeUpload2() { + try { + const parts = await this.options.listParts({ + uploadId: this.uploadId, + key: this.key + }); + if (_classPrivateFieldLooseBase(this, _aborted)[_aborted]()) throw createAbortError(); + parts.forEach(part => { + const i = part.PartNumber - 1; + this.chunkState[i] = { + uploaded: ensureInt(part.Size), + etag: part.ETag, + done: true + }; // Only add if we did not yet know about this part. + + if (!this.parts.some(p => p.PartNumber === part.PartNumber)) { + this.parts.push({ + PartNumber: part.PartNumber, + ETag: part.ETag + }); + } + }); + + _classPrivateFieldLooseBase(this, _uploadParts)[_uploadParts](); + } catch (err) { + _classPrivateFieldLooseBase(this, _onError)[_onError](err); + } +} + +function _uploadParts2() { + if (this.isPaused) return; // All parts are uploaded. + + if (this.chunkState.every(state => state.done)) { + _classPrivateFieldLooseBase(this, _completeUpload)[_completeUpload](); + + return; + } // For a 100MB file, with the default min chunk size of 5MB and a limit of 10: + // + // Total 20 parts + // --------- + // Need 1 is 10 + // Need 2 is 5 + // Need 3 is 5 + + + const need = this.options.limit - this.partsInProgress; + const completeChunks = this.chunkState.filter(state => state.done).length; + const remainingChunks = this.chunks.length - completeChunks; + let minNeeded = Math.ceil(this.options.limit / 2); + + if (minNeeded > remainingChunks) { + minNeeded = remainingChunks; + } + + if (need < minNeeded) return; + const candidates = []; + + for (let i = 0; i < this.chunkState.length; i++) { + // eslint-disable-next-line no-continue + if (this.lockedCandidatesForBatch.includes(i)) continue; + const state = this.chunkState[i]; // eslint-disable-next-line no-continue + + if (state.done || state.busy) continue; + candidates.push(i); + + if (candidates.length >= need) { + break; + } + } + + if (candidates.length === 0) return; + + _classPrivateFieldLooseBase(this, _prepareUploadParts)[_prepareUploadParts](candidates).then(result => { + candidates.forEach(index => { + const partNumber = index + 1; + const prePreparedPart = { + url: result.presignedUrls[partNumber], + headers: result.headers + }; + + _classPrivateFieldLooseBase(this, _uploadPartRetryable)[_uploadPartRetryable](index, prePreparedPart).then(() => { + _classPrivateFieldLooseBase(this, _uploadParts)[_uploadParts](); + }, err => { + _classPrivateFieldLooseBase(this, _onError)[_onError](err); + }); + }); + }); +} + +function _retryable2({ + before, + attempt, + after +}) { + const { + retryDelays + } = this.options; + const { + signal + } = this.abortController; + if (before) before(); + + function shouldRetry(err) { + if (err.source && typeof err.source.status === 'number') { + const { + status + } = err.source; // 0 probably indicates network failure + + return status === 0 || status === 409 || status === 423 || status >= 500 && status < 600; + } + + return false; + } + + const doAttempt = retryAttempt => attempt().catch(err => { + if (_classPrivateFieldLooseBase(this, _aborted)[_aborted]()) throw createAbortError(); + + if (shouldRetry(err) && retryAttempt < retryDelays.length) { + return delay(retryDelays[retryAttempt], { + signal + }).then(() => doAttempt(retryAttempt + 1)); + } + + throw err; + }); + + return doAttempt(0).then(result => { + if (after) after(); + return result; + }, err => { + if (after) after(); + throw err; + }); +} + +async function _prepareUploadParts2(candidates) { + this.lockedCandidatesForBatch.push(...candidates); + const result = await this.options.prepareUploadParts({ + key: this.key, + uploadId: this.uploadId, + partNumbers: candidates.map(index => index + 1) + }); + const valid = typeof (result == null ? void 0 : result.presignedUrls) === 'object'; + + if (!valid) { + throw new TypeError('AwsS3/Multipart: Got incorrect result from `prepareUploadParts()`, expected an object `{ presignedUrls }`.'); + } + + return result; +} + +function _uploadPartRetryable2(index, prePreparedPart) { + return _classPrivateFieldLooseBase(this, _retryable)[_retryable]({ + before: () => { + this.partsInProgress += 1; + }, + attempt: () => _classPrivateFieldLooseBase(this, _uploadPart)[_uploadPart](index, prePreparedPart), + after: () => { + this.partsInProgress -= 1; + } + }); +} + +function _uploadPart2(index, prePreparedPart) { + this.chunkState[index].busy = true; + const valid = typeof (prePreparedPart == null ? void 0 : prePreparedPart.url) === 'string'; + + if (!valid) { + throw new TypeError('AwsS3/Multipart: Got incorrect result for `prePreparedPart`, expected an object `{ url }`.'); + } + + const { + url, + headers + } = prePreparedPart; + + if (_classPrivateFieldLooseBase(this, _aborted)[_aborted]()) { + this.chunkState[index].busy = false; + throw createAbortError(); + } + + return _classPrivateFieldLooseBase(this, _uploadPartBytes)[_uploadPartBytes](index, url, headers); +} + +function _onPartProgress2(index, sent) { + this.chunkState[index].uploaded = ensureInt(sent); + const totalUploaded = this.chunkState.reduce((n, c) => n + c.uploaded, 0); + this.options.onProgress(totalUploaded, this.file.size); +} + +function _onPartComplete2(index, etag) { + this.chunkState[index].etag = etag; + this.chunkState[index].done = true; + const part = { + PartNumber: index + 1, + ETag: etag + }; + this.parts.push(part); + this.options.onPartComplete(part); +} + +function _uploadPartBytes2(index, url, headers) { + const body = this.chunks[index]; + const { + signal + } = this.abortController; + let defer; + const promise = new Promise((resolve, reject) => { + defer = { + resolve, + reject + }; + }); + const xhr = new XMLHttpRequest(); + xhr.open('PUT', url, true); + + if (headers) { + Object.keys(headers).forEach(key => { + xhr.setRequestHeader(key, headers[key]); + }); + } + + xhr.responseType = 'text'; + + function cleanup() { + signal.removeEventListener('abort', onabort); + } + + function onabort() { + xhr.abort(); + } + + signal.addEventListener('abort', onabort); + xhr.upload.addEventListener('progress', ev => { + if (!ev.lengthComputable) return; + + _classPrivateFieldLooseBase(this, _onPartProgress)[_onPartProgress](index, ev.loaded, ev.total); + }); + xhr.addEventListener('abort', () => { + cleanup(); + this.chunkState[index].busy = false; + defer.reject(createAbortError()); + }); + xhr.addEventListener('load', ev => { + cleanup(); + this.chunkState[index].busy = false; + + if (ev.target.status < 200 || ev.target.status >= 300) { + const error = new Error('Non 2xx'); + error.source = ev.target; + defer.reject(error); + return; + } + + _classPrivateFieldLooseBase(this, _onPartProgress)[_onPartProgress](index, body.size, body.size); // NOTE This must be allowed by CORS. + + + const etag = ev.target.getResponseHeader('ETag'); + + if (etag === null) { + defer.reject(new Error('AwsS3/Multipart: Could not read the ETag header. This likely means CORS is not configured correctly on the S3 Bucket. See https://uppy.io/docs/aws-s3-multipart#S3-Bucket-Configuration for instructions.')); + return; + } + + _classPrivateFieldLooseBase(this, _onPartComplete)[_onPartComplete](index, etag); + + defer.resolve(); + }); + xhr.addEventListener('error', ev => { + cleanup(); + this.chunkState[index].busy = false; + const error = new Error('Unknown error'); + error.source = ev.target; + defer.reject(error); + }); + xhr.send(body); + return promise; +} + +async function _completeUpload2() { + // Parts may not have completed uploading in sorted order, if limit > 1. + this.parts.sort((a, b) => a.PartNumber - b.PartNumber); + + try { + const result = await this.options.completeMultipartUpload({ + key: this.key, + uploadId: this.uploadId, + parts: this.parts + }); + this.options.onSuccess(result); + } catch (err) { + _classPrivateFieldLooseBase(this, _onError)[_onError](err); + } +} + +function _abortUpload2() { + this.abortController.abort(); + this.createdPromise.then(() => { + this.options.abortMultipartUpload({ + key: this.key, + uploadId: this.uploadId + }); + }, () => {// if the creation failed we do not need to abort + }); +} + +function _onError2(err) { + if (err && err.name === 'AbortError') { + return; + } + + this.options.onError(err); +} module.exports = MultipartUploader; -},{"@uppy/utils/lib/AbortController":21,"@uppy/utils/lib/delay":27}],3:[function(require,module,exports){ +},{"@uppy/utils/lib/AbortController":22,"@uppy/utils/lib/delay":28}],3:[function(require,module,exports){ +"use strict"; + var _class, _temp; -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } +const { + BasePlugin +} = require('@uppy/core'); -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } +const { + Socket, + Provider, + RequestClient +} = require('@uppy/companion-client'); -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } +const EventTracker = require('@uppy/utils/lib/EventTracker'); -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +const emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress'); -var _require = require('@uppy/core'), - Plugin = _require.Plugin; +const getSocketHost = require('@uppy/utils/lib/getSocketHost'); -var _require2 = require('@uppy/companion-client'), - Socket = _require2.Socket, - Provider = _require2.Provider, - RequestClient = _require2.RequestClient; +const { + RateLimitedQueue +} = require('@uppy/utils/lib/RateLimitedQueue'); -var EventTracker = require('@uppy/utils/lib/EventTracker'); - -var emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress'); - -var getSocketHost = require('@uppy/utils/lib/getSocketHost'); - -var RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue'); - -var Uploader = require('./MultipartUploader'); +const Uploader = require('./MultipartUploader'); function assertServerError(res) { if (res && res.error) { - var error = new Error(res.message); - - _extends(error, res.error); - + const error = new Error(res.message); + Object.assign(error, res.error); throw error; } return res; } -module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { - _inheritsLoose(AwsS3Multipart, _Plugin); - - function AwsS3Multipart(uppy, opts) { - var _this; - - _this = _Plugin.call(this, uppy, opts) || this; - _this.type = 'uploader'; - _this.id = _this.opts.id || 'AwsS3Multipart'; - _this.title = 'AWS S3 Multipart'; - _this.client = new RequestClient(uppy, opts); - var defaultOptions = { +module.exports = (_temp = _class = class AwsS3Multipart extends BasePlugin { + constructor(uppy, opts) { + super(uppy, opts); + this.type = 'uploader'; + this.id = this.opts.id || 'AwsS3Multipart'; + this.title = 'AWS S3 Multipart'; + this.client = new RequestClient(uppy, opts); + const defaultOptions = { timeout: 30 * 1000, limit: 0, retryDelays: [0, 1000, 3000, 5000], - createMultipartUpload: _this.createMultipartUpload.bind(_assertThisInitialized(_this)), - listParts: _this.listParts.bind(_assertThisInitialized(_this)), - prepareUploadPart: _this.prepareUploadPart.bind(_assertThisInitialized(_this)), - abortMultipartUpload: _this.abortMultipartUpload.bind(_assertThisInitialized(_this)), - completeMultipartUpload: _this.completeMultipartUpload.bind(_assertThisInitialized(_this)) + createMultipartUpload: this.createMultipartUpload.bind(this), + listParts: this.listParts.bind(this), + prepareUploadParts: this.prepareUploadParts.bind(this), + abortMultipartUpload: this.abortMultipartUpload.bind(this), + completeMultipartUpload: this.completeMultipartUpload.bind(this) }; - _this.opts = _extends({}, defaultOptions, opts); - _this.upload = _this.upload.bind(_assertThisInitialized(_this)); - _this.requests = new RateLimitedQueue(_this.opts.limit); - _this.uploaders = Object.create(null); - _this.uploaderEvents = Object.create(null); - _this.uploaderSockets = Object.create(null); - return _this; + this.opts = { ...defaultOptions, + ...opts + }; + this.upload = this.upload.bind(this); + this.requests = new RateLimitedQueue(this.opts.limit); + this.uploaders = Object.create(null); + this.uploaderEvents = Object.create(null); + this.uploaderSockets = Object.create(null); } /** * Clean up all references for a file's upload: the MultipartUploader instance, @@ -579,13 +661,7 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { */ - var _proto = AwsS3Multipart.prototype; - - _proto.resetUploaderReferences = function resetUploaderReferences(fileID, opts) { - if (opts === void 0) { - opts = {}; - } - + resetUploaderReferences(fileID, opts = {}) { if (this.uploaders[fileID]) { this.uploaders[fileID].abort({ really: opts.abort || false @@ -602,18 +678,18 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { this.uploaderSockets[fileID].close(); this.uploaderSockets[fileID] = null; } - }; + } - _proto.assertHost = function assertHost(method) { + assertHost(method) { if (!this.opts.companionUrl) { - throw new Error("Expected a `companionUrl` option containing a Companion address, or if you are not using Companion, a custom `" + method + "` implementation."); + throw new Error(`Expected a \`companionUrl\` option containing a Companion address, or if you are not using Companion, a custom \`${method}\` implementation.`); } - }; + } - _proto.createMultipartUpload = function createMultipartUpload(file) { + createMultipartUpload(file) { this.assertHost('createMultipartUpload'); - var metadata = {}; - Object.keys(file.meta).map(function (key) { + const metadata = {}; + Object.keys(file.meta).forEach(key => { if (file.meta[key] != null) { metadata[key] = file.meta[key].toString(); } @@ -621,133 +697,128 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { return this.client.post('s3/multipart', { filename: file.name, type: file.type, - metadata: metadata + metadata }).then(assertServerError); - }; + } - _proto.listParts = function listParts(file, _ref) { - var key = _ref.key, - uploadId = _ref.uploadId; + listParts(file, { + key, + uploadId + }) { this.assertHost('listParts'); - var filename = encodeURIComponent(key); - return this.client.get("s3/multipart/" + uploadId + "?key=" + filename).then(assertServerError); - }; + const filename = encodeURIComponent(key); + return this.client.get(`s3/multipart/${uploadId}?key=${filename}`).then(assertServerError); + } - _proto.prepareUploadPart = function prepareUploadPart(file, _ref2) { - var key = _ref2.key, - uploadId = _ref2.uploadId, - number = _ref2.number; - this.assertHost('prepareUploadPart'); - var filename = encodeURIComponent(key); - return this.client.get("s3/multipart/" + uploadId + "/" + number + "?key=" + filename).then(assertServerError); - }; + prepareUploadParts(file, { + key, + uploadId, + partNumbers + }) { + this.assertHost('prepareUploadParts'); + const filename = encodeURIComponent(key); + return this.client.get(`s3/multipart/${uploadId}/batch?key=${filename}&partNumbers=${partNumbers.join(',')}`).then(assertServerError); + } - _proto.completeMultipartUpload = function completeMultipartUpload(file, _ref3) { - var key = _ref3.key, - uploadId = _ref3.uploadId, - parts = _ref3.parts; + completeMultipartUpload(file, { + key, + uploadId, + parts + }) { this.assertHost('completeMultipartUpload'); - var filename = encodeURIComponent(key); - var uploadIdEnc = encodeURIComponent(uploadId); - return this.client.post("s3/multipart/" + uploadIdEnc + "/complete?key=" + filename, { - parts: parts + const filename = encodeURIComponent(key); + const uploadIdEnc = encodeURIComponent(uploadId); + return this.client.post(`s3/multipart/${uploadIdEnc}/complete?key=${filename}`, { + parts }).then(assertServerError); - }; + } - _proto.abortMultipartUpload = function abortMultipartUpload(file, _ref4) { - var key = _ref4.key, - uploadId = _ref4.uploadId; + abortMultipartUpload(file, { + key, + uploadId + }) { this.assertHost('abortMultipartUpload'); - var filename = encodeURIComponent(key); - var uploadIdEnc = encodeURIComponent(uploadId); - return this.client.delete("s3/multipart/" + uploadIdEnc + "?key=" + filename).then(assertServerError); - }; + const filename = encodeURIComponent(key); + const uploadIdEnc = encodeURIComponent(uploadId); + return this.client.delete(`s3/multipart/${uploadIdEnc}?key=${filename}`).then(assertServerError); + } - _proto.uploadFile = function uploadFile(file) { - var _this2 = this; - - return new Promise(function (resolve, reject) { - var onStart = function onStart(data) { - var cFile = _this2.uppy.getFile(file.id); - - _this2.uppy.setFileState(file.id, { - s3Multipart: _extends({}, cFile.s3Multipart, { + uploadFile(file) { + return new Promise((resolve, reject) => { + const onStart = data => { + const cFile = this.uppy.getFile(file.id); + this.uppy.setFileState(file.id, { + s3Multipart: { ...cFile.s3Multipart, key: data.key, uploadId: data.uploadId - }) + } }); }; - var onProgress = function onProgress(bytesUploaded, bytesTotal) { - _this2.uppy.emit('upload-progress', file, { - uploader: _this2, - bytesUploaded: bytesUploaded, - bytesTotal: bytesTotal + const onProgress = (bytesUploaded, bytesTotal) => { + this.uppy.emit('upload-progress', file, { + uploader: this, + bytesUploaded, + bytesTotal }); }; - var onError = function onError(err) { - _this2.uppy.log(err); - - _this2.uppy.emit('upload-error', file, err); - + const onError = err => { + this.uppy.log(err); + this.uppy.emit('upload-error', file, err); queuedRequest.done(); - - _this2.resetUploaderReferences(file.id); - + this.resetUploaderReferences(file.id); reject(err); }; - var onSuccess = function onSuccess(result) { - var uploadResp = { - body: _extends({}, result), + const onSuccess = result => { + const uploadResp = { + body: { ...result + }, uploadURL: result.location }; queuedRequest.done(); - - _this2.resetUploaderReferences(file.id); - - var cFile = _this2.uppy.getFile(file.id); - - _this2.uppy.emit('upload-success', cFile || file, uploadResp); + this.resetUploaderReferences(file.id); + const cFile = this.uppy.getFile(file.id); + this.uppy.emit('upload-success', cFile || file, uploadResp); if (result.location) { - _this2.uppy.log("Download " + upload.file.name + " from " + result.location); + this.uppy.log(`Download ${upload.file.name} from ${result.location}`); } resolve(upload); }; - var onPartComplete = function onPartComplete(part) { - var cFile = _this2.uppy.getFile(file.id); + const onPartComplete = part => { + const cFile = this.uppy.getFile(file.id); if (!cFile) { return; } - _this2.uppy.emit('s3-multipart:part-uploaded', cFile, part); + this.uppy.emit('s3-multipart:part-uploaded', cFile, part); }; - var upload = new Uploader(file.data, _extends({ + const upload = new Uploader(file.data, { // .bind to pass the file object to each handler. - createMultipartUpload: _this2.opts.createMultipartUpload.bind(_this2, file), - listParts: _this2.opts.listParts.bind(_this2, file), - prepareUploadPart: _this2.opts.prepareUploadPart.bind(_this2, file), - completeMultipartUpload: _this2.opts.completeMultipartUpload.bind(_this2, file), - abortMultipartUpload: _this2.opts.abortMultipartUpload.bind(_this2, file), - getChunkSize: _this2.opts.getChunkSize ? _this2.opts.getChunkSize.bind(_this2) : null, - onStart: onStart, - onProgress: onProgress, - onError: onError, - onSuccess: onSuccess, - onPartComplete: onPartComplete, - limit: _this2.opts.limit || 5, - retryDelays: _this2.opts.retryDelays || [] - }, file.s3Multipart)); - _this2.uploaders[file.id] = upload; - _this2.uploaderEvents[file.id] = new EventTracker(_this2.uppy); - - var queuedRequest = _this2.requests.run(function () { + createMultipartUpload: this.opts.createMultipartUpload.bind(this, file), + listParts: this.opts.listParts.bind(this, file), + prepareUploadParts: this.opts.prepareUploadParts.bind(this, file), + completeMultipartUpload: this.opts.completeMultipartUpload.bind(this, file), + abortMultipartUpload: this.opts.abortMultipartUpload.bind(this, file), + getChunkSize: this.opts.getChunkSize ? this.opts.getChunkSize.bind(this) : null, + onStart, + onProgress, + onError, + onSuccess, + onPartComplete, + limit: this.opts.limit || 5, + retryDelays: this.opts.retryDelays || [], + ...file.s3Multipart + }); + this.uploaders[file.id] = upload; + this.uploaderEvents[file.id] = new EventTracker(this.uppy); + let queuedRequest = this.requests.run(() => { if (!file.isPaused) { upload.start(); } // Don't do anything here, the caller will take care of cancelling the upload itself @@ -756,72 +827,61 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { // that point this cancellation function is not going to be called. - return function () {}; + return () => {}; }); - - _this2.onFileRemove(file.id, function (removed) { + this.onFileRemove(file.id, removed => { queuedRequest.abort(); - - _this2.resetUploaderReferences(file.id, { + this.resetUploaderReferences(file.id, { abort: true }); - - resolve("upload " + removed.id + " was removed"); + resolve(`upload ${removed.id} was removed`); }); - - _this2.onCancelAll(file.id, function () { + this.onCancelAll(file.id, () => { queuedRequest.abort(); - - _this2.resetUploaderReferences(file.id, { + this.resetUploaderReferences(file.id, { abort: true }); - - resolve("upload " + file.id + " was canceled"); + resolve(`upload ${file.id} was canceled`); }); - - _this2.onFilePause(file.id, function (isPaused) { + this.onFilePause(file.id, isPaused => { if (isPaused) { // Remove this file from the queue so another file can start in its place. queuedRequest.abort(); upload.pause(); } else { - // Resuming an upload should be queued, else you could pause and then resume a queued upload to make it skip the queue. + // Resuming an upload should be queued, else you could pause and then + // resume a queued upload to make it skip the queue. queuedRequest.abort(); - queuedRequest = _this2.requests.run(function () { + queuedRequest = this.requests.run(() => { upload.start(); - return function () {}; + return () => {}; }); } }); - - _this2.onPauseAll(file.id, function () { + this.onPauseAll(file.id, () => { queuedRequest.abort(); upload.pause(); }); - - _this2.onResumeAll(file.id, function () { + this.onResumeAll(file.id, () => { queuedRequest.abort(); if (file.error) { upload.abort(); } - queuedRequest = _this2.requests.run(function () { + queuedRequest = this.requests.run(() => { upload.start(); - return function () {}; + return () => {}; }); }); // Don't double-emit upload-started for Golden Retriever-restored files that were already started - if (!file.progress.uploadStarted || !file.isRestored) { - _this2.uppy.emit('upload-started', file); + this.uppy.emit('upload-started', file); } }); - }; - - _proto.uploadRemote = function uploadRemote(file) { - var _this3 = this; + } + uploadRemote(file) { this.resetUploaderReferences(file.id); // Don't double-emit upload-started for Golden Retriever-restored files that were already started if (!file.progress.uploadStarted || !file.isRestored) { @@ -832,98 +892,85 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { return this.connectToServerSocket(file); } - return new Promise(function (resolve, reject) { - var Client = file.remote.providerOptions.provider ? Provider : RequestClient; - var client = new Client(_this3.uppy, file.remote.providerOptions); - client.post(file.remote.url, _extends({}, file.remote.body, { + return new Promise((resolve, reject) => { + const Client = file.remote.providerOptions.provider ? Provider : RequestClient; + const client = new Client(this.uppy, file.remote.providerOptions); + client.post(file.remote.url, { ...file.remote.body, protocol: 's3-multipart', size: file.data.size, metadata: file.meta - })).then(function (res) { - _this3.uppy.setFileState(file.id, { + }).then(res => { + this.uppy.setFileState(file.id, { serverToken: res.token }); - - file = _this3.uppy.getFile(file.id); + file = this.uppy.getFile(file.id); return file; - }).then(function (file) { - return _this3.connectToServerSocket(file); - }).then(function () { + }).then(file => { + return this.connectToServerSocket(file); + }).then(() => { resolve(); - }).catch(function (err) { - _this3.uppy.emit('upload-error', file, err); - + }).catch(err => { + this.uppy.emit('upload-error', file, err); reject(err); }); }); - }; + } - _proto.connectToServerSocket = function connectToServerSocket(file) { - var _this4 = this; - - return new Promise(function (resolve, reject) { - var token = file.serverToken; - var host = getSocketHost(file.remote.companionUrl); - var socket = new Socket({ - target: host + "/api/" + token, + connectToServerSocket(file) { + return new Promise((resolve, reject) => { + const token = file.serverToken; + const host = getSocketHost(file.remote.companionUrl); + const socket = new Socket({ + target: `${host}/api/${token}`, autoOpen: false }); - _this4.uploaderSockets[file.id] = socket; - _this4.uploaderEvents[file.id] = new EventTracker(_this4.uppy); - - _this4.onFileRemove(file.id, function (removed) { + this.uploaderSockets[file.id] = socket; + this.uploaderEvents[file.id] = new EventTracker(this.uppy); + this.onFileRemove(file.id, () => { queuedRequest.abort(); socket.send('pause', {}); - - _this4.resetUploaderReferences(file.id, { + this.resetUploaderReferences(file.id, { abort: true }); - - resolve("upload " + file.id + " was removed"); + resolve(`upload ${file.id} was removed`); }); - - _this4.onFilePause(file.id, function (isPaused) { + this.onFilePause(file.id, isPaused => { if (isPaused) { // Remove this file from the queue so another file can start in its place. queuedRequest.abort(); socket.send('pause', {}); } else { - // Resuming an upload should be queued, else you could pause and then resume a queued upload to make it skip the queue. + // Resuming an upload should be queued, else you could pause and then + // resume a queued upload to make it skip the queue. queuedRequest.abort(); - queuedRequest = _this4.requests.run(function () { + queuedRequest = this.requests.run(() => { socket.send('resume', {}); - return function () {}; + return () => {}; }); } }); - - _this4.onPauseAll(file.id, function () { + this.onPauseAll(file.id, () => { queuedRequest.abort(); socket.send('pause', {}); }); - - _this4.onCancelAll(file.id, function () { + this.onCancelAll(file.id, () => { queuedRequest.abort(); socket.send('pause', {}); - - _this4.resetUploaderReferences(file.id); - - resolve("upload " + file.id + " was canceled"); + this.resetUploaderReferences(file.id); + resolve(`upload ${file.id} was canceled`); }); - - _this4.onResumeAll(file.id, function () { + this.onResumeAll(file.id, () => { queuedRequest.abort(); if (file.error) { socket.send('pause', {}); } - queuedRequest = _this4.requests.run(function () { + queuedRequest = this.requests.run(() => { socket.send('resume', {}); }); }); - - _this4.onRetry(file.id, function () { + this.onRetry(file.id, () => { // Only do the retry if the upload is actually in progress; // else we could try to send these messages when the upload is still queued. // We may need a better check for this since the socket may also be closed @@ -933,575 +980,513 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { socket.send('resume', {}); } }); - - _this4.onRetryAll(file.id, function () { + this.onRetryAll(file.id, () => { if (socket.isOpen) { socket.send('pause', {}); socket.send('resume', {}); } }); - - socket.on('progress', function (progressData) { - return emitSocketProgress(_this4, progressData, file); - }); - socket.on('error', function (errData) { - _this4.uppy.emit('upload-error', file, new Error(errData.error)); - - _this4.resetUploaderReferences(file.id); - + socket.on('progress', progressData => emitSocketProgress(this, progressData, file)); + socket.on('error', errData => { + this.uppy.emit('upload-error', file, new Error(errData.error)); + this.resetUploaderReferences(file.id); queuedRequest.done(); reject(new Error(errData.error)); }); - socket.on('success', function (data) { - var uploadResp = { + socket.on('success', data => { + const uploadResp = { uploadURL: data.url }; - - _this4.uppy.emit('upload-success', file, uploadResp); - - _this4.resetUploaderReferences(file.id); - + this.uppy.emit('upload-success', file, uploadResp); + this.resetUploaderReferences(file.id); queuedRequest.done(); resolve(); }); - - var queuedRequest = _this4.requests.run(function () { + let queuedRequest = this.requests.run(() => { socket.open(); if (file.isPaused) { socket.send('pause', {}); } - return function () {}; + return () => {}; }); }); - }; - - _proto.upload = function upload(fileIDs) { - var _this5 = this; + } + upload(fileIDs) { if (fileIDs.length === 0) return Promise.resolve(); - var promises = fileIDs.map(function (id) { - var file = _this5.uppy.getFile(id); + const promises = fileIDs.map(id => { + const file = this.uppy.getFile(id); if (file.isRemote) { - return _this5.uploadRemote(file); + return this.uploadRemote(file); } - return _this5.uploadFile(file); + return this.uploadFile(file); }); return Promise.all(promises); - }; + } - _proto.onFileRemove = function onFileRemove(fileID, cb) { - this.uploaderEvents[fileID].on('file-removed', function (file) { + onFileRemove(fileID, cb) { + this.uploaderEvents[fileID].on('file-removed', file => { if (fileID === file.id) cb(file.id); }); - }; + } - _proto.onFilePause = function onFilePause(fileID, cb) { - this.uploaderEvents[fileID].on('upload-pause', function (targetFileID, isPaused) { + onFilePause(fileID, cb) { + this.uploaderEvents[fileID].on('upload-pause', (targetFileID, isPaused) => { if (fileID === targetFileID) { // const isPaused = this.uppy.pauseResume(fileID) cb(isPaused); } }); - }; + } - _proto.onRetry = function onRetry(fileID, cb) { - this.uploaderEvents[fileID].on('upload-retry', function (targetFileID) { + onRetry(fileID, cb) { + this.uploaderEvents[fileID].on('upload-retry', targetFileID => { if (fileID === targetFileID) { cb(); } }); - }; + } - _proto.onRetryAll = function onRetryAll(fileID, cb) { - var _this6 = this; - - this.uploaderEvents[fileID].on('retry-all', function (filesToRetry) { - if (!_this6.uppy.getFile(fileID)) return; + onRetryAll(fileID, cb) { + this.uploaderEvents[fileID].on('retry-all', () => { + if (!this.uppy.getFile(fileID)) return; cb(); }); - }; + } - _proto.onPauseAll = function onPauseAll(fileID, cb) { - var _this7 = this; - - this.uploaderEvents[fileID].on('pause-all', function () { - if (!_this7.uppy.getFile(fileID)) return; + onPauseAll(fileID, cb) { + this.uploaderEvents[fileID].on('pause-all', () => { + if (!this.uppy.getFile(fileID)) return; cb(); }); - }; + } - _proto.onCancelAll = function onCancelAll(fileID, cb) { - var _this8 = this; - - this.uploaderEvents[fileID].on('cancel-all', function () { - if (!_this8.uppy.getFile(fileID)) return; + onCancelAll(fileID, cb) { + this.uploaderEvents[fileID].on('cancel-all', () => { + if (!this.uppy.getFile(fileID)) return; cb(); }); - }; + } - _proto.onResumeAll = function onResumeAll(fileID, cb) { - var _this9 = this; - - this.uploaderEvents[fileID].on('resume-all', function () { - if (!_this9.uppy.getFile(fileID)) return; + onResumeAll(fileID, cb) { + this.uploaderEvents[fileID].on('resume-all', () => { + if (!this.uppy.getFile(fileID)) return; cb(); }); - }; - - _proto.install = function install() { - var _this$uppy$getState = this.uppy.getState(), - capabilities = _this$uppy$getState.capabilities; + } + install() { + const { + capabilities + } = this.uppy.getState(); this.uppy.setState({ - capabilities: _extends({}, capabilities, { + capabilities: { ...capabilities, resumableUploads: true - }) + } }); this.uppy.addUploader(this.upload); - }; - - _proto.uninstall = function uninstall() { - var _this$uppy$getState2 = this.uppy.getState(), - capabilities = _this$uppy$getState2.capabilities; + } + uninstall() { + const { + capabilities + } = this.uppy.getState(); this.uppy.setState({ - capabilities: _extends({}, capabilities, { + capabilities: { ...capabilities, resumableUploads: false - }) + } }); this.uppy.removeUploader(this.upload); - }; + } - return AwsS3Multipart; -}(Plugin), _class.VERSION = "1.8.18", _temp); -},{"./MultipartUploader":2,"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/EventTracker":22,"@uppy/utils/lib/RateLimitedQueue":25,"@uppy/utils/lib/emitSocketProgress":28,"@uppy/utils/lib/getSocketHost":40}],4:[function(require,module,exports){ -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +}, _class.VERSION = "2.0.2", _temp); +},{"./MultipartUploader":2,"@uppy/companion-client":12,"@uppy/core":17,"@uppy/utils/lib/EventTracker":23,"@uppy/utils/lib/RateLimitedQueue":26,"@uppy/utils/lib/emitSocketProgress":29,"@uppy/utils/lib/getSocketHost":40}],4:[function(require,module,exports){ +"use strict"; -var cuid = require('cuid'); +var _getOptions, _addEventHandlerForFile, _addEventHandlerIfFileStillExists, _uploadLocalFile, _uploadRemoteFile; -var _require = require('@uppy/companion-client'), - Provider = _require.Provider, - RequestClient = _require.RequestClient, - Socket = _require.Socket; +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } -var emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress'); +var id = 0; -var getSocketHost = require('@uppy/utils/lib/getSocketHost'); +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } -var EventTracker = require('@uppy/utils/lib/EventTracker'); +const { + nanoid +} = require('nanoid'); -var ProgressTimeout = require('@uppy/utils/lib/ProgressTimeout'); +const { + Provider, + RequestClient, + Socket +} = require('@uppy/companion-client'); -var NetworkError = require('@uppy/utils/lib/NetworkError'); +const emitSocketProgress = require('@uppy/utils/lib/emitSocketProgress'); -var isNetworkError = require('@uppy/utils/lib/isNetworkError'); // See XHRUpload +const getSocketHost = require('@uppy/utils/lib/getSocketHost'); + +const EventTracker = require('@uppy/utils/lib/EventTracker'); + +const ProgressTimeout = require('@uppy/utils/lib/ProgressTimeout'); + +const NetworkError = require('@uppy/utils/lib/NetworkError'); + +const isNetworkError = require('@uppy/utils/lib/isNetworkError'); + +const { + internalRateLimitedQueue +} = require('@uppy/utils/lib/RateLimitedQueue'); // See XHRUpload function buildResponseError(xhr, error) { - // No error message - if (!error) error = new Error('Upload error'); // Got an error message string + if (isNetworkError(xhr)) return new NetworkError(error, xhr); // TODO: when we drop support for browsers that do not support this syntax, use: + // return new Error('Upload error', { cause: error, request: xhr }) - if (typeof error === 'string') error = new Error(error); // Got something else - - if (!(error instanceof Error)) { - error = _extends(new Error('Upload error'), { - data: error - }); - } - - if (isNetworkError(xhr)) { - error = new NetworkError(error, xhr); - return error; - } - - error.request = xhr; - return error; + const err = new Error('Upload error'); + err.cause = error; + err.request = xhr; + return err; } // See XHRUpload function setTypeInBlob(file) { - var dataWithUpdatedType = file.data.slice(0, file.data.size, file.meta.type); + const dataWithUpdatedType = file.data.slice(0, file.data.size, file.meta.type); return dataWithUpdatedType; } -module.exports = /*#__PURE__*/function () { - function MiniXHRUpload(uppy, opts) { - this.uppy = uppy; - this.opts = _extends({ - validateStatus: function validateStatus(status, responseText, response) { - return status >= 200 && status < 300; - } - }, opts); - this.requests = opts.__queue; - this.uploaderEvents = Object.create(null); - this.i18n = opts.i18n; +function addMetadata(formData, meta, opts) { + const metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default. + : Object.keys(meta); + metaFields.forEach(item => { + formData.append(item, meta[item]); + }); +} + +function createFormDataUpload(file, opts) { + const formPost = new FormData(); + addMetadata(formPost, file.meta, opts); + const dataWithUpdatedType = setTypeInBlob(file); + + if (file.name) { + formPost.append(opts.fieldName, dataWithUpdatedType, file.meta.name); + } else { + formPost.append(opts.fieldName, dataWithUpdatedType); } - var _proto = MiniXHRUpload.prototype; + return formPost; +} - _proto._getOptions = function _getOptions(file) { - var uppy = this.uppy; - var overrides = uppy.getState().xhrUpload; +const createBareUpload = file => file.data; - var opts = _extends({}, this.opts, overrides || {}, file.xhrUpload || {}, { - headers: {} +module.exports = (_getOptions = /*#__PURE__*/_classPrivateFieldLooseKey("getOptions"), _addEventHandlerForFile = /*#__PURE__*/_classPrivateFieldLooseKey("addEventHandlerForFile"), _addEventHandlerIfFileStillExists = /*#__PURE__*/_classPrivateFieldLooseKey("addEventHandlerIfFileStillExists"), _uploadLocalFile = /*#__PURE__*/_classPrivateFieldLooseKey("uploadLocalFile"), _uploadRemoteFile = /*#__PURE__*/_classPrivateFieldLooseKey("uploadRemoteFile"), class MiniXHRUpload { + constructor(_uppy, _opts) { + Object.defineProperty(this, _uploadRemoteFile, { + value: _uploadRemoteFile2 }); + Object.defineProperty(this, _uploadLocalFile, { + value: _uploadLocalFile2 + }); + Object.defineProperty(this, _addEventHandlerIfFileStillExists, { + value: _addEventHandlerIfFileStillExists2 + }); + Object.defineProperty(this, _addEventHandlerForFile, { + value: _addEventHandlerForFile2 + }); + Object.defineProperty(this, _getOptions, { + value: _getOptions2 + }); + this.uppy = _uppy; + this.opts = { + validateStatus(status) { + return status >= 200 && status < 300; + }, - _extends(opts.headers, this.opts.headers); + ..._opts + }; + this.requests = _opts[internalRateLimitedQueue]; + this.uploaderEvents = Object.create(null); + this.i18n = _opts.i18n; + } - if (overrides) { - _extends(opts.headers, overrides.headers); - } - - if (file.xhrUpload) { - _extends(opts.headers, file.xhrUpload.headers); - } - - return opts; - }; - - _proto.uploadFile = function uploadFile(id, current, total) { - var file = this.uppy.getFile(id); + uploadFile(id, current, total) { + const file = this.uppy.getFile(id); if (file.error) { throw new Error(file.error); } else if (file.isRemote) { - return this._uploadRemoteFile(file, current, total); + return _classPrivateFieldLooseBase(this, _uploadRemoteFile)[_uploadRemoteFile](file, current, total); } - return this._uploadLocalFile(file, current, total); - }; + return _classPrivateFieldLooseBase(this, _uploadLocalFile)[_uploadLocalFile](file, current, total); + } - _proto._addMetadata = function _addMetadata(formData, meta, opts) { - var metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default. - : Object.keys(meta); - metaFields.forEach(function (item) { - formData.append(item, meta[item]); - }); - }; +}); - _proto._createFormDataUpload = function _createFormDataUpload(file, opts) { - var formPost = new FormData(); +function _getOptions2(file) { + var _file$xhrUpload; - this._addMetadata(formPost, file.meta, opts); - - var dataWithUpdatedType = setTypeInBlob(file); - - if (file.name) { - formPost.append(opts.fieldName, dataWithUpdatedType, file.meta.name); - } else { - formPost.append(opts.fieldName, dataWithUpdatedType); + const { + uppy + } = this; + const overrides = uppy.getState().xhrUpload; + const opts = { ...this.opts, + ...(overrides || {}), + ...(file.xhrUpload || {}), + headers: { ...this.opts.headers, + ...(overrides == null ? void 0 : overrides.headers), + ...((_file$xhrUpload = file.xhrUpload) == null ? void 0 : _file$xhrUpload.headers) } - - return formPost; }; + return opts; +} - _proto._createBareUpload = function _createBareUpload(file, opts) { - return file.data; - }; +function _addEventHandlerForFile2(eventName, fileID, eventHandler) { + this.uploaderEvents[fileID].on(eventName, targetFileID => { + if (fileID === targetFileID) eventHandler(); + }); +} - _proto._onFileRemoved = function _onFileRemoved(fileID, cb) { - this.uploaderEvents[fileID].on('file-removed', function (file) { - if (fileID === file.id) cb(file.id); - }); - }; +function _addEventHandlerIfFileStillExists2(eventName, fileID, eventHandler) { + this.uploaderEvents[fileID].on(eventName, () => { + if (this.uppy.getFile(fileID)) eventHandler(); + }); +} - _proto._onRetry = function _onRetry(fileID, cb) { - this.uploaderEvents[fileID].on('upload-retry', function (targetFileID) { - if (fileID === targetFileID) { - cb(); - } - }); - }; +function _uploadLocalFile2(file, current, total) { + const opts = _classPrivateFieldLooseBase(this, _getOptions)[_getOptions](file); - _proto._onRetryAll = function _onRetryAll(fileID, cb) { - var _this = this; - - this.uploaderEvents[fileID].on('retry-all', function (filesToRetry) { - if (!_this.uppy.getFile(fileID)) return; - cb(); - }); - }; - - _proto._onCancelAll = function _onCancelAll(fileID, cb) { - var _this2 = this; - - this.uploaderEvents[fileID].on('cancel-all', function () { - if (!_this2.uppy.getFile(fileID)) return; - cb(); - }); - }; - - _proto._uploadLocalFile = function _uploadLocalFile(file, current, total) { - var _this3 = this; - - var opts = this._getOptions(file); - - this.uppy.log("uploading " + current + " of " + total); - return new Promise(function (resolve, reject) { - // This is done in index.js in the S3 plugin. - // this.uppy.emit('upload-started', file) - var data = opts.formData ? _this3._createFormDataUpload(file, opts) : _this3._createBareUpload(file, opts); - var xhr = new XMLHttpRequest(); - _this3.uploaderEvents[file.id] = new EventTracker(_this3.uppy); - var timer = new ProgressTimeout(opts.timeout, function () { + this.uppy.log(`uploading ${current} of ${total}`); + return new Promise((resolve, reject) => { + // This is done in index.js in the S3 plugin. + // this.uppy.emit('upload-started', file) + const data = opts.formData ? createFormDataUpload(file, opts) : createBareUpload(file, opts); + const xhr = new XMLHttpRequest(); + this.uploaderEvents[file.id] = new EventTracker(this.uppy); + const queuedRequest = this.requests.run(() => { + xhr.send(data); + return () => { + // eslint-disable-next-line no-use-before-define + timer.done(); xhr.abort(); - queuedRequest.done(); - var error = new Error(_this3.i18n('timedOut', { - seconds: Math.ceil(opts.timeout / 1000) - })); + }; + }, { + priority: 1 + }); + const timer = new ProgressTimeout(opts.timeout, () => { + xhr.abort(); + queuedRequest.done(); + const error = new Error(this.i18n('timedOut', { + seconds: Math.ceil(opts.timeout / 1000) + })); + this.uppy.emit('upload-error', file, error); + reject(error); + }); + const id = nanoid(); + xhr.upload.addEventListener('loadstart', () => { + this.uppy.log(`[AwsS3/XHRUpload] ${id} started`); + }); + xhr.upload.addEventListener('progress', ev => { + this.uppy.log(`[AwsS3/XHRUpload] ${id} progress: ${ev.loaded} / ${ev.total}`); // Begin checking for timeouts when progress starts, instead of loading, + // to avoid timing out requests on browser concurrency queue - _this3.uppy.emit('upload-error', file, error); + timer.progress(); - reject(error); - }); - var id = cuid(); - xhr.upload.addEventListener('loadstart', function (ev) { - _this3.uppy.log("[AwsS3/XHRUpload] " + id + " started"); - }); - xhr.upload.addEventListener('progress', function (ev) { - _this3.uppy.log("[AwsS3/XHRUpload] " + id + " progress: " + ev.loaded + " / " + ev.total); // Begin checking for timeouts when progress starts, instead of loading, - // to avoid timing out requests on browser concurrency queue + if (ev.lengthComputable) { + this.uppy.emit('upload-progress', file, { + uploader: this, + bytesUploaded: ev.loaded, + bytesTotal: ev.total + }); + } + }); + xhr.addEventListener('load', ev => { + this.uppy.log(`[AwsS3/XHRUpload] ${id} finished`); + timer.done(); + queuedRequest.done(); - - timer.progress(); - - if (ev.lengthComputable) { - _this3.uppy.emit('upload-progress', file, { - uploader: _this3, - bytesUploaded: ev.loaded, - bytesTotal: ev.total - }); - } - }); - xhr.addEventListener('load', function (ev) { - _this3.uppy.log("[AwsS3/XHRUpload] " + id + " finished"); - - timer.done(); - queuedRequest.done(); - - if (_this3.uploaderEvents[file.id]) { - _this3.uploaderEvents[file.id].remove(); - - _this3.uploaderEvents[file.id] = null; - } - - if (opts.validateStatus(ev.target.status, xhr.responseText, xhr)) { - var _body = opts.getResponseData(xhr.responseText, xhr); - - var uploadURL = _body[opts.responseUrlFieldName]; - var uploadResp = { - status: ev.target.status, - body: _body, - uploadURL: uploadURL - }; - - _this3.uppy.emit('upload-success', file, uploadResp); - - if (uploadURL) { - _this3.uppy.log("Download " + file.name + " from " + uploadURL); - } - - return resolve(file); - } - - var body = opts.getResponseData(xhr.responseText, xhr); - var error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr)); - var response = { - status: ev.target.status, - body: body - }; - - _this3.uppy.emit('upload-error', file, error, response); - - return reject(error); - }); - xhr.addEventListener('error', function (ev) { - _this3.uppy.log("[AwsS3/XHRUpload] " + id + " errored"); - - timer.done(); - queuedRequest.done(); - - if (_this3.uploaderEvents[file.id]) { - _this3.uploaderEvents[file.id].remove(); - - _this3.uploaderEvents[file.id] = null; - } - - var error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr)); - - _this3.uppy.emit('upload-error', file, error); - - return reject(error); - }); - xhr.open(opts.method.toUpperCase(), opts.endpoint, true); // IE10 does not allow setting `withCredentials` and `responseType` - // before `open()` is called. - - xhr.withCredentials = opts.withCredentials; - - if (opts.responseType !== '') { - xhr.responseType = opts.responseType; + if (this.uploaderEvents[file.id]) { + this.uploaderEvents[file.id].remove(); + this.uploaderEvents[file.id] = null; } - Object.keys(opts.headers).forEach(function (header) { - xhr.setRequestHeader(header, opts.headers[header]); - }); - - var queuedRequest = _this3.requests.run(function () { - xhr.send(data); - return function () { - timer.done(); - xhr.abort(); + if (opts.validateStatus(ev.target.status, xhr.responseText, xhr)) { + const body = opts.getResponseData(xhr.responseText, xhr); + const uploadURL = body[opts.responseUrlFieldName]; + const uploadResp = { + status: ev.target.status, + body, + uploadURL }; - }, { - priority: 1 - }); + this.uppy.emit('upload-success', file, uploadResp); - _this3._onFileRemoved(file.id, function () { - queuedRequest.abort(); - reject(new Error('File removed')); - }); + if (uploadURL) { + this.uppy.log(`Download ${file.name} from ${uploadURL}`); + } - _this3._onCancelAll(file.id, function () { - queuedRequest.abort(); - reject(new Error('Upload cancelled')); - }); + return resolve(file); + } + + const body = opts.getResponseData(xhr.responseText, xhr); + const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr)); + const response = { + status: ev.target.status, + body + }; + this.uppy.emit('upload-error', file, error, response); + return reject(error); }); - }; + xhr.addEventListener('error', () => { + this.uppy.log(`[AwsS3/XHRUpload] ${id} errored`); + timer.done(); + queuedRequest.done(); - _proto._uploadRemoteFile = function _uploadRemoteFile(file, current, total) { - var _this4 = this; + if (this.uploaderEvents[file.id]) { + this.uploaderEvents[file.id].remove(); + this.uploaderEvents[file.id] = null; + } - var opts = this._getOptions(file); - - return new Promise(function (resolve, reject) { - // This is done in index.js in the S3 plugin. - // this.uppy.emit('upload-started', file) - var fields = {}; - var metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default. - : Object.keys(file.meta); - metaFields.forEach(function (name) { - fields[name] = file.meta[name]; - }); - var Client = file.remote.providerOptions.provider ? Provider : RequestClient; - var client = new Client(_this4.uppy, file.remote.providerOptions); - client.post(file.remote.url, _extends({}, file.remote.body, { - endpoint: opts.endpoint, - size: file.data.size, - fieldname: opts.fieldName, - metadata: fields, - httpMethod: opts.method, - useFormData: opts.formData, - headers: opts.headers - })).then(function (res) { - var token = res.token; - var host = getSocketHost(file.remote.companionUrl); - var socket = new Socket({ - target: host + "/api/" + token, - autoOpen: false - }); - _this4.uploaderEvents[file.id] = new EventTracker(_this4.uppy); - - _this4._onFileRemoved(file.id, function () { - socket.send('pause', {}); - queuedRequest.abort(); - resolve("upload " + file.id + " was removed"); - }); - - _this4._onCancelAll(file.id, function () { - socket.send('pause', {}); - queuedRequest.abort(); - resolve("upload " + file.id + " was canceled"); - }); - - _this4._onRetry(file.id, function () { - socket.send('pause', {}); - socket.send('resume', {}); - }); - - _this4._onRetryAll(file.id, function () { - socket.send('pause', {}); - socket.send('resume', {}); - }); - - socket.on('progress', function (progressData) { - return emitSocketProgress(_this4, progressData, file); - }); - socket.on('success', function (data) { - var body = opts.getResponseData(data.response.responseText, data.response); - var uploadURL = body[opts.responseUrlFieldName]; - var uploadResp = { - status: data.response.status, - body: body, - uploadURL: uploadURL - }; - - _this4.uppy.emit('upload-success', file, uploadResp); - - queuedRequest.done(); - - if (_this4.uploaderEvents[file.id]) { - _this4.uploaderEvents[file.id].remove(); - - _this4.uploaderEvents[file.id] = null; - } - - return resolve(); - }); - socket.on('error', function (errData) { - var resp = errData.response; - var error = resp ? opts.getResponseError(resp.responseText, resp) : _extends(new Error(errData.error.message), { - cause: errData.error - }); - - _this4.uppy.emit('upload-error', file, error); - - queuedRequest.done(); - - if (_this4.uploaderEvents[file.id]) { - _this4.uploaderEvents[file.id].remove(); - - _this4.uploaderEvents[file.id] = null; - } - - reject(error); - }); - - var queuedRequest = _this4.requests.run(function () { - socket.open(); - - if (file.isPaused) { - socket.send('pause', {}); - } - - return function () { - return socket.close(); - }; - }); - }).catch(function (err) { - _this4.uppy.emit('upload-error', file, err); - - reject(err); - }); + const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr)); + this.uppy.emit('upload-error', file, error); + return reject(error); }); - }; + xhr.open(opts.method.toUpperCase(), opts.endpoint, true); // IE10 does not allow setting `withCredentials` and `responseType` + // before `open()` is called. - return MiniXHRUpload; -}(); -},{"@uppy/companion-client":12,"@uppy/utils/lib/EventTracker":22,"@uppy/utils/lib/NetworkError":23,"@uppy/utils/lib/ProgressTimeout":24,"@uppy/utils/lib/emitSocketProgress":28,"@uppy/utils/lib/getSocketHost":40,"@uppy/utils/lib/isNetworkError":44,"cuid":50}],5:[function(require,module,exports){ -var _class, _temp; + xhr.withCredentials = opts.withCredentials; -function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + if (opts.responseType !== '') { + xhr.responseType = opts.responseType; + } -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } + Object.keys(opts.headers).forEach(header => { + xhr.setRequestHeader(header, opts.headers[header]); + }); -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + _classPrivateFieldLooseBase(this, _addEventHandlerForFile)[_addEventHandlerForFile]('file-removed', file.id, () => { + queuedRequest.abort(); + reject(new Error('File removed')); + }); -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + _classPrivateFieldLooseBase(this, _addEventHandlerIfFileStillExists)[_addEventHandlerIfFileStillExists]('cancel-all', file.id, () => { + queuedRequest.abort(); + reject(new Error('Upload cancelled')); + }); + }); +} + +function _uploadRemoteFile2(file) { + const opts = _classPrivateFieldLooseBase(this, _getOptions)[_getOptions](file); // This is done in index.js in the S3 plugin. + // this.uppy.emit('upload-started', file) + + + const metaFields = Array.isArray(opts.metaFields) ? opts.metaFields // Send along all fields by default. + : Object.keys(file.meta); + const Client = file.remote.providerOptions.provider ? Provider : RequestClient; + const client = new Client(this.uppy, file.remote.providerOptions); + return client.post(file.remote.url, { ...file.remote.body, + endpoint: opts.endpoint, + size: file.data.size, + fieldname: opts.fieldName, + metadata: Object.fromEntries(metaFields.map(name => [name, file.meta[name]])), + httpMethod: opts.method, + useFormData: opts.formData, + headers: opts.headers + }).then(res => new Promise((resolve, reject) => { + const { + token + } = res; + const host = getSocketHost(file.remote.companionUrl); + const socket = new Socket({ + target: `${host}/api/${token}`, + autoOpen: false + }); + this.uploaderEvents[file.id] = new EventTracker(this.uppy); + const queuedRequest = this.requests.run(() => { + socket.open(); + + if (file.isPaused) { + socket.send('pause', {}); + } + + return () => socket.close(); + }); + + _classPrivateFieldLooseBase(this, _addEventHandlerForFile)[_addEventHandlerForFile]('file-removed', file.id, () => { + socket.send('pause', {}); + queuedRequest.abort(); + resolve(`upload ${file.id} was removed`); + }); + + _classPrivateFieldLooseBase(this, _addEventHandlerIfFileStillExists)[_addEventHandlerIfFileStillExists]('cancel-all', file.id, () => { + socket.send('pause', {}); + queuedRequest.abort(); + resolve(`upload ${file.id} was canceled`); + }); + + _classPrivateFieldLooseBase(this, _addEventHandlerForFile)[_addEventHandlerForFile]('upload-retry', file.id, () => { + socket.send('pause', {}); + socket.send('resume', {}); + }); + + _classPrivateFieldLooseBase(this, _addEventHandlerIfFileStillExists)[_addEventHandlerIfFileStillExists]('retry-all', file.id, () => { + socket.send('pause', {}); + socket.send('resume', {}); + }); + + socket.on('progress', progressData => emitSocketProgress(this, progressData, file)); + socket.on('success', data => { + const body = opts.getResponseData(data.response.responseText, data.response); + const uploadURL = body[opts.responseUrlFieldName]; + const uploadResp = { + status: data.response.status, + body, + uploadURL, + bytesUploaded: data.bytesUploaded + }; + this.uppy.emit('upload-success', file, uploadResp); + queuedRequest.done(); + + if (this.uploaderEvents[file.id]) { + this.uploaderEvents[file.id].remove(); + this.uploaderEvents[file.id] = null; + } + + return resolve(); + }); + socket.on('error', errData => { + const resp = errData.response; + const error = resp ? opts.getResponseError(resp.responseText, resp) : Object.assign(new Error(errData.error.message), { + cause: errData.error + }); + this.uppy.emit('upload-error', file, error); + queuedRequest.done(); + + if (this.uploaderEvents[file.id]) { + this.uploaderEvents[file.id].remove(); + this.uploaderEvents[file.id] = null; + } + + reject(error); + }); + }).catch(err => { + this.uppy.emit('upload-error', file, err); + return Promise.reject(err); + })); +} +},{"@uppy/companion-client":12,"@uppy/utils/lib/EventTracker":23,"@uppy/utils/lib/NetworkError":24,"@uppy/utils/lib/ProgressTimeout":25,"@uppy/utils/lib/RateLimitedQueue":26,"@uppy/utils/lib/emitSocketProgress":29,"@uppy/utils/lib/getSocketHost":40,"@uppy/utils/lib/isNetworkError":44,"nanoid":52}],5:[function(require,module,exports){ +"use strict"; + +var _class, _client, _requests, _uploader, _handleUpload, _temp; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } /** * This plugin is currently a A Big Hack™! The core reason for that is how this plugin @@ -1529,31 +1514,27 @@ function _extends() { _extends = Object.assign || function (target) { for (var i * This isn't as nicely modular as we'd like and requires us to maintain two copies of * the XHRUpload code, but at least it's not horrifically broken :) */ -// If global `URL` constructor is available, use it -var URL_ = typeof URL === 'function' ? URL : require('url-parse'); +const { + BasePlugin +} = require('@uppy/core'); -var _require = require('@uppy/core'), - Plugin = _require.Plugin; +const { + RateLimitedQueue, + internalRateLimitedQueue +} = require('@uppy/utils/lib/RateLimitedQueue'); -var Translator = require('@uppy/utils/lib/Translator'); +const settle = require('@uppy/utils/lib/settle'); -var RateLimitedQueue = require('@uppy/utils/lib/RateLimitedQueue'); +const { + RequestClient +} = require('@uppy/companion-client'); -var settle = require('@uppy/utils/lib/settle'); +const MiniXHRUpload = require('./MiniXHRUpload'); -var hasProperty = require('@uppy/utils/lib/hasProperty'); - -var _require2 = require('@uppy/companion-client'), - RequestClient = _require2.RequestClient; - -var qsStringify = require('qs-stringify'); - -var MiniXHRUpload = require('./MiniXHRUpload'); - -var isXml = require('./isXml'); +const isXml = require('./isXml'); function resolveUrl(origin, link) { - return origin ? new URL_(link, origin).toString() : new URL_(link).toString(); + return new URL(link, origin || undefined).toString(); } /** * Get the contents of a named tag in an XML source string. @@ -1565,194 +1546,190 @@ function resolveUrl(origin, link) { function getXmlValue(source, tagName) { - var start = source.indexOf("<" + tagName + ">"); - var end = source.indexOf("", start); + const start = source.indexOf(`<${tagName}>`); + const end = source.indexOf(``, start); return start !== -1 && end !== -1 ? source.slice(start + tagName.length + 2, end) : ''; } function assertServerError(res) { if (res && res.error) { - var error = new Error(res.message); - - _extends(error, res.error); - + const error = new Error(res.message); + Object.assign(error, res.error); throw error; } return res; +} + +function validateParameters(file, params) { + const valid = params != null && typeof params.url === 'string' && (typeof params.fields === 'object' || params.fields == null); + + if (!valid) { + const err = new TypeError(`AwsS3: got incorrect result from 'getUploadParameters()' for file '${file.name}', expected an object '{ url, method, fields, headers }' but got '${JSON.stringify(params)}' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`); + throw err; + } + + const methodIsValid = params.method == null || /^p(u|os)t$/i.test(params.method); + + if (!methodIsValid) { + const err = new TypeError(`AwsS3: got incorrect method from 'getUploadParameters()' for file '${file.name}', expected 'put' or 'post' but got '${params.method}' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format.`); + throw err; + } +} // Get the error data from a failed XMLHttpRequest instance. +// `content` is the S3 response as a string. +// `xhr` is the XMLHttpRequest instance. + + +function defaultGetResponseError(content, xhr) { + // If no response, we don't have a specific error message, use the default. + if (!isXml(content, xhr)) { + return undefined; + } + + const error = getXmlValue(content, 'Message'); + return new Error(error); } // warning deduplication flag: see `getResponseData()` XHRUpload option definition -var warnedSuccessActionStatus = false; -module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { - _inheritsLoose(AwsS3, _Plugin); +let warnedSuccessActionStatus = false; +module.exports = (_temp = (_client = /*#__PURE__*/_classPrivateFieldLooseKey("client"), _requests = /*#__PURE__*/_classPrivateFieldLooseKey("requests"), _uploader = /*#__PURE__*/_classPrivateFieldLooseKey("uploader"), _handleUpload = /*#__PURE__*/_classPrivateFieldLooseKey("handleUpload"), _class = class AwsS3 extends BasePlugin { + // eslint-disable-next-line global-require + constructor(uppy, opts) { + super(uppy, opts); + Object.defineProperty(this, _client, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _requests, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _uploader, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _handleUpload, { + writable: true, + value: fileIDs => { + /** + * keep track of `getUploadParameters()` responses + * so we can cancel the calls individually using just a file ID + * + * @type {object.} + */ + const paramsPromises = Object.create(null); - function AwsS3(uppy, opts) { - var _this; + function onremove(file) { + var _paramsPromises$id; - _this = _Plugin.call(this, uppy, opts) || this; - _this.type = 'uploader'; - _this.id = _this.opts.id || 'AwsS3'; - _this.title = 'AWS S3'; - _this.defaultLocale = { + const { + id + } = file; + (_paramsPromises$id = paramsPromises[id]) == null ? void 0 : _paramsPromises$id.abort(); + } + + this.uppy.on('file-removed', onremove); + fileIDs.forEach(id => { + const file = this.uppy.getFile(id); + this.uppy.emit('upload-started', file); + }); + + const getUploadParameters = _classPrivateFieldLooseBase(this, _requests)[_requests].wrapPromiseFunction(file => { + return this.opts.getUploadParameters(file); + }); + + const numberOfFiles = fileIDs.length; + return settle(fileIDs.map((id, index) => { + paramsPromises[id] = getUploadParameters(this.uppy.getFile(id)); + return paramsPromises[id].then(params => { + delete paramsPromises[id]; + const file = this.uppy.getFile(id); + validateParameters(file, params); + const { + method = 'post', + url, + fields, + headers + } = params; + const xhrOpts = { + method, + formData: method.toLowerCase() === 'post', + endpoint: url, + metaFields: fields ? Object.keys(fields) : [] + }; + + if (headers) { + xhrOpts.headers = headers; + } + + this.uppy.setFileState(file.id, { + meta: { ...file.meta, + ...fields + }, + xhrUpload: xhrOpts + }); + return _classPrivateFieldLooseBase(this, _uploader)[_uploader].uploadFile(file.id, index, numberOfFiles); + }).catch(error => { + delete paramsPromises[id]; + const file = this.uppy.getFile(id); + this.uppy.emit('upload-error', file, error); + }); + })).finally(() => { + // cleanup. + this.uppy.off('file-removed', onremove); + }); + } + }); + this.type = 'uploader'; + this.id = this.opts.id || 'AwsS3'; + this.title = 'AWS S3'; + this.defaultLocale = { strings: { timedOut: 'Upload stalled for %{seconds} seconds, aborting.' } }; - var defaultOptions = { + const defaultOptions = { timeout: 30 * 1000, limit: 0, metaFields: [], // have to opt in - getUploadParameters: _this.getUploadParameters.bind(_assertThisInitialized(_this)) + getUploadParameters: this.getUploadParameters.bind(this) }; - _this.opts = _extends({}, defaultOptions, opts); - - _this.i18nInit(); - - _this.client = new RequestClient(uppy, opts); - _this.handleUpload = _this.handleUpload.bind(_assertThisInitialized(_this)); - _this.requests = new RateLimitedQueue(_this.opts.limit); - return _this; + this.opts = { ...defaultOptions, + ...opts + }; + _classPrivateFieldLooseBase(this, _client)[_client] = new RequestClient(uppy, opts); + _classPrivateFieldLooseBase(this, _requests)[_requests] = new RateLimitedQueue(this.opts.limit); } - var _proto = AwsS3.prototype; - - _proto.setOptions = function setOptions(newOpts) { - _Plugin.prototype.setOptions.call(this, newOpts); - - this.i18nInit(); - }; - - _proto.i18nInit = function i18nInit() { - this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]); - this.i18n = this.translator.translate.bind(this.translator); - this.setPluginState(); // so that UI re-renders and we see the updated locale - }; - - _proto.getUploadParameters = function getUploadParameters(file) { + getUploadParameters(file) { if (!this.opts.companionUrl) { throw new Error('Expected a `companionUrl` option containing a Companion address.'); } - var filename = file.meta.name; - var type = file.meta.type; - var metadata = {}; - this.opts.metaFields.forEach(function (key) { - if (file.meta[key] != null) { - metadata[key] = file.meta[key].toString(); - } + const filename = file.meta.name; + const { + type + } = file.meta; + const metadata = Object.fromEntries(this.opts.metaFields.filter(key => file.meta[key] != null).map(key => [`metadata[${key}]`, file.meta[key].toString()])); + const query = new URLSearchParams({ + filename, + type, + ...metadata }); - var query = qsStringify({ - filename: filename, - type: type, - metadata: metadata - }); - return this.client.get("s3/params?" + query).then(assertServerError); - }; + return _classPrivateFieldLooseBase(this, _client)[_client].get(`s3/params?${query}`).then(assertServerError); + } - _proto.validateParameters = function validateParameters(file, params) { - var valid = typeof params === 'object' && params && typeof params.url === 'string' && (typeof params.fields === 'object' || params.fields == null); - - if (!valid) { - var err = new TypeError("AwsS3: got incorrect result from 'getUploadParameters()' for file '" + file.name + "', expected an object '{ url, method, fields, headers }' but got '" + JSON.stringify(params) + "' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format."); - console.error(err); - throw err; - } - - var methodIsValid = params.method == null || /^(put|post)$/i.test(params.method); - - if (!methodIsValid) { - var _err = new TypeError("AwsS3: got incorrect method from 'getUploadParameters()' for file '" + file.name + "', expected 'put' or 'post' but got '" + params.method + "' instead.\nSee https://uppy.io/docs/aws-s3/#getUploadParameters-file for more on the expected format."); - - console.error(_err); - throw _err; - } - }; - - _proto.handleUpload = function handleUpload(fileIDs) { - var _this2 = this; - - /** - * keep track of `getUploadParameters()` responses - * so we can cancel the calls individually using just a file ID - * - * @type {object.} - */ - var paramsPromises = Object.create(null); - - function onremove(file) { - var id = file.id; - - if (hasProperty(paramsPromises, id)) { - paramsPromises[id].abort(); - } - } - - this.uppy.on('file-removed', onremove); - fileIDs.forEach(function (id) { - var file = _this2.uppy.getFile(id); - - _this2.uppy.emit('upload-started', file); - }); - var getUploadParameters = this.requests.wrapPromiseFunction(function (file) { - return _this2.opts.getUploadParameters(file); - }); - var numberOfFiles = fileIDs.length; - return settle(fileIDs.map(function (id, index) { - paramsPromises[id] = getUploadParameters(_this2.uppy.getFile(id)); - return paramsPromises[id].then(function (params) { - delete paramsPromises[id]; - - var file = _this2.uppy.getFile(id); - - _this2.validateParameters(file, params); - - var _params$method = params.method, - method = _params$method === void 0 ? 'post' : _params$method, - url = params.url, - fields = params.fields, - headers = params.headers; - var xhrOpts = { - method: method, - formData: method.toLowerCase() === 'post', - endpoint: url, - metaFields: fields ? Object.keys(fields) : [] - }; - - if (headers) { - xhrOpts.headers = headers; - } - - _this2.uppy.setFileState(file.id, { - meta: _extends({}, file.meta, fields), - xhrUpload: xhrOpts - }); - - return _this2._uploader.uploadFile(file.id, index, numberOfFiles); - }).catch(function (error) { - delete paramsPromises[id]; - - var file = _this2.uppy.getFile(id); - - _this2.uppy.emit('upload-error', file, error); - }); - })).then(function (settled) { - // cleanup. - _this2.uppy.off('file-removed', onremove); - - return settled; - }); - }; - - _proto.install = function install() { - var uppy = this.uppy; - this.uppy.addUploader(this.handleUpload); // Get the response data from a successful XMLHttpRequest instance. + install() { + const { + uppy + } = this; + uppy.addUploader(_classPrivateFieldLooseBase(this, _handleUpload)[_handleUpload]); // Get the response data from a successful XMLHttpRequest instance. // `content` is the S3 response as a string. // `xhr` is the XMLHttpRequest instance. function defaultGetResponseData(content, xhr) { - var opts = this; // If no response, we've hopefully done a PUT request to the file + const opts = this; // If no response, we've hopefully done a PUT request to the file // in the bucket on its full URL. if (!isXml(content, xhr)) { @@ -1791,45 +1768,33 @@ module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { key: getXmlValue(content, 'Key'), etag: getXmlValue(content, 'ETag') }; - } // Get the error data from a failed XMLHttpRequest instance. - // `content` is the S3 response as a string. - // `xhr` is the XMLHttpRequest instance. - - - function defaultGetResponseError(content, xhr) { - // If no response, we don't have a specific error message, use the default. - if (!isXml(content, xhr)) { - return; - } - - var error = getXmlValue(content, 'Message'); - return new Error(error); } - var xhrOptions = { + const xhrOptions = { fieldName: 'file', responseUrlFieldName: 'location', timeout: this.opts.timeout, // Share the rate limiting queue with XHRUpload. - __queue: this.requests, + [internalRateLimitedQueue]: _classPrivateFieldLooseBase(this, _requests)[_requests], responseType: 'text', getResponseData: this.opts.getResponseData || defaultGetResponseData, getResponseError: defaultGetResponseError }; // Only for MiniXHRUpload, remove once we can depend on XHRUpload directly again - xhrOptions.i18n = this.i18n; // Revert to `this.uppy.use(XHRUpload)` once the big comment block at the top of + xhrOptions.i18n = this.i18n; // Revert to `uppy.use(XHRUpload)` once the big comment block at the top of // this file is solved - this._uploader = new MiniXHRUpload(this.uppy, xhrOptions); - }; + _classPrivateFieldLooseBase(this, _uploader)[_uploader] = new MiniXHRUpload(uppy, xhrOptions); + } - _proto.uninstall = function uninstall() { - this.uppy.removeUploader(this.handleUpload); - }; + uninstall() { + this.uppy.removeUploader(_classPrivateFieldLooseBase(this, _handleUpload)[_handleUpload]); + } + +}), _class.VERSION = "2.0.1", _temp); +},{"./MiniXHRUpload":4,"./isXml":6,"@uppy/companion-client":12,"@uppy/core":17,"@uppy/utils/lib/RateLimitedQueue":26,"@uppy/utils/lib/settle":46}],6:[function(require,module,exports){ +"use strict"; - return AwsS3; -}(Plugin), _class.VERSION = "1.7.12", _temp); -},{"./MiniXHRUpload":4,"./isXml":6,"@uppy/companion-client":12,"@uppy/core":15,"@uppy/utils/lib/RateLimitedQueue":25,"@uppy/utils/lib/Translator":26,"@uppy/utils/lib/hasProperty":42,"@uppy/utils/lib/settle":46,"qs-stringify":58,"url-parse":61}],6:[function(require,module,exports){ /** * Remove parameters like `charset=utf-8` from the end of a mime type string. * @@ -1849,10 +1814,10 @@ function removeMimeParameters(mimeType) { function isXml(content, xhr) { - var rawContentType = xhr.headers ? xhr.headers['content-type'] : xhr.getResponseHeader('Content-Type'); + const rawContentType = xhr.headers ? xhr.headers['content-type'] : xhr.getResponseHeader('Content-Type'); if (typeof rawContentType === 'string') { - var contentType = removeMimeParameters(rawContentType).toLowerCase(); + const contentType = removeMimeParameters(rawContentType).toLowerCase(); if (contentType === 'application/xml' || contentType === 'text/xml') { return true; @@ -1872,175 +1837,120 @@ module.exports = isXml; },{}],7:[function(require,module,exports){ 'use strict'; -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } - -function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -var AuthError = /*#__PURE__*/function (_Error) { - _inheritsLoose(AuthError, _Error); - - function AuthError() { - var _this; - - _this = _Error.call(this, 'Authorization required') || this; - _this.name = 'AuthError'; - _this.isAuthError = true; - return _this; +class AuthError extends Error { + constructor() { + super('Authorization required'); + this.name = 'AuthError'; + this.isAuthError = true; } - return AuthError; -}( /*#__PURE__*/_wrapNativeSuper(Error)); +} module.exports = AuthError; },{}],8:[function(require,module,exports){ 'use strict'; -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +const RequestClient = require('./RequestClient'); -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } +const tokenStorage = require('./tokenStorage'); -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -var qsStringify = require('qs-stringify'); - -var URL = require('url-parse'); - -var RequestClient = require('./RequestClient'); - -var tokenStorage = require('./tokenStorage'); - -var _getName = function _getName(id) { - return id.split('-').map(function (s) { - return s.charAt(0).toUpperCase() + s.slice(1); - }).join(' '); +const getName = id => { + return id.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(' '); }; -module.exports = /*#__PURE__*/function (_RequestClient) { - _inheritsLoose(Provider, _RequestClient); - - function Provider(uppy, opts) { - var _this; - - _this = _RequestClient.call(this, uppy, opts) || this; - _this.provider = opts.provider; - _this.id = _this.provider; - _this.name = _this.opts.name || _getName(_this.id); - _this.pluginId = _this.opts.pluginId; - _this.tokenKey = "companion-" + _this.pluginId + "-auth-token"; - _this.companionKeysParams = _this.opts.companionKeysParams; - _this.preAuthToken = null; - return _this; +module.exports = class Provider extends RequestClient { + constructor(uppy, opts) { + super(uppy, opts); + this.provider = opts.provider; + this.id = this.provider; + this.name = this.opts.name || getName(this.id); + this.pluginId = this.opts.pluginId; + this.tokenKey = `companion-${this.pluginId}-auth-token`; + this.companionKeysParams = this.opts.companionKeysParams; + this.preAuthToken = null; } - var _proto = Provider.prototype; - - _proto.headers = function headers() { - var _this2 = this; - - return Promise.all([_RequestClient.prototype.headers.call(this), this.getAuthToken()]).then(function (_ref) { - var headers = _ref[0], - token = _ref[1]; - var authHeaders = {}; + headers() { + return Promise.all([super.headers(), this.getAuthToken()]).then(([headers, token]) => { + const authHeaders = {}; if (token) { authHeaders['uppy-auth-token'] = token; } - if (_this2.companionKeysParams) { + if (this.companionKeysParams) { authHeaders['uppy-credentials-params'] = btoa(JSON.stringify({ - params: _this2.companionKeysParams + params: this.companionKeysParams })); } - return _extends({}, headers, authHeaders); + return { ...headers, + ...authHeaders + }; }); - }; + } - _proto.onReceiveResponse = function onReceiveResponse(response) { - response = _RequestClient.prototype.onReceiveResponse.call(this, response); - var plugin = this.uppy.getPlugin(this.pluginId); - var oldAuthenticated = plugin.getPluginState().authenticated; - var authenticated = oldAuthenticated ? response.status !== 401 : response.status < 400; + onReceiveResponse(response) { + response = super.onReceiveResponse(response); + const plugin = this.uppy.getPlugin(this.pluginId); + const oldAuthenticated = plugin.getPluginState().authenticated; + const authenticated = oldAuthenticated ? response.status !== 401 : response.status < 400; plugin.setPluginState({ - authenticated: authenticated + authenticated }); return response; - } // @todo(i.olarewaju) consider whether or not this method should be exposed - ; + } - _proto.setAuthToken = function setAuthToken(token) { + setAuthToken(token) { return this.uppy.getPlugin(this.pluginId).storage.setItem(this.tokenKey, token); - }; + } - _proto.getAuthToken = function getAuthToken() { + getAuthToken() { return this.uppy.getPlugin(this.pluginId).storage.getItem(this.tokenKey); - }; - - _proto.authUrl = function authUrl(queries) { - if (queries === void 0) { - queries = {}; - } + } + authUrl(queries = {}) { if (this.preAuthToken) { queries.uppyPreAuthToken = this.preAuthToken; } - var strigifiedQueries = qsStringify(queries); - strigifiedQueries = strigifiedQueries ? "?" + strigifiedQueries : strigifiedQueries; - return this.hostname + "/" + this.id + "/connect" + strigifiedQueries; - }; + return `${this.hostname}/${this.id}/connect?${new URLSearchParams(queries)}`; + } - _proto.fileUrl = function fileUrl(id) { - return this.hostname + "/" + this.id + "/get/" + id; - }; - - _proto.fetchPreAuthToken = function fetchPreAuthToken() { - var _this3 = this; + fileUrl(id) { + return `${this.hostname}/${this.id}/get/${id}`; + } + fetchPreAuthToken() { if (!this.companionKeysParams) { return Promise.resolve(); } - return this.post(this.id + "/preauth/", { + return this.post(`${this.id}/preauth/`, { params: this.companionKeysParams - }).then(function (res) { - _this3.preAuthToken = res.token; - }).catch(function (err) { - _this3.uppy.log("[CompanionClient] unable to fetch preAuthToken " + err, 'warning'); + }).then(res => { + this.preAuthToken = res.token; + }).catch(err => { + this.uppy.log(`[CompanionClient] unable to fetch preAuthToken ${err}`, 'warning'); }); - }; + } - _proto.list = function list(directory) { - return this.get(this.id + "/list/" + (directory || '')); - }; + list(directory) { + return this.get(`${this.id}/list/${directory || ''}`); + } - _proto.logout = function logout() { - var _this4 = this; + logout() { + return this.get(`${this.id}/logout`).then(response => Promise.all([response, this.uppy.getPlugin(this.pluginId).storage.removeItem(this.tokenKey)])).then(([response]) => response); + } - return this.get(this.id + "/logout").then(function (response) { - return Promise.all([response, _this4.uppy.getPlugin(_this4.pluginId).storage.removeItem(_this4.tokenKey)]); - }).then(function (_ref2) { - var response = _ref2[0]; - return response; - }); - }; - - Provider.initPlugin = function initPlugin(plugin, opts, defaultOpts) { + static initPlugin(plugin, opts, defaultOpts) { plugin.type = 'acquirer'; plugin.files = []; if (defaultOpts) { - plugin.opts = _extends({}, defaultOpts, opts); + plugin.opts = { ...defaultOpts, + ...opts + }; } if (opts.serverUrl || opts.serverPattern) { @@ -2048,49 +1958,80 @@ module.exports = /*#__PURE__*/function (_RequestClient) { } if (opts.companionAllowedHosts) { - var pattern = opts.companionAllowedHosts; // validate companionAllowedHosts param + const pattern = opts.companionAllowedHosts; // validate companionAllowedHosts param if (typeof pattern !== 'string' && !Array.isArray(pattern) && !(pattern instanceof RegExp)) { - throw new TypeError(plugin.id + ": the option \"companionAllowedHosts\" must be one of string, Array, RegExp"); + throw new TypeError(`${plugin.id}: the option "companionAllowedHosts" must be one of string, Array, RegExp`); } plugin.opts.companionAllowedHosts = pattern; - } else { + } else if (/^(?!https?:\/\/).*$/i.test(opts.companionUrl)) { // does not start with https:// - if (/^(?!https?:\/\/).*$/i.test(opts.companionUrl)) { - plugin.opts.companionAllowedHosts = "https://" + opts.companionUrl.replace(/^\/\//, ''); - } else { - plugin.opts.companionAllowedHosts = new URL(opts.companionUrl).origin; - } + plugin.opts.companionAllowedHosts = `https://${opts.companionUrl.replace(/^\/\//, '')}`; + } else { + plugin.opts.companionAllowedHosts = new URL(opts.companionUrl).origin; } plugin.storage = plugin.opts.storage || tokenStorage; - }; + } - return Provider; -}(RequestClient); -},{"./RequestClient":9,"./tokenStorage":13,"qs-stringify":58,"url-parse":61}],9:[function(require,module,exports){ +}; +},{"./RequestClient":9,"./tokenStorage":13}],9:[function(require,module,exports){ 'use strict'; -var _class, _temp; +var _class, _getPostResponseFunc, _getUrl, _errorHandler, _temp; -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } +var id = 0; -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } -var AuthError = require('./AuthError'); +const fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError'); -var fetchWithNetworkError = require('@uppy/utils/lib/fetchWithNetworkError'); // Remove the trailing slash so we can always safely append /xyz. +const AuthError = require('./AuthError'); // Remove the trailing slash so we can always safely append /xyz. function stripSlash(url) { return url.replace(/\/$/, ''); } -module.exports = (_temp = _class = /*#__PURE__*/function () { - function RequestClient(uppy, opts) { +async function handleJSONResponse(res) { + if (res.status === 401) { + throw new AuthError(); + } + + const jsonPromise = res.json(); + + if (res.status < 200 || res.status > 300) { + let errMsg = `Failed request with status: ${res.status}. ${res.statusText}`; + + try { + const errData = await jsonPromise; + errMsg = errData.message ? `${errMsg} message: ${errData.message}` : errMsg; + errMsg = errData.requestId ? `${errMsg} request-Id: ${errData.requestId}` : errMsg; + } finally { + // eslint-disable-next-line no-unsafe-finally + throw new Error(errMsg); + } + } + + return jsonPromise; +} + +module.exports = (_temp = (_getPostResponseFunc = /*#__PURE__*/_classPrivateFieldLooseKey("getPostResponseFunc"), _getUrl = /*#__PURE__*/_classPrivateFieldLooseKey("getUrl"), _errorHandler = /*#__PURE__*/_classPrivateFieldLooseKey("errorHandler"), _class = class RequestClient { + // eslint-disable-next-line global-require + constructor(uppy, opts) { + Object.defineProperty(this, _errorHandler, { + value: _errorHandler2 + }); + Object.defineProperty(this, _getUrl, { + value: _getUrl2 + }); + Object.defineProperty(this, _getPostResponseFunc, { + writable: true, + value: skip => response => skip ? response : this.onReceiveResponse(response) + }); this.uppy = uppy; this.opts = opts; this.onReceiveResponse = this.onReceiveResponse.bind(this); @@ -2098,351 +2039,297 @@ module.exports = (_temp = _class = /*#__PURE__*/function () { this.preflightDone = false; } - var _proto = RequestClient.prototype; + get hostname() { + const { + companion + } = this.uppy.getState(); + const host = this.opts.companionUrl; + return stripSlash(companion && companion[host] ? companion[host] : host); + } - _proto.headers = function headers() { - var userHeaders = this.opts.companionHeaders || this.opts.serverHeaders || {}; - return Promise.resolve(_extends({}, this.defaultHeaders, userHeaders)); - }; + headers() { + const userHeaders = this.opts.companionHeaders || {}; + return Promise.resolve({ ...RequestClient.defaultHeaders, + ...userHeaders + }); + } - _proto._getPostResponseFunc = function _getPostResponseFunc(skip) { - var _this = this; - - return function (response) { - if (!skip) { - return _this.onReceiveResponse(response); - } - - return response; - }; - }; - - _proto.onReceiveResponse = function onReceiveResponse(response) { - var state = this.uppy.getState(); - var companion = state.companion || {}; - var host = this.opts.companionUrl; - var headers = response.headers; // Store the self-identified domain name for the Companion instance we just hit. + onReceiveResponse(response) { + const state = this.uppy.getState(); + const companion = state.companion || {}; + const host = this.opts.companionUrl; + const { + headers + } = response; // Store the self-identified domain name for the Companion instance we just hit. if (headers.has('i-am') && headers.get('i-am') !== companion[host]) { - var _extends2; - this.uppy.setState({ - companion: _extends({}, companion, (_extends2 = {}, _extends2[host] = headers.get('i-am'), _extends2)) + companion: { ...companion, + [host]: headers.get('i-am') + } }); } return response; - }; - - _proto._getUrl = function _getUrl(url) { - if (/^(https?:|)\/\//.test(url)) { - return url; - } - - return this.hostname + "/" + url; - }; - - _proto._json = function _json(res) { - if (res.status === 401) { - throw new AuthError(); - } - - if (res.status < 200 || res.status > 300) { - var errMsg = "Failed request with status: " + res.status + ". " + res.statusText; - return res.json().then(function (errData) { - errMsg = errData.message ? errMsg + " message: " + errData.message : errMsg; - errMsg = errData.requestId ? errMsg + " request-Id: " + errData.requestId : errMsg; - throw new Error(errMsg); - }).catch(function () { - throw new Error(errMsg); - }); - } - - return res.json(); - }; - - _proto.preflight = function preflight(path) { - var _this2 = this; + } + preflight(path) { if (this.preflightDone) { return Promise.resolve(this.allowedHeaders.slice()); } - return fetch(this._getUrl(path), { + return fetch(_classPrivateFieldLooseBase(this, _getUrl)[_getUrl](path), { method: 'OPTIONS' - }).then(function (response) { + }).then(response => { if (response.headers.has('access-control-allow-headers')) { - _this2.allowedHeaders = response.headers.get('access-control-allow-headers').split(',').map(function (headerName) { - return headerName.trim().toLowerCase(); - }); + this.allowedHeaders = response.headers.get('access-control-allow-headers').split(',').map(headerName => headerName.trim().toLowerCase()); } - _this2.preflightDone = true; - return _this2.allowedHeaders.slice(); - }).catch(function (err) { - _this2.uppy.log("[CompanionClient] unable to make preflight request " + err, 'warning'); - - _this2.preflightDone = true; - return _this2.allowedHeaders.slice(); + this.preflightDone = true; + return this.allowedHeaders.slice(); + }).catch(err => { + this.uppy.log(`[CompanionClient] unable to make preflight request ${err}`, 'warning'); + this.preflightDone = true; + return this.allowedHeaders.slice(); }); - }; + } - _proto.preflightAndHeaders = function preflightAndHeaders(path) { - var _this3 = this; - - return Promise.all([this.preflight(path), this.headers()]).then(function (_ref) { - var allowedHeaders = _ref[0], - headers = _ref[1]; + preflightAndHeaders(path) { + return Promise.all([this.preflight(path), this.headers()]).then(([allowedHeaders, headers]) => { // filter to keep only allowed Headers - Object.keys(headers).forEach(function (header) { - if (allowedHeaders.indexOf(header.toLowerCase()) === -1) { - _this3.uppy.log("[CompanionClient] excluding unallowed header " + header); - - delete headers[header]; + Object.keys(headers).forEach(header => { + if (!allowedHeaders.includes(header.toLowerCase())) { + this.uppy.log(`[CompanionClient] excluding disallowed header ${header}`); + delete headers[header]; // eslint-disable-line no-param-reassign } }); return headers; }); - }; - - _proto.get = function get(path, skipPostResponse) { - var _this4 = this; - - return this.preflightAndHeaders(path).then(function (headers) { - return fetchWithNetworkError(_this4._getUrl(path), { - method: 'get', - headers: headers, - credentials: _this4.opts.companionCookiesRule || 'same-origin' - }); - }).then(this._getPostResponseFunc(skipPostResponse)).then(function (res) { - return _this4._json(res); - }).catch(function (err) { - if (!err.isAuthError) { - err.message = "Could not get " + _this4._getUrl(path) + ". " + err.message; - } - - return Promise.reject(err); - }); - }; - - _proto.post = function post(path, data, skipPostResponse) { - var _this5 = this; - - return this.preflightAndHeaders(path).then(function (headers) { - return fetchWithNetworkError(_this5._getUrl(path), { - method: 'post', - headers: headers, - credentials: _this5.opts.companionCookiesRule || 'same-origin', - body: JSON.stringify(data) - }); - }).then(this._getPostResponseFunc(skipPostResponse)).then(function (res) { - return _this5._json(res); - }).catch(function (err) { - if (!err.isAuthError) { - err.message = "Could not post " + _this5._getUrl(path) + ". " + err.message; - } - - return Promise.reject(err); - }); - }; - - _proto.delete = function _delete(path, data, skipPostResponse) { - var _this6 = this; - - return this.preflightAndHeaders(path).then(function (headers) { - return fetchWithNetworkError(_this6.hostname + "/" + path, { - method: 'delete', - headers: headers, - credentials: _this6.opts.companionCookiesRule || 'same-origin', - body: data ? JSON.stringify(data) : null - }); - }).then(this._getPostResponseFunc(skipPostResponse)).then(function (res) { - return _this6._json(res); - }).catch(function (err) { - if (!err.isAuthError) { - err.message = "Could not delete " + _this6._getUrl(path) + ". " + err.message; - } - - return Promise.reject(err); - }); - }; - - _createClass(RequestClient, [{ - key: "hostname", - get: function get() { - var _this$uppy$getState = this.uppy.getState(), - companion = _this$uppy$getState.companion; - - var host = this.opts.companionUrl; - return stripSlash(companion && companion[host] ? companion[host] : host); - } - }, { - key: "defaultHeaders", - get: function get() { - return { - Accept: 'application/json', - 'Content-Type': 'application/json', - 'Uppy-Versions': "@uppy/companion-client=" + RequestClient.VERSION - }; - } - }]); - - return RequestClient; -}(), _class.VERSION = "1.10.2", _temp); -},{"./AuthError":7,"@uppy/utils/lib/fetchWithNetworkError":29}],10:[function(require,module,exports){ -'use strict'; - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -var RequestClient = require('./RequestClient'); - -var _getName = function _getName(id) { - return id.split('-').map(function (s) { - return s.charAt(0).toUpperCase() + s.slice(1); - }).join(' '); -}; - -module.exports = /*#__PURE__*/function (_RequestClient) { - _inheritsLoose(SearchProvider, _RequestClient); - - function SearchProvider(uppy, opts) { - var _this; - - _this = _RequestClient.call(this, uppy, opts) || this; - _this.provider = opts.provider; - _this.id = _this.provider; - _this.name = _this.opts.name || _getName(_this.id); - _this.pluginId = _this.opts.pluginId; - return _this; } - var _proto = SearchProvider.prototype; + get(path, skipPostResponse) { + const method = 'get'; + return this.preflightAndHeaders(path).then(headers => fetchWithNetworkError(_classPrivateFieldLooseBase(this, _getUrl)[_getUrl](path), { + method, + headers, + credentials: this.opts.companionCookiesRule || 'same-origin' + })).then(_classPrivateFieldLooseBase(this, _getPostResponseFunc)[_getPostResponseFunc](skipPostResponse)).then(handleJSONResponse).catch(_classPrivateFieldLooseBase(this, _errorHandler)[_errorHandler](method, path)); + } - _proto.fileUrl = function fileUrl(id) { - return this.hostname + "/search/" + this.id + "/get/" + id; + post(path, data, skipPostResponse) { + const method = 'post'; + return this.preflightAndHeaders(path).then(headers => fetchWithNetworkError(_classPrivateFieldLooseBase(this, _getUrl)[_getUrl](path), { + method, + headers, + credentials: this.opts.companionCookiesRule || 'same-origin', + body: JSON.stringify(data) + })).then(_classPrivateFieldLooseBase(this, _getPostResponseFunc)[_getPostResponseFunc](skipPostResponse)).then(handleJSONResponse).catch(_classPrivateFieldLooseBase(this, _errorHandler)[_errorHandler](method, path)); + } + + delete(path, data, skipPostResponse) { + const method = 'delete'; + return this.preflightAndHeaders(path).then(headers => fetchWithNetworkError(`${this.hostname}/${path}`, { + method, + headers, + credentials: this.opts.companionCookiesRule || 'same-origin', + body: data ? JSON.stringify(data) : null + })).then(_classPrivateFieldLooseBase(this, _getPostResponseFunc)[_getPostResponseFunc](skipPostResponse)).then(handleJSONResponse).catch(_classPrivateFieldLooseBase(this, _errorHandler)[_errorHandler](method, path)); + } + +}), _class.VERSION = "2.0.0", _class.defaultHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json', + 'Uppy-Versions': `@uppy/companion-client=${_class.VERSION}` +}, _temp); + +function _getUrl2(url) { + if (/^(https?:|)\/\//.test(url)) { + return url; + } + + return `${this.hostname}/${url}`; +} + +function _errorHandler2(method, path) { + return err => { + var _err; + + if (!((_err = err) != null && _err.isAuthError)) { + const error = new Error(`Could not ${method} ${_classPrivateFieldLooseBase(this, _getUrl)[_getUrl](path)}`); + error.cause = err; + err = error; // eslint-disable-line no-param-reassign + } + + return Promise.reject(err); }; +} +},{"./AuthError":7,"@uppy/utils/lib/fetchWithNetworkError":30}],10:[function(require,module,exports){ +'use strict'; - _proto.search = function search(text, queries) { - queries = queries ? "&" + queries : ''; - return this.get("search/" + this.id + "/list?q=" + encodeURIComponent(text) + queries); - }; +const RequestClient = require('./RequestClient'); - return SearchProvider; -}(RequestClient); +const getName = id => { + return id.split('-').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join(' '); +}; + +module.exports = class SearchProvider extends RequestClient { + constructor(uppy, opts) { + super(uppy, opts); + this.provider = opts.provider; + this.id = this.provider; + this.name = this.opts.name || getName(this.id); + this.pluginId = this.opts.pluginId; + } + + fileUrl(id) { + return `${this.hostname}/search/${this.id}/get/${id}`; + } + + search(text, queries) { + queries = queries ? `&${queries}` : ''; + return this.get(`search/${this.id}/list?q=${encodeURIComponent(text)}${queries}`); + } + +}; },{"./RequestClient":9}],11:[function(require,module,exports){ -var ee = require('namespace-emitter'); +"use strict"; -module.exports = /*#__PURE__*/function () { - function UppySocket(opts) { +var _queued, _emitter, _isOpen, _socket, _handleMessage; + +let _Symbol$for, _Symbol$for2; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +const ee = require('namespace-emitter'); + +module.exports = (_queued = /*#__PURE__*/_classPrivateFieldLooseKey("queued"), _emitter = /*#__PURE__*/_classPrivateFieldLooseKey("emitter"), _isOpen = /*#__PURE__*/_classPrivateFieldLooseKey("isOpen"), _socket = /*#__PURE__*/_classPrivateFieldLooseKey("socket"), _handleMessage = /*#__PURE__*/_classPrivateFieldLooseKey("handleMessage"), _Symbol$for = Symbol.for('uppy test: getSocket'), _Symbol$for2 = Symbol.for('uppy test: getQueued'), class UppySocket { + constructor(opts) { + Object.defineProperty(this, _queued, { + writable: true, + value: [] + }); + Object.defineProperty(this, _emitter, { + writable: true, + value: ee() + }); + Object.defineProperty(this, _isOpen, { + writable: true, + value: false + }); + Object.defineProperty(this, _socket, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _handleMessage, { + writable: true, + value: e => { + try { + const message = JSON.parse(e.data); + this.emit(message.action, message.payload); + } catch (err) { + // TODO: use a more robust error handler. + console.log(err); // eslint-disable-line no-console + } + } + }); this.opts = opts; - this._queued = []; - this.isOpen = false; - this.emitter = ee(); - this._handleMessage = this._handleMessage.bind(this); - this.close = this.close.bind(this); - this.emit = this.emit.bind(this); - this.on = this.on.bind(this); - this.once = this.once.bind(this); - this.send = this.send.bind(this); if (!opts || opts.autoOpen !== false) { this.open(); } } - var _proto = UppySocket.prototype; + get isOpen() { + return _classPrivateFieldLooseBase(this, _isOpen)[_isOpen]; + } - _proto.open = function open() { - var _this = this; + [_Symbol$for]() { + return _classPrivateFieldLooseBase(this, _socket)[_socket]; + } - this.socket = new WebSocket(this.opts.target); + [_Symbol$for2]() { + return _classPrivateFieldLooseBase(this, _queued)[_queued]; + } - this.socket.onopen = function (e) { - _this.isOpen = true; + open() { + _classPrivateFieldLooseBase(this, _socket)[_socket] = new WebSocket(this.opts.target); - while (_this._queued.length > 0 && _this.isOpen) { - var first = _this._queued[0]; + _classPrivateFieldLooseBase(this, _socket)[_socket].onopen = () => { + _classPrivateFieldLooseBase(this, _isOpen)[_isOpen] = true; - _this.send(first.action, first.payload); + while (_classPrivateFieldLooseBase(this, _queued)[_queued].length > 0 && _classPrivateFieldLooseBase(this, _isOpen)[_isOpen]) { + const first = _classPrivateFieldLooseBase(this, _queued)[_queued].shift(); - _this._queued = _this._queued.slice(1); + this.send(first.action, first.payload); } }; - this.socket.onclose = function (e) { - _this.isOpen = false; + _classPrivateFieldLooseBase(this, _socket)[_socket].onclose = () => { + _classPrivateFieldLooseBase(this, _isOpen)[_isOpen] = false; }; - this.socket.onmessage = this._handleMessage; - }; + _classPrivateFieldLooseBase(this, _socket)[_socket].onmessage = _classPrivateFieldLooseBase(this, _handleMessage)[_handleMessage]; + } - _proto.close = function close() { - if (this.socket) { - this.socket.close(); - } - }; + close() { + var _classPrivateFieldLoo; - _proto.send = function send(action, payload) { + (_classPrivateFieldLoo = _classPrivateFieldLooseBase(this, _socket)[_socket]) == null ? void 0 : _classPrivateFieldLoo.close(); + } + + send(action, payload) { // attach uuid - if (!this.isOpen) { - this._queued.push({ - action: action, - payload: payload + if (!_classPrivateFieldLooseBase(this, _isOpen)[_isOpen]) { + _classPrivateFieldLooseBase(this, _queued)[_queued].push({ + action, + payload }); return; } - this.socket.send(JSON.stringify({ - action: action, - payload: payload + _classPrivateFieldLooseBase(this, _socket)[_socket].send(JSON.stringify({ + action, + payload })); - }; + } - _proto.on = function on(action, handler) { - this.emitter.on(action, handler); - }; + on(action, handler) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].on(action, handler); + } - _proto.emit = function emit(action, payload) { - this.emitter.emit(action, payload); - }; + emit(action, payload) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].emit(action, payload); + } - _proto.once = function once(action, handler) { - this.emitter.once(action, handler); - }; + once(action, handler) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].once(action, handler); + } - _proto._handleMessage = function _handleMessage(e) { - try { - var message = JSON.parse(e.data); - this.emit(message.action, message.payload); - } catch (err) { - console.log(err); - } - }; - - return UppySocket; -}(); -},{"namespace-emitter":56}],12:[function(require,module,exports){ +}); +},{"namespace-emitter":51}],12:[function(require,module,exports){ 'use strict'; /** * Manages communications with Companion */ -var RequestClient = require('./RequestClient'); +const RequestClient = require('./RequestClient'); -var Provider = require('./Provider'); +const Provider = require('./Provider'); -var SearchProvider = require('./SearchProvider'); +const SearchProvider = require('./SearchProvider'); -var Socket = require('./Socket'); +const Socket = require('./Socket'); module.exports = { - RequestClient: RequestClient, - Provider: Provider, - SearchProvider: SearchProvider, - Socket: Socket + RequestClient, + Provider, + SearchProvider, + Socket }; },{"./Provider":8,"./RequestClient":9,"./SearchProvider":10,"./Socket":11}],13:[function(require,module,exports){ 'use strict'; @@ -2450,52 +2337,153 @@ module.exports = { * This module serves as an Async wrapper for LocalStorage */ -module.exports.setItem = function (key, value) { - return new Promise(function (resolve) { +module.exports.setItem = (key, value) => { + return new Promise(resolve => { localStorage.setItem(key, value); resolve(); }); }; -module.exports.getItem = function (key) { +module.exports.getItem = key => { return Promise.resolve(localStorage.getItem(key)); }; -module.exports.removeItem = function (key) { - return new Promise(function (resolve) { +module.exports.removeItem = key => { + return new Promise(resolve => { localStorage.removeItem(key); resolve(); }); }; },{}],14:[function(require,module,exports){ -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +"use strict"; -var preact = require('preact'); +/** + * Core plugin logic that all plugins share. + * + * BasePlugin does not contain DOM rendering so it can be used for plugins + * without a user interface. + * + * See `Plugin` for the extended version with Preact rendering for interfaces. + */ +const Translator = require('@uppy/utils/lib/Translator'); -var findDOMElement = require('@uppy/utils/lib/findDOMElement'); +module.exports = class BasePlugin { + constructor(uppy, opts = {}) { + this.uppy = uppy; + this.opts = opts; + } + + getPluginState() { + const { + plugins + } = this.uppy.getState(); + return plugins[this.id] || {}; + } + + setPluginState(update) { + const { + plugins + } = this.uppy.getState(); + this.uppy.setState({ + plugins: { ...plugins, + [this.id]: { ...plugins[this.id], + ...update + } + } + }); + } + + setOptions(newOpts) { + this.opts = { ...this.opts, + ...newOpts + }; + this.setPluginState(); // so that UI re-renders with new options + + this.i18nInit(); + } + + i18nInit() { + const translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]); + this.i18n = translator.translate.bind(translator); + this.i18nArray = translator.translateArray.bind(translator); + this.setPluginState(); // so that UI re-renders and we see the updated locale + } + /** + * Extendable methods + * ================== + * These methods are here to serve as an overview of the extendable methods as well as + * making them not conditional in use, such as `if (this.afterUpdate)`. + */ + // eslint-disable-next-line class-methods-use-this + + + addTarget() { + throw new Error('Extend the addTarget method to add your plugin to another plugin\'s target'); + } // eslint-disable-next-line class-methods-use-this + + + install() {} // eslint-disable-next-line class-methods-use-this + + + uninstall() {} + /** + * Called when plugin is mounted, whether in DOM or into another plugin. + * Needed because sometimes plugins are mounted separately/after `install`, + * so this.el and this.parent might not be available in `install`. + * This is the case with @uppy/react plugins, for example. + */ + + + render() { + throw new Error('Extend the render method to add your plugin to a DOM element'); + } // eslint-disable-next-line class-methods-use-this + + + update() {} // Called after every state update, after everything's mounted. Debounced. + // eslint-disable-next-line class-methods-use-this + + + afterUpdate() {} + +}; +},{"@uppy/utils/lib/Translator":27}],15:[function(require,module,exports){ +"use strict"; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +const { + render +} = require('preact'); + +const findDOMElement = require('@uppy/utils/lib/findDOMElement'); + +const BasePlugin = require('./BasePlugin'); /** * Defer a frequent call to the microtask queue. + * + * @param {() => T} fn + * @returns {Promise} */ function debounce(fn) { - var calling = null; - var latestArgs = null; - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - + let calling = null; + let latestArgs = null; + return (...args) => { latestArgs = args; if (!calling) { - calling = Promise.resolve().then(function () { + calling = Promise.resolve().then(() => { calling = null; // At this point `args` may be different from the most // recent state, if multiple calls happened since this task // was queued. So we use the `latestArgs`, which definitely // is the most recent call. - return fn.apply(void 0, latestArgs); + return fn(...latestArgs); }); } @@ -2503,140 +2491,91 @@ function debounce(fn) { }; } /** - * Boilerplate that all Plugins share - and should not be used - * directly. It also shows which methods final plugins should implement/override, - * this deciding on structure. + * UIPlugin is the extended version of BasePlugin to incorporate rendering with Preact. + * Use this for plugins that need a user interface. * - * @param {object} main Uppy core object - * @param {object} object with plugin options - * @returns {Array|string} files or success/fail message + * For plugins without an user interface, see BasePlugin. */ -module.exports = /*#__PURE__*/function () { - function Plugin(uppy, opts) { - this.uppy = uppy; - this.opts = opts || {}; - this.update = this.update.bind(this); - this.mount = this.mount.bind(this); - this.install = this.install.bind(this); - this.uninstall = this.uninstall.bind(this); +var _updateUI = /*#__PURE__*/_classPrivateFieldLooseKey("updateUI"); + +class UIPlugin extends BasePlugin { + constructor(...args) { + super(...args); + Object.defineProperty(this, _updateUI, { + writable: true, + value: void 0 + }); } - var _proto = Plugin.prototype; - - _proto.getPluginState = function getPluginState() { - var _this$uppy$getState = this.uppy.getState(), - plugins = _this$uppy$getState.plugins; - - return plugins[this.id] || {}; - }; - - _proto.setPluginState = function setPluginState(update) { - var _extends2; - - var _this$uppy$getState2 = this.uppy.getState(), - plugins = _this$uppy$getState2.plugins; - - this.uppy.setState({ - plugins: _extends({}, plugins, (_extends2 = {}, _extends2[this.id] = _extends({}, plugins[this.id], update), _extends2)) - }); - }; - - _proto.setOptions = function setOptions(newOpts) { - this.opts = _extends({}, this.opts, newOpts); - this.setPluginState(); // so that UI re-renders with new options - }; - - _proto.update = function update(state) { - if (typeof this.el === 'undefined') { - return; - } - - if (this._updateUI) { - this._updateUI(state); - } - } // Called after every state update, after everything's mounted. Debounced. - ; - - _proto.afterUpdate = function afterUpdate() {} - /** - * Called when plugin is mounted, whether in DOM or into another plugin. - * Needed because sometimes plugins are mounted separately/after `install`, - * so this.el and this.parent might not be available in `install`. - * This is the case with @uppy/react plugins, for example. - */ - ; - - _proto.onMount = function onMount() {} /** * Check if supplied `target` is a DOM element or an `object`. * If it’s an object — target is a plugin, and we search `plugins` * for a plugin with same name and return its target. - * - * @param {string|object} target - * */ - ; - - _proto.mount = function mount(target, plugin) { - var _this = this; - - var callerPluginName = plugin.id; - var targetElement = findDOMElement(target); + mount(target, plugin) { + const callerPluginName = plugin.id; + const targetElement = findDOMElement(target); if (targetElement) { - this.isTargetDOMEl = true; // API for plugins that require a synchronous rerender. + this.isTargetDOMEl = true; // When target is with a single
element, + // Preact thinks it’s the Uppy root element in there when doing a diff, + // and destroys it. So we are creating a fragment (could be empty div) - this.rerender = function (state) { + const uppyRootElement = document.createDocumentFragment(); // API for plugins that require a synchronous rerender. + + _classPrivateFieldLooseBase(this, _updateUI)[_updateUI] = debounce(state => { // plugin could be removed, but this.rerender is debounced below, // so it could still be called even after uppy.removePlugin or uppy.close // hence the check - if (!_this.uppy.getPlugin(_this.id)) return; - _this.el = preact.render(_this.render(state), targetElement, _this.el); - - _this.afterUpdate(); - }; - - this._updateUI = debounce(this.rerender); - this.uppy.log("Installing " + callerPluginName + " to a DOM element '" + target + "'"); // clear everything inside the target container + if (!this.uppy.getPlugin(this.id)) return; + render(this.render(state), uppyRootElement); + this.afterUpdate(); + }); + this.uppy.log(`Installing ${callerPluginName} to a DOM element '${target}'`); if (this.opts.replaceTargetContent) { + // Doing render(h(null), targetElement), which should have been + // a better way, since because the component might need to do additional cleanup when it is removed, + // stopped working — Preact just adds null into target, not replacing targetElement.innerHTML = ''; } - this.el = preact.render(this.render(this.uppy.getState()), targetElement); + render(this.render(this.uppy.getState()), uppyRootElement); + this.el = uppyRootElement.firstElementChild; + targetElement.appendChild(uppyRootElement); this.onMount(); return this.el; } - var targetPlugin; + let targetPlugin; - if (typeof target === 'object' && target instanceof Plugin) { + if (typeof target === 'object' && target instanceof UIPlugin) { // Targeting a plugin *instance* targetPlugin = target; } else if (typeof target === 'function') { // Targeting a plugin type - var Target = target; // Find the target plugin instance. + const Target = target; // Find the target plugin instance. - this.uppy.iteratePlugins(function (plugin) { - if (plugin instanceof Target) { - targetPlugin = plugin; + this.uppy.iteratePlugins(p => { + if (p instanceof Target) { + targetPlugin = p; return false; } }); } if (targetPlugin) { - this.uppy.log("Installing " + callerPluginName + " to " + targetPlugin.id); + this.uppy.log(`Installing ${callerPluginName} to ${targetPlugin.id}`); this.parent = targetPlugin; this.el = targetPlugin.addTarget(plugin); this.onMount(); return this.el; } - this.uppy.log("Not installing " + callerPluginName); - var message = "Invalid target option given to " + callerPluginName + "."; + this.uppy.log(`Not installing ${callerPluginName}`); + let message = `Invalid target option given to ${callerPluginName}.`; if (typeof target === 'function') { message += ' The given target is not a Plugin class. ' + 'Please check that you\'re not specifying a React Component instead of a plugin. ' + 'If you are using @uppy/* packages directly, make sure you have only 1 version of @uppy/core installed: ' + 'run `npm ls @uppy/core` on the command line and verify that all the versions match and are deduped correctly.'; @@ -2645,103 +2584,123 @@ module.exports = /*#__PURE__*/function () { } throw new Error(message); - }; - - _proto.render = function render(state) { - throw new Error('Extend the render method to add your plugin to a DOM element'); - }; - - _proto.addTarget = function addTarget(plugin) { - throw new Error('Extend the addTarget method to add your plugin to another plugin\'s target'); - }; - - _proto.unmount = function unmount() { - if (this.isTargetDOMEl && this.el && this.el.parentNode) { - this.el.parentNode.removeChild(this.el); - } - }; - - _proto.install = function install() {}; - - _proto.uninstall = function uninstall() { - this.unmount(); - }; - - return Plugin; -}(); -},{"@uppy/utils/lib/findDOMElement":30,"preact":57}],15:[function(require,module,exports){ -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - -function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } - -function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } - -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } - -function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -/* global AggregateError */ -var Translator = require('@uppy/utils/lib/Translator'); - -var ee = require('namespace-emitter'); - -var cuid = require('cuid'); - -var throttle = require('lodash.throttle'); - -var prettierBytes = require('@transloadit/prettier-bytes'); - -var match = require('mime-match'); - -var DefaultStore = require('@uppy/store-default'); - -var getFileType = require('@uppy/utils/lib/getFileType'); - -var getFileNameAndExtension = require('@uppy/utils/lib/getFileNameAndExtension'); - -var generateFileID = require('@uppy/utils/lib/generateFileID'); - -var findIndex = require('@uppy/utils/lib/findIndex'); - -var supportsUploadProgress = require('./supportsUploadProgress'); - -var _require = require('./loggers'), - justErrorsLogger = _require.justErrorsLogger, - debugLogger = _require.debugLogger; - -var Plugin = require('./Plugin'); - -var _require2 = require('../package.json'), - version = _require2.version; // Exported from here. - - -var RestrictionError = /*#__PURE__*/function (_Error) { - _inheritsLoose(RestrictionError, _Error); - - function RestrictionError() { - var _this; - - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - _this = _Error.call.apply(_Error, [this].concat(args)) || this; - _this.isRestriction = true; - return _this; } - return RestrictionError; -}( /*#__PURE__*/_wrapNativeSuper(Error)); + update(state) { + if (this.el != null) { + var _classPrivateFieldLoo, _classPrivateFieldLoo2; + + (_classPrivateFieldLoo = (_classPrivateFieldLoo2 = _classPrivateFieldLooseBase(this, _updateUI))[_updateUI]) == null ? void 0 : _classPrivateFieldLoo.call(_classPrivateFieldLoo2, state); + } + } + + unmount() { + if (this.isTargetDOMEl) { + var _this$el; + + (_this$el = this.el) == null ? void 0 : _this$el.remove(); + } + + this.onUnmount(); + } // eslint-disable-next-line class-methods-use-this + + + onMount() {} // eslint-disable-next-line class-methods-use-this + + + onUnmount() {} + +} + +module.exports = UIPlugin; +},{"./BasePlugin":14,"@uppy/utils/lib/findDOMElement":31,"preact":54}],16:[function(require,module,exports){ +"use strict"; + +module.exports = function getFileName(fileType, fileDescriptor) { + if (fileDescriptor.name) { + return fileDescriptor.name; + } + + if (fileType.split('/')[0] === 'image') { + return `${fileType.split('/')[0]}.${fileType.split('/')[1]}`; + } + + return 'noname'; +}; +},{}],17:[function(require,module,exports){ +"use strict"; + +let _Symbol$for, _Symbol$for2; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +/* global AggregateError */ +const Translator = require('@uppy/utils/lib/Translator'); + +const ee = require('namespace-emitter'); + +const { + nanoid +} = require('nanoid'); + +const throttle = require('lodash.throttle'); + +const prettierBytes = require('@transloadit/prettier-bytes'); + +const match = require('mime-match'); + +const DefaultStore = require('@uppy/store-default'); + +const getFileType = require('@uppy/utils/lib/getFileType'); + +const getFileNameAndExtension = require('@uppy/utils/lib/getFileNameAndExtension'); + +const generateFileID = require('@uppy/utils/lib/generateFileID'); + +const supportsUploadProgress = require('./supportsUploadProgress'); + +const getFileName = require('./getFileName'); + +const { + justErrorsLogger, + debugLogger +} = require('./loggers'); + +const UIPlugin = require('./UIPlugin'); + +const BasePlugin = require('./BasePlugin'); // Exported from here. + + +class RestrictionError extends Error { + constructor(...args) { + super(...args); + this.isRestriction = true; + } + +} + +if (typeof AggregateError === 'undefined') { + // eslint-disable-next-line no-global-assign + globalThis.AggregateError = class AggregateError extends Error { + constructor(message, errors) { + super(message); + this.errors = errors; + } + + }; +} + +class AggregateRestrictionError extends AggregateError { + constructor(...args) { + super(...args); + this.isRestriction = true; + } + +} /** * Uppy Core module. * Manages plugins, state updates, acts as an event bus, @@ -2749,15 +2708,122 @@ var RestrictionError = /*#__PURE__*/function (_Error) { */ -var Uppy = /*#__PURE__*/function () { +var _plugins = /*#__PURE__*/_classPrivateFieldLooseKey("plugins"); + +var _storeUnsubscribe = /*#__PURE__*/_classPrivateFieldLooseKey("storeUnsubscribe"); + +var _emitter = /*#__PURE__*/_classPrivateFieldLooseKey("emitter"); + +var _preProcessors = /*#__PURE__*/_classPrivateFieldLooseKey("preProcessors"); + +var _uploaders = /*#__PURE__*/_classPrivateFieldLooseKey("uploaders"); + +var _postProcessors = /*#__PURE__*/_classPrivateFieldLooseKey("postProcessors"); + +var _checkRestrictions = /*#__PURE__*/_classPrivateFieldLooseKey("checkRestrictions"); + +var _checkMinNumberOfFiles = /*#__PURE__*/_classPrivateFieldLooseKey("checkMinNumberOfFiles"); + +var _checkRequiredMetaFields = /*#__PURE__*/_classPrivateFieldLooseKey("checkRequiredMetaFields"); + +var _showOrLogErrorAndThrow = /*#__PURE__*/_classPrivateFieldLooseKey("showOrLogErrorAndThrow"); + +var _assertNewUploadAllowed = /*#__PURE__*/_classPrivateFieldLooseKey("assertNewUploadAllowed"); + +var _checkAndCreateFileStateObject = /*#__PURE__*/_classPrivateFieldLooseKey("checkAndCreateFileStateObject"); + +var _startIfAutoProceed = /*#__PURE__*/_classPrivateFieldLooseKey("startIfAutoProceed"); + +var _addListeners = /*#__PURE__*/_classPrivateFieldLooseKey("addListeners"); + +var _updateOnlineStatus = /*#__PURE__*/_classPrivateFieldLooseKey("updateOnlineStatus"); + +var _createUpload = /*#__PURE__*/_classPrivateFieldLooseKey("createUpload"); + +var _getUpload = /*#__PURE__*/_classPrivateFieldLooseKey("getUpload"); + +var _removeUpload = /*#__PURE__*/_classPrivateFieldLooseKey("removeUpload"); + +var _runUpload = /*#__PURE__*/_classPrivateFieldLooseKey("runUpload"); + +_Symbol$for = Symbol.for('uppy test: getPlugins'); +_Symbol$for2 = Symbol.for('uppy test: createUpload'); + +class Uppy { + // eslint-disable-next-line global-require + + /** @type {Record} */ + /** * Instantiate Uppy * * @param {object} opts — Uppy options */ - function Uppy(opts) { - var _this2 = this; - + constructor(_opts) { + Object.defineProperty(this, _runUpload, { + value: _runUpload2 + }); + Object.defineProperty(this, _removeUpload, { + value: _removeUpload2 + }); + Object.defineProperty(this, _getUpload, { + value: _getUpload2 + }); + Object.defineProperty(this, _createUpload, { + value: _createUpload2 + }); + Object.defineProperty(this, _addListeners, { + value: _addListeners2 + }); + Object.defineProperty(this, _startIfAutoProceed, { + value: _startIfAutoProceed2 + }); + Object.defineProperty(this, _checkAndCreateFileStateObject, { + value: _checkAndCreateFileStateObject2 + }); + Object.defineProperty(this, _assertNewUploadAllowed, { + value: _assertNewUploadAllowed2 + }); + Object.defineProperty(this, _showOrLogErrorAndThrow, { + value: _showOrLogErrorAndThrow2 + }); + Object.defineProperty(this, _checkRequiredMetaFields, { + value: _checkRequiredMetaFields2 + }); + Object.defineProperty(this, _checkMinNumberOfFiles, { + value: _checkMinNumberOfFiles2 + }); + Object.defineProperty(this, _checkRestrictions, { + value: _checkRestrictions2 + }); + Object.defineProperty(this, _plugins, { + writable: true, + value: Object.create(null) + }); + Object.defineProperty(this, _storeUnsubscribe, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _emitter, { + writable: true, + value: ee() + }); + Object.defineProperty(this, _preProcessors, { + writable: true, + value: new Set() + }); + Object.defineProperty(this, _uploaders, { + writable: true, + value: new Set() + }); + Object.defineProperty(this, _postProcessors, { + writable: true, + value: new Set() + }); + Object.defineProperty(this, _updateOnlineStatus, { + writable: true, + value: this.updateOnlineStatus.bind(this) + }); this.defaultLocale = { strings: { addBulkFilesFailed: { @@ -2772,16 +2838,12 @@ var Uppy = /*#__PURE__*/function () { 0: 'You have to select at least %{smart_count} file', 1: 'You have to select at least %{smart_count} files' }, - // The default `exceedsSize2` string only combines the `exceedsSize` string (%{backwardsCompat}) with the size. - // Locales can override `exceedsSize2` to specify a different word order. This is for backwards compat with - // Uppy 1.9.x and below which did a naive concatenation of `exceedsSize2 + size` instead of using a locale-specific - // substitution. - // TODO: In 2.0 `exceedsSize2` should be removed in and `exceedsSize` updated to use substitution. - exceedsSize2: '%{backwardsCompat} %{size}', - exceedsSize: '%{file} exceeds maximum allowed size of', + exceedsSize: '%{file} exceeds maximum allowed size of %{size}', + missingRequiredMetaField: 'Missing required meta fields', + missingRequiredMetaFieldOnFile: 'Missing required meta fields in %{fileName}', inferiorSize: 'This file is smaller than the allowed size of %{size}', youCanOnlyUploadFileTypes: 'You can only upload: %{types}', - noNewAlreadyUploading: 'Cannot add new files: already uploading', + noMoreFilesAllowed: 'Cannot add more files', noDuplicates: 'Cannot add the duplicate file \'%{fileName}\', it already exists', companionError: 'Connection with Companion failed', companionUnauthorizeHint: 'To unauthorize to your %{provider} account, please go to %{url}', @@ -2794,10 +2856,7 @@ var Uppy = /*#__PURE__*/function () { 0: 'Select %{smart_count}', 1: 'Select %{smart_count}' }, - selectAllFilesFromFolderNamed: 'Select all files from folder %{name}', - unselectAllFilesFromFolderNamed: 'Unselect all files from folder %{name}', - selectFileNamed: 'Select file %{name}', - unselectFileNamed: 'Unselect file %{name}', + allFilesFromFolderNamed: 'All files from folder %{name}', openFolderNamed: 'Open folder %{name}', cancel: 'Cancel', logOut: 'Log out', @@ -2810,16 +2869,22 @@ var Uppy = /*#__PURE__*/function () { enterTextToSearch: 'Enter text to search for images', backToSearch: 'Back to Search', emptyFolderAdded: 'No files were added from empty folder', + folderAlreadyAdded: 'The folder "%{folder}" was already added', folderAdded: { 0: 'Added %{smart_count} file from %{folder}', 1: 'Added %{smart_count} files from %{folder}' } } }; - var defaultOptions = { + const defaultOptions = { id: 'uppy', autoProceed: false, + + /** + * @deprecated The method should not be used + */ allowMultipleUploads: true, + allowMultipleUploadBatches: true, debug: false, restrictions: { maxFileSize: null, @@ -2827,52 +2892,39 @@ var Uppy = /*#__PURE__*/function () { maxTotalFileSize: null, maxNumberOfFiles: null, minNumberOfFiles: null, - allowedFileTypes: null + allowedFileTypes: null, + requiredMetaFields: [] }, meta: {}, - onBeforeFileAdded: function onBeforeFileAdded(currentFile) { - return currentFile; - }, - onBeforeUpload: function onBeforeUpload(files) { - return files; - }, + onBeforeFileAdded: currentFile => currentFile, + onBeforeUpload: files => files, store: DefaultStore(), logger: justErrorsLogger, infoTimeout: 5000 }; // Merge default options with the ones set by user, // making sure to merge restrictions too - this.opts = _extends({}, defaultOptions, opts, { - restrictions: _extends({}, defaultOptions.restrictions, opts && opts.restrictions) - }); // Support debug: true for backwards-compatability, unless logger is set in opts + this.opts = { ...defaultOptions, + ..._opts, + restrictions: { ...defaultOptions.restrictions, + ...(_opts && _opts.restrictions) + } + }; // Support debug: true for backwards-compatability, unless logger is set in opts // opts instead of this.opts to avoid comparing objects — we set logger: justErrorsLogger in defaultOptions - if (opts && opts.logger && opts.debug) { + if (_opts && _opts.logger && _opts.debug) { this.log('You are using a custom `logger`, but also set `debug: true`, which uses built-in logger to output logs to console. Ignoring `debug: true` and using your custom `logger`.', 'warning'); - } else if (opts && opts.debug) { + } else if (_opts && _opts.debug) { this.opts.logger = debugLogger; } - this.log("Using Core v" + this.constructor.VERSION); + this.log(`Using Core v${this.constructor.VERSION}`); if (this.opts.restrictions.allowedFileTypes && this.opts.restrictions.allowedFileTypes !== null && !Array.isArray(this.opts.restrictions.allowedFileTypes)) { throw new TypeError('`restrictions.allowedFileTypes` must be an array'); } - this.i18nInit(); // Container for different types of plugins - - this.plugins = {}; - this.getState = this.getState.bind(this); - this.getPlugin = this.getPlugin.bind(this); - this.setFileMeta = this.setFileMeta.bind(this); - this.setFileState = this.setFileState.bind(this); - this.log = this.log.bind(this); - this.info = this.info.bind(this); - this.hideInfo = this.hideInfo.bind(this); - this.addFile = this.addFile.bind(this); - this.removeFile = this.removeFile.bind(this); - this.pauseResume = this.pauseResume.bind(this); - this.validateRestrictions = this.validateRestrictions.bind(this); // ___Why throttle at 500ms? + this.i18nInit(); // ___Why throttle at 500ms? // - We must throttle at >250ms for superfocus in Dashboard to work well // (because animation takes 0.25s, and we want to wait for all animations to be over before refocusing). // [Practical Check]: if thottle is at 100ms, then if you are uploading a file, @@ -2884,22 +2936,6 @@ var Uppy = /*#__PURE__*/function () { leading: true, trailing: true }); - this.updateOnlineStatus = this.updateOnlineStatus.bind(this); - this.resetProgress = this.resetProgress.bind(this); - this.pauseAll = this.pauseAll.bind(this); - this.resumeAll = this.resumeAll.bind(this); - this.retryAll = this.retryAll.bind(this); - this.cancelAll = this.cancelAll.bind(this); - this.retryUpload = this.retryUpload.bind(this); - this.upload = this.upload.bind(this); - this.emitter = ee(); - this.on = this.on.bind(this); - this.off = this.off.bind(this); - this.once = this.emitter.once.bind(this.emitter); - this.emit = this.emitter.emit.bind(this.emitter); - this.preProcessors = []; - this.uploaders = []; - this.postProcessors = []; this.store = this.opts.store; this.setState({ plugins: {}, @@ -2912,46 +2948,42 @@ var Uppy = /*#__PURE__*/function () { resumableUploads: false }, totalProgress: 0, - meta: _extends({}, this.opts.meta), - info: { - isHidden: true, - type: 'info', - message: '' + meta: { ...this.opts.meta }, + info: [], recoveredState: null }); - this.storeUnsubscribe = this.store.subscribe(function (prevState, nextState, patch) { - _this2.emit('state-update', prevState, nextState, patch); - - _this2.updateAll(nextState); + _classPrivateFieldLooseBase(this, _storeUnsubscribe)[_storeUnsubscribe] = this.store.subscribe((prevState, nextState, patch) => { + this.emit('state-update', prevState, nextState, patch); + this.updateAll(nextState); }); // Exposing uppy object on window for debugging and testing if (this.opts.debug && typeof window !== 'undefined') { window[this.opts.id] = this; } - this.addListeners(); // Re-enable if we’ll need some capabilities on boot, like isMobileDevice - // this._setCapabilities() - } // _setCapabilities = () => { - // const capabilities = { - // isMobileDevice: isMobileDevice() - // } - // this.setState({ - // ...this.getState().capabilities, - // capabilities - // }) - // } + _classPrivateFieldLooseBase(this, _addListeners)[_addListeners](); + } + emit(event, ...args) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].emit(event, ...args); + } - var _proto = Uppy.prototype; + on(event, callback) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].on(event, callback); - _proto.on = function on(event, callback) { - this.emitter.on(event, callback); return this; - }; + } + + once(event, callback) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].once(event, callback); + + return this; + } + + off(event, callback) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].off(event, callback); - _proto.off = function off(event, callback) { - this.emitter.off(event, callback); return this; } /** @@ -2959,10 +2991,10 @@ var Uppy = /*#__PURE__*/function () { * Called each time state changes. * */ - ; - _proto.updateAll = function updateAll(state) { - this.iteratePlugins(function (plugin) { + + updateAll(state) { + this.iteratePlugins(plugin => { plugin.update(state); }); } @@ -2971,9 +3003,9 @@ var Uppy = /*#__PURE__*/function () { * * @param {object} patch {foo: 'bar'} */ - ; - _proto.setState = function setState(patch) { + + setState(patch) { this.store.setState(patch); } /** @@ -2981,42 +3013,55 @@ var Uppy = /*#__PURE__*/function () { * * @returns {object} */ - ; - _proto.getState = function getState() { + + getState() { return this.store.getState(); } /** * Back compat for when uppy.state is used instead of uppy.getState(). + * + * @deprecated */ - ; + + get state() { + // Here, state is a non-enumerable property. + return this.getState(); + } /** * Shorthand to set state for a specific file. */ - _proto.setFileState = function setFileState(fileID, state) { - var _extends2; + + setFileState(fileID, state) { if (!this.getState().files[fileID]) { - throw new Error("Can\u2019t set state for " + fileID + " (the file could have been removed)"); + throw new Error(`Can’t set state for ${fileID} (the file could have been removed)`); } this.setState({ - files: _extends({}, this.getState().files, (_extends2 = {}, _extends2[fileID] = _extends({}, this.getState().files[fileID], state), _extends2)) + files: { ...this.getState().files, + [fileID]: { ...this.getState().files[fileID], + ...state + } + } }); - }; + } - _proto.i18nInit = function i18nInit() { - this.translator = new Translator([this.defaultLocale, this.opts.locale]); - this.locale = this.translator.locale; - this.i18n = this.translator.translate.bind(this.translator); - this.i18nArray = this.translator.translateArray.bind(this.translator); - }; + i18nInit() { + const translator = new Translator([this.defaultLocale, this.opts.locale]); + this.i18n = translator.translate.bind(translator); + this.i18nArray = translator.translateArray.bind(translator); + this.locale = translator.locale; + } - _proto.setOptions = function setOptions(newOpts) { - this.opts = _extends({}, this.opts, newOpts, { - restrictions: _extends({}, this.opts.restrictions, newOpts && newOpts.restrictions) - }); + setOptions(newOpts) { + this.opts = { ...this.opts, + ...newOpts, + restrictions: { ...this.opts.restrictions, + ...(newOpts && newOpts.restrictions) + } + }; if (newOpts.meta) { this.setMeta(newOpts.meta); @@ -3025,30 +3070,31 @@ var Uppy = /*#__PURE__*/function () { this.i18nInit(); if (newOpts.locale) { - this.iteratePlugins(function (plugin) { + this.iteratePlugins(plugin => { plugin.setOptions(); }); } // Note: this is not the preact `setState`, it's an internal function that has the same name. this.setState(); // so that UI re-renders with new options - }; + } - _proto.resetProgress = function resetProgress() { - var defaultProgress = { + resetProgress() { + const defaultProgress = { percentage: 0, bytesUploaded: 0, uploadComplete: false, uploadStarted: null }; - - var files = _extends({}, this.getState().files); - - var updatedFiles = {}; - Object.keys(files).forEach(function (fileID) { - var updatedFile = _extends({}, files[fileID]); - - updatedFile.progress = _extends({}, updatedFile.progress, defaultProgress); + const files = { ...this.getState().files + }; + const updatedFiles = {}; + Object.keys(files).forEach(fileID => { + const updatedFile = { ...files[fileID] + }; + updatedFile.progress = { ...updatedFile.progress, + ...defaultProgress + }; updatedFiles[fileID] = updatedFile; }); this.setState({ @@ -3056,53 +3102,44 @@ var Uppy = /*#__PURE__*/function () { totalProgress: 0 }); this.emit('reset-progress'); - }; + } - _proto.addPreProcessor = function addPreProcessor(fn) { - this.preProcessors.push(fn); - }; + addPreProcessor(fn) { + _classPrivateFieldLooseBase(this, _preProcessors)[_preProcessors].add(fn); + } - _proto.removePreProcessor = function removePreProcessor(fn) { - var i = this.preProcessors.indexOf(fn); + removePreProcessor(fn) { + return _classPrivateFieldLooseBase(this, _preProcessors)[_preProcessors].delete(fn); + } - if (i !== -1) { - this.preProcessors.splice(i, 1); - } - }; + addPostProcessor(fn) { + _classPrivateFieldLooseBase(this, _postProcessors)[_postProcessors].add(fn); + } - _proto.addPostProcessor = function addPostProcessor(fn) { - this.postProcessors.push(fn); - }; + removePostProcessor(fn) { + return _classPrivateFieldLooseBase(this, _postProcessors)[_postProcessors].delete(fn); + } - _proto.removePostProcessor = function removePostProcessor(fn) { - var i = this.postProcessors.indexOf(fn); + addUploader(fn) { + _classPrivateFieldLooseBase(this, _uploaders)[_uploaders].add(fn); + } - if (i !== -1) { - this.postProcessors.splice(i, 1); - } - }; + removeUploader(fn) { + return _classPrivateFieldLooseBase(this, _uploaders)[_uploaders].delete(fn); + } - _proto.addUploader = function addUploader(fn) { - this.uploaders.push(fn); - }; - - _proto.removeUploader = function removeUploader(fn) { - var i = this.uploaders.indexOf(fn); - - if (i !== -1) { - this.uploaders.splice(i, 1); - } - }; - - _proto.setMeta = function setMeta(data) { - var updatedMeta = _extends({}, this.getState().meta, data); - - var updatedFiles = _extends({}, this.getState().files); - - Object.keys(updatedFiles).forEach(function (fileID) { - updatedFiles[fileID] = _extends({}, updatedFiles[fileID], { - meta: _extends({}, updatedFiles[fileID].meta, data) - }); + setMeta(data) { + const updatedMeta = { ...this.getState().meta, + ...data + }; + const updatedFiles = { ...this.getState().files + }; + Object.keys(updatedFiles).forEach(fileID => { + updatedFiles[fileID] = { ...updatedFiles[fileID], + meta: { ...updatedFiles[fileID].meta, + ...data + } + }; }); this.log('Adding metadata:'); this.log(data); @@ -3110,21 +3147,23 @@ var Uppy = /*#__PURE__*/function () { meta: updatedMeta, files: updatedFiles }); - }; + } - _proto.setFileMeta = function setFileMeta(fileID, data) { - var updatedFiles = _extends({}, this.getState().files); + setFileMeta(fileID, data) { + const updatedFiles = { ...this.getState().files + }; if (!updatedFiles[fileID]) { this.log('Was trying to set metadata for a file that has been removed: ', fileID); return; } - var newMeta = _extends({}, updatedFiles[fileID].meta, data); - - updatedFiles[fileID] = _extends({}, updatedFiles[fileID], { + const newMeta = { ...updatedFiles[fileID].meta, + ...data + }; + updatedFiles[fileID] = { ...updatedFiles[fileID], meta: newMeta - }); + }; this.setState({ files: updatedFiles }); @@ -3134,23 +3173,58 @@ var Uppy = /*#__PURE__*/function () { * * @param {string} fileID The ID of the file object to return. */ - ; - _proto.getFile = function getFile(fileID) { + + getFile(fileID) { return this.getState().files[fileID]; } /** * Get all files in an array. */ - ; - _proto.getFiles = function getFiles() { - var _this$getState = this.getState(), - files = _this$getState.files; - return Object.keys(files).map(function (fileID) { - return files[fileID]; - }); + getFiles() { + const { + files + } = this.getState(); + return Object.values(files); + } + + getObjectOfFilesPerState() { + const { + files: filesObject, + totalProgress, + error + } = this.getState(); + const files = Object.values(filesObject); + const inProgressFiles = files.filter(({ + progress + }) => !progress.uploadComplete && progress.uploadStarted); + const newFiles = files.filter(file => !file.progress.uploadStarted); + const startedFiles = files.filter(file => file.progress.uploadStarted || file.progress.preprocess || file.progress.postprocess); + const uploadStartedFiles = files.filter(file => file.progress.uploadStarted); + const pausedFiles = files.filter(file => file.isPaused); + const completeFiles = files.filter(file => file.progress.uploadComplete); + const erroredFiles = files.filter(file => file.error); + const inProgressNotPausedFiles = inProgressFiles.filter(file => !file.isPaused); + const processingFiles = files.filter(file => file.progress.preprocess || file.progress.postprocess); + return { + newFiles, + startedFiles, + uploadStartedFiles, + pausedFiles, + completeFiles, + erroredFiles, + inProgressFiles, + inProgressNotPausedFiles, + processingFiles, + isUploadStarted: uploadStartedFiles.length > 0, + isAllComplete: totalProgress === 100 && completeFiles.length === files.length && processingFiles.length === 0, + isAllErrored: !!error && erroredFiles.length === files.length, + isAllPaused: inProgressFiles.length !== 0 && pausedFiles.length === inProgressFiles.length, + isUploadInProgress: inProgressFiles.length > 0, + isSomeGhost: files.some(file => file.isGhost) + }; } /** * A public wrapper for _checkRestrictions — checks if a file passes a set of restrictions. @@ -3160,11 +3234,12 @@ var Uppy = /*#__PURE__*/function () { * @param {Array} [files] array to check maxNumberOfFiles and maxTotalFileSize * @returns {object} { result: true/false, reason: why file didn’t pass restrictions } */ - ; - _proto.validateRestrictions = function validateRestrictions(file, files) { + + validateRestrictions(file, files) { try { - this.checkRestrictions(file, files); + _classPrivateFieldLooseBase(this, _checkRestrictions)[_checkRestrictions](file, files); + return { result: true }; @@ -3183,273 +3258,29 @@ var Uppy = /*#__PURE__*/function () { * @param {Array} [files] array to check maxNumberOfFiles and maxTotalFileSize * @private */ - ; - _proto.checkRestrictions = function checkRestrictions(file, files) { - if (files === void 0) { - files = this.getFiles(); + + checkIfFileAlreadyExists(fileID) { + const { + files + } = this.getState(); + + if (files[fileID] && !files[fileID].isGhost) { + return true; } - var _this$opts$restrictio = this.opts.restrictions, - maxFileSize = _this$opts$restrictio.maxFileSize, - minFileSize = _this$opts$restrictio.minFileSize, - maxTotalFileSize = _this$opts$restrictio.maxTotalFileSize, - maxNumberOfFiles = _this$opts$restrictio.maxNumberOfFiles, - allowedFileTypes = _this$opts$restrictio.allowedFileTypes; - - if (maxNumberOfFiles) { - if (files.length + 1 > maxNumberOfFiles) { - throw new RestrictionError("" + this.i18n('youCanOnlyUploadX', { - smart_count: maxNumberOfFiles - })); - } - } - - if (allowedFileTypes) { - var isCorrectFileType = allowedFileTypes.some(function (type) { - // check if this is a mime-type - if (type.indexOf('/') > -1) { - if (!file.type) return false; - return match(file.type.replace(/;.*?$/, ''), type); - } // otherwise this is likely an extension - - - if (type[0] === '.' && file.extension) { - return file.extension.toLowerCase() === type.substr(1).toLowerCase(); - } - - return false; - }); - - if (!isCorrectFileType) { - var allowedFileTypesString = allowedFileTypes.join(', '); - throw new RestrictionError(this.i18n('youCanOnlyUploadFileTypes', { - types: allowedFileTypesString - })); - } - } // We can't check maxTotalFileSize if the size is unknown. - - - if (maxTotalFileSize && file.size != null) { - var totalFilesSize = 0; - totalFilesSize += file.size; - files.forEach(function (f) { - totalFilesSize += f.size; - }); - - if (totalFilesSize > maxTotalFileSize) { - throw new RestrictionError(this.i18n('exceedsSize2', { - backwardsCompat: this.i18n('exceedsSize'), - size: prettierBytes(maxTotalFileSize), - file: file.name - })); - } - } // We can't check maxFileSize if the size is unknown. - - - if (maxFileSize && file.size != null) { - if (file.size > maxFileSize) { - throw new RestrictionError(this.i18n('exceedsSize2', { - backwardsCompat: this.i18n('exceedsSize'), - size: prettierBytes(maxFileSize), - file: file.name - })); - } - } // We can't check minFileSize if the size is unknown. - - - if (minFileSize && file.size != null) { - if (file.size < minFileSize) { - throw new RestrictionError(this.i18n('inferiorSize', { - size: prettierBytes(minFileSize) - })); - } - } - } - /** - * Check if minNumberOfFiles restriction is reached before uploading. - * - * @private - */ - ; - - _proto.checkMinNumberOfFiles = function checkMinNumberOfFiles(files) { - var minNumberOfFiles = this.opts.restrictions.minNumberOfFiles; - - if (Object.keys(files).length < minNumberOfFiles) { - throw new RestrictionError("" + this.i18n('youHaveToAtLeastSelectX', { - smart_count: minNumberOfFiles - })); - } - } - /** - * Logs an error, sets Informer message, then throws the error. - * Emits a 'restriction-failed' event if it’s a restriction error - * - * @param {object | string} err — Error object or plain string message - * @param {object} [options] - * @param {boolean} [options.showInformer=true] — Sometimes developer might want to show Informer manually - * @param {object} [options.file=null] — File object used to emit the restriction error - * @param {boolean} [options.throwErr=true] — Errors shouldn’t be thrown, for example, in `upload-error` event - * @private - */ - ; - - _proto.showOrLogErrorAndThrow = function showOrLogErrorAndThrow(err, _temp) { - var _ref = _temp === void 0 ? {} : _temp, - _ref$showInformer = _ref.showInformer, - showInformer = _ref$showInformer === void 0 ? true : _ref$showInformer, - _ref$file = _ref.file, - file = _ref$file === void 0 ? null : _ref$file, - _ref$throwErr = _ref.throwErr, - throwErr = _ref$throwErr === void 0 ? true : _ref$throwErr; - - var message = typeof err === 'object' ? err.message : err; - var details = typeof err === 'object' && err.details ? err.details : ''; // Restriction errors should be logged, but not as errors, - // as they are expected and shown in the UI. - - var logMessageWithDetails = message; - - if (details) { - logMessageWithDetails += " " + details; - } - - if (err.isRestriction) { - this.log(logMessageWithDetails); - this.emit('restriction-failed', file, err); - } else { - this.log(logMessageWithDetails, 'error'); - } // Sometimes informer has to be shown manually by the developer, - // for example, in `onBeforeFileAdded`. - - - if (showInformer) { - this.info({ - message: message, - details: details - }, 'error', this.opts.infoTimeout); - } - - if (throwErr) { - throw typeof err === 'object' ? err : new Error(err); - } - }; - - _proto.assertNewUploadAllowed = function assertNewUploadAllowed(file) { - var _this$getState2 = this.getState(), - allowNewUpload = _this$getState2.allowNewUpload; - - if (allowNewUpload === false) { - this.showOrLogErrorAndThrow(new RestrictionError(this.i18n('noNewAlreadyUploading')), { - file: file - }); - } + return false; } /** * Create a file state object based on user-provided `addFile()` options. * - * Note this is extremely side-effectful and should only be done when a file state object will be added to state immediately afterward! + * Note this is extremely side-effectful and should only be done when a file state object + * will be added to state immediately afterward! * * The `files` value is passed in because it may be updated by the caller without updating the store. */ - ; - _proto.checkAndCreateFileStateObject = function checkAndCreateFileStateObject(files, f) { - var fileType = getFileType(f); - var file = f; - file.type = fileType; - var onBeforeFileAddedResult = this.opts.onBeforeFileAdded(file, files); - if (onBeforeFileAddedResult === false) { - // Don’t show UI info for this error, as it should be done by the developer - this.showOrLogErrorAndThrow(new RestrictionError('Cannot add the file because onBeforeFileAdded returned false.'), { - showInformer: false, - file: file - }); - } - - if (typeof onBeforeFileAddedResult === 'object' && onBeforeFileAddedResult) { - file = onBeforeFileAddedResult; - } - - var fileName; - - if (file.name) { - fileName = file.name; - } else if (fileType.split('/')[0] === 'image') { - fileName = fileType.split('/')[0] + "." + fileType.split('/')[1]; - } else { - fileName = 'noname'; - } - - var fileExtension = getFileNameAndExtension(fileName).extension; - var isRemote = file.isRemote || false; - var fileID = generateFileID(file); - - if (files[fileID] && !files[fileID].isGhost) { - this.showOrLogErrorAndThrow(new RestrictionError(this.i18n('noDuplicates', { - fileName: fileName - })), { - file: file - }); - } - - var meta = file.meta || {}; - meta.name = fileName; - meta.type = fileType; // `null` means the size is unknown. - - var size = Number.isFinite(file.data.size) ? file.data.size : null; - var newFile = { - source: file.source || '', - id: fileID, - name: fileName, - extension: fileExtension || '', - meta: _extends({}, this.getState().meta, meta), - type: fileType, - data: file.data, - progress: { - percentage: 0, - bytesUploaded: 0, - bytesTotal: size, - uploadComplete: false, - uploadStarted: null - }, - size: size, - isRemote: isRemote, - remote: file.remote || '', - preview: file.preview - }; - - try { - var filesArray = Object.keys(files).map(function (i) { - return files[i]; - }); - this.checkRestrictions(newFile, filesArray); - } catch (err) { - this.showOrLogErrorAndThrow(err, { - file: newFile - }); - } - - return newFile; - } // Schedule an upload if `autoProceed` is enabled. - ; - - _proto.startIfAutoProceed = function startIfAutoProceed() { - var _this3 = this; - - if (this.opts.autoProceed && !this.scheduledAutoProceed) { - this.scheduledAutoProceed = setTimeout(function () { - _this3.scheduledAutoProceed = null; - - _this3.upload().catch(function (err) { - if (!err.isRestriction) { - _this3.log(err.stack || err.message || err); - } - }); - }, 4); - } - } /** * Add a new file to `state.files`. This will run `onBeforeFileAdded`, * try to guess file type in a clever way, check file against restrictions, @@ -3458,34 +3289,36 @@ var Uppy = /*#__PURE__*/function () { * @param {object} file object to add * @returns {string} id for the added file */ - ; + addFile(file) { + _classPrivateFieldLooseBase(this, _assertNewUploadAllowed)[_assertNewUploadAllowed](file); - _proto.addFile = function addFile(file) { - var _extends3; + const { + files + } = this.getState(); - this.assertNewUploadAllowed(file); - - var _this$getState3 = this.getState(), - files = _this$getState3.files; - - var newFile = this.checkAndCreateFileStateObject(files, file); // Users are asked to re-select recovered files without data, + let newFile = _classPrivateFieldLooseBase(this, _checkAndCreateFileStateObject)[_checkAndCreateFileStateObject](files, file); // Users are asked to re-select recovered files without data, // and to keep the progress, meta and everthing else, we only replace said data + if (files[newFile.id] && files[newFile.id].isGhost) { - newFile = _extends({}, files[newFile.id], { + newFile = { ...files[newFile.id], data: file.data, isGhost: false - }); - this.log("Replaced the blob in the restored ghost file: " + newFile.name + ", " + newFile.id); + }; + this.log(`Replaced the blob in the restored ghost file: ${newFile.name}, ${newFile.id}`); } this.setState({ - files: _extends({}, files, (_extends3 = {}, _extends3[newFile.id] = newFile, _extends3)) + files: { ...files, + [newFile.id]: newFile + } }); this.emit('file-added', newFile); this.emit('files-added', [newFile]); - this.log("Added file: " + newFile.name + ", " + newFile.id + ", mime type: " + newFile.type); - this.startIfAutoProceed(); + this.log(`Added file: ${newFile.name}, ${newFile.id}, mime type: ${newFile.type}`); + + _classPrivateFieldLooseBase(this, _startIfAutoProceed)[_startIfAutoProceed](); + return newFile.id; } /** @@ -3495,29 +3328,29 @@ var Uppy = /*#__PURE__*/function () { * This is good for UI plugins, but not for programmatic use. * Programmatic users should usually still use `addFile()` on individual files. */ - ; - _proto.addFiles = function addFiles(fileDescriptors) { - var _this4 = this; - this.assertNewUploadAllowed(); // create a copy of the files object only once + addFiles(fileDescriptors) { + _classPrivateFieldLooseBase(this, _assertNewUploadAllowed)[_assertNewUploadAllowed](); // create a copy of the files object only once - var files = _extends({}, this.getState().files); - var newFiles = []; - var errors = []; + const files = { ...this.getState().files + }; + const newFiles = []; + const errors = []; - for (var i = 0; i < fileDescriptors.length; i++) { + for (let i = 0; i < fileDescriptors.length; i++) { try { - var newFile = this.checkAndCreateFileStateObject(files, fileDescriptors[i]); // Users are asked to re-select recovered files without data, + let newFile = _classPrivateFieldLooseBase(this, _checkAndCreateFileStateObject)[_checkAndCreateFileStateObject](files, fileDescriptors[i]); // Users are asked to re-select recovered files without data, // and to keep the progress, meta and everthing else, we only replace said data + if (files[newFile.id] && files[newFile.id].isGhost) { - newFile = _extends({}, files[newFile.id], { + newFile = { ...files[newFile.id], data: fileDescriptors[i].data, isGhost: false - }); - this.log("Replaced blob in a ghost file: " + newFile.name + ", " + newFile.id); + }; + this.log(`Replaced blob in a ghost file: ${newFile.name}, ${newFile.id}`); } files[newFile.id] = newFile; @@ -3530,29 +3363,29 @@ var Uppy = /*#__PURE__*/function () { } this.setState({ - files: files + files }); - newFiles.forEach(function (newFile) { - _this4.emit('file-added', newFile); + newFiles.forEach(newFile => { + this.emit('file-added', newFile); }); this.emit('files-added', newFiles); if (newFiles.length > 5) { - this.log("Added batch of " + newFiles.length + " files"); + this.log(`Added batch of ${newFiles.length} files`); } else { - Object.keys(newFiles).forEach(function (fileID) { - _this4.log("Added file: " + newFiles[fileID].name + "\n id: " + newFiles[fileID].id + "\n type: " + newFiles[fileID].type); + Object.keys(newFiles).forEach(fileID => { + this.log(`Added file: ${newFiles[fileID].name}\n id: ${newFiles[fileID].id}\n type: ${newFiles[fileID].type}`); }); } if (newFiles.length > 0) { - this.startIfAutoProceed(); + _classPrivateFieldLooseBase(this, _startIfAutoProceed)[_startIfAutoProceed](); } if (errors.length > 0) { - var message = 'Multiple errors occurred while adding files:\n'; - errors.forEach(function (subError) { - message += "\n * " + subError.message; + let message = 'Multiple errors occurred while adding files:\n'; + errors.forEach(subError => { + message += `\n * ${subError.message}`; }); this.info({ message: this.i18n('addBulkFilesFailed', { @@ -3564,26 +3397,24 @@ var Uppy = /*#__PURE__*/function () { if (typeof AggregateError === 'function') { throw new AggregateError(errors, message); } else { - var err = new Error(message); + const err = new Error(message); err.errors = errors; throw err; } } - }; + } - _proto.removeFiles = function removeFiles(fileIDs, reason) { - var _this5 = this; - - var _this$getState4 = this.getState(), - files = _this$getState4.files, - currentUploads = _this$getState4.currentUploads; - - var updatedFiles = _extends({}, files); - - var updatedUploads = _extends({}, currentUploads); - - var removedFiles = Object.create(null); - fileIDs.forEach(function (fileID) { + removeFiles(fileIDs, reason) { + const { + files, + currentUploads + } = this.getState(); + const updatedFiles = { ...files + }; + const updatedUploads = { ...currentUploads + }; + const removedFiles = Object.create(null); + fileIDs.forEach(fileID => { if (files[fileID]) { removedFiles[fileID] = files[fileID]; delete updatedFiles[fileID]; @@ -3594,19 +3425,19 @@ var Uppy = /*#__PURE__*/function () { return removedFiles[uploadFileID] === undefined; } - Object.keys(updatedUploads).forEach(function (uploadID) { - var newFileIDs = currentUploads[uploadID].fileIDs.filter(fileIsNotRemoved); // Remove the upload if no files are associated with it anymore. + Object.keys(updatedUploads).forEach(uploadID => { + const newFileIDs = currentUploads[uploadID].fileIDs.filter(fileIsNotRemoved); // Remove the upload if no files are associated with it anymore. if (newFileIDs.length === 0) { delete updatedUploads[uploadID]; return; } - updatedUploads[uploadID] = _extends({}, currentUploads[uploadID], { + updatedUploads[uploadID] = { ...currentUploads[uploadID], fileIDs: newFileIDs - }); + }; }); - var stateUpdate = { + const stateUpdate = { currentUploads: updatedUploads, files: updatedFiles }; // If all files were removed - allow new uploads, @@ -3620,91 +3451,84 @@ var Uppy = /*#__PURE__*/function () { this.setState(stateUpdate); this.calculateTotalProgress(); - var removedFileIDs = Object.keys(removedFiles); - removedFileIDs.forEach(function (fileID) { - _this5.emit('file-removed', removedFiles[fileID], reason); + const removedFileIDs = Object.keys(removedFiles); + removedFileIDs.forEach(fileID => { + this.emit('file-removed', removedFiles[fileID], reason); }); if (removedFileIDs.length > 5) { - this.log("Removed " + removedFileIDs.length + " files"); + this.log(`Removed ${removedFileIDs.length} files`); } else { - this.log("Removed files: " + removedFileIDs.join(', ')); - } - }; - - _proto.removeFile = function removeFile(fileID, reason) { - if (reason === void 0) { - reason = null; + this.log(`Removed files: ${removedFileIDs.join(', ')}`); } + } + removeFile(fileID, reason = null) { this.removeFiles([fileID], reason); - }; + } - _proto.pauseResume = function pauseResume(fileID) { + pauseResume(fileID) { if (!this.getState().capabilities.resumableUploads || this.getFile(fileID).uploadComplete) { return undefined; } - var wasPaused = this.getFile(fileID).isPaused || false; - var isPaused = !wasPaused; + const wasPaused = this.getFile(fileID).isPaused || false; + const isPaused = !wasPaused; this.setFileState(fileID, { - isPaused: isPaused + isPaused }); this.emit('upload-pause', fileID, isPaused); return isPaused; - }; + } - _proto.pauseAll = function pauseAll() { - var updatedFiles = _extends({}, this.getState().files); - - var inProgressUpdatedFiles = Object.keys(updatedFiles).filter(function (file) { + pauseAll() { + const updatedFiles = { ...this.getState().files + }; + const inProgressUpdatedFiles = Object.keys(updatedFiles).filter(file => { return !updatedFiles[file].progress.uploadComplete && updatedFiles[file].progress.uploadStarted; }); - inProgressUpdatedFiles.forEach(function (file) { - var updatedFile = _extends({}, updatedFiles[file], { + inProgressUpdatedFiles.forEach(file => { + const updatedFile = { ...updatedFiles[file], isPaused: true - }); - + }; updatedFiles[file] = updatedFile; }); this.setState({ files: updatedFiles }); this.emit('pause-all'); - }; + } - _proto.resumeAll = function resumeAll() { - var updatedFiles = _extends({}, this.getState().files); - - var inProgressUpdatedFiles = Object.keys(updatedFiles).filter(function (file) { + resumeAll() { + const updatedFiles = { ...this.getState().files + }; + const inProgressUpdatedFiles = Object.keys(updatedFiles).filter(file => { return !updatedFiles[file].progress.uploadComplete && updatedFiles[file].progress.uploadStarted; }); - inProgressUpdatedFiles.forEach(function (file) { - var updatedFile = _extends({}, updatedFiles[file], { + inProgressUpdatedFiles.forEach(file => { + const updatedFile = { ...updatedFiles[file], isPaused: false, error: null - }); - + }; updatedFiles[file] = updatedFile; }); this.setState({ files: updatedFiles }); this.emit('resume-all'); - }; + } - _proto.retryAll = function retryAll() { - var updatedFiles = _extends({}, this.getState().files); - - var filesToRetry = Object.keys(updatedFiles).filter(function (file) { + retryAll() { + const updatedFiles = { ...this.getState().files + }; + const filesToRetry = Object.keys(updatedFiles).filter(file => { return updatedFiles[file].error; }); - filesToRetry.forEach(function (file) { - var updatedFile = _extends({}, updatedFiles[file], { + filesToRetry.forEach(file => { + const updatedFile = { ...updatedFiles[file], isPaused: false, error: null - }); - + }; updatedFiles[file] = updatedFile; }); this.setState({ @@ -3720,20 +3544,20 @@ var Uppy = /*#__PURE__*/function () { }); } - var uploadID = this.createUpload(filesToRetry, { + const uploadID = _classPrivateFieldLooseBase(this, _createUpload)[_createUpload](filesToRetry, { forceAllowNewUpload: true // create new upload even if allowNewUpload: false }); - return this.runUpload(uploadID); - }; - _proto.cancelAll = function cancelAll() { + return _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID); + } + + cancelAll() { this.emit('cancel-all'); - - var _this$getState5 = this.getState(), - files = _this$getState5.files; - - var fileIDs = Object.keys(files); + const { + files + } = this.getState(); + const fileIDs = Object.keys(files); if (fileIDs.length) { this.removeFiles(fileIDs, 'cancel-all'); @@ -3744,58 +3568,58 @@ var Uppy = /*#__PURE__*/function () { error: null, recoveredState: null }); - }; + } - _proto.retryUpload = function retryUpload(fileID) { + retryUpload(fileID) { this.setFileState(fileID, { error: null, isPaused: false }); this.emit('upload-retry', fileID); - var uploadID = this.createUpload([fileID], { + + const uploadID = _classPrivateFieldLooseBase(this, _createUpload)[_createUpload]([fileID], { forceAllowNewUpload: true // create new upload even if allowNewUpload: false }); - return this.runUpload(uploadID); - }; - _proto.reset = function reset() { + return _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID); + } + + reset() { this.cancelAll(); - }; + } - _proto.logout = function logout() { - this.iteratePlugins(function (plugin) { + logout() { + this.iteratePlugins(plugin => { if (plugin.provider && plugin.provider.logout) { plugin.provider.logout(); } }); - }; + } - _proto.calculateProgress = function calculateProgress(file, data) { + calculateProgress(file, data) { if (!this.getFile(file.id)) { - this.log("Not setting progress for a file that has been removed: " + file.id); + this.log(`Not setting progress for a file that has been removed: ${file.id}`); return; } // bytesTotal may be null or zero; in that case we can't divide by it - var canHavePercentage = Number.isFinite(data.bytesTotal) && data.bytesTotal > 0; + const canHavePercentage = Number.isFinite(data.bytesTotal) && data.bytesTotal > 0; this.setFileState(file.id, { - progress: _extends({}, this.getFile(file.id).progress, { + progress: { ...this.getFile(file.id).progress, bytesUploaded: data.bytesUploaded, bytesTotal: data.bytesTotal, - percentage: canHavePercentage // TODO(goto-bus-stop) flooring this should probably be the choice of the UI? - // we get more accurate calculations if we don't round this at all. - ? Math.round(data.bytesUploaded / data.bytesTotal * 100) : 0 - }) + percentage: canHavePercentage ? Math.round(data.bytesUploaded / data.bytesTotal * 100) : 0 + } }); this.calculateTotalProgress(); - }; + } - _proto.calculateTotalProgress = function calculateTotalProgress() { + calculateTotalProgress() { // calculate total progress, using the number of files currently uploading, // multiplied by 100 and the summ of individual progress of each file - var files = this.getFiles(); - var inProgress = files.filter(function (file) { + const files = this.getFiles(); + const inProgress = files.filter(file => { return file.progress.uploadStarted || file.progress.preprocess || file.progress.postprocess; }); @@ -3807,40 +3631,34 @@ var Uppy = /*#__PURE__*/function () { return; } - var sizedFiles = inProgress.filter(function (file) { - return file.progress.bytesTotal != null; - }); - var unsizedFiles = inProgress.filter(function (file) { - return file.progress.bytesTotal == null; - }); + const sizedFiles = inProgress.filter(file => file.progress.bytesTotal != null); + const unsizedFiles = inProgress.filter(file => file.progress.bytesTotal == null); if (sizedFiles.length === 0) { - var progressMax = inProgress.length * 100; - var currentProgress = unsizedFiles.reduce(function (acc, file) { + const progressMax = inProgress.length * 100; + const currentProgress = unsizedFiles.reduce((acc, file) => { return acc + file.progress.percentage; }, 0); - - var _totalProgress = Math.round(currentProgress / progressMax * 100); - + const totalProgress = Math.round(currentProgress / progressMax * 100); this.setState({ - totalProgress: _totalProgress + totalProgress }); return; } - var totalSize = sizedFiles.reduce(function (acc, file) { + let totalSize = sizedFiles.reduce((acc, file) => { return acc + file.progress.bytesTotal; }, 0); - var averageSize = totalSize / sizedFiles.length; + const averageSize = totalSize / sizedFiles.length; totalSize += averageSize * unsizedFiles.length; - var uploadedSize = 0; - sizedFiles.forEach(function (file) { + let uploadedSize = 0; + sizedFiles.forEach(file => { uploadedSize += file.progress.bytesUploaded; }); - unsizedFiles.forEach(function (file) { + unsizedFiles.forEach(file => { uploadedSize += averageSize * (file.progress.percentage || 0) / 100; }); - var totalProgress = totalSize === 0 ? 0 : Math.round(uploadedSize / totalSize * 100); // hot fix, because: + let totalProgress = totalSize === 0 ? 0 : Math.round(uploadedSize / totalSize * 100); // hot fix, because: // uploadedSize ended up larger than totalSize, resulting in 1325% total if (totalProgress > 100) { @@ -3848,7 +3666,7 @@ var Uppy = /*#__PURE__*/function () { } this.setState({ - totalProgress: totalProgress + totalProgress }); this.emit('progress', totalProgress); } @@ -3856,192 +3674,10 @@ var Uppy = /*#__PURE__*/function () { * Registers listeners for all global actions, like: * `error`, `file-removed`, `upload-progress` */ - ; - _proto.addListeners = function addListeners() { - var _this6 = this; - /** - * @param {Error} error - * @param {object} [file] - * @param {object} [response] - */ - var errorHandler = function errorHandler(error, file, response) { - var errorMsg = error.message || 'Unknown error'; - - if (error.details) { - errorMsg += " " + error.details; - } - - _this6.setState({ - error: errorMsg - }); - - if (file != null) { - _this6.setFileState(file.id, { - error: errorMsg, - response: response - }); - } - }; - - this.on('error', errorHandler); - this.on('upload-error', function (file, error, response) { - errorHandler(error, file, response); - - if (typeof error === 'object' && error.message) { - var newError = new Error(error.message); - newError.details = error.message; - - if (error.details) { - newError.details += " " + error.details; - } - - newError.message = _this6.i18n('failedToUpload', { - file: file.name - }); - - _this6.showOrLogErrorAndThrow(newError, { - throwErr: false - }); - } else { - _this6.showOrLogErrorAndThrow(error, { - throwErr: false - }); - } - }); - this.on('upload', function () { - _this6.setState({ - error: null - }); - }); - this.on('upload-started', function (file) { - if (!_this6.getFile(file.id)) { - _this6.log("Not setting progress for a file that has been removed: " + file.id); - - return; - } - - _this6.setFileState(file.id, { - progress: { - uploadStarted: Date.now(), - uploadComplete: false, - percentage: 0, - bytesUploaded: 0, - bytesTotal: file.size - } - }); - }); - this.on('upload-progress', this.calculateProgress); - this.on('upload-success', function (file, uploadResp) { - if (!_this6.getFile(file.id)) { - _this6.log("Not setting progress for a file that has been removed: " + file.id); - - return; - } - - var currentProgress = _this6.getFile(file.id).progress; - - _this6.setFileState(file.id, { - progress: _extends({}, currentProgress, { - postprocess: _this6.postProcessors.length > 0 ? { - mode: 'indeterminate' - } : null, - uploadComplete: true, - percentage: 100, - bytesUploaded: currentProgress.bytesTotal - }), - response: uploadResp, - uploadURL: uploadResp.uploadURL, - isPaused: false - }); - - _this6.calculateTotalProgress(); - }); - this.on('preprocess-progress', function (file, progress) { - if (!_this6.getFile(file.id)) { - _this6.log("Not setting progress for a file that has been removed: " + file.id); - - return; - } - - _this6.setFileState(file.id, { - progress: _extends({}, _this6.getFile(file.id).progress, { - preprocess: progress - }) - }); - }); - this.on('preprocess-complete', function (file) { - if (!_this6.getFile(file.id)) { - _this6.log("Not setting progress for a file that has been removed: " + file.id); - - return; - } - - var files = _extends({}, _this6.getState().files); - - files[file.id] = _extends({}, files[file.id], { - progress: _extends({}, files[file.id].progress) - }); - delete files[file.id].progress.preprocess; - - _this6.setState({ - files: files - }); - }); - this.on('postprocess-progress', function (file, progress) { - if (!_this6.getFile(file.id)) { - _this6.log("Not setting progress for a file that has been removed: " + file.id); - - return; - } - - _this6.setFileState(file.id, { - progress: _extends({}, _this6.getState().files[file.id].progress, { - postprocess: progress - }) - }); - }); - this.on('postprocess-complete', function (file) { - if (!_this6.getFile(file.id)) { - _this6.log("Not setting progress for a file that has been removed: " + file.id); - - return; - } - - var files = _extends({}, _this6.getState().files); - - files[file.id] = _extends({}, files[file.id], { - progress: _extends({}, files[file.id].progress) - }); - delete files[file.id].progress.postprocess; // TODO should we set some kind of `fullyComplete` property on the file object - // so it's easier to see that the file is upload…fully complete…rather than - // what we have to do now (`uploadComplete && !postprocess`) - - _this6.setState({ - files: files - }); - }); - this.on('restored', function () { - // Files may have changed--ensure progress is still accurate. - _this6.calculateTotalProgress(); - }); // show informer if offline - - if (typeof window !== 'undefined' && window.addEventListener) { - window.addEventListener('online', function () { - return _this6.updateOnlineStatus(); - }); - window.addEventListener('offline', function () { - return _this6.updateOnlineStatus(); - }); - setTimeout(function () { - return _this6.updateOnlineStatus(); - }, 3000); - } - }; - - _proto.updateOnlineStatus = function updateOnlineStatus() { - var online = typeof window.navigator.onLine !== 'undefined' ? window.navigator.onLine : true; + updateOnlineStatus() { + const online = typeof window.navigator.onLine !== 'undefined' ? window.navigator.onLine : true; if (!online) { this.emit('is-offline'); @@ -4056,9 +3692,9 @@ var Uppy = /*#__PURE__*/function () { this.wasOffline = false; } } - }; + } - _proto.getID = function getID() { + getID() { return this.opts.id; } /** @@ -4069,18 +3705,17 @@ var Uppy = /*#__PURE__*/function () { * @returns {object} self for chaining */ // eslint-disable-next-line no-shadow - ; - _proto.use = function use(Plugin, opts) { + + use(Plugin, opts) { if (typeof Plugin !== 'function') { - var msg = "Expected a plugin class, but got " + (Plugin === null ? 'null' : typeof Plugin) + "." + ' Please verify that the plugin was imported and spelled correctly.'; + const msg = `Expected a plugin class, but got ${Plugin === null ? 'null' : typeof Plugin}.` + ' Please verify that the plugin was imported and spelled correctly.'; throw new TypeError(msg); } // Instantiate - var plugin = new Plugin(this, opts); - var pluginId = plugin.id; - this.plugins[plugin.type] = this.plugins[plugin.type] || []; + const plugin = new Plugin(this, opts); + const pluginId = plugin.id; if (!pluginId) { throw new Error('Your plugin must have an id'); @@ -4090,19 +3725,23 @@ var Uppy = /*#__PURE__*/function () { throw new Error('Your plugin must have a type'); } - var existsPluginAlready = this.getPlugin(pluginId); + const existsPluginAlready = this.getPlugin(pluginId); if (existsPluginAlready) { - var _msg = "Already found a plugin named '" + existsPluginAlready.id + "'. " + ("Tried to use: '" + pluginId + "'.\n") + 'Uppy plugins must have unique `id` options. See https://uppy.io/docs/plugins/#id.'; - - throw new Error(_msg); + const msg = `Already found a plugin named '${existsPluginAlready.id}'. ` + `Tried to use: '${pluginId}'.\n` + 'Uppy plugins must have unique `id` options. See https://uppy.io/docs/plugins/#id.'; + throw new Error(msg); } if (Plugin.VERSION) { - this.log("Using " + pluginId + " v" + Plugin.VERSION); + this.log(`Using ${pluginId} v${Plugin.VERSION}`); + } + + if (plugin.type in _classPrivateFieldLooseBase(this, _plugins)[_plugins]) { + _classPrivateFieldLooseBase(this, _plugins)[_plugins][plugin.type].push(plugin); + } else { + _classPrivateFieldLooseBase(this, _plugins)[_plugins][plugin.type] = [plugin]; } - this.plugins[plugin.type].push(plugin); plugin.install(); return this; } @@ -4110,84 +3749,95 @@ var Uppy = /*#__PURE__*/function () { * Find one Plugin by name. * * @param {string} id plugin id - * @returns {object|boolean} + * @returns {BasePlugin|undefined} */ - ; - _proto.getPlugin = function getPlugin(id) { - var foundPlugin = null; - this.iteratePlugins(function (plugin) { - if (plugin.id === id) { - foundPlugin = plugin; - return false; - } - }); - return foundPlugin; + + getPlugin(id) { + for (const plugins of Object.values(_classPrivateFieldLooseBase(this, _plugins)[_plugins])) { + const foundPlugin = plugins.find(plugin => plugin.id === id); + if (foundPlugin != null) return foundPlugin; + } + + return undefined; + } + + [_Symbol$for](type) { + return _classPrivateFieldLooseBase(this, _plugins)[_plugins][type]; } /** * Iterate through all `use`d plugins. * * @param {Function} method that will be run on each plugin */ - ; - _proto.iteratePlugins = function iteratePlugins(method) { - var _this7 = this; - Object.keys(this.plugins).forEach(function (pluginType) { - _this7.plugins[pluginType].forEach(method); - }); + iteratePlugins(method) { + Object.values(_classPrivateFieldLooseBase(this, _plugins)[_plugins]).flat(1).forEach(method); } /** * Uninstall and remove a plugin. * * @param {object} instance The plugin instance to remove. */ - ; - _proto.removePlugin = function removePlugin(instance) { - var _extends4; - this.log("Removing plugin " + instance.id); + removePlugin(instance) { + this.log(`Removing plugin ${instance.id}`); this.emit('plugin-remove', instance); if (instance.uninstall) { instance.uninstall(); } - var list = this.plugins[instance.type].slice(); // list.indexOf failed here, because Vue3 converted the plugin instance + const list = _classPrivateFieldLooseBase(this, _plugins)[_plugins][instance.type]; // list.indexOf failed here, because Vue3 converted the plugin instance // to a Proxy object, which failed the strict comparison test: // obj !== objProxy - var index = findIndex(list, function (item) { - return item.id === instance.id; - }); + + const index = list.findIndex(item => item.id === instance.id); if (index !== -1) { list.splice(index, 1); - this.plugins[instance.type] = list; } - var state = this.getState(); - var updatedState = { - plugins: _extends({}, state.plugins, (_extends4 = {}, _extends4[instance.id] = undefined, _extends4)) + const state = this.getState(); + const updatedState = { + plugins: { ...state.plugins, + [instance.id]: undefined + } }; this.setState(updatedState); } /** * Uninstall all plugins and close down this Uppy instance. */ - ; - _proto.close = function close() { - var _this8 = this; - this.log("Closing Uppy instance " + this.opts.id + ": removing all files and uninstalling plugins"); + close() { + this.log(`Closing Uppy instance ${this.opts.id}: removing all files and uninstalling plugins`); this.reset(); - this.storeUnsubscribe(); - this.iteratePlugins(function (plugin) { - _this8.removePlugin(plugin); + + _classPrivateFieldLooseBase(this, _storeUnsubscribe)[_storeUnsubscribe](); + + this.iteratePlugins(plugin => { + this.removePlugin(plugin); }); + + if (typeof window !== 'undefined' && window.removeEventListener) { + window.removeEventListener('online', _classPrivateFieldLooseBase(this, _updateOnlineStatus)[_updateOnlineStatus]); + window.removeEventListener('offline', _classPrivateFieldLooseBase(this, _updateOnlineStatus)[_updateOnlineStatus]); + } + } + + hideInfo() { + const { + info + } = this.getState(); + this.setState({ + info: info.slice(1) + }); + this.emit('info-hidden'); } /** * Set info message in `state.info`, so that UI plugins like `Informer` @@ -4197,47 +3847,19 @@ var Uppy = /*#__PURE__*/function () { * @param {string} [type] * @param {number} [duration] */ - ; - _proto.info = function info(message, type, duration) { - if (type === void 0) { - type = 'info'; - } - if (duration === void 0) { - duration = 3000; - } - - var isComplexMessage = typeof message === 'object'; + info(message, type = 'info', duration = 3000) { + const isComplexMessage = typeof message === 'object'; this.setState({ - info: { - isHidden: false, - type: type, + info: [...this.getState().info, { + type, message: isComplexMessage ? message.message : message, details: isComplexMessage ? message.details : null - } + }] }); + setTimeout(() => this.hideInfo(), duration); this.emit('info-visible'); - clearTimeout(this.infoTimeoutID); - - if (duration === 0) { - this.infoTimeoutID = undefined; - return; - } // hide the informer after `duration` milliseconds - - - this.infoTimeoutID = setTimeout(this.hideInfo, duration); - }; - - _proto.hideInfo = function hideInfo() { - var newInfo = _extends({}, this.getState().info, { - isHidden: true - }); - - this.setState({ - info: newInfo - }); - this.emit('info-hidden'); } /** * Passes messages to a function, provided in `opts.logger`. @@ -4246,10 +3868,12 @@ var Uppy = /*#__PURE__*/function () { * @param {string|object} message to log * @param {string} [type] optional `error` or `warning` */ - ; - _proto.log = function log(message, type) { - var logger = this.opts.logger; + + log(message, type) { + const { + logger + } = this.opts; switch (type) { case 'error': @@ -4265,29 +3889,21 @@ var Uppy = /*#__PURE__*/function () { break; } } - /** - * Obsolete, event listeners are now added in the constructor. - */ - ; - - _proto.run = function run() { - this.log('Calling run() is no longer necessary.', 'warning'); - return this; - } /** * Restore an upload by its ID. */ - ; - _proto.restore = function restore(uploadID) { - this.log("Core: attempting to restore upload \"" + uploadID + "\""); + + restore(uploadID) { + this.log(`Core: attempting to restore upload "${uploadID}"`); if (!this.getState().currentUploads[uploadID]) { - this.removeUpload(uploadID); + _classPrivateFieldLooseBase(this, _removeUpload)[_removeUpload](uploadID); + return Promise.reject(new Error('Nonexistent upload')); } - return this.runUpload(uploadID); + return _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID); } /** * Create an upload for a bunch of files. @@ -4295,75 +3911,36 @@ var Uppy = /*#__PURE__*/function () { * @param {Array} fileIDs File IDs to include in this upload. * @returns {string} ID of this upload. */ - ; - _proto.createUpload = function createUpload(fileIDs, opts) { - var _extends5; - if (opts === void 0) { - opts = {}; - } - - // uppy.retryAll sets this to true — when retrying we want to ignore `allowNewUpload: false` - var _opts = opts, - _opts$forceAllowNewUp = _opts.forceAllowNewUpload, - forceAllowNewUpload = _opts$forceAllowNewUp === void 0 ? false : _opts$forceAllowNewUp; - - var _this$getState6 = this.getState(), - allowNewUpload = _this$getState6.allowNewUpload, - currentUploads = _this$getState6.currentUploads; - - if (!allowNewUpload && !forceAllowNewUpload) { - throw new Error('Cannot create a new upload: already uploading.'); - } - - var uploadID = cuid(); - this.emit('upload', { - id: uploadID, - fileIDs: fileIDs - }); - this.setState({ - allowNewUpload: this.opts.allowMultipleUploads !== false, - currentUploads: _extends({}, currentUploads, (_extends5 = {}, _extends5[uploadID] = { - fileIDs: fileIDs, - step: 0, - result: {} - }, _extends5)) - }); - return uploadID; - }; - - _proto.getUpload = function getUpload(uploadID) { - var _this$getState7 = this.getState(), - currentUploads = _this$getState7.currentUploads; - - return currentUploads[uploadID]; + [_Symbol$for2](...args) { + return _classPrivateFieldLooseBase(this, _createUpload)[_createUpload](...args); } + /** * Add data to an upload's result object. * * @param {string} uploadID The ID of the upload. * @param {object} data Data properties to add to the result object. */ - ; - - _proto.addResultData = function addResultData(uploadID, data) { - var _extends6; - - if (!this.getUpload(uploadID)) { - this.log("Not setting result for an upload that has been removed: " + uploadID); + addResultData(uploadID, data) { + if (!_classPrivateFieldLooseBase(this, _getUpload)[_getUpload](uploadID)) { + this.log(`Not setting result for an upload that has been removed: ${uploadID}`); return; } - var _this$getState8 = this.getState(), - currentUploads = _this$getState8.currentUploads; - - var currentUpload = _extends({}, currentUploads[uploadID], { - result: _extends({}, currentUploads[uploadID].result, data) - }); - + const { + currentUploads + } = this.getState(); + const currentUpload = { ...currentUploads[uploadID], + result: { ...currentUploads[uploadID].result, + ...data + } + }; this.setState({ - currentUploads: _extends({}, currentUploads, (_extends6 = {}, _extends6[uploadID] = currentUpload, _extends6)) + currentUploads: { ...currentUploads, + [uploadID]: currentUpload + } }); } /** @@ -4371,161 +3948,24 @@ var Uppy = /*#__PURE__*/function () { * * @param {string} uploadID The ID of the upload. */ - ; - - _proto.removeUpload = function removeUpload(uploadID) { - var currentUploads = _extends({}, this.getState().currentUploads); - - delete currentUploads[uploadID]; - this.setState({ - currentUploads: currentUploads - }); - } - /** - * Run an upload. This picks up where it left off in case the upload is being restored. - * - * @private - */ - ; - - _proto.runUpload = function runUpload(uploadID) { - var _this9 = this; - - var uploadData = this.getState().currentUploads[uploadID]; - var restoreStep = uploadData.step; - var steps = [].concat(this.preProcessors, this.uploaders, this.postProcessors); - var lastStep = Promise.resolve(); - steps.forEach(function (fn, step) { - // Skip this step if we are restoring and have already completed this step before. - if (step < restoreStep) { - return; - } - - lastStep = lastStep.then(function () { - var _extends7; - - var _this9$getState = _this9.getState(), - currentUploads = _this9$getState.currentUploads; - - var currentUpload = currentUploads[uploadID]; - - if (!currentUpload) { - return; - } - - var updatedUpload = _extends({}, currentUpload, { - step: step - }); - - _this9.setState({ - currentUploads: _extends({}, currentUploads, (_extends7 = {}, _extends7[uploadID] = updatedUpload, _extends7)) - }); // TODO give this the `updatedUpload` object as its only parameter maybe? - // Otherwise when more metadata may be added to the upload this would keep getting more parameters - // eslint-disable-next-line consistent-return - return fn(updatedUpload.fileIDs, uploadID); - }).then(function () { - return null; - }); - }); // Not returning the `catch`ed promise, because we still want to return a rejected - // promise from this method if the upload failed. - - lastStep.catch(function (err) { - _this9.emit('error', err, uploadID); - - _this9.removeUpload(uploadID); - }); - return lastStep.then(function () { - // Set result data. - var _this9$getState2 = _this9.getState(), - currentUploads = _this9$getState2.currentUploads; - - var currentUpload = currentUploads[uploadID]; - - if (!currentUpload) { - return; - } // Mark postprocessing step as complete if necessary; this addresses a case where we might get - // stuck in the postprocessing UI while the upload is fully complete. - // If the postprocessing steps do not do any work, they may not emit postprocessing events at - // all, and never mark the postprocessing as complete. This is fine on its own but we - // introduced code in the @uppy/core upload-success handler to prepare postprocessing progress - // state if any postprocessors are registered. That is to avoid a "flash of completed state" - // before the postprocessing plugins can emit events. - // - // So, just in case an upload with postprocessing plugins *has* completed *without* emitting - // postprocessing completion, we do it instead. - - - currentUpload.fileIDs.forEach(function (fileID) { - var file = _this9.getFile(fileID); - - if (file && file.progress.postprocess) { - _this9.emit('postprocess-complete', file); - } - }); - var files = currentUpload.fileIDs.map(function (fileID) { - return _this9.getFile(fileID); - }); - var successful = files.filter(function (file) { - return !file.error; - }); - var failed = files.filter(function (file) { - return file.error; - }); - - _this9.addResultData(uploadID, { - successful: successful, - failed: failed, - uploadID: uploadID - }); - }).then(function () { - // Emit completion events. - // This is in a separate function so that the `currentUploads` variable - // always refers to the latest state. In the handler right above it refers - // to an outdated object without the `.result` property. - var _this9$getState3 = _this9.getState(), - currentUploads = _this9$getState3.currentUploads; - - if (!currentUploads[uploadID]) { - return; - } - - var currentUpload = currentUploads[uploadID]; - var result = currentUpload.result; - - _this9.emit('complete', result); - - _this9.removeUpload(uploadID); // eslint-disable-next-line consistent-return - - - return result; - }).then(function (result) { - if (result == null) { - _this9.log("Not setting result for an upload that has been removed: " + uploadID); - } - - return result; - }); - } /** * Start an upload for all the files that are not currently being uploaded. * * @returns {Promise} */ - ; + upload() { + var _classPrivateFieldLoo; - _proto.upload = function upload() { - var _this10 = this; - - if (!this.plugins.uploader) { + if (!((_classPrivateFieldLoo = _classPrivateFieldLooseBase(this, _plugins)[_plugins].uploader) != null && _classPrivateFieldLoo.length)) { this.log('No uploader type plugins are used', 'warning'); } - var _this$getState9 = this.getState(), - files = _this$getState9.files; - - var onBeforeUploadResult = this.opts.onBeforeUpload(files); + let { + files + } = this.getState(); + const onBeforeUploadResult = this.opts.onBeforeUpload(files); if (onBeforeUploadResult === false) { return Promise.reject(new Error('Not starting the upload because onBeforeUpload returned false')); @@ -4536,117 +3976,661 @@ var Uppy = /*#__PURE__*/function () { // and then fetch the actual file object from state this.setState({ - files: files + files }); } - return Promise.resolve().then(function () { - return _this10.checkMinNumberOfFiles(files); - }).catch(function (err) { - _this10.showOrLogErrorAndThrow(err); - }).then(function () { - var _this10$getState = _this10.getState(), - currentUploads = _this10$getState.currentUploads; // get a list of files that are currently assigned to uploads + return Promise.resolve().then(() => { + _classPrivateFieldLooseBase(this, _checkMinNumberOfFiles)[_checkMinNumberOfFiles](files); + _classPrivateFieldLooseBase(this, _checkRequiredMetaFields)[_checkRequiredMetaFields](files); + }).catch(err => { + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err); + }).then(() => { + const { + currentUploads + } = this.getState(); // get a list of files that are currently assigned to uploads - var currentlyUploadingFiles = Object.keys(currentUploads).reduce(function (prev, curr) { - return prev.concat(currentUploads[curr].fileIDs); - }, []); - var waitingFileIDs = []; - Object.keys(files).forEach(function (fileID) { - var file = _this10.getFile(fileID); // if the file hasn't started uploading and hasn't already been assigned to an upload.. - + const currentlyUploadingFiles = Object.values(currentUploads).flatMap(curr => curr.fileIDs); + const waitingFileIDs = []; + Object.keys(files).forEach(fileID => { + const file = this.getFile(fileID); // if the file hasn't started uploading and hasn't already been assigned to an upload.. if (!file.progress.uploadStarted && currentlyUploadingFiles.indexOf(fileID) === -1) { waitingFileIDs.push(file.id); } }); - var uploadID = _this10.createUpload(waitingFileIDs); + const uploadID = _classPrivateFieldLooseBase(this, _createUpload)[_createUpload](waitingFileIDs); - return _this10.runUpload(uploadID); - }).catch(function (err) { - _this10.showOrLogErrorAndThrow(err, { + return _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID); + }).catch(err => { + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err, { showInformer: false }); }); + } + +} // Expose class constructor. + + +function _checkRestrictions2(file, files = this.getFiles()) { + const { + maxFileSize, + minFileSize, + maxTotalFileSize, + maxNumberOfFiles, + allowedFileTypes + } = this.opts.restrictions; + + if (maxNumberOfFiles) { + if (files.length + 1 > maxNumberOfFiles) { + throw new RestrictionError(`${this.i18n('youCanOnlyUploadX', { + smart_count: maxNumberOfFiles + })}`); + } + } + + if (allowedFileTypes) { + const isCorrectFileType = allowedFileTypes.some(type => { + // check if this is a mime-type + if (type.indexOf('/') > -1) { + if (!file.type) return false; + return match(file.type.replace(/;.*?$/, ''), type); + } // otherwise this is likely an extension + + + if (type[0] === '.' && file.extension) { + return file.extension.toLowerCase() === type.substr(1).toLowerCase(); + } + + return false; + }); + + if (!isCorrectFileType) { + const allowedFileTypesString = allowedFileTypes.join(', '); + throw new RestrictionError(this.i18n('youCanOnlyUploadFileTypes', { + types: allowedFileTypesString + })); + } + } // We can't check maxTotalFileSize if the size is unknown. + + + if (maxTotalFileSize && file.size != null) { + let totalFilesSize = 0; + totalFilesSize += file.size; + files.forEach(f => { + totalFilesSize += f.size; + }); + + if (totalFilesSize > maxTotalFileSize) { + throw new RestrictionError(this.i18n('exceedsSize', { + size: prettierBytes(maxTotalFileSize), + file: file.name + })); + } + } // We can't check maxFileSize if the size is unknown. + + + if (maxFileSize && file.size != null) { + if (file.size > maxFileSize) { + throw new RestrictionError(this.i18n('exceedsSize', { + size: prettierBytes(maxFileSize), + file: file.name + })); + } + } // We can't check minFileSize if the size is unknown. + + + if (minFileSize && file.size != null) { + if (file.size < minFileSize) { + throw new RestrictionError(this.i18n('inferiorSize', { + size: prettierBytes(minFileSize) + })); + } + } +} + +function _checkMinNumberOfFiles2(files) { + const { + minNumberOfFiles + } = this.opts.restrictions; + + if (Object.keys(files).length < minNumberOfFiles) { + throw new RestrictionError(`${this.i18n('youHaveToAtLeastSelectX', { + smart_count: minNumberOfFiles + })}`); + } +} + +function _checkRequiredMetaFields2(files) { + const { + requiredMetaFields + } = this.opts.restrictions; + const { + hasOwnProperty + } = Object.prototype; + const errors = []; + const fileIDs = Object.keys(files); + + for (let i = 0; i < fileIDs.length; i++) { + const file = this.getFile(fileIDs[i]); + + for (let i = 0; i < requiredMetaFields.length; i++) { + if (!hasOwnProperty.call(file.meta, requiredMetaFields[i]) || file.meta[requiredMetaFields[i]] === '') { + const err = new RestrictionError(`${this.i18n('missingRequiredMetaFieldOnFile', { + fileName: file.name + })}`); + errors.push(err); + + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err, { + file, + showInformer: false, + throwErr: false + }); + } + } + } + + if (errors.length) { + throw new AggregateRestrictionError(`${this.i18n('missingRequiredMetaField')}`, errors); + } +} + +function _showOrLogErrorAndThrow2(err, { + showInformer = true, + file = null, + throwErr = true +} = {}) { + const message = typeof err === 'object' ? err.message : err; + const details = typeof err === 'object' && err.details ? err.details : ''; // Restriction errors should be logged, but not as errors, + // as they are expected and shown in the UI. + + let logMessageWithDetails = message; + + if (details) { + logMessageWithDetails += ` ${details}`; + } + + if (err.isRestriction) { + this.log(logMessageWithDetails); + this.emit('restriction-failed', file, err); + } else { + this.log(logMessageWithDetails, 'error'); + } // Sometimes informer has to be shown manually by the developer, + // for example, in `onBeforeFileAdded`. + + + if (showInformer) { + this.info({ + message, + details + }, 'error', this.opts.infoTimeout); + } + + if (throwErr) { + throw typeof err === 'object' ? err : new Error(err); + } +} + +function _assertNewUploadAllowed2(file) { + const { + allowNewUpload + } = this.getState(); + + if (allowNewUpload === false) { + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](new RestrictionError(this.i18n('noMoreFilesAllowed')), { + file + }); + } +} + +function _checkAndCreateFileStateObject2(files, fileDescriptor) { + const fileType = getFileType(fileDescriptor); + const fileName = getFileName(fileType, fileDescriptor); + const fileExtension = getFileNameAndExtension(fileName).extension; + const isRemote = Boolean(fileDescriptor.isRemote); + const fileID = generateFileID({ ...fileDescriptor, + type: fileType + }); + + if (this.checkIfFileAlreadyExists(fileID)) { + const error = new RestrictionError(this.i18n('noDuplicates', { + fileName + })); + + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](error, { + file: fileDescriptor + }); + } + + const meta = fileDescriptor.meta || {}; + meta.name = fileName; + meta.type = fileType; // `null` means the size is unknown. + + const size = Number.isFinite(fileDescriptor.data.size) ? fileDescriptor.data.size : null; + let newFile = { + source: fileDescriptor.source || '', + id: fileID, + name: fileName, + extension: fileExtension || '', + meta: { ...this.getState().meta, + ...meta + }, + type: fileType, + data: fileDescriptor.data, + progress: { + percentage: 0, + bytesUploaded: 0, + bytesTotal: size, + uploadComplete: false, + uploadStarted: null + }, + size, + isRemote, + remote: fileDescriptor.remote || '', + preview: fileDescriptor.preview + }; + const onBeforeFileAddedResult = this.opts.onBeforeFileAdded(newFile, files); + + if (onBeforeFileAddedResult === false) { + // Don’t show UI info for this error, as it should be done by the developer + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](new RestrictionError('Cannot add the file because onBeforeFileAdded returned false.'), { + showInformer: false, + fileDescriptor + }); + } else if (typeof onBeforeFileAddedResult === 'object' && onBeforeFileAddedResult !== null) { + newFile = onBeforeFileAddedResult; + } + + try { + const filesArray = Object.keys(files).map(i => files[i]); + + _classPrivateFieldLooseBase(this, _checkRestrictions)[_checkRestrictions](newFile, filesArray); + } catch (err) { + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](err, { + file: newFile + }); + } + + return newFile; +} + +function _startIfAutoProceed2() { + if (this.opts.autoProceed && !this.scheduledAutoProceed) { + this.scheduledAutoProceed = setTimeout(() => { + this.scheduledAutoProceed = null; + this.upload().catch(err => { + if (!err.isRestriction) { + this.log(err.stack || err.message || err); + } + }); + }, 4); + } +} + +function _addListeners2() { + /** + * @param {Error} error + * @param {object} [file] + * @param {object} [response] + */ + const errorHandler = (error, file, response) => { + let errorMsg = error.message || 'Unknown error'; + + if (error.details) { + errorMsg += ` ${error.details}`; + } + + this.setState({ + error: errorMsg + }); + + if (file != null && file.id in this.getState().files) { + this.setFileState(file.id, { + error: errorMsg, + response + }); + } }; - _createClass(Uppy, [{ - key: "state", - get: function get() { - return this.getState(); + this.on('error', errorHandler); + this.on('upload-error', (file, error, response) => { + errorHandler(error, file, response); + + if (typeof error === 'object' && error.message) { + const newError = new Error(error.message); + newError.details = error.message; + + if (error.details) { + newError.details += ` ${error.details}`; + } + + newError.message = this.i18n('failedToUpload', { + file: file.name + }); + + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](newError, { + throwErr: false + }); + } else { + _classPrivateFieldLooseBase(this, _showOrLogErrorAndThrow)[_showOrLogErrorAndThrow](error, { + throwErr: false + }); + } + }); + this.on('upload', () => { + this.setState({ + error: null + }); + }); + this.on('upload-started', file => { + if (!this.getFile(file.id)) { + this.log(`Not setting progress for a file that has been removed: ${file.id}`); + return; } - }]); - return Uppy; -}(); + this.setFileState(file.id, { + progress: { + uploadStarted: Date.now(), + uploadComplete: false, + percentage: 0, + bytesUploaded: 0, + bytesTotal: file.size + } + }); + }); + this.on('upload-progress', this.calculateProgress); + this.on('upload-success', (file, uploadResp) => { + if (!this.getFile(file.id)) { + this.log(`Not setting progress for a file that has been removed: ${file.id}`); + return; + } -Uppy.VERSION = version; + const currentProgress = this.getFile(file.id).progress; + this.setFileState(file.id, { + progress: { ...currentProgress, + postprocess: _classPrivateFieldLooseBase(this, _postProcessors)[_postProcessors].size > 0 ? { + mode: 'indeterminate' + } : null, + uploadComplete: true, + percentage: 100, + bytesUploaded: currentProgress.bytesTotal + }, + response: uploadResp, + uploadURL: uploadResp.uploadURL, + isPaused: false + }); // Remote providers sometimes don't tell us the file size, + // but we can know how many bytes we uploaded once the upload is complete. -module.exports = function core(opts) { - return new Uppy(opts); -}; // Expose class constructor. + if (file.size == null) { + this.setFileState(file.id, { + size: uploadResp.bytesUploaded || currentProgress.bytesTotal + }); + } + + this.calculateTotalProgress(); + }); + this.on('preprocess-progress', (file, progress) => { + if (!this.getFile(file.id)) { + this.log(`Not setting progress for a file that has been removed: ${file.id}`); + return; + } + + this.setFileState(file.id, { + progress: { ...this.getFile(file.id).progress, + preprocess: progress + } + }); + }); + this.on('preprocess-complete', file => { + if (!this.getFile(file.id)) { + this.log(`Not setting progress for a file that has been removed: ${file.id}`); + return; + } + + const files = { ...this.getState().files + }; + files[file.id] = { ...files[file.id], + progress: { ...files[file.id].progress + } + }; + delete files[file.id].progress.preprocess; + this.setState({ + files + }); + }); + this.on('postprocess-progress', (file, progress) => { + if (!this.getFile(file.id)) { + this.log(`Not setting progress for a file that has been removed: ${file.id}`); + return; + } + + this.setFileState(file.id, { + progress: { ...this.getState().files[file.id].progress, + postprocess: progress + } + }); + }); + this.on('postprocess-complete', file => { + if (!this.getFile(file.id)) { + this.log(`Not setting progress for a file that has been removed: ${file.id}`); + return; + } + + const files = { ...this.getState().files + }; + files[file.id] = { ...files[file.id], + progress: { ...files[file.id].progress + } + }; + delete files[file.id].progress.postprocess; + this.setState({ + files + }); + }); + this.on('restored', () => { + // Files may have changed--ensure progress is still accurate. + this.calculateTotalProgress(); + }); // show informer if offline + + if (typeof window !== 'undefined' && window.addEventListener) { + window.addEventListener('online', _classPrivateFieldLooseBase(this, _updateOnlineStatus)[_updateOnlineStatus]); + window.addEventListener('offline', _classPrivateFieldLooseBase(this, _updateOnlineStatus)[_updateOnlineStatus]); + setTimeout(_classPrivateFieldLooseBase(this, _updateOnlineStatus)[_updateOnlineStatus], 3000); + } +} + +function _createUpload2(fileIDs, opts = {}) { + // uppy.retryAll sets this to true — when retrying we want to ignore `allowNewUpload: false` + const { + forceAllowNewUpload = false + } = opts; + const { + allowNewUpload, + currentUploads + } = this.getState(); + + if (!allowNewUpload && !forceAllowNewUpload) { + throw new Error('Cannot create a new upload: already uploading.'); + } + + const uploadID = nanoid(); + this.emit('upload', { + id: uploadID, + fileIDs + }); + this.setState({ + allowNewUpload: this.opts.allowMultipleUploadBatches !== false && this.opts.allowMultipleUploads !== false, + currentUploads: { ...currentUploads, + [uploadID]: { + fileIDs, + step: 0, + result: {} + } + } + }); + return uploadID; +} + +function _getUpload2(uploadID) { + const { + currentUploads + } = this.getState(); + return currentUploads[uploadID]; +} + +function _removeUpload2(uploadID) { + const currentUploads = { ...this.getState().currentUploads + }; + delete currentUploads[uploadID]; + this.setState({ + currentUploads + }); +} + +function _runUpload2(uploadID) { + const uploadData = this.getState().currentUploads[uploadID]; + const restoreStep = uploadData.step; + const steps = [..._classPrivateFieldLooseBase(this, _preProcessors)[_preProcessors], ..._classPrivateFieldLooseBase(this, _uploaders)[_uploaders], ..._classPrivateFieldLooseBase(this, _postProcessors)[_postProcessors]]; + let lastStep = Promise.resolve(); + steps.forEach((fn, step) => { + // Skip this step if we are restoring and have already completed this step before. + if (step < restoreStep) { + return; + } + + lastStep = lastStep.then(() => { + const { + currentUploads + } = this.getState(); + const currentUpload = currentUploads[uploadID]; + + if (!currentUpload) { + return; + } + + const updatedUpload = { ...currentUpload, + step + }; + this.setState({ + currentUploads: { ...currentUploads, + [uploadID]: updatedUpload + } + }); // TODO give this the `updatedUpload` object as its only parameter maybe? + // Otherwise when more metadata may be added to the upload this would keep getting more parameters + + return fn(updatedUpload.fileIDs, uploadID); // eslint-disable-line consistent-return + }).then(() => null); + }); // Not returning the `catch`ed promise, because we still want to return a rejected + // promise from this method if the upload failed. + + lastStep.catch(err => { + this.emit('error', err); + + _classPrivateFieldLooseBase(this, _removeUpload)[_removeUpload](uploadID); + }); + return lastStep.then(() => { + // Set result data. + const { + currentUploads + } = this.getState(); + const currentUpload = currentUploads[uploadID]; + + if (!currentUpload) { + return; + } // Mark postprocessing step as complete if necessary; this addresses a case where we might get + // stuck in the postprocessing UI while the upload is fully complete. + // If the postprocessing steps do not do any work, they may not emit postprocessing events at + // all, and never mark the postprocessing as complete. This is fine on its own but we + // introduced code in the @uppy/core upload-success handler to prepare postprocessing progress + // state if any postprocessors are registered. That is to avoid a "flash of completed state" + // before the postprocessing plugins can emit events. + // + // So, just in case an upload with postprocessing plugins *has* completed *without* emitting + // postprocessing completion, we do it instead. + currentUpload.fileIDs.forEach(fileID => { + const file = this.getFile(fileID); + + if (file && file.progress.postprocess) { + this.emit('postprocess-complete', file); + } + }); + const files = currentUpload.fileIDs.map(fileID => this.getFile(fileID)); + const successful = files.filter(file => !file.error); + const failed = files.filter(file => file.error); + this.addResultData(uploadID, { + successful, + failed, + uploadID + }); + }).then(() => { + // Emit completion events. + // This is in a separate function so that the `currentUploads` variable + // always refers to the latest state. In the handler right above it refers + // to an outdated object without the `.result` property. + const { + currentUploads + } = this.getState(); + + if (!currentUploads[uploadID]) { + return; + } + + const currentUpload = currentUploads[uploadID]; + const { + result + } = currentUpload; + this.emit('complete', result); + + _classPrivateFieldLooseBase(this, _removeUpload)[_removeUpload](uploadID); // eslint-disable-next-line consistent-return + + + return result; + }).then(result => { + if (result == null) { + this.log(`Not setting result for an upload that has been removed: ${uploadID}`); + } + + return result; + }); +} + +Uppy.VERSION = "2.0.1"; +module.exports = Uppy; module.exports.Uppy = Uppy; -module.exports.Plugin = Plugin; +module.exports.UIPlugin = UIPlugin; +module.exports.BasePlugin = BasePlugin; module.exports.debugLogger = debugLogger; -},{"../package.json":18,"./Plugin":14,"./loggers":16,"./supportsUploadProgress":17,"@transloadit/prettier-bytes":1,"@uppy/store-default":20,"@uppy/utils/lib/Translator":26,"@uppy/utils/lib/findIndex":31,"@uppy/utils/lib/generateFileID":32,"@uppy/utils/lib/getFileNameAndExtension":38,"@uppy/utils/lib/getFileType":39,"cuid":50,"lodash.throttle":54,"mime-match":55,"namespace-emitter":56}],16:[function(require,module,exports){ -var getTimeStamp = require('@uppy/utils/lib/getTimeStamp'); // Swallow all logs, except errors. +},{"./BasePlugin":14,"./UIPlugin":15,"./getFileName":16,"./loggers":18,"./supportsUploadProgress":19,"@transloadit/prettier-bytes":1,"@uppy/store-default":21,"@uppy/utils/lib/Translator":27,"@uppy/utils/lib/generateFileID":32,"@uppy/utils/lib/getFileNameAndExtension":38,"@uppy/utils/lib/getFileType":39,"lodash.throttle":49,"mime-match":50,"namespace-emitter":51,"nanoid":52}],18:[function(require,module,exports){ +"use strict"; + +/* eslint-disable no-console */ +const getTimeStamp = require('@uppy/utils/lib/getTimeStamp'); // Swallow all logs, except errors. // default if logger is not set or debug: false -var justErrorsLogger = { - debug: function debug() {}, - warn: function warn() {}, - error: function error() { - var _console; - - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return (_console = console).error.apply(_console, ["[Uppy] [" + getTimeStamp() + "]"].concat(args)); - } +const justErrorsLogger = { + debug: () => {}, + warn: () => {}, + error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args) }; // Print logs to console with namespace + timestamp, // set by logger: Uppy.debugLogger or debug: true -var debugLogger = { - debug: function debug() { - // IE 10 doesn’t support console.debug - var debug = console.debug || console.log; - - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - - debug.call.apply(debug, [console, "[Uppy] [" + getTimeStamp() + "]"].concat(args)); - }, - warn: function warn() { - var _console2; - - for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { - args[_key3] = arguments[_key3]; - } - - return (_console2 = console).warn.apply(_console2, ["[Uppy] [" + getTimeStamp() + "]"].concat(args)); - }, - error: function error() { - var _console3; - - for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { - args[_key4] = arguments[_key4]; - } - - return (_console3 = console).error.apply(_console3, ["[Uppy] [" + getTimeStamp() + "]"].concat(args)); - } +const debugLogger = { + debug: (...args) => console.debug(`[Uppy] [${getTimeStamp()}]`, ...args), + warn: (...args) => console.warn(`[Uppy] [${getTimeStamp()}]`, ...args), + error: (...args) => console.error(`[Uppy] [${getTimeStamp()}]`, ...args) }; module.exports = { - justErrorsLogger: justErrorsLogger, - debugLogger: debugLogger + justErrorsLogger, + debugLogger }; -},{"@uppy/utils/lib/getTimeStamp":41}],17:[function(require,module,exports){ +},{"@uppy/utils/lib/getTimeStamp":41}],19:[function(require,module,exports){ +"use strict"; + // Edge 15.x does not fire 'progress' events on uploads. // See https://github.com/transloadit/uppy/issues/945 // And https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12224510/ @@ -4658,14 +4642,10 @@ module.exports = function supportsUploadProgress(userAgent) { if (!userAgent) return true; - var m = /Edge\/(\d+\.\d+)/.exec(userAgent); + const m = /Edge\/(\d+\.\d+)/.exec(userAgent); if (!m) return true; - var edgeVersion = m[1]; - - var _edgeVersion$split = edgeVersion.split('.'), - major = _edgeVersion$split[0], - minor = _edgeVersion$split[1]; - + const edgeVersion = m[1]; + let [major, minor] = edgeVersion.split('.'); major = parseInt(major, 10); minor = parseInt(minor, 10); // Worked before: // Edge 40.15063.0.0 @@ -4684,557 +4664,440 @@ module.exports = function supportsUploadProgress(userAgent) { return false; }; -},{}],18:[function(require,module,exports){ -module.exports={ - "name": "@uppy/core", - "description": "Core module for the extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:", - "version": "1.19.2", - "license": "MIT", - "main": "lib/index.js", - "style": "dist/style.min.css", - "types": "types/index.d.ts", - "keywords": [ - "file uploader", - "uppy", - "uppy-plugin" - ], - "homepage": "https://uppy.io", - "bugs": { - "url": "https://github.com/transloadit/uppy/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/transloadit/uppy.git" - }, - "dependencies": { - "@transloadit/prettier-bytes": "0.0.7", - "@uppy/store-default": "^1.2.7", - "@uppy/utils": "^3.6.2", - "cuid": "^2.1.1", - "lodash.throttle": "^4.1.1", - "mime-match": "^1.0.2", - "namespace-emitter": "^2.0.1", - "preact": "8.2.9" - }, - "gitHead": "4b782ffbbb443672843d7b4096956bed3b11d612" -} +},{}],20:[function(require,module,exports){ +"use strict"; -},{}],19:[function(require,module,exports){ var _class, _temp; -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +const { + BasePlugin +} = require('@uppy/core'); -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } +const getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles'); -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -var _require = require('@uppy/core'), - Plugin = _require.Plugin; - -var getDroppedFiles = require('@uppy/utils/lib/getDroppedFiles'); - -var toArray = require('@uppy/utils/lib/toArray'); +const toArray = require('@uppy/utils/lib/toArray'); /** * Drop Target plugin * */ -module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) { - _inheritsLoose(DropTarget, _Plugin); +module.exports = (_temp = _class = class DropTarget extends BasePlugin { + constructor(uppy, opts) { + super(uppy, opts); - function DropTarget(uppy, opts) { - var _this; - - _this = _Plugin.call(this, uppy, opts) || this; - - _this.addFiles = function (files) { - var descriptors = files.map(function (file) { - return { - source: _this.id, - name: file.name, - type: file.type, - data: file, - meta: { - // path of the file relative to the ancestor directory the user selected. - // e.g. 'docs/Old Prague/airbnb.pdf' - relativePath: file.relativePath || null - } - }; - }); + this.addFiles = files => { + const descriptors = files.map(file => ({ + source: this.id, + name: file.name, + type: file.type, + data: file, + meta: { + // path of the file relative to the ancestor directory the user selected. + // e.g. 'docs/Old Prague/airbnb.pdf' + relativePath: file.relativePath || null + } + })); try { - _this.uppy.addFiles(descriptors); + this.uppy.addFiles(descriptors); } catch (err) { - _this.uppy.log(err); + this.uppy.log(err); } }; - _this.handleDrop = function (event) { + this.handleDrop = event => { event.preventDefault(); event.stopPropagation(); - clearTimeout(_this.removeDragOverClassTimeout); // 2. Remove dragover class + clearTimeout(this.removeDragOverClassTimeout); // 2. Remove dragover class event.currentTarget.classList.remove('uppy-is-drag-over'); - - _this.setPluginState({ + this.setPluginState({ isDraggingOver: false }); // 3. Add all dropped files + this.uppy.log('[DropTarget] Files were dropped'); - _this.uppy.log('[DropTarget] Files were dropped'); - - var logDropError = function logDropError(error) { - _this.uppy.log(error, 'error'); + const logDropError = error => { + this.uppy.log(error, 'error'); }; getDroppedFiles(event.dataTransfer, { - logDropError: logDropError - }).then(function (files) { - return _this.addFiles(files); - }); + logDropError + }).then(files => this.addFiles(files)); }; - _this.handleDragOver = function (event) { + this.handleDragOver = event => { event.preventDefault(); event.stopPropagation(); // 1. Add a small (+) icon on drop // (and prevent browsers from interpreting this as files being _moved_ into the browser, // https://github.com/transloadit/uppy/issues/1978) event.dataTransfer.dropEffect = 'copy'; - clearTimeout(_this.removeDragOverClassTimeout); + clearTimeout(this.removeDragOverClassTimeout); event.currentTarget.classList.add('uppy-is-drag-over'); - - _this.setPluginState({ + this.setPluginState({ isDraggingOver: true }); }; - _this.handleDragLeave = function (event) { + this.handleDragLeave = event => { event.preventDefault(); event.stopPropagation(); - var currentTarget = event.currentTarget; - clearTimeout(_this.removeDragOverClassTimeout); // Timeout against flickering, this solution is taken from drag-drop library. + const { + currentTarget + } = event; + clearTimeout(this.removeDragOverClassTimeout); // Timeout against flickering, this solution is taken from drag-drop library. // Solution with 'pointer-events: none' didn't work across browsers. - _this.removeDragOverClassTimeout = setTimeout(function () { + this.removeDragOverClassTimeout = setTimeout(() => { currentTarget.classList.remove('uppy-is-drag-over'); - - _this.setPluginState({ + this.setPluginState({ isDraggingOver: false }); }, 50); }; - _this.addListeners = function () { - var target = _this.opts.target; + this.addListeners = () => { + const { + target + } = this.opts; if (target instanceof Element) { - _this.nodes = [target]; + this.nodes = [target]; } else if (typeof target === 'string') { - _this.nodes = toArray(document.querySelectorAll(target)); + this.nodes = toArray(document.querySelectorAll(target)); } - if (!_this.nodes && !_this.nodes.length > 0) { - throw new Error("\"" + target + "\" does not match any HTML elements"); + if (!this.nodes && !this.nodes.length > 0) { + throw new Error(`"${target}" does not match any HTML elements`); } - _this.nodes.forEach(function (node) { - node.addEventListener('dragover', _this.handleDragOver, false); - node.addEventListener('dragleave', _this.handleDragLeave, false); - node.addEventListener('drop', _this.handleDrop, false); + this.nodes.forEach(node => { + node.addEventListener('dragover', this.handleDragOver, false); + node.addEventListener('dragleave', this.handleDragLeave, false); + node.addEventListener('drop', this.handleDrop, false); }); }; - _this.removeListeners = function () { - if (_this.nodes) { - _this.nodes.forEach(function (node) { - node.removeEventListener('dragover', _this.handleDragOver, false); - node.removeEventListener('dragleave', _this.handleDragLeave, false); - node.removeEventListener('drop', _this.handleDrop, false); + this.removeListeners = () => { + if (this.nodes) { + this.nodes.forEach(node => { + node.removeEventListener('dragover', this.handleDragOver, false); + node.removeEventListener('dragleave', this.handleDragLeave, false); + node.removeEventListener('drop', this.handleDrop, false); }); } }; - _this.type = 'acquirer'; - _this.id = _this.opts.id || 'DropTarget'; - _this.title = 'Drop Target'; // Default options + this.type = 'acquirer'; + this.id = this.opts.id || 'DropTarget'; + this.title = 'Drop Target'; // Default options - var defaultOpts = { + const defaultOpts = { target: null }; // Merge default options with the ones set by user - _this.opts = _extends({}, defaultOpts, opts); - _this.removeDragOverClassTimeout = null; - return _this; + this.opts = { ...defaultOpts, + ...opts + }; + this.removeDragOverClassTimeout = null; } - var _proto = DropTarget.prototype; - - _proto.install = function install() { + install() { this.setPluginState({ isDraggingOver: false }); this.addListeners(); - }; + } - _proto.uninstall = function uninstall() { + uninstall() { this.removeListeners(); - }; + } - return DropTarget; -}(Plugin), _class.VERSION = "0.2.4", _temp); -},{"@uppy/core":15,"@uppy/utils/lib/getDroppedFiles":33,"@uppy/utils/lib/toArray":47}],20:[function(require,module,exports){ -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } +}, _class.VERSION = "1.0.1", _temp); +},{"@uppy/core":17,"@uppy/utils/lib/getDroppedFiles":33,"@uppy/utils/lib/toArray":47}],21:[function(require,module,exports){ +"use strict"; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +var _publish = /*#__PURE__*/_classPrivateFieldLooseKey("publish"); /** * Default store that keeps state in a simple object. */ -var DefaultStore = /*#__PURE__*/function () { - function DefaultStore() { +class DefaultStore { + constructor() { + Object.defineProperty(this, _publish, { + value: _publish2 + }); this.state = {}; this.callbacks = []; } - var _proto = DefaultStore.prototype; - - _proto.getState = function getState() { + getState() { return this.state; - }; - - _proto.setState = function setState(patch) { - var prevState = _extends({}, this.state); - - var nextState = _extends({}, this.state, patch); + } + setState(patch) { + const prevState = { ...this.state + }; + const nextState = { ...this.state, + ...patch + }; this.state = nextState; - this._publish(prevState, nextState, patch); - }; - - _proto.subscribe = function subscribe(listener) { - var _this = this; + _classPrivateFieldLooseBase(this, _publish)[_publish](prevState, nextState, patch); + } + subscribe(listener) { this.callbacks.push(listener); - return function () { + return () => { // Remove the listener. - _this.callbacks.splice(_this.callbacks.indexOf(listener), 1); + this.callbacks.splice(this.callbacks.indexOf(listener), 1); }; - }; + } - _proto._publish = function _publish() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } +} - this.callbacks.forEach(function (listener) { - listener.apply(void 0, args); - }); - }; +function _publish2(...args) { + this.callbacks.forEach(listener => { + listener(...args); + }); +} - return DefaultStore; -}(); - -DefaultStore.VERSION = "1.2.7"; +DefaultStore.VERSION = "2.0.0"; module.exports = function defaultStore() { return new DefaultStore(); }; -},{}],21:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ +"use strict"; + /** * Little AbortController proxy module so we can swap out the implementation easily later. */ -var _require = require('abortcontroller-polyfill/dist/abortcontroller'), - AbortController = _require.AbortController, - AbortSignal = _require.AbortSignal; - -function createAbortError(message) { - if (message === void 0) { - message = 'Aborted'; - } - - try { - return new DOMException(message, 'AbortError'); - } catch (_unused) { - // For Internet Explorer - var error = new Error(message); - error.name = 'AbortError'; - return error; - } -} - exports.AbortController = AbortController; exports.AbortSignal = AbortSignal; -exports.createAbortError = createAbortError; -},{"abortcontroller-polyfill/dist/abortcontroller":49}],22:[function(require,module,exports){ + +exports.createAbortError = (message = 'Aborted') => new DOMException(message, 'AbortError'); +},{}],23:[function(require,module,exports){ +"use strict"; + +var _emitter, _events; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + /** * Create a wrapper around an event emitter with a `remove` method to remove * all events that were added using the wrapped emitter. */ -module.exports = /*#__PURE__*/function () { - function EventTracker(emitter) { - this._events = []; - this._emitter = emitter; - } - - var _proto = EventTracker.prototype; - - _proto.on = function on(event, fn) { - this._events.push([event, fn]); - - return this._emitter.on(event, fn); - }; - - _proto.remove = function remove() { - var _this = this; - - this._events.forEach(function (_ref) { - var event = _ref[0], - fn = _ref[1]; - - _this._emitter.off(event, fn); +module.exports = (_emitter = /*#__PURE__*/_classPrivateFieldLooseKey("emitter"), _events = /*#__PURE__*/_classPrivateFieldLooseKey("events"), class EventTracker { + constructor(emitter) { + Object.defineProperty(this, _emitter, { + writable: true, + value: void 0 }); - }; - - return EventTracker; -}(); -},{}],23:[function(require,module,exports){ -function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } - -function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } - -function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } - -function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } - -function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } - -function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } - -function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } - -var NetworkError = /*#__PURE__*/function (_Error) { - _inheritsLoose(NetworkError, _Error); - - function NetworkError(error, xhr) { - var _this; - - if (xhr === void 0) { - xhr = null; - } - - _this = _Error.call(this, "This looks like a network error, the endpoint might be blocked by an internet provider or a firewall.\n\nSource error: [" + error + "]") || this; - _this.isNetworkError = true; - _this.request = xhr; - return _this; + Object.defineProperty(this, _events, { + writable: true, + value: [] + }); + _classPrivateFieldLooseBase(this, _emitter)[_emitter] = emitter; } - return NetworkError; -}( /*#__PURE__*/_wrapNativeSuper(Error)); + on(event, fn) { + _classPrivateFieldLooseBase(this, _events)[_events].push([event, fn]); + + return _classPrivateFieldLooseBase(this, _emitter)[_emitter].on(event, fn); + } + + remove() { + for (const [event, fn] of _classPrivateFieldLooseBase(this, _events)[_events].splice(0)) { + _classPrivateFieldLooseBase(this, _emitter)[_emitter].off(event, fn); + } + } + +}); +},{}],24:[function(require,module,exports){ +"use strict"; + +class NetworkError extends Error { + constructor(error, xhr = null) { + super(`This looks like a network error, the endpoint might be blocked by an internet provider or a firewall.`); + this.cause = error; + this.isNetworkError = true; + this.request = xhr; + } + +} module.exports = NetworkError; -},{}],24:[function(require,module,exports){ +},{}],25:[function(require,module,exports){ +"use strict"; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +var _aliveTimer = /*#__PURE__*/_classPrivateFieldLooseKey("aliveTimer"); + +var _isDone = /*#__PURE__*/_classPrivateFieldLooseKey("isDone"); + +var _onTimedOut = /*#__PURE__*/_classPrivateFieldLooseKey("onTimedOut"); + +var _timeout = /*#__PURE__*/_classPrivateFieldLooseKey("timeout"); + /** * Helper to abort upload requests if there has not been any progress for `timeout` ms. * Create an instance using `timer = new ProgressTimeout(10000, onTimeout)` * Call `timer.progress()` to signal that there has been progress of any kind. * Call `timer.done()` when the upload has completed. */ -var ProgressTimeout = /*#__PURE__*/function () { - function ProgressTimeout(timeout, timeoutHandler) { - this._timeout = timeout; - this._onTimedOut = timeoutHandler; - this._isDone = false; - this._aliveTimer = null; - this._onTimedOut = this._onTimedOut.bind(this); +class ProgressTimeout { + constructor(timeout, timeoutHandler) { + Object.defineProperty(this, _aliveTimer, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _isDone, { + writable: true, + value: false + }); + Object.defineProperty(this, _onTimedOut, { + writable: true, + value: void 0 + }); + Object.defineProperty(this, _timeout, { + writable: true, + value: void 0 + }); + _classPrivateFieldLooseBase(this, _timeout)[_timeout] = timeout; + _classPrivateFieldLooseBase(this, _onTimedOut)[_onTimedOut] = timeoutHandler; } - var _proto = ProgressTimeout.prototype; - - _proto.progress = function progress() { + progress() { // Some browsers fire another progress event when the upload is // cancelled, so we have to ignore progress after the timer was // told to stop. - if (this._isDone) return; + if (_classPrivateFieldLooseBase(this, _isDone)[_isDone]) return; - if (this._timeout > 0) { - if (this._aliveTimer) clearTimeout(this._aliveTimer); - this._aliveTimer = setTimeout(this._onTimedOut, this._timeout); + if (_classPrivateFieldLooseBase(this, _timeout)[_timeout] > 0) { + clearTimeout(_classPrivateFieldLooseBase(this, _aliveTimer)[_aliveTimer]); + _classPrivateFieldLooseBase(this, _aliveTimer)[_aliveTimer] = setTimeout(_classPrivateFieldLooseBase(this, _onTimedOut)[_onTimedOut], _classPrivateFieldLooseBase(this, _timeout)[_timeout]); } - }; + } - _proto.done = function done() { - if (this._aliveTimer) { - clearTimeout(this._aliveTimer); - this._aliveTimer = null; + done() { + if (!_classPrivateFieldLooseBase(this, _isDone)[_isDone]) { + clearTimeout(_classPrivateFieldLooseBase(this, _aliveTimer)[_aliveTimer]); + _classPrivateFieldLooseBase(this, _aliveTimer)[_aliveTimer] = null; + _classPrivateFieldLooseBase(this, _isDone)[_isDone] = true; } + } - this._isDone = true; - }; - - return ProgressTimeout; -}(); +} module.exports = ProgressTimeout; -},{}],25:[function(require,module,exports){ -var findIndex = require('./findIndex'); +},{}],26:[function(require,module,exports){ +"use strict"; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } function createCancelError() { return new Error('Cancelled'); } -module.exports = /*#__PURE__*/function () { - function RateLimitedQueue(limit) { +var _activeRequests = /*#__PURE__*/_classPrivateFieldLooseKey("activeRequests"); + +var _queuedHandlers = /*#__PURE__*/_classPrivateFieldLooseKey("queuedHandlers"); + +var _call = /*#__PURE__*/_classPrivateFieldLooseKey("call"); + +var _queueNext = /*#__PURE__*/_classPrivateFieldLooseKey("queueNext"); + +var _next = /*#__PURE__*/_classPrivateFieldLooseKey("next"); + +var _queue = /*#__PURE__*/_classPrivateFieldLooseKey("queue"); + +var _dequeue = /*#__PURE__*/_classPrivateFieldLooseKey("dequeue"); + +class RateLimitedQueue { + constructor(limit) { + Object.defineProperty(this, _dequeue, { + value: _dequeue2 + }); + Object.defineProperty(this, _queue, { + value: _queue2 + }); + Object.defineProperty(this, _next, { + value: _next2 + }); + Object.defineProperty(this, _queueNext, { + value: _queueNext2 + }); + Object.defineProperty(this, _call, { + value: _call2 + }); + Object.defineProperty(this, _activeRequests, { + writable: true, + value: 0 + }); + Object.defineProperty(this, _queuedHandlers, { + writable: true, + value: [] + }); + if (typeof limit !== 'number' || limit === 0) { this.limit = Infinity; } else { this.limit = limit; } - - this.activeRequests = 0; - this.queuedHandlers = []; } - var _proto = RateLimitedQueue.prototype; - - _proto._call = function _call(fn) { - var _this = this; - - this.activeRequests += 1; - var _done = false; - var cancelActive; - - try { - cancelActive = fn(); - } catch (err) { - this.activeRequests -= 1; - throw err; + run(fn, queueOptions) { + if (_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] < this.limit) { + return _classPrivateFieldLooseBase(this, _call)[_call](fn); } - return { - abort: function abort() { - if (_done) return; - _done = true; - _this.activeRequests -= 1; - cancelActive(); + return _classPrivateFieldLooseBase(this, _queue)[_queue](fn, queueOptions); + } - _this._queueNext(); - }, - done: function done() { - if (_done) return; - _done = true; - _this.activeRequests -= 1; - - _this._queueNext(); - } - }; - }; - - _proto._queueNext = function _queueNext() { - var _this2 = this; - - // Do it soon but not immediately, this allows clearing out the entire queue synchronously - // one by one without continuously _advancing_ it (and starting new tasks before immediately - // aborting them) - Promise.resolve().then(function () { - _this2._next(); - }); - }; - - _proto._next = function _next() { - if (this.activeRequests >= this.limit) { - return; - } - - if (this.queuedHandlers.length === 0) { - return; - } // Dispatch the next request, and update the abort/done handlers - // so that cancelling it does the Right Thing (and doesn't just try - // to dequeue an already-running request). - - - var next = this.queuedHandlers.shift(); - - var handler = this._call(next.fn); - - next.abort = handler.abort; - next.done = handler.done; - }; - - _proto._queue = function _queue(fn, options) { - var _this3 = this; - - if (options === void 0) { - options = {}; - } - - var handler = { - fn: fn, - priority: options.priority || 0, - abort: function abort() { - _this3._dequeue(handler); - }, - done: function done() { - throw new Error('Cannot mark a queued request as done: this indicates a bug'); - } - }; - var index = findIndex(this.queuedHandlers, function (other) { - return handler.priority > other.priority; - }); - - if (index === -1) { - this.queuedHandlers.push(handler); - } else { - this.queuedHandlers.splice(index, 0, handler); - } - - return handler; - }; - - _proto._dequeue = function _dequeue(handler) { - var index = this.queuedHandlers.indexOf(handler); - - if (index !== -1) { - this.queuedHandlers.splice(index, 1); - } - }; - - _proto.run = function run(fn, queueOptions) { - if (this.activeRequests < this.limit) { - return this._call(fn); - } - - return this._queue(fn, queueOptions); - }; - - _proto.wrapPromiseFunction = function wrapPromiseFunction(fn, queueOptions) { - var _this4 = this; - - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var queuedRequest; - var outerPromise = new Promise(function (resolve, reject) { - queuedRequest = _this4.run(function () { - var cancelError; - var innerPromise; + wrapPromiseFunction(fn, queueOptions) { + return (...args) => { + let queuedRequest; + const outerPromise = new Promise((resolve, reject) => { + queuedRequest = this.run(() => { + let cancelError; + let innerPromise; try { - innerPromise = Promise.resolve(fn.apply(void 0, args)); + innerPromise = Promise.resolve(fn(...args)); } catch (err) { innerPromise = Promise.reject(err); } - innerPromise.then(function (result) { + innerPromise.then(result => { if (cancelError) { reject(cancelError); } else { queuedRequest.done(); resolve(result); } - }, function (err) { + }, err => { if (cancelError) { reject(cancelError); } else { @@ -5242,26 +5105,193 @@ module.exports = /*#__PURE__*/function () { reject(err); } }); - return function () { + return () => { cancelError = createCancelError(); }; }, queueOptions); }); - outerPromise.abort = function () { + outerPromise.abort = () => { queuedRequest.abort(); }; return outerPromise; }; + } + +} + +function _call2(fn) { + _classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] += 1; + let done = false; + let cancelActive; + + try { + cancelActive = fn(); + } catch (err) { + _classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] -= 1; + throw err; + } + + return { + abort: () => { + if (done) return; + done = true; + _classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] -= 1; + cancelActive(); + + _classPrivateFieldLooseBase(this, _queueNext)[_queueNext](); + }, + done: () => { + if (done) return; + done = true; + _classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] -= 1; + + _classPrivateFieldLooseBase(this, _queueNext)[_queueNext](); + } + }; +} + +function _queueNext2() { + // Do it soon but not immediately, this allows clearing out the entire queue synchronously + // one by one without continuously _advancing_ it (and starting new tasks before immediately + // aborting them) + queueMicrotask(() => _classPrivateFieldLooseBase(this, _next)[_next]()); +} + +function _next2() { + if (_classPrivateFieldLooseBase(this, _activeRequests)[_activeRequests] >= this.limit) { + return; + } + + if (_classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].length === 0) { + return; + } // Dispatch the next request, and update the abort/done handlers + // so that cancelling it does the Right Thing (and doesn't just try + // to dequeue an already-running request). + + + const next = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].shift(); + + const handler = _classPrivateFieldLooseBase(this, _call)[_call](next.fn); + + next.abort = handler.abort; + next.done = handler.done; +} + +function _queue2(fn, options = {}) { + const handler = { + fn, + priority: options.priority || 0, + abort: () => { + _classPrivateFieldLooseBase(this, _dequeue)[_dequeue](handler); + }, + done: () => { + throw new Error('Cannot mark a queued request as done: this indicates a bug'); + } }; - return RateLimitedQueue; -}(); -},{"./findIndex":31}],26:[function(require,module,exports){ -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + const index = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].findIndex(other => { + return handler.priority > other.priority; + }); -var has = require('./hasProperty'); + if (index === -1) { + _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].push(handler); + } else { + _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].splice(index, 0, handler); + } + + return handler; +} + +function _dequeue2(handler) { + const index = _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].indexOf(handler); + + if (index !== -1) { + _classPrivateFieldLooseBase(this, _queuedHandlers)[_queuedHandlers].splice(index, 1); + } +} + +module.exports = { + RateLimitedQueue, + internalRateLimitedQueue: Symbol('__queue') +}; +},{}],27:[function(require,module,exports){ +"use strict"; + +var _apply; + +function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } + +var id = 0; + +function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; } + +const has = require('./hasProperty'); + +function insertReplacement(source, rx, replacement) { + const newParts = []; + source.forEach(chunk => { + // When the source contains multiple placeholders for interpolation, + // we should ignore chunks that are not strings, because those + // can be JSX objects and will be otherwise incorrectly turned into strings. + // Without this condition we’d get this: [object Object] hello [object Object] my