From 90232af7788f5b9c0d69c47f80c0564275a54060 Mon Sep 17 00:00:00 2001 From: Martin Brennan Date: Fri, 27 Aug 2021 11:02:57 +1000 Subject: [PATCH] DEV: Bump Uppy to v2.X and rebuild bundle (#14173) Uppy V2 includes the S3 multipart batch presigning change we contributed in https://github.com/transloadit/uppy/commit/d613b849a6591083f8a0968aa8d66537e231bbcd so we need to upgrade it. This also brings both package.json files into line and accounts for the renaming of Plugin to BasePlugin in Uppy. This has been tested and is working locally for both regular Ember and Ember CLI, for uploads.json XHR uploads and for direct S3 uploads (single and multipart). --- app/assets/javascripts/discourse-shims.js | 2 +- .../discourse/app/lib/uppy-checksum-plugin.js | 4 +- .../app/lib/uppy-media-optimization-plugin.js | 4 +- app/assets/javascripts/discourse/package.json | 10 +- app/assets/javascripts/yarn.lock | 140 +- package.json | 10 +- vendor/assets/javascripts/custom-uppy.js | 1 - vendor/assets/javascripts/uppy.js | 9803 +++++++---------- yarn.lock | 145 +- 9 files changed, 4374 insertions(+), 5745 deletions(-) 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