diff --git a/.prettierignore b/.prettierignore index ce46d1cd4b..d8404c9801 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,5 +4,6 @@ node_modules/ *.cjs *.mjs !private/js2ts/* +!examples/svelte-example/* *.lock CHANGELOG.md diff --git a/.yarn/patches/tus-js-client-npm-3.1.3-dc57874d23.patch b/.yarn/patches/tus-js-client-npm-3.1.3-dc57874d23.patch deleted file mode 100644 index 9bc37127da..0000000000 --- a/.yarn/patches/tus-js-client-npm-3.1.3-dc57874d23.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/lib/index.d.ts b/lib/index.d.ts -index 7a4efead6df94263db77b12c72ddaeafaeaa406c..e47e63f1159f19dd780986f7e33ffdd70bfdc371 100644 ---- a/lib/index.d.ts -+++ b/lib/index.d.ts -@@ -2,7 +2,12 @@ - - export const isSupported: boolean - export const canStoreURLs: boolean --export const defaultOptions: UploadOptions -+export const defaultOptions: UploadOptions & Required> - - // TODO: Consider using { read: () => Promise<{ done: boolean; value?: any; }>; } as type - export class Upload { -@@ -12,7 +17,7 @@ export class Upload { - options: UploadOptions - url: string | null - -- static terminate(url: string, options?: UploadOptions): Promise -+ static terminate(url: string, options: UploadOptions): Promise - start(): void - abort(shouldTerminate?: boolean): Promise - findPreviousUploads(): Promise -@@ -25,7 +30,7 @@ interface UploadOptions { - - uploadUrl?: string | null - metadata?: { [key: string]: string } -- fingerprint?: (file: File, options?: UploadOptions) => Promise -+ fingerprint?: (file: File, options: UploadOptions) => Promise - uploadSize?: number | null - - onProgress?: ((bytesSent: number, bytesTotal: number) => void) | null diff --git a/BUNDLE-README.md b/BUNDLE-README.md index a8c4479c92..478d44b29a 100644 --- a/BUNDLE-README.md +++ b/BUNDLE-README.md @@ -2,7 +2,7 @@ Hi, thanks for trying out the bundled version of the Uppy File Uploader. You can use this from a CDN -(``) +(``) or bundle it with your webapp. Note that the recommended way to use Uppy is to install it with yarn/npm and use diff --git a/CHANGELOG.md b/CHANGELOG.md index 78a170c5d9..0fbbc50d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,69 @@ Please add your entries in this format: In the current stage we aim to release a new version at least every month. +## 4.0.0-beta.9 + +Released: 2024-05-23 + +| Package | Version | Package | Version | +| ----------------- | ------------ | ----------------- | ------------ | +| @uppy/companion | 5.0.0-beta.8 | @uppy/xhr-upload | 4.0.0-beta.5 | +| @uppy/transloadit | 4.0.0-beta.6 | uppy | 4.0.0-beta.9 | + +- @uppy/companion: remove `chalk` from dependencies (Antoine du Hamel / #5178) +- @uppy/transloadit: do not cancel assembly when removing all files (Merlijn Vos / #5191) +- @uppy/xhr-upload: fix regression for lowercase HTTP methods (Antoine du Hamel / #5179) +- meta: improve changelog generator (Antoine du Hamel / #5190) + + +## 4.0.0-beta.8 + +Released: 2024-05-22 + +| Package | Version | Package | Version | +| -------------------- | ------------ | -------------------- | ------------ | +| @uppy/aws-s3 | 4.0.0-beta.4 | @uppy/status-bar | 4.0.0-beta.8 | +| @uppy/companion | 5.0.0-beta.7 | @uppy/svelte | 4.0.0-beta.4 | +| @uppy/compressor | 2.0.0-beta.8 | @uppy/tus | 4.0.0-beta.5 | +| @uppy/core | 4.0.0-beta.8 | @uppy/utils | 6.0.0-beta.7 | +| @uppy/dashboard | 4.0.0-beta.8 | @uppy/vue | 2.0.0-beta.3 | +| @uppy/image-editor | 3.0.0-beta.5 | @uppy/webcam | 4.0.0-beta.7 | +| @uppy/provider-views | 4.0.0-beta.6 | uppy | 4.0.0-beta.8 | + +- @uppy/core: resolve some (breaking) TODOs (Antoine du Hamel / #4824) +- @uppy/companion: encode `uploadId` (Mikael Finstad / #5168) +- @uppy/companion: bump `express-session` (Antoine du Hamel / #5177) +- @uppy/companion: remove dependency on `express-request-id` (Antoine du Hamel / #5176) +- @uppy/companion: bump prom to v15 (Antoine du Hamel / #5175) +- docs: fix linter (Antoine du Hamel) +- meta: remove `nodemon` from the deps (Antoine du Hamel / #5172) +- docs: update `@uppy/aws-s3` docs (Antoine du Hamel / #5093) +- meta: update more dependencies (Antoine du Hamel / #5171) +- @uppy/companion: upgrade deps (Antoine du Hamel / #5119) + + +## 4.0.0-beta.7 + +Released: 2024-05-14 + +| Package | Version | Package | Version | +| ---------------------- | ------------ | ---------------------- | ------------ | +| @uppy/companion | 5.0.0-beta.6 | @uppy/status-bar | 4.0.0-beta.7 | +| @uppy/companion-client | 4.0.0-beta.6 | @uppy/unsplash | 4.0.0-beta.6 | +| @uppy/compressor | 2.0.0-beta.7 | @uppy/url | 4.0.0-beta.6 | +| @uppy/core | 4.0.0-beta.7 | @uppy/utils | 6.0.0-beta.6 | +| @uppy/dashboard | 4.0.0-beta.7 | @uppy/webcam | 4.0.0-beta.6 | +| @uppy/dropbox | 4.0.0-beta.6 | @uppy/xhr-upload | 4.0.0-beta.4 | +| @uppy/image-editor | 3.0.0-beta.4 | uppy | 4.0.0-beta.7 | +| @uppy/screen-capture | 4.0.0-beta.5 | | | + +- @uppy/companion: switch from `node-redis` to `ioredis` (Dominik Schmidt / #4623) +- meta: Fix headings in xhr.mdx (Merlijn Vos) +- @uppy/xhr-upload: introduce hooks similar to tus (Merlijn Vos / #5094) +- @uppy/core: close->destroy, clearUploadedFiles->clear (Merlijn Vos / #5154) +- @uppy/companion-client,@uppy/dropbox,@uppy/screen-capture,@uppy/unsplash,@uppy/url,@uppy/webcam: Use `title` consistently from locales (Merlijn Vos / #5134) + + ## 4.0.0-beta.6 Released: 2024-05-08 @@ -287,6 +350,53 @@ Released: 2024-03-28 - @uppy/vue: [v4.x] remove manual types (Antoine du Hamel / #4803) - meta: prepare release workflow for beta versions (Antoine du Hamel) +## 3.25.5 + +Released: 2024-05-23 + +| Package | Version | Package | Version | +| ----------------- | ------- | ----------------- | ------- | +| @uppy/transloadit | 3.6.2 | uppy | 3.25.5 | +| @uppy/xhr-upload | 3.6.7 | | | + +- @uppy/transloadit: do not cancel assembly when removing all files (Merlijn Vos / #5191) +- @uppy/xhr-upload: fix regression for lowercase HTTP methods (Antoine du Hamel / #5179) +- meta: improve changelog generator (Antoine du Hamel / #5190) + + +## 3.25.4 + +Released: 2024-05-22 + +| Package | Version | Package | Version | +| --------------- | ------- | --------------- | ------- | +| @uppy/companion | 4.13.3 | @uppy/tus | 3.5.5 | +| @uppy/svelte | 3.1.5 | uppy | 3.25.4 | + +- @uppy/svelte: do not attempt removing plugin before it's created (Antoine du Hamel / #5186) +- docs: Update `facebook.mdx` (Evgenia Karunus) +- @uppy/tus: fix no headers passed to companion if argument is a function (netdown / #5182) +- @uppy/companion: fix google drive gsuite export large size (Milan Nakum / #5144) +- meta: Improve provider docs: Box & Zoom (Evgenia Karunus / #5166) +- meta: add MDX file to `lint-staged` list (Antoine du Hamel / #5174) +- @uppy/companion: handle ws `'error'` event (Mikael Finstad / #5167) + + +## 3.25.3 + +Released: 2024-05-14 + +| Package | Version | Package | Version | +| ------------------ | ------- | ------------------ | ------- | +| @uppy/core | 3.11.3 | uppy | 3.25.3 | +| @uppy/image-editor | 2.4.6 | | | + +- @uppy/image-editor: fix tooltips (Avneet Singh Malhotra / #5156) +- meta: Remove redundant `plugins` prop from examples (Merlijn Vos / #5145) +- @uppy/image-editor: Remove `target` option from examples and document consistently (Merlijn Vos / #5146) +- @uppy/core: make getObjectOfFilesPerState more efficient (Merlijn Vos / #5155) + + ## 3.25.2 Released: 2024-05-07 diff --git a/README.md b/README.md index b9327d499a..b9f5c776b9 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ import Tus from '@uppy/tus' const uppy = new Uppy() .use(Dashboard, { trigger: '#select-files' }) .use(RemoteSources, { companionUrl: 'https://companion.uppy.io' }) - .use(Webcam, { target: Dashboard }) - .use(ImageEditor, { target: Dashboard }) + .use(Webcam) + .use(ImageEditor) .use(Tus, { endpoint: 'https://tusd.tusdemo.net/files/' }) .on('complete', (result) => { console.log('Upload result:', result) @@ -79,7 +79,7 @@ npm install @uppy/core @uppy/dashboard @uppy/tus ``` Add CSS -[uppy.min.css](https://releases.transloadit.com/uppy/v4.0.0-beta.6/uppy.min.css), +[uppy.min.css](https://releases.transloadit.com/uppy/v4.0.0-beta.9/uppy.min.css), either to your HTML page’s `` or include in JS, if your bundler of choice supports it. @@ -94,7 +94,7 @@ object. ```html @@ -105,7 +105,7 @@ object. Uppy, Dashboard, Tus, - } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.6/uppy.min.mjs' + } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.9/uppy.min.mjs' const uppy = new Uppy() uppy.use(Dashboard, { target: '#files-drag-drop' }) @@ -309,18 +309,18 @@ Use Uppy in your project? darthf1fortriebfrederikhorsheocoijareymuhammadInam rettgerstmkabatekjukakoskiolemoignbtrice5idereal AndrwMbehnammodiBePo65bradedelmancamiloforerocommand-tab -craig-jenningsdavekissdenysdesignethanwillisfrobinsonjrichartkeil -paescujrichmeijmsandmartiuslimMartin005mskelton -mactavishzlafedogrockerjedwoodjasonboscoghasrfakhri -geertclerxeman8519luarmrraulibanezrefoSxDx -robwilson1scherromanTashowsPzocoppadmavilasomphillipalexander +craig-jenningsdavekissdenysdesignethanwillisfrobinsonjrichmeij +richartkeilpaescujmsandmartiuslimMartin005mskelton +mactavishzlafedogrockerjedwoodgeertclerxjasonbosco +ghasrfakhrirossngscherromanrobwilson1SxDxrefo +raulibanezluarmreman8519Pzocoppadmavilasomphillipalexander pmusarajpedrofsplnetopatricklindsaypascalwengerterParsaArvanehPA tajstrayersjauldsteverobamaituquigebo waptikSpazzMarticusszhsergei-zelinskysebasegovia01sdebacker samuelcolburnfortunto2GNURubrartrossngmkopinsky mhulethrshmauricioribeiromatthewhartstongemjesuelemattfik mateuscruzmasumulu28masaokmartin-brennanmarcusforsbergmarcosthejew -mperrandoonhatemarc-mabesercraigcryptic022Ozodbek1405 +mperrandoonhatemarc-mabeLucklj521cryptic022Ozodbek1405 leftdevelnil1511coreprocessnicojonestrungcva10a6tnnaveed-ahmad pleasespammelatermarton-laszlo-attilanavruzmmogzolshahimcltmnafees boudraachmiralken-kuroneuronet77mosi-khamaddy-jo @@ -338,27 +338,27 @@ Use Uppy in your project? yafkariYehudaKremerardeoisCommanderRootczjcbush06 Aarbelcfracspranceprattcmpsubvertallchrischarlybillaud Cretezychaocellvinchungcartfiskcyubryanjswift -functinoeliOcsyoldarefbautistaemuellEdgarSantiago93 +bedgerottofunctinoyoldarefbautistaemuellEdgarSantiago93 sweetrojeetissDennisKofflardhoangsvitdavilima6akizor KaminskiDaniellCantabarmrboomerdanilatdanschalowdanmichaelo -CruaieramitporttekacsDogfaloalirezahiaalepis -alexnjasmt3ahmadissaadritasharmaAdrreiadityapatadia -adamvigneaultajh-sradamdottvabannachsuperhawk610ajschmidt8 -bedgerottowbaaronQuorafindbducharmeazizkazeemba -ayhankesiciogluatsawinash-jc-allenapuyouarthurdennerAbourass -tyndriaanthony0030andychongyzandrii-bodnarsuperandrew213radarhere -kergekacsafiresharkstudioskaspermeinematykaroljveltenmellow-fellow +CruaiersercraigamitporttekacsDogfaloalirezahi +aalepisalexnjasmt3ahmadissaadritasharmaAdrrei +adityapatadiaadamvigneaultajh-sradamdottvabannachsuperhawk610 +ajschmidt8wbaaronQuorafindbducharmeazizkazeemba +ayhankesiciogluavneetmalhotraatsawinash-jc-allenapuyouarthurdenner +Abourasstyndriaanthony0030andychongyzandrii-bodnarsuperandrew213 +radarherefiresharkstudioskaspermeinematykaroljveltenmellow-fellow jmontoyaajcalonsojbelejjszobodyjorgeepcjondewoo -jonathanarbelyjsanchez034JokcychromacomaprofsmallpineIanVS -Lucklj521lucax88xlucaperretombrlouimdolphinigle +jonathanarbelyjsanchez034JokcychromacomaprofsmallpinetheJoeBiz +huydodlucax88xlucaperretombrlouimdolphinigle leomelzerleods92galli-leodvirylarowlanleaanthony hoangbitslabohkip81kyleparisielkebabkidonngkevin-west-10x -huydodHussainAlkhalifahHughbertDhiromi2424giacomocerquoneroenschg +kergekacsaHussainAlkhalifahHughbertDhiromi2424giacomocerquoneroenschg gjungbgeoffapplefordgabiganamfuadscodesdtrucsferdiusa -fgallinariGkleinerevaepexaEnricoSottileelliotdickisontheJoeBiz +fgallinariGkleinerevaepexaEnricoSottileelliotdickisoneliOcs Jmalesjessica-courseravithjanwiltsjanklimojamestiotio jcjmccleanJbithellJakubHaladejjakemcallistergaejabongJacobMGEvans -mazorussGreenJimmyintenziveNaxYoishendyweb +mazorussGreenJimmyintenziveNaxYoishendywebIanVS diff --git a/bin/companion.sh b/bin/companion.sh index 4b31af6684..dc7a3ee16d 100755 --- a/bin/companion.sh +++ b/bin/companion.sh @@ -2,7 +2,7 @@ # Load local env vars. In CI, these are injected. if [ -f .env ]; then - nodemon --watch packages/@uppy/companion/src --exec node -r dotenv/config ./packages/@uppy/companion/src/standalone/start-server.js + node --watch -r dotenv/config ./packages/@uppy/companion/src/standalone/start-server.js else env \ COMPANION_DATADIR="./output" \ @@ -13,6 +13,6 @@ else COMPANION_SECRET="development" \ COMPANION_PREAUTH_SECRET="development2" \ COMPANION_ALLOW_LOCAL_URLS="true" \ - nodemon --watch packages/@uppy/companion/src --exec node ./packages/@uppy/companion/src/standalone/start-server.js + node --watch ./packages/@uppy/companion/src/standalone/start-server.js fi diff --git a/docs/README.md b/docs/README.md index 7ae9800ddc..ee7415a35a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,4 @@ # Uppy documentation -To build the documentation, see . +See instructions for linting this documentation and seeing this documentation in +the browser in . diff --git a/docs/companion.md b/docs/companion.md index c8dfd0fcb6..7d5720aac8 100644 --- a/docs/companion.md +++ b/docs/companion.md @@ -910,8 +910,8 @@ See also ``` This would get the Companion instance running on `http://localhost:3020`. It -uses [nodemon](https://github.com/remy/nodemon) so it will automatically restart -when files are changed. +uses [`node --watch`](https://nodejs.org/api/cli.html#--watch) so it will +automatically restart when files are changed. [`http.incomingmessage`]: https://nodejs.org/api/http.html#class-httpincomingmessage diff --git a/docs/framework-integrations/react.mdx b/docs/framework-integrations/react.mdx index e04684f242..c4b0e04990 100644 --- a/docs/framework-integrations/react.mdx +++ b/docs/framework-integrations/react.mdx @@ -117,7 +117,7 @@ function Component() { // IMPORTANT: passing an initializer function to prevent Uppy from being reinstantiated on every render. const [uppy] = useState(() => new Uppy().use(Webcam)); - return ; + return ; } ``` @@ -175,7 +175,7 @@ function Component(props) { uppy.getPlugin('Webcam').setOptions({ modes: props.webcamModes }); }, [props.webcamModes]); - return ; + return ; } ``` diff --git a/docs/framework-integrations/svelte.mdx b/docs/framework-integrations/svelte.mdx index 4bb490b4c0..a0735f7cac 100644 --- a/docs/framework-integrations/svelte.mdx +++ b/docs/framework-integrations/svelte.mdx @@ -50,7 +50,7 @@ instance can be passed into components as an `uppy` prop. Due to the way Svelte handles reactivity, you can initialize Uppy the same way you would with vanilla JavaScript. -```html +```svelte -
+
``` [svelte]: https://svelte.dev diff --git a/docs/framework-integrations/vue.mdx b/docs/framework-integrations/vue.mdx index 4564e5d83b..2d348f8022 100644 --- a/docs/framework-integrations/vue.mdx +++ b/docs/framework-integrations/vue.mdx @@ -66,7 +66,7 @@ JavaScript. ``` diff --git a/docs/guides/building-plugins.md b/docs/guides/building-plugins.md index 11fe7035c1..d6b44178cf 100644 --- a/docs/guides/building-plugins.md +++ b/docs/guides/building-plugins.md @@ -33,7 +33,7 @@ The plugin constructor receives the Uppy instance in the first parameter, and any options passed to `uppy.use()` in the second parameter. ```js -import BasePlugin from '@uppy/core/lib/BasePlugin.js'; +import BasePlugin from '@uppy/core'; export default class MyPlugin extends BasePlugin { constructor(uppy, opts) { diff --git a/docs/guides/migration-guides.md b/docs/guides/migration-guides.md index ca09b5f75f..4413da8fea 100644 --- a/docs/guides/migration-guides.md +++ b/docs/guides/migration-guides.md @@ -60,16 +60,14 @@ new Uppy() companionAllowedHosts: COMPANION_ALLOWED_HOSTS, }) .use(Webcam, { - target: Dashboard, showVideoSourceDropdown: true, showRecordingLength: true, }) .use(Audio, { - target: Dashboard, showRecordingLength: true, }) - .use(ScreenCapture, { target: Dashboard }) - .use(ImageEditor, { target: Dashboard }) + .use(ScreenCapture) + .use(ImageEditor) .use(Transloadit, { service: 'https://api2.transloadit.com', async getAssemblyOptions(file) { diff --git a/docs/presets/remote-sources.mdx b/docs/presets/remote-sources.mdx index 8c7655621c..1169bf90ab 100644 --- a/docs/presets/remote-sources.mdx +++ b/docs/presets/remote-sources.mdx @@ -135,7 +135,8 @@ default: `same-origin`). #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string`, `Element`, `Function`, or `UIPlugin`, default: `Dashboard`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). [`request.credentials` value]: https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials diff --git a/docs/sources/audio.mdx b/docs/sources/audio.mdx index 0a612cfcc4..c9528d3f22 100644 --- a/docs/sources/audio.mdx +++ b/docs/sources/audio.mdx @@ -50,7 +50,7 @@ yarn add @uppy/audio import { Uppy, Dashboard, Audio } from "{{UPPY_JS_URL}}" const uppy = new Uppy() uppy.use(Dashboard, { inline: true, target: 'body' }) - uppy.use(Audio, { target: Uppy.Dashboard }) + uppy.use(Audio) `} @@ -67,9 +67,7 @@ import '@uppy/core/dist/style.min.css'; import '@uppy/dashboard/dist/style.min.css'; import '@uppy/audio/dist/style.min.css'; -new Uppy() - .use(Dashboard, { inline: true, target: 'body' }) - .use(Audio, { target: Dashboard }); +new Uppy().use(Dashboard, { inline: true, target: 'body' }).use(Audio); ``` ### API @@ -87,8 +85,9 @@ Configures the title / name shown in the UI, for instance, on Dashboard tabs #### `target` -DOM element, CSS selector, or plugin to place the audio into (`string` or -`Element`, default: `null`). +DOM element, CSS selector, or plugin to place the drag and drop area into +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `showAudioSourceDropdown` diff --git a/docs/sources/companion-plugins/box.mdx b/docs/sources/companion-plugins/box.mdx index 695a0579cd..aabde9c9ef 100644 --- a/docs/sources/companion-plugins/box.mdx +++ b/docs/sources/companion-plugins/box.mdx @@ -76,10 +76,9 @@ import Box from '@uppy/box'; import '@uppy/core/dist/style.min.css'; import '@uppy/dashboard/dist/style.min.css'; -new Uppy().use(Dashboard, { inline: true, target: '#dashboard' }).use(Box, { - target: Dashboard, - companionUrl: 'https://your-companion.com', -}); +new Uppy() + .use(Dashboard, { inline: true, target: '#dashboard' }) + .use(Box, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion @@ -89,8 +88,7 @@ You can create a Box App on the Things to note: -- Choose `Custom App` and select the `Standard OAuth 2.0 (User Authentication)` - app type. +- Choose `Custom App` and select the `User Authentication (OAuth 2.0)` app type. - You must enable full write access, or you will get [403 when downloading files](https://support.box.com/hc/en-us/community/posts/360049195613-403-error-while-file-download-API-Call) @@ -150,7 +148,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/dropbox.mdx b/docs/sources/companion-plugins/dropbox.mdx index 4ac6b712ec..b5c52dd86c 100644 --- a/docs/sources/companion-plugins/dropbox.mdx +++ b/docs/sources/companion-plugins/dropbox.mdx @@ -76,10 +76,9 @@ import Dropbox from '@uppy/dropbox'; import '@uppy/core/dist/style.min.css'; import '@uppy/dashboard/dist/style.min.css'; -new Uppy().use(Dashboard, { inline: true, target: '#dashboard' }).use(Dropbox, { - target: Dashboard, - companionUrl: 'https://your-companion.com', -}); +new Uppy() + .use(Dashboard, { inline: true, target: '#dashboard' }) + .use(Dropbox, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion @@ -149,7 +148,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/facebook.mdx b/docs/sources/companion-plugins/facebook.mdx index 40927d7c66..e0d87bf8a2 100644 --- a/docs/sources/companion-plugins/facebook.mdx +++ b/docs/sources/companion-plugins/facebook.mdx @@ -78,16 +78,13 @@ import '@uppy/dashboard/dist/style.min.css'; new Uppy() .use(Dashboard, { inline: true, target: '#dashboard' }) - .use(Facebook, { - target: Dashboard, - companionUrl: 'https://your-companion.com', - }); + .use(Facebook, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion You can create a Facebook App on the -[Facebook Developers site](https://developers.facebook.com/). +[Facebook Developers site](https://developers.facebook.com/apps). The app page has a “Redirect URIs” field. Here, add: @@ -148,7 +145,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/google-drive.mdx b/docs/sources/companion-plugins/google-drive.mdx index 0c58b86e8f..3685c7ddc9 100644 --- a/docs/sources/companion-plugins/google-drive.mdx +++ b/docs/sources/companion-plugins/google-drive.mdx @@ -78,10 +78,7 @@ import '@uppy/dashboard/dist/style.min.css'; new Uppy() .use(Dashboard, { inline: true, target: '#dashboard' }) - .use(GoogleDrive, { - target: Dashboard, - companionUrl: 'https://your-companion.com', - }); + .use(GoogleDrive, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion @@ -152,7 +149,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/instagram.mdx b/docs/sources/companion-plugins/instagram.mdx index 8a032ed615..358f184940 100644 --- a/docs/sources/companion-plugins/instagram.mdx +++ b/docs/sources/companion-plugins/instagram.mdx @@ -78,10 +78,7 @@ import '@uppy/dashboard/dist/style.min.css'; new Uppy() .use(Dashboard, { inline: true, target: '#dashboard' }) - .use(Instagram, { - target: Dashboard, - companionUrl: 'https://your-companion.com', - }); + .use(Instagram, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion @@ -142,7 +139,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/onedrive.mdx b/docs/sources/companion-plugins/onedrive.mdx index e88397f6bd..499cddb3de 100644 --- a/docs/sources/companion-plugins/onedrive.mdx +++ b/docs/sources/companion-plugins/onedrive.mdx @@ -78,10 +78,7 @@ import '@uppy/dashboard/dist/style.min.css'; new Uppy() .use(Dashboard, { inline: true, target: '#dashboard' }) - .use(OneDrive, { - target: Dashboard, - companionUrl: 'https://your-companion.com', - }); + .use(OneDrive, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion @@ -142,7 +139,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/unsplash.mdx b/docs/sources/companion-plugins/unsplash.mdx index 6e8da0d745..7bb1f59d14 100644 --- a/docs/sources/companion-plugins/unsplash.mdx +++ b/docs/sources/companion-plugins/unsplash.mdx @@ -78,10 +78,7 @@ import '@uppy/dashboard/dist/style.min.css'; new Uppy() .use(Dashboard, { inline: true, target: '#dashboard' }) - .use(Unsplash, { - target: Dashboard, - companionUrl: 'https://your-companion.com', - }); + .use(Unsplash, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion @@ -127,7 +124,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/url.mdx b/docs/sources/companion-plugins/url.mdx index 8ad4d207da..000ecebf38 100644 --- a/docs/sources/companion-plugins/url.mdx +++ b/docs/sources/companion-plugins/url.mdx @@ -83,10 +83,9 @@ import Url from '@uppy/url'; import '@uppy/core/dist/style.min.css'; import '@uppy/dashboard/dist/style.min.css'; -new Uppy().use(Dashboard, { inline: true, target: '#dashboard' }).use(Url, { - target: Dashboard, - companionUrl: 'https://your-companion.com', -}); +new Uppy() + .use(Dashboard, { inline: true, target: '#dashboard' }) + .use(Url, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion @@ -110,7 +109,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/companion-plugins/zoom.mdx b/docs/sources/companion-plugins/zoom.mdx index 141bf151b6..e30eb455bc 100644 --- a/docs/sources/companion-plugins/zoom.mdx +++ b/docs/sources/companion-plugins/zoom.mdx @@ -9,8 +9,11 @@ import UppyCdnExample from '/src/components/UppyCdnExample'; # Zoom -The `@uppy/zoom` plugin lets users import files from their -[Zoom](https://zoom.com) account. +The `@uppy/zoom` plugin lets users import cloud video recordings from their +[Zoom](https://zoom.com) account. Note that +[only licensed](https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0063923) +Zoom accounts can store their recordings in the cloud, so this functionality +will only be available to users with a paid Zoom account. :::tip @@ -21,8 +24,8 @@ The `@uppy/zoom` plugin lets users import files from their ## When should I use this? -When you want to let users import files from their [Zoom](https://zoom.com) -account. +When you want to let users import cloud video recordings from their +[Zoom](https://zoom.com) account. A [Companion](/docs/companion) instance is required for the Zoom plugin to work. Companion handles authentication with Zoom, downloads the files, and uploads @@ -76,34 +79,59 @@ import Zoom from '@uppy/zoom'; import '@uppy/core/dist/style.min.css'; import '@uppy/dashboard/dist/style.min.css'; -new Uppy().use(Dashboard, { inline: true, target: '#dashboard' }).use(Zoom, { - target: Dashboard, - companionUrl: 'https://your-companion.com', -}); +new Uppy() + .use(Dashboard, { inline: true, target: '#dashboard' }) + .use(Zoom, { companionUrl: 'https://your-companion.com' }); ``` ### Use in Companion -Configure the Zoom key and secret. With the standalone Companion server, specify -environment variables: +To sign up for API keys, go through the following steps: -```shell -export COMPANION_ZOOM_KEY="Zoom API key" -export COMPANION_ZOOM_SECRET="Zoom API secret" -``` +1. Sign up on [Zoom Marketplace](https://marketplace.zoom.us) -When using the Companion Node.js API, configure these options: +2. Go to [https://marketplace.zoom.us](https://marketplace.zoom.us). There will + be a dropdown in the header called “Develop”. From that dropdown, select + “Build app”. -```js -companion.app({ - providerOptions: { - zoom: { - key: 'Zoom API key', - secret: 'Zoom API secret', - }, - }, -}); -``` +3. In the “Basic Information” tab, Zoom shows your new “Client ID” and “Client + Secret” - copy them. + + With the standalone Companion server, specify environment variables: + + ```shell + export COMPANION_ZOOM_KEY="Zoom API key" + export COMPANION_ZOOM_SECRET="Zoom API secret" + ``` + + When using the Companion Node.js API, configure these options: + + ```js + companion.app({ + providerOptions: { + zoom: { + key: 'Zoom API key', + secret: 'Zoom API secret', + }, + }, + }); + ``` + +4. In the “Basic Information” tab, set “OAuth Redirect URL” input field to: + + ``` + https://$YOUR_COMPANION_HOST_NAME/zoom/redirect + ``` + + If you are using Transloadit hosted Companion: + + ``` + https://api2.transloadit.com/companion/zoom/redirect + ``` + +5. In the “Scopes” tab, add “cloud_recording:read:list_user_recordings” and + “user:read:user” scopes. If Zoom asks for further permissions when you + interact with your Zoom integration - add those too. ## API @@ -121,7 +149,8 @@ Title / name shown in the UI, such as Dashboard tabs (`string`, default: #### `target` DOM element, CSS selector, or plugin to place the drag and drop area into -(`string` or `Element`, default: `null`). +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `companionUrl` diff --git a/docs/sources/screen-capture.mdx b/docs/sources/screen-capture.mdx index 131ae50278..a2329f7336 100644 --- a/docs/sources/screen-capture.mdx +++ b/docs/sources/screen-capture.mdx @@ -62,7 +62,7 @@ yarn add @uppy/screen-capture import { Uppy, Dashboard, ScreenCapture } from "{{UPPY_JS_URL}}" const uppy = new Uppy() uppy.use(Dashboard, { inline: true, target: 'body' }) - uppy.use(ScreenCapture, { target: Uppy.Dashboard }) + uppy.use(ScreenCapture) `} @@ -79,9 +79,7 @@ import '@uppy/core/dist/style.min.css'; import '@uppy/dashboard/dist/style.min.css'; import '@uppy/screen-capture/dist/style.min.css'; -new Uppy() - .use(Dashboard, { inline: true, target: 'body' }) - .use(ScreenCapture, { target: Dashboard }); +new Uppy().use(Dashboard, { inline: true, target: 'body' }).use(ScreenCapture); ``` ### API @@ -99,8 +97,9 @@ Configures the title / name shown in the UI, for instance, on Dashboard tabs #### `target` -DOM element, CSS selector, or plugin to place the screen capture into (`string` -or `Element`, default: `null`). +DOM element, CSS selector, or plugin to place the drag and drop area into +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `displayMediaConstraints` diff --git a/docs/sources/webcam.mdx b/docs/sources/webcam.mdx index 8df2bf2234..08cf5e3bf4 100644 --- a/docs/sources/webcam.mdx +++ b/docs/sources/webcam.mdx @@ -51,7 +51,7 @@ yarn add @uppy/webcam import { Uppy, Dashboard, Webcam } from "{{UPPY_JS_URL}}" const uppy = new Uppy() uppy.use(Dashboard, { inline: true, target: 'body' }) - uppy.use(Webcam, { target: Uppy.Dashboard }) + uppy.use(Webcam) `} @@ -77,9 +77,7 @@ import '@uppy/core/dist/style.min.css'; import '@uppy/dashboard/dist/style.min.css'; import '@uppy/webcam/dist/style.min.css'; -new Uppy() - .use(Dashboard, { inline: true, target: 'body' }) - .use(Webcam, { target: Dashboard }); +new Uppy().use(Dashboard, { inline: true, target: 'body' }).use(Webcam); ``` ## API @@ -92,8 +90,9 @@ A unique identifier for this plugin (`string`, default: `'Webcam'`). #### `target` -DOM element, CSS selector, or plugin to place the webcam into (`string` or -`Element`, default: `null`). +DOM element, CSS selector, or plugin to place the drag and drop area into +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `countdown` diff --git a/docs/uploader/aws-s3-multipart.mdx b/docs/uploader/aws-s3-multipart.mdx index 0185e8595e..9154926f69 100644 --- a/docs/uploader/aws-s3-multipart.mdx +++ b/docs/uploader/aws-s3-multipart.mdx @@ -41,8 +41,8 @@ milliseconds on uploading. **In short** -- We recommend to set [`shouldUseMultipart`][] to enable multipart uploads only - for large files. +- We recommend the default value of [`shouldUseMultipart`][], which enable + multipart uploads only for large files. - If you prefer to have less overhead (+20% upload speed) you can use temporary S3 credentials with [`getTemporarySecurityCredentials`][]. This means users get a single token which allows them to do bucket operations for longer, @@ -166,7 +166,6 @@ import '@uppy/dashboard/dist/style.min.css'; const uppy = new Uppy() .use(Dashboard, { inline: true, target: 'body' }) .use(AwsS3, { - shouldUseMultipart: (file) => file.size > 100 * 2 ** 20, companionUrl: 'https://companion.uppy.io', }); ``` @@ -177,21 +176,11 @@ const uppy = new Uppy() #### `shouldUseMultipart(file)` -:::warning - -Until the next major version, not setting this option uses the -[legacy version of this plugin](../aws-s3/). This is a suboptimal experience for -some of your user’s uploads. It’s best for speed and stability to upload large -(100 MiB+) files with multipart and small files with regular uploads. - -::: - A boolean, or a function that returns a boolean which is called for each file that is uploaded with the corresponding `UppyFile` instance as argument. -By default, all files are uploaded as multipart. In a future version, all files -with a `file.size` ≤ 100 MiB will be uploaded in a single chunk, all files -larger than that as multipart. +By default, all files with a `file.size` ≤ 100 MiB will be uploaded in a +single chunk, all files larger than that as multipart. Here’s how to use it: @@ -254,12 +243,12 @@ disable automatic retries, and fail instantly if any chunk fails to upload. #### `getChunkSize(file)` A function that returns the minimum chunk size to use when uploading the given -file. +file as multipart. -The S3 Multipart plugin uploads files in chunks. Chunks are sent in batches to -have presigned URLs generated with [`signPart()`](#signpartfile-partdata). To -reduce the amount of requests for large files, you can choose a larger chunk -size, at the cost of having to re-upload more data if one chunk fails to upload. +For multipart uploads, chunks are sent in batches to have presigned URLs +generated with [`signPart()`](#signpartfile-partdata). To reduce the amount of +requests for large files, you can choose a larger chunk size, at the cost of +having to re-upload more data if one chunk fails to upload. S3 requires a minimum chunk size of 5MiB, and supports at most 10,000 chunks per multipart upload. If `getChunkSize()` returns a size that’s too small, Uppy will @@ -404,57 +393,6 @@ upload as query parameters.
Deprecated options -#### `prepareUploadParts(file, partData)` - -A function that generates a batch of signed URLs for the specified part numbers. - -Receives the `file` object from Uppy’s state. The `partData` argument is an -object with keys: - -- `uploadId` - The UploadID of this Multipart upload. -- `key` - The object key in the S3 bucket. -- `parts` - An array of objects with the part number and chunk - (`Array<{ number: number, chunk: blob }>`). `number` can’t be zero. - -`prepareUploadParts` should return a `Promise` with an `Object` with keys: - -- `presignedUrls` - A JavaScript object with the part numbers as keys and the - presigned URL for each part as the value. -- `headers` - **(Optional)** Custom headers to send along with every request per - part (`{ 1: { 'Content-MD5': 'hash' }}`). These are (1-based) indexed by part - number too so you can for instance send the MD5 hash validation for each part - to S3. - -An example of what the return value should look like: - -```json -{ - "presignedUrls": { - "1": "https://bucket.region.amazonaws.com/path/to/file.jpg?partNumber=1&...", - "2": "https://bucket.region.amazonaws.com/path/to/file.jpg?partNumber=2&...", - "3": "https://bucket.region.amazonaws.com/path/to/file.jpg?partNumber=3&..." - }, - "headers": { - "1": { "Content-MD5": "foo" }, - "2": { "Content-MD5": "bar" }, - "3": { "Content-MD5": "baz" } - } -} -``` - -If an error occurred, reject the `Promise` with an `Object` with the following -keys: - -```json -{ "source": { "status": 500 } } -``` - -`status` is the HTTP code and is required for determining whether to retry the -request. `prepareUploadParts` will be retried if the code is `0`, `409`, `423`, -or between `500` and `600`. - -
- #### `getTemporarySecurityCredentials(options)` :::note @@ -516,6 +454,8 @@ uppy.use(AwsS3, { }); ``` + + [`gettemporarysecuritycredentials`]: #gettemporarysecuritycredentialsoptions [`shouldusemultipart`]: #shouldusemultipartfile [companion docs]: /docs/companion diff --git a/docs/uploader/aws-s3.mdx b/docs/uploader/aws-s3.mdx deleted file mode 100644 index 5313b52d61..0000000000 --- a/docs/uploader/aws-s3.mdx +++ /dev/null @@ -1,463 +0,0 @@ ---- -sidebar_position: 3 -slug: /aws-s3 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import UppyCdnExample from '/src/components/UppyCdnExample'; - -# AWS S3 (legacy) - -The `@uppy/aws-s3` plugin can be used to upload files directly to a S3 bucket or -a S3-compatible provider, such as Google Cloud Storage or DigitalOcean Spaces. -Uploads can be signed using either [Companion][companion docs] or a custom -signing function. - -This documents the legacy version of this plugin that we plan to remove on the -next version. - -## When should I use it? - -:::tip - -Not sure which uploader is best for you? Read -“[Choosing the uploader you need](/docs/guides/choosing-uploader)”. - -::: - -:::warning - -This plugin is deprecated, you should switch to using the -[modern version of this plugin](/docs/aws-s3-multipart). - -::: - -You can use this plugin when you prefer a _client-to-storage_ over a -_client-to-server-to-storage_ (such as [Transloadit](/docs/transloadit) or -[Tus](/docs/tus)) setup. This may in some cases be preferable, for instance, to -reduce costs or the complexity of running a server and load balancer with -[Tus](/docs/tus). - -This plugin can be used with AWS S3, DigitalOcean Spaces, Google Cloud Storage, -or any S3-compatible provider. Although all S3-compatible providers are -supported, we don’t test against them, this plugin was developed against S3 so a -small risk is involved in using the others. - -`@uppy/aws-s3` is best suited for small files and/or lots of files. If you are -planning to upload mostly large files (100 MB+), consider using -[`@uppy/aws-s3-multipart`](/docs/aws-s3-multipart). - -## Install - - - - -```shell -npm install @uppy/aws-s3 -``` - - - - - -```shell -yarn add @uppy/aws-s3 -``` - - - - - - {` - import { Uppy, AwsS3 } from "{{UPPY_JS_URL}}" - new Uppy().use(AwsS3, { /* see options */ }) - `} - - - - -## Use - -A quick overview of the complete API. - -```js {10} showLineNumbers -import Uppy from '@uppy/core'; -import Dashboard from '@uppy/dashboard'; -import AwsS3 from '@uppy/aws-s3'; - -import '@uppy/core/dist/style.min.css'; -import '@uppy/dashboard/dist/style.min.css'; - -const uppy = new Uppy() - .use(Dashboard, { inline: true, target: 'body' }) - .use(AwsS3, { companionUrl: 'http://companion.uppy.io' }); -``` - -### With a AWS S3 bucket - -To use this plugin with S3 we need to setup a bucket with the right permissions -and CORS settings. - -S3 buckets do not allow public uploads for security reasons. To allow Uppy and -the browser to upload directly to a bucket, its CORS permissions need to be -configured. - -CORS permissions can be found in the -[S3 Management Console](https://console.aws.amazon.com/s3/home). Click the -bucket that will receive the uploads, then go into the `Permissions` tab and -select the `CORS configuration` button. A JSON document will be shown that -defines the CORS configuration. (AWS used to use XML but now only allow JSON). -More information about the -[S3 CORS format here](https://docs.amazonaws.cn/en_us/AmazonS3/latest/userguide/ManageCorsUsing.html). - -The configuration required for Uppy and Companion is this: - -```json -[ - { - "AllowedOrigins": ["https://my-app.com"], - "AllowedMethods": ["GET", "POST"], - "MaxAgeSeconds": 3000, - "AllowedHeaders": [ - "Authorization", - "x-amz-date", - "x-amz-content-sha256", - "content-type" - ] - }, - { - "AllowedOrigins": ["*"], - "AllowedMethods": ["GET"], - "MaxAgeSeconds": 3000 - } -] -``` - -A good practice is to use two CORS rules: one for viewing the uploaded files, -and one for uploading files. This is done above where the first object in the -array defines the rules for uploading, and the second for viewing. The example -above **makes files publicly viewable**. You can change it according to your -needs. - -If you are using an IAM policy to allow access to the S3 bucket, the policy must -have at least the `s3:PutObject` and `s3:PutObjectAcl` permissions scoped to the -bucket in question. In-depth documentation about CORS rules is available on the -[AWS documentation site](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html). - -### With a DigitalOcean Spaces bucket - -:::tip - -Checkout the -[DigitalOcean Spaces example](https://github.com/transloadit/uppy/tree/main/examples/digitalocean-spaces) -in the Uppy repository for a complete, runnable example. - -::: - -DigitalOcean Spaces is S3-compatible so you only need to change the endpoint and -bucket. Make sure you have a `key` and `secret`. If not, refer to -“[How To Create a DigitalOcean Space and API Key](https://www.digitalocean.com/community/tutorials/how-to-create-a-digitalocean-space-and-api-key)”. - -When using [Companion](/docs/companion) as standalone, you can set these as -environment variables: - -```bash -export COMPANION_AWS_KEY="xxx" -export COMPANION_AWS_SECRET="xxx" -export COMPANION_AWS_REGION="us-east-1" -export COMPANION_AWS_ENDPOINT="https://{region}.digitaloceanspaces.com" -export COMPANION_AWS_BUCKET="my-space-name" -``` - -The `{region}` string will be replaced by the contents of the -`COMPANION_AWS_REGION` environment variable. - -When using [Companion](/docs/companion) as an Express integration, configure the -`s3` options: - -```js -const options = { - s3: { - key: 'xxx', - secret: 'xxx', - bucket: 'my-space-name', - region: 'us-east-1', - endpoint: 'https://{region}.digitaloceanspaces.com', - }, -}; -``` - -### With a Google Cloud Storage bucket - -For the `@uppy/aws-s3` plugin to be able to upload to a GCS bucket, it needs the -Interoperability setting enabled. You can enable the Interoperability setting -and -[generate interoperable storage access keys](https://cloud.google.com/storage/docs/migrating#keys) -by going to [Google Cloud Storage](https://console.cloud.google.com/storage) » -Settings » Interoperability. Then set the environment variables for Companion -like this: - -```bash -export COMPANION_AWS_ENDPOINT="https://storage.googleapis.com" -export COMPANION_AWS_BUCKET="YOUR-GCS-BUCKET-NAME" -export COMPANION_AWS_KEY="GOOGxxxxxxxxx" # The Access Key -export COMPANION_AWS_SECRET="YOUR-GCS-SECRET" # The Secret -``` - -You do not need to configure the region with GCS. - -You also need to configure CORS with their HTTP API. If you haven’t done this -already, see -[Configuring CORS on a Bucket](https://cloud.google.com/storage/docs/configuring-cors#Configuring-CORS-on-a-Bucket) -in the GCS documentation, or follow the steps below to do it using Google’s API -playground. - -The JSON format consists of an array of CORS configuration objects. For -instance: - -```json -{ - "cors": [ - { - "origin": ["https://my-app.com"], - "method": ["GET", "POST"], - "maxAgeSeconds": 3000 - }, - { - "origin": ["*"], - "method": ["GET"], - "maxAgeSeconds": 3000 - } - ] -} -``` - -When using presigned `PUT` uploads, replace the `"POST"` method by `"PUT"` in -the first entry. - -If you have the [gsutil](https://cloud.google.com/storage/docs/gsutil) -command-line tool, you can apply this configuration using the -[gsutil cors](https://cloud.google.com/storage/docs/configuring-cors#configure-cors-bucket) -command. - -```bash -gsutil cors set THAT-FILE.json gs://BUCKET-NAME -``` - -Otherwise, you can manually apply it through the OAuth playground: - -1. Get a temporary API token from the - [Google OAuth2.0 playground](https://developers.google.com/oauthplayground/) -2. Select the `Cloud Storage JSON API v1` » `devstorage.full_control` scope -3. Press `Authorize APIs` and allow access -4. Click `Step 3 - Configure request to API` -5. Configure it as follows: - 1. HTTP Method: PATCH - 2. Request URI: `https://www.googleapis.com/storage/v1/b/YOUR_BUCKET_NAME` - 3. Content-Type: application/json (should be the default) - 4. Press `Enter request body` and input your CORS configuration -6. Press `Send the request`. - -### Use with your own server - -The recommended approach is to integrate `@uppy/aws-s3` with your own server. -You will need to do the following things: - -1. Setup a bucket -2. Create endpoints in your server. You can create them as edge functions (such - as AWS Lambdas), inside Next.js as an API route, or wherever your server runs - - `POST` > `/uppy/s3`: get upload parameters -3. [Setup Uppy](https://github.com/transloadit/uppy/blob/main/examples/aws-nodejs/public/index.html) - -### Use with Companion - -[Companion](/docs/companion) has S3 routes built-in for a plug-and-play -experience with Uppy. - -:::caution - -Generally it’s better for access control, observability, and scaling to -integrate `@uppy/aws-s3` with your own server. You may want to use -[Companion](/docs/companion) for creating, signing, and completing your S3 -uploads if you already need Companion for remote files (such as from Google -Drive). Otherwise it’s not worth the hosting effort. - -::: - -```js {10} showLineNumbers -import Uppy from '@uppy/core'; -import Dashboard from '@uppy/dashboard'; -import AwsS3 from '@uppy/aws-s3'; - -import '@uppy/core/dist/style.min.css'; -import '@uppy/dashboard/dist/style.min.css'; - -const uppy = new Uppy.use(Dashboard, { inline: true, target: 'body' }).use( - AwsS3, - { companionUrl: 'http://companion.uppy.io' }, -); -``` - -## Options - -The `@uppy/aws-s3` plugin has the following configurable options: - -#### `id` - -A unique identifier for this plugin (`string`, default: `'AwsS3'`). - -#### `companionUrl` - -Companion instance to use for signing S3 uploads (`string`, default: `null`). - -#### `companionHeaders` - -Custom headers that should be sent along to [Companion](/docs/companion) on -every request (`Object`, default: `{}`). - -#### `allowedMetaFields` - -Pass an array of field names to limit the metadata fields that will be added to -upload as query parameters (`Array`, default: `null`). - -- Set this to `['name']` to only send the `name` field. -- Set this to `null` (the default) to send _all_ metadata fields. -- Set this to an empty array `[]` to not send any fields. - -#### `getUploadParameters(file)` - -:::note - -When using [Companion][companion docs] to sign S3 uploads, do not define this -option. - -::: - -A function that returns upload parameters for a file (`Promise`, default: -`null`). - -Parameters should be returned as an object, or as a `Promise` that fulfills with -an object, with keys `{ method, url, fields, headers }`. - -- The `method` field is the HTTP method to be used for the upload. This should - be one of either `PUT` or `POST`, depending on the type of upload used. -- The `url` field is the URL to which the upload request will be sent. When - using a presigned PUT upload, this should be the URL to the S3 object with - signing parameters included in the query string. When using a POST upload with - a policy document, this should be the root URL of the bucket. -- The `fields` field is an object with form fields to send along with the upload - request. For presigned PUT uploads, this should be left empty. -- The `headers` field is an object with request headers to send along with the - upload request. When using a presigned PUT upload, it’s a good idea to provide - `headers['content-type']`. That will make sure that the request uses the same - content-type that was used to generate the signature. Without it, the browser - may decide on a different content-type instead, causing S3 to reject the - upload. - -#### `timeout` - -When no upload progress events have been received for this amount of -milliseconds, assume the connection has an issue and abort the upload (`number`, -default: `30_000`). - -This is passed through to [XHRUpload](/docs/xhr-upload#timeout-30-1000); see its -documentation page for details. Set to `0` to disable this check. - -#### `limit` - -Limit the amount of uploads going on at the same time (`number`, default: `5`). - -Setting this to `0` means no limit on concurrent uploads, but we recommend a -value between `5` and `20`. - -#### `getResponseData(responseText, response)` - -:::note - -This is an advanced option intended for use with _almost_ S3-compatible storage -solutions. - -::: - -Customize response handling once an upload is completed. This passes the -function through to @uppy/xhr-upload, see its -[documentation](https://uppy.io/docs/xhr-upload/#getResponseData-responseText-response) -for API details. - -This option is useful when uploading to an S3-like service that doesn’t reply -with an XML document, but with something else such as JSON. - -#### `locale: {}` - -```js -export default { - strings: { - timedOut: 'Upload stalled for %{seconds} seconds, aborting.', - }, -}; -``` - -## Frequently Asked Questions - -### How can I generate a presigned URL server-side? - -The `getUploadParameters` function can return a `Promise`, so upload parameters -can be prepared server-side. That way, no private keys to the S3 bucket need to -be shared on the client. For example, there could be a PHP server endpoint that -prepares a presigned URL for a file: - -```js -uppy.use(AwsS3, { - getUploadParameters(file) { - // Send a request to our PHP signing endpoint. - return fetch('/s3-sign.php', { - method: 'post', - // Send and receive JSON. - headers: { - accept: 'application/json', - 'content-type': 'application/json', - }, - body: JSON.stringify({ - filename: file.name, - contentType: file.type, - }), - }) - .then((response) => { - // Parse the JSON response. - return response.json(); - }) - .then((data) => { - // Return an object in the correct shape. - return { - method: data.method, - url: data.url, - fields: data.fields, - // Provide content type header required by S3 - headers: { - 'Content-Type': file.type, - }, - }; - }); - }, -}); -``` - -See either the -[aws-nodejs](https://github.com/transloadit/uppy/tree/HEAD/examples/aws-nodejs) -or [aws-php](https://github.com/transloadit/uppy/tree/HEAD/examples/aws-php) -examples in the uppy repository for a demonstration of how to implement handling -of presigned URLs on both the server-side and client-side. - -### How can I retrieve the presigned parameters of the uploaded file? - -Once the file is uploaded, it’s possible to retrieve the parameters that were -generated in `getUploadParameters(file)` via the `file.meta` field: - -```js -uppy.on('upload-success', (file, data) => { - const s3Key = file.meta['key']; // the S3 object key of the uploaded file -}); -``` - -[companion docs]: /docs/companion diff --git a/docs/uploader/xhr.mdx b/docs/uploader/xhr.mdx index 0d94ff7813..5f4a2813df 100644 --- a/docs/uploader/xhr.mdx +++ b/docs/uploader/xhr.mdx @@ -87,7 +87,7 @@ URL of the HTTP server (`string`, default: `null`). #### `method` Configures which HTTP method to use for the upload (`string`, default: -`'post'`). +`'POST'`). #### `formData` diff --git a/docs/uppy-core.mdx b/docs/uppy-core.mdx index 6abb41bf09..a74a07e2e8 100644 --- a/docs/uppy-core.mdx +++ b/docs/uppy-core.mdx @@ -764,11 +764,7 @@ Retry an upload (after an error, for example). Retry all uploads (after an error, for example). -#### `cancelAll({ reason: 'user' })` - -| Argument | Type | Description | -| -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `reason` | `string` | The reason for canceling. Plugins can use this to provide different cleanup behavior (Transloadit plugin cancels an Assembly if user clicked on the “cancel” button). Possible values are: `user` (default) - The user has pressed “cancel”; `unmount` - The Uppy instance has been closed programmatically | +#### `cancelAll()` Cancel all uploads, reset progress and remove all files. @@ -874,11 +870,7 @@ uppy.getPlugin('Dashboard').setOptions({ }); ``` -#### `close({ reason: 'user' })` - -| Argument | Type | Description | -| -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `reason` | `string` | The reason for canceling. Plugins can use this to provide different cleanup behavior (Transloadit plugin cancels an Assembly if user clicked on the “cancel” button). Possible values are: `user` (default) - The user has pressed “cancel”; `unmount` - The Uppy instance has been closed programmatically | +#### `destroy()` Uninstall all plugins and close down this Uppy instance. Also runs `uppy.cancelAll()` before uninstalling. @@ -1024,25 +1016,19 @@ Fired each time a file is removed. **Parameters** - `file` - The [Uppy file](#working-with-uppy-files) that was removed. -- `reason` - A string explaining why the file was removed. See - [#2301](https://github.com/transloadit/uppy/issues/2301#issue-628931176) for - details. Current reasons are: `removed-by-user` and `cancel-all`. **Example** ```js -uppy.on('file-removed', (file, reason) => { +uppy.on('file-removed', (file) => { console.log('Removed file', file); }); ``` ```js -uppy.on('file-removed', (file, reason) => { +uppy.on('file-removed', (file) => { removeFileFromUploadingCounterUI(file); - - if (reason === 'removed-by-user') { - sendDeleteRequestForFile(file); - } + sendDeleteRequestForFile(file); }); ``` @@ -1322,10 +1308,6 @@ Fired when “info” message should be hidden in the UI. See #### `cancel-all` -| Argument | Type | Description | -| -------- | -------- | ----------------------------------- | -| `reason` | `string` | See [uppy.cancelAll](####cancelAll) | - Fired when `cancelAll()` is called, all uploads are canceled, files removed and progress is reset. @@ -1374,9 +1356,10 @@ Checkout the [building plugins](/docs/guides/building-plugins) guide. :::note -If you don’t use any UI plugins and want to make sure Preact isn’t bundled into -your app, import `BasePlugin` like this: -`import BasePlugin from '@uppy/core/lib/BasePlugin`. +If you don’t use any UI plugins, any modern bundler should be able to tree-shake +Preact code away. If you are not using a bundler that supports tree-shaking, +it’s also possible to import `BasePlugin` like this: +`import BasePlugin from '@uppy/core/lib/BasePlugin.js`. ::: diff --git a/docs/user-interfaces/elements/image-editor.mdx b/docs/user-interfaces/elements/image-editor.mdx index 255038693e..033dd635ee 100644 --- a/docs/user-interfaces/elements/image-editor.mdx +++ b/docs/user-interfaces/elements/image-editor.mdx @@ -48,7 +48,7 @@ yarn add @uppy/core @uppy/dashboard @uppy/image-editor import { Uppy, Dashboard, ImageEditor } from "{{UPPY_JS_URL}}" const uppy = new Uppy() uppy.use(Dashboard, { target: '#uppy', inline: true }) - uppy.use(ImageEditor, { target: Uppy.Dashboard }) + uppy.use(ImageEditor) `} @@ -67,7 +67,7 @@ import '@uppy/image-editor/dist/style.min.css'; new Uppy() .use(Dashboard, { inline: true, target: '#dashboard' }) - .use(ImageEditor, { target: Dashboard }); + .use(ImageEditor); ``` ## API diff --git a/docs/user-interfaces/elements/status-bar.mdx b/docs/user-interfaces/elements/status-bar.mdx index 663414f22b..b740672feb 100644 --- a/docs/user-interfaces/elements/status-bar.mdx +++ b/docs/user-interfaces/elements/status-bar.mdx @@ -82,8 +82,9 @@ Use this if you need to add several StatusBar instances. #### `target` -DOM element, CSS selector, or plugin to mount the Status Bar into (`Element`, -`string`, `UIPlugin`, default: `'body'`). +DOM element, CSS selector, or plugin to place the drag and drop area into +(`string`, `Element`, `Function`, or `UIPlugin`, default: +[`Dashboard`](/docs/dashboard)). #### `hideAfterFinish` diff --git a/examples/aws-nodejs/public/drag.html b/examples/aws-nodejs/public/drag.html index 9843b79b02..d4d98a5a25 100644 --- a/examples/aws-nodejs/public/drag.html +++ b/examples/aws-nodejs/public/drag.html @@ -4,7 +4,7 @@ Uppy @@ -22,7 +22,7 @@
Uploaded files:
DragDrop, ProgressBar, AwsS3, - } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.6/uppy.min.mjs' + } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.9/uppy.min.mjs' // Function for displaying uploaded files const onUploadSuccess = (elForUploadedFiles) => (file, response) => { diff --git a/examples/aws-nodejs/public/index.html b/examples/aws-nodejs/public/index.html index 01381747c2..008fe5ddb0 100644 --- a/examples/aws-nodejs/public/index.html +++ b/examples/aws-nodejs/public/index.html @@ -4,7 +4,7 @@ Uppy – AWS upload example @@ -16,7 +16,7 @@

AWS upload example

Uppy, Dashboard, AwsS3, - } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.6/uppy.min.mjs' + } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.9/uppy.min.mjs' /** * This generator transforms a deep object into URL-encodable pairs * to work with `URLSearchParams` on the client and `body-parser` on the server. diff --git a/examples/aws-php/package.json b/examples/aws-php/package.json index 94752fbe4a..cd54377c6e 100644 --- a/examples/aws-php/package.json +++ b/examples/aws-php/package.json @@ -8,7 +8,7 @@ "uppy": "workspace:*" }, "devDependencies": { - "esbuild": "^0.20.1" + "esbuild": "^0.21.2" }, "private": true, "type": "module", diff --git a/examples/cdn-example/index.html b/examples/cdn-example/index.html index 2a11fc1a60..c53aa1a46c 100644 --- a/examples/cdn-example/index.html +++ b/examples/cdn-example/index.html @@ -5,7 +5,7 @@ @@ -19,7 +19,7 @@ Dashboard, Webcam, Tus, - } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.6/uppy.min.mjs' + } from 'https://releases.transloadit.com/uppy/v4.0.0-beta.9/uppy.min.mjs' const uppy = new Uppy({ debug: true, autoProceed: false }) .use(Dashboard, { trigger: '#uppyModalOpener' }) diff --git a/examples/svelte-example/.gitignore b/examples/svelte-example/.gitignore index 97888f66c6..8c39b2ae7f 100644 --- a/examples/svelte-example/.gitignore +++ b/examples/svelte-example/.gitignore @@ -1,6 +1,12 @@ /node_modules/ /uploads/ -/public/build/ .DS_Store -package-lock.json \ No newline at end of file +/build/ +/.svelte-kit +/package +.env +.env.* +!.env.example +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/examples/svelte-example/README.md b/examples/svelte-example/README.md index 2e1b7e12ed..957e96796a 100644 --- a/examples/svelte-example/README.md +++ b/examples/svelte-example/README.md @@ -13,5 +13,5 @@ corepack yarn build Then, again in the **repository root**, start this example by doing: ```sh -corepack yarn workspace @uppy-example/svelte-app start +corepack yarn workspace @uppy-example/svelte-app dev ``` diff --git a/examples/svelte-example/package.json b/examples/svelte-example/package.json index 767bfba0ad..003d7ed236 100644 --- a/examples/svelte-example/package.json +++ b/examples/svelte-example/package.json @@ -2,41 +2,36 @@ "name": "@uppy-example/svelte-app", "version": "0.0.0", "scripts": { - "build": "rollup -c", - "serve": "sirv public", - "start:client": "rollup -c -w", - "start:server": "node ./server.mjs", - "start": "npm-run-all --parallel start:client start:server", - "validate": "svelte-check" + "dev": "npm-run-all --parallel dev:frontend dev:backend", + "dev:frontend": "vite dev", + "dev:backend": "node --watch ./server.js", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { - "@rollup/plugin-commonjs": "^22.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.0", - "@rollup/plugin-typescript": "^8.0.0", - "@tsconfig/svelte": "^1.0.0", + "@sveltejs/adapter-static": "^3.0.1", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "@types/formidable": "^3", "npm-run-all": "^4.1.5", - "postcss": "^8.4.31", - "postcss-import": "^13.0.0", - "postcss-load-config": "^3.0.0", - "rollup": "^2.60.2", - "rollup-plugin-css-only": "^3.0.0", - "rollup-plugin-livereload": "^2.0.0", - "rollup-plugin-svelte": "^7.0.0", - "rollup-plugin-terser": "^7.0.0", - "svelte": ">=3.24.0", - "svelte-check": "^1.6.0", - "svelte-preprocess": "^5.0.0", - "tslib": "^2.0.0", - "typescript": "~5.4" + "svelte": "^4.2.7", + "svelte-check": "^3.6.0", + "tslib": "^2.4.1", + "typescript": "~5.4", + "vite": "^5.0.0" }, "dependencies": { "@uppy/core": "workspace:*", + "@uppy/dashboard": "workspace:*", + "@uppy/drag-drop": "workspace:*", + "@uppy/progress-bar": "workspace:*", "@uppy/svelte": "workspace:*", "@uppy/webcam": "workspace:*", "@uppy/xhr-upload": "workspace:*", - "formidable": "^2.0.1", - "sirv-cli": "^1.0.0" + "formidable": "^3.5.1" }, + "type": "module", "private": true } diff --git a/examples/svelte-example/postcss.config.js b/examples/svelte-example/postcss.config.js deleted file mode 100644 index 0483ffe0b2..0000000000 --- a/examples/svelte-example/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: [ - // eslint-disable-next-line global-require - require('postcss-import')(), - ], -} diff --git a/examples/svelte-example/public/global.css b/examples/svelte-example/public/global.css deleted file mode 100644 index 619a92f331..0000000000 --- a/examples/svelte-example/public/global.css +++ /dev/null @@ -1,68 +0,0 @@ -html, -body { - position: relative; - width: 100%; - height: 100%; -} - -body { - color: #333; - margin: 0; - padding: 8px; - box-sizing: border-box; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, - Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; -} - -a { - color: rgb(0, 100, 200); - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -a:visited { - color: rgb(0, 80, 160); -} - -label { - display: block; -} - -input, -button, -select, -textarea { - font-family: inherit; - font-size: inherit; - -webkit-padding: 0.4em 0; - padding: 0.4em; - margin: 0 0 0.5em 0; - box-sizing: border-box; - border: 1px solid #ccc; - border-radius: 2px; -} - -input:disabled { - color: #ccc; -} - -button { - color: #333; - background-color: #f4f4f4; - outline: none; -} - -button:disabled { - color: #999; -} - -button:not(:disabled):active { - background-color: #ddd; -} - -button:focus { - border-color: #666; -} diff --git a/examples/svelte-example/public/index.html b/examples/svelte-example/public/index.html deleted file mode 100644 index 2b86c92861..0000000000 --- a/examples/svelte-example/public/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - Svelte app - - - - - - - - - diff --git a/examples/svelte-example/rollup.config.js b/examples/svelte-example/rollup.config.js deleted file mode 100644 index 848c0d0e46..0000000000 --- a/examples/svelte-example/rollup.config.js +++ /dev/null @@ -1,86 +0,0 @@ -import svelte from 'rollup-plugin-svelte' -import commonjs from '@rollup/plugin-commonjs' -import resolve from '@rollup/plugin-node-resolve' -import livereload from 'rollup-plugin-livereload' -import { terser } from 'rollup-plugin-terser' -import sveltePreprocess from 'svelte-preprocess' -import typescript from '@rollup/plugin-typescript' -import css from 'rollup-plugin-css-only' - -const production = !process.env.ROLLUP_WATCH - -function serve () { - let server - - function toExit () { - if (server) server.kill(0) - } - - return { - writeBundle () { - if (server) return - // eslint-disable-next-line global-require - server = require('node:child_process').spawn('npm', ['run', 'serve', '--', '--dev'], { - stdio: ['ignore', 'inherit', 'inherit'], - shell: true, - }) - - process.on('SIGTERM', toExit) - process.on('exit', toExit) - }, - } -} - -export default { - input: 'src/main.ts', - output: { - sourcemap: true, - format: 'iife', - name: 'app', - file: 'public/build/bundle.js', - }, - plugins: [ - svelte({ - preprocess: sveltePreprocess({ - postcss: true, - }), - compilerOptions: { - // enable run-time checks when not in production - dev: !production, - }, - }), - // we'll extract any component CSS out into - // a separate file - better for performance - css({ output: 'bundle.css' }), - - // If you have external dependencies installed from - // npm, you'll most likely need these plugins. In - // some cases you'll need additional configuration - - // consult the documentation for details: - // https://github.com/rollup/plugins/tree/master/packages/commonjs - resolve({ - browser: true, - dedupe: ['svelte', '@uppy/core'], - }), - commonjs(), - typescript({ - sourceMap: !production, - inlineSources: !production, - }), - - // In dev mode, call `npm run start` once - // the bundle has been generated - !production && serve(), - - // Watch the `public` directory and refresh the - // browser on changes when not in production - !production && livereload('public'), - - // If we're building for production (npm run build - // instead of npm run dev), minify - production && terser(), - ], - watch: { - clearScreen: false, - }, -} diff --git a/examples/svelte-example/server.js b/examples/svelte-example/server.js new file mode 100755 index 0000000000..c860903354 --- /dev/null +++ b/examples/svelte-example/server.js @@ -0,0 +1,64 @@ +#!/usr/bin/env node + +/* eslint-disable no-console */ + +import http from 'node:http' +import { fileURLToPath } from 'node:url' +import { mkdir } from 'node:fs/promises' + +import formidable from 'formidable' + +const UPLOAD_DIR = new URL('./uploads/', import.meta.url) + +await mkdir(UPLOAD_DIR, { recursive: true }) + +http + .createServer((req, res) => { + const headers = { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET', + 'Access-Control-Max-Age': 2592000, // 30 days + /** add other headers as per requirement */ + } + + if (req.method === 'OPTIONS') { + res.writeHead(204, headers) + res.end() + return + } + if (req.url === '/upload' && req.method.toLowerCase() === 'post') { + // parse a file upload + const form = formidable({ + keepExtensions: true, + uploadDir: fileURLToPath(UPLOAD_DIR), + }) + + form.parse(req, (err, fields, files) => { + res.writeHead(200, headers) + if (err) { + console.log('some error', err) + res.write(JSON.stringify(err)) + } else { + for (const { + filepath, + originalFilename, + mimetype, + size, + } of files.files) { + console.log('saved file', { + filepath, + originalFilename, + mimetype, + size, + }) + } + res.write(JSON.stringify({ fields, files })) + } + res.end() + }) + } + }) + .listen(9967, () => { + console.log('server started') + }) diff --git a/examples/svelte-example/server.mjs b/examples/svelte-example/server.mjs deleted file mode 100755 index 2cfbd95566..0000000000 --- a/examples/svelte-example/server.mjs +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env node - -/* eslint-disable no-console */ - -import http from 'node:http' -import { fileURLToPath } from 'node:url' -import { mkdir } from 'node:fs/promises' - -import formidable from 'formidable' - -const UPLOAD_DIR = new URL('./uploads/', import.meta.url) - -await mkdir(UPLOAD_DIR, { recursive: true }) - -http.createServer((req, res) => { - const headers = { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET', - 'Access-Control-Max-Age': 2592000, // 30 days - /** add other headers as per requirement */ - } - - if (req.method === 'OPTIONS') { - res.writeHead(204, headers) - res.end() - return - } - if (req.url === '/upload' && req.method.toLowerCase() === 'post') { - // parse a file upload - const form = formidable({ - keepExtensions: true, - uploadDir: fileURLToPath(UPLOAD_DIR), - }) - - form.parse(req, (err, fields, files) => { - if (err) { - console.log('some error', err) - res.writeHead(200, headers) - res.write(JSON.stringify(err)) - return res.end() - } - const { files: { filepath, originalFilename, mimetype, size } } = files - console.log('saved file', { filepath, originalFilename, mimetype, size }) - res.writeHead(200, headers) - res.write(JSON.stringify({ fields, files })) - return res.end() - }) - } -}).listen(9967, () => { - console.log('server started') -}) diff --git a/examples/svelte-example/src/app.d.ts b/examples/svelte-example/src/app.d.ts new file mode 100644 index 0000000000..367926a580 --- /dev/null +++ b/examples/svelte-example/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {} diff --git a/examples/svelte-example/src/app.html b/examples/svelte-example/src/app.html new file mode 100644 index 0000000000..e39ebf1403 --- /dev/null +++ b/examples/svelte-example/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + + %sveltekit.body% + + diff --git a/examples/svelte-example/src/main.ts b/examples/svelte-example/src/main.ts deleted file mode 100644 index d6bce1ad79..0000000000 --- a/examples/svelte-example/src/main.ts +++ /dev/null @@ -1,7 +0,0 @@ -import App from './App.svelte' - -const app = new App({ - target: document.body, -}) - -export default app diff --git a/examples/svelte-example/src/routes/+layout.ts b/examples/svelte-example/src/routes/+layout.ts new file mode 100644 index 0000000000..7f52afb882 --- /dev/null +++ b/examples/svelte-example/src/routes/+layout.ts @@ -0,0 +1,6 @@ +import '@uppy/core/dist/style.min.css' +import '@uppy/dashboard/dist/style.min.css' +import '@uppy/drag-drop/dist/style.min.css' +import '@uppy/progress-bar/dist/style.min.css' + +export const ssr = false diff --git a/examples/svelte-example/src/App.svelte b/examples/svelte-example/src/routes/+page.svelte similarity index 79% rename from examples/svelte-example/src/App.svelte rename to examples/svelte-example/src/routes/+page.svelte index daf1450ee2..90c2753d04 100644 --- a/examples/svelte-example/src/App.svelte +++ b/examples/svelte-example/src/routes/+page.svelte @@ -14,7 +14,7 @@ } let uppy1 = createUppy() - let uppy2 = createUppy() + let uppy2 = createUppy() let open = false; let showInlineDashboard = true; @@ -31,7 +31,7 @@ Show Dashboard {#if showInlineDashboard} - @@ -39,23 +39,23 @@

Modal Dashboard

- open = false, plugins: ['Webcam'] - }} + }} />

Drag Drop Area

-

Progress Bar

-