diff --git a/.changeset/bumpy-cougars-open.md b/.changeset/bumpy-cougars-open.md deleted file mode 100644 index ba7f4c611..000000000 --- a/.changeset/bumpy-cougars-open.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@uppy/xhr-upload": minor -"@uppy/utils": minor ---- - -Introduce modern, minimal TaskQueue to replace RateLimitedQueue diff --git a/.changeset/curvy-feet-chew.md b/.changeset/curvy-feet-chew.md new file mode 100644 index 000000000..4cfe7f172 --- /dev/null +++ b/.changeset/curvy-feet-chew.md @@ -0,0 +1,45 @@ +--- +"@uppy/angular": patch +"@uppy/google-photos-picker": patch +"@uppy/google-drive-picker": patch +"@uppy/thumbnail-generator": patch +"@uppy/companion-client": patch +"@uppy/golden-retriever": patch +"@uppy/image-generator": patch +"@uppy/provider-views": patch +"@uppy/remote-sources": patch +"@uppy/screen-capture": patch +"@uppy/store-default": patch +"@uppy/google-drive": patch +"@uppy/image-editor": patch +"@uppy/transloadit": patch +"@uppy/components": patch +"@uppy/compressor": patch +"@uppy/status-bar": patch +"@uppy/xhr-upload": patch +"@uppy/companion": patch +"@uppy/dashboard": patch +"@uppy/drag-drop": patch +"@uppy/facebook": patch +"@uppy/onedrive": patch +"@uppy/unsplash": patch +"@uppy/dropbox": patch +"@uppy/locales": patch +"@uppy/aws-s3": patch +"@uppy/svelte": patch +"@uppy/webcam": patch +"@uppy/webdav": patch +"@uppy/audio": patch +"@uppy/react": patch +"@uppy/utils": patch +"@uppy/core": patch +"@uppy/form": patch +"@uppy/zoom": patch +"@uppy/box": patch +"@uppy/tus": patch +"@uppy/url": patch +"@uppy/vue": patch +"uppy": patch +--- + +Bump shared runtime dependencies (preact, nanoid, lodash, classnames, shallow-equal, pretty-bytes, p-queue, tus-js-client, @transloadit/types @transloadit/prettier-bytes v1, is-mobile, exifr, compressorjs, rxjs, tslib). Also includes type-only fixes in `@uppy/companion`'s `jwt.ts` and `request.ts` to track `@types/jsonwebtoken` v9 and `@types/node`. \ No newline at end of file diff --git a/.changeset/few-plants-pump.md b/.changeset/few-plants-pump.md new file mode 100644 index 000000000..a094e2988 --- /dev/null +++ b/.changeset/few-plants-pump.md @@ -0,0 +1,5 @@ +--- +"@uppy/dashboard": patch +--- + +fix "My Device" button in dashboard, it now respects the fileManagerSelectionType. diff --git a/.changeset/gold-rice-jog.md b/.changeset/gold-rice-jog.md new file mode 100644 index 000000000..71b7a8fc0 --- /dev/null +++ b/.changeset/gold-rice-jog.md @@ -0,0 +1,9 @@ +--- +"@uppy/components": major +"@uppy/companion": major +"uppy": major +"@uppy/transloadit": minor +"@uppy/locales": minor +--- + +Remove @uppy/instagram references from all the packages diff --git a/.changeset/good-chicken-brake.md b/.changeset/good-chicken-brake.md deleted file mode 100644 index 7341ac512..000000000 --- a/.changeset/good-chicken-brake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@uppy/companion": patch ---- - -Fix bug with 429 not returning JSON response with message diff --git a/.changeset/happy-timers-kick.md b/.changeset/happy-timers-kick.md new file mode 100644 index 000000000..d06fc6eb1 --- /dev/null +++ b/.changeset/happy-timers-kick.md @@ -0,0 +1,5 @@ +--- +"@uppy/aws-s3": patch +--- + +Improve type diff --git a/.changeset/lazy-berries-brake.md b/.changeset/lazy-berries-brake.md new file mode 100644 index 000000000..5aa8c52c5 --- /dev/null +++ b/.changeset/lazy-berries-brake.md @@ -0,0 +1,5 @@ +--- +"@uppy/companion-client": patch +--- + +uploadRemoteFile() now queues token request and websocket request as a single job in the request queue. diff --git a/.changeset/legal-drinks-marry.md b/.changeset/legal-drinks-marry.md new file mode 100644 index 000000000..e859660be --- /dev/null +++ b/.changeset/legal-drinks-marry.md @@ -0,0 +1,5 @@ +--- +"@uppy/transloadit": minor +--- + +Add assemblyStatus and lastAssemblyStatus to transloadit's plugin state diff --git a/.changeset/mighty-deers-sin.md b/.changeset/mighty-deers-sin.md new file mode 100644 index 000000000..71159166a --- /dev/null +++ b/.changeset/mighty-deers-sin.md @@ -0,0 +1,8 @@ +--- +"@uppy/companion-client": major +"@uppy/companion": major +--- + +Send token using websocket instead of window.opener. +Breaking in `@uppy/companion-client` because it needs newest version of Companion in order to work. +Breaking in `@uppy/companion` because `companion.socket()` now requires `companionOptions` to be passed as the second argument. diff --git a/.changeset/proud-spies-train.md b/.changeset/proud-spies-train.md new file mode 100644 index 000000000..10d332013 --- /dev/null +++ b/.changeset/proud-spies-train.md @@ -0,0 +1,5 @@ +--- +"@uppy/transloadit": patch +--- + +emit updated AssemblyState in 'transloadit:assembly-cancelled' event diff --git a/.changeset/smooth-chefs-occur.md b/.changeset/smooth-chefs-occur.md new file mode 100644 index 000000000..66a598445 --- /dev/null +++ b/.changeset/smooth-chefs-occur.md @@ -0,0 +1,5 @@ +--- +"@uppy/companion": major +--- + +Upgrade to express 5 - Companion no longer works when used as a middleware with Express 4. diff --git a/.changeset/three-cobras-lick.md b/.changeset/three-cobras-lick.md new file mode 100644 index 000000000..e601129d4 --- /dev/null +++ b/.changeset/three-cobras-lick.md @@ -0,0 +1,5 @@ +--- +"@uppy/companion": patch +--- + +Port Companion to TypeScript. Not really a breaking change but there could be some unexpected breakage. diff --git a/.env.example b/.env.example index a3bbe74b7..f8ccdd5f4 100644 --- a/.env.example +++ b/.env.example @@ -44,9 +44,6 @@ COMPANION_DROPBOX_SECRET=*** COMPANION_GOOGLE_KEY=*** COMPANION_GOOGLE_SECRET=*** -COMPANION_INSTAGRAM_KEY=*** -COMPANION_INSTAGRAM_SECRET=*** - COMPANION_FACEBOOK_KEY=*** COMPANION_FACEBOOK_SECRET=*** diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 91272bce3..b8884df1e 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -61,7 +61,7 @@ This is not needed for changing existing components. ## Companion If you’d like to work on features that the basic development version of Uppy -doesn’t support, such as Uppy integrations with Instagram/Google Drive/Facebook +doesn’t support, such as Uppy integrations with Google Drive/Facebook etc., you need to set up your `.env` file (copy the contents of `.env.example` and adjust them based on what you need to work on), and run: @@ -82,7 +82,7 @@ when files are changed. ### How the Authentication and Token mechanism works This section describes how Authentication works between Companion and Providers. -While this behaviour is the same for all Providers (Dropbox, Instagram, Google +While this behaviour is the same for all Providers (Dropbox, Google Drive, etc.), we are going to be referring to Dropbox in place of any Provider throughout this section. diff --git a/.github/workflows/bundlers.yml b/.github/workflows/bundlers.yml index 23bbf645e..3ba0c96c4 100644 --- a/.github/workflows/bundlers.yml +++ b/.github/workflows/bundlers.yml @@ -42,7 +42,7 @@ jobs: node-version: lts/* - name: Install dependencies run: - corepack yarn install + corepack yarn install --immutable env: # https://docs.cypress.io/guides/references/advanced-installation#Skipping-installation CYPRESS_INSTALL_BINARY: 0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4c8bd147..38d9cd07f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: node-version: ${{matrix.node-version}} - name: Install dependencies run: - corepack yarn install + corepack yarn install --immutable - name: Install Playwright Browsers run: corepack yarn workspace @uppy/dashboard playwright install --with-deps - name: Build @@ -85,7 +85,7 @@ jobs: node-version: lts/* - name: Install dependencies run: - corepack yarn install + corepack yarn install --immutable - run: corepack yarn run typecheck lint_js: diff --git a/.github/workflows/companion-deploy.yml b/.github/workflows/companion-deploy.yml index 603768ee3..c1de42d81 100644 --- a/.github/workflows/companion-deploy.yml +++ b/.github/workflows/companion-deploy.yml @@ -38,56 +38,49 @@ jobs: path: /tmp/companion-${{ github.sha }}.tar.gz docker: - name: DockerHub - runs-on: ubuntu-latest - env: - DOCKER_BUILDKIT: 0 - COMPOSE_DOCKER_CLI_BUILD: 0 + name: DockerHub (${{ matrix.platform }}) + strategy: + matrix: + include: + - runner: ubuntu-24.04 + platform: linux/amd64 + platform_tag: amd64 + - runner: ubuntu-24.04-arm + platform: linux/arm64 + platform_tag: arm64 + runs-on: ${{ matrix.runner }} steps: - name: Checkout sources uses: actions/checkout@v6 - - name: Docker meta - id: docker_meta - uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 - with: - images: transloadit/companion - tags: | - type=edge - type=raw,value=latest,enable=false - - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f - name: Log in to DockerHub uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: - username: ${{secrets.DOCKER_USERNAME}} - password: ${{secrets.DOCKER_PASSWORD}} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push - uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 with: push: true context: . - platforms: linux/amd64,linux/arm64 + platforms: ${{ matrix.platform }} file: Dockerfile - tags: ${{ steps.docker_meta.outputs.tags }} - labels: ${{ steps.docker_meta.outputs.labels }} + tags: transloadit/companion:edge-${{ matrix.platform_tag }} - heroku: - name: Heroku + docker-manifest: + name: DockerHub manifest + needs: docker runs-on: ubuntu-latest steps: - - name: Checkout sources - uses: actions/checkout@v6 - - name: Alter dockerfile - run: | - sed -i 's/^EXPOSE 3020$/EXPOSE $PORT/g' Dockerfile - # https://github.com/AkhileshNS/heroku-deploy/issues/188 - - name: Install Heroku CLI - run: | - curl https://cli-assets.heroku.com/install.sh | sh - - name: Deploy to heroku - uses: akhileshns/heroku-deploy@e3eb99d45a8e2ec5dca08735e089607befa4bf28 # v3.14.15 + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f + - name: Log in to DockerHub + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: - heroku_api_key: ${{secrets.HEROKU_API_KEY}} - heroku_app_name: companion-demo - heroku_email: ${{secrets.HEROKU_EMAIL}} - usedocker: true + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Publish edge manifest + run: | + docker buildx imagetools create \ + --tag transloadit/companion:edge \ + transloadit/companion:edge-amd64 \ + transloadit/companion:edge-arm64 diff --git a/.github/workflows/manual-cdn.yml b/.github/workflows/manual-cdn.yml index 2d511a965..0efbe6fa7 100644 --- a/.github/workflows/manual-cdn.yml +++ b/.github/workflows/manual-cdn.yml @@ -30,18 +30,6 @@ jobs: steps: - name: Checkout sources uses: actions/checkout@v6 - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: - echo "dir=$(corepack yarn config get cacheFolder)" >> $GITHUB_OUTPUT - - - uses: actions/cache@v5 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - name: Install Node.js uses: actions/setup-node@v6 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30075e127..58284cdc7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: - name: Create Release Pull Request or Publish id: changesets - uses: changesets/action@v1 + uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d with: version: corepack yarn run version publish: corepack yarn run release @@ -102,14 +102,14 @@ jobs: # set latest tag for default branch type=raw,value=latest,enable=true - uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f - name: Log in to DockerHub uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: username: ${{secrets.DOCKER_USERNAME}} password: ${{secrets.DOCKER_PASSWORD}} - name: Build and push - uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6.19.2 with: push: true context: . diff --git a/.yarnrc.yml b/.yarnrc.yml index d2890fb76..2057decd7 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -9,5 +9,6 @@ initScope: uppy nodeLinker: node-modules -npmPublishAccess: public +npmMinimalAgeGate: 2880 +npmPublishAccess: public diff --git a/BUNDLE-README.md b/BUNDLE-README.md index de13cd256..5e6396bd5 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 @@ -83,7 +83,7 @@ inline into the page. This, and many more configuration options can be found here: . Uppy has many more Plugins besides Xhr and the Dashboard. For example, you can -enable Webcam, Instagram, or video encoding support. Note that for some Plugins, +enable Webcam or video encoding support. Note that for some Plugins, you will need to run a server side component called: Companion. Those plugins are marked with a (c) symbol. Alternatively, you can sign up for a free Transloadit account. Transloadit runs Companion for you, tusd servers to handle diff --git a/CLAUDE.md b/CLAUDE.md index eb73dda14..4091038aa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -46,7 +46,7 @@ yarn workspace @uppy/[package-name] build - **Uppy Core** (`@uppy/core`) - Main class that manages plugins, state, and events - **Plugins** - Modular components for different functionalities: - **UI Plugins**: Dashboard, Drag & Drop, File Input, Webcam, etc. - - **Provider Plugins**: Google Drive, Dropbox, Instagram, etc. (require Companion) + - **Provider Plugins**: Google Drive, Dropbox, etc. (require Companion) - **Uploader Plugins**: Tus (resumable), XHR Upload, AWS S3, etc. - **Utility Plugins**: Golden Retriever (recovery), Thumbnail Generator, etc. diff --git a/Dockerfile b/Dockerfile index 5ce604c25..3d7cbc3ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,13 +22,12 @@ FROM node:22.18.0-alpine WORKDIR /app # copy required files from build stage. -COPY --from=build /app/packages/@uppy/companion/bin /app/bin -COPY --from=build /app/packages/@uppy/companion/lib /app/lib +COPY --from=build /app/packages/@uppy/companion/dist /app/dist COPY --from=build /app/packages/@uppy/companion/package.json /app/package.json COPY --from=build /app/packages/@uppy/companion/node_modules /app/node_modules ENV PATH "${PATH}:/app/node_modules/.bin" -CMD ["node","/app/bin/companion"] +CMD ["node","/app/dist/bin/companion.js"] # This can be overruled later EXPOSE 3020 diff --git a/README.md b/README.md index 611aafed1..2b63aff7f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ with any application. It’s fast, has a comprehensible API and lets you worry about more important problems than building a file uploader. - **Fetch** files from local disk, remote URLs, Google Drive, Dropbox, Box, - Instagram or snap and record selfies with a camera + or snap and record selfies with a camera - **Preview** and edit metadata with a nice interface - **Upload** to the final destination, optionally process/encode @@ -82,7 +82,7 @@ For the supported frameworks (except Angular) Uppy offers three ways to build us - Lightweight, modular plugin-based architecture, light on dependencies :zap: - Resumable file uploads via the open [tus](https://tus.io/) standard, so large uploads survive network hiccups -- Supports picking files from: Webcam, Dropbox, Box, Google Drive, Instagram, +- Supports picking files from: Webcam, Dropbox, Box, Google Drive, bypassing the user’s device where possible, syncing between servers directly via [@uppy/companion](https://uppy.io/docs/companion) - Works great with file encoding and processing backends, such as @@ -103,7 +103,7 @@ npm install @uppy/core @uppy/dashboard @uppy/tus ``` Add CSS -[uppy.min.css](https://releases.transloadit.com/uppy/v5.2.3/uppy.min.css), +[uppy.min.css](https://releases.transloadit.com/uppy/v5.2.4/uppy.min.css), either to your HTML page’s `` or include in JS, if your bundler of choice supports it. @@ -117,7 +117,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. ```html @@ -128,7 +128,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. Uppy, Dashboard, Tus, - } from 'https://releases.transloadit.com/uppy/v5.2.3/uppy.min.mjs' + } from 'https://releases.transloadit.com/uppy/v5.2.4/uppy.min.mjs' const uppy = new Uppy() uppy.use(Dashboard, { target: '#files-drag-drop' }) @@ -140,7 +140,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. - [Uppy](https://uppy.io/docs/uppy/) — full list of options, methods and events - [Companion](https://uppy.io/docs/companion/) — setting up and running a - Companion instance, which adds support for Instagram, Dropbox, Box, Google + Companion instance, which adds support for Dropbox, Box, Google Drive and remote URLs - [React](https://uppy.io/docs/react/) — components to integrate Uppy UI plugins with React apps @@ -153,7 +153,7 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. - [`Dashboard`](https://uppy.io/docs/dashboard/) — universal UI with previews, progress bars, metadata editor and all the cool stuff. Required for most UI - plugins like Webcam and Instagram + plugins like Webcam - Headless components ([react](https://uppy.io/docs/react/), [svelte](https://uppy.io/docs/svelte/), [vue](https://uppy.io/docs/vue/)) ### Sources @@ -166,8 +166,6 @@ CDN. In that case `Uppy` will attach itself to the global `window.Uppy` object. Google Drive - ⓒ [`Dropbox`](https://uppy.io/docs/dropbox/) — import files from Dropbox - ⓒ [`Box`](https://uppy.io/docs/box/) — import files from Box -- ⓒ [`Instagram`](https://uppy.io/docs/instagram/) — import images and videos - from Instagram - ⓒ [`Facebook`](https://uppy.io/docs/facebook/) — import images and videos from Facebook - ⓒ [`OneDrive`](https://uppy.io/docs/onedrive/) — import files from Microsoft @@ -222,7 +220,7 @@ cases, the file input leaves some to be desired: - Uppy supports editing meta information before uploading. - Uppy allows cropping images before uploading. - There’s the situation where people are using their mobile devices and want to - upload on the go, but they have their picture on Instagram, files in Dropbox + upload on the go, but they have files in Dropbox or a plain file URL from anywhere on the open web. Uppy allows to pick files from those and push it to the destination without downloading it to your mobile device first. @@ -272,7 +270,7 @@ If you want resumability with the Tus plugin, use [one of the tus server implementations](https://tus.io/implementations.html) 👌🏼 And you’ll need [`@uppy/companion`](https://uppy.io/docs/companion) if you’d -like your users to be able to pick files from Instagram, Google Drive, Dropbox +like your users to be able to pick files from Google Drive, Dropbox or via direct URLs (with more services coming). ## Contributions are welcome diff --git a/biome.json b/biome.json index 5ccb0bae6..13f580c8c 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.0.5/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.15/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -14,10 +14,11 @@ "bin/**", "e2e/**", "private/**", - "!packages/**/{dist,lib}/**", + "!packages/**/{dist,lib}", "!node_modules", "!.svelte-kit", - "!packages/@uppy/components/src/input.css" + "!packages/@uppy/components/src/input.css", + "!examples/angular/**/*.html" ] }, "formatter": { @@ -25,20 +26,11 @@ "indentStyle": "space", "formatWithErrors": true }, + "html": { + "experimentalFullSupportEnabled": true + }, "linter": { "enabled": true, - "includes": [ - "packages/**", - "examples/**", - "scripts/**", - "private/**", - "!packages/**/{dist,lib}/**", - "!node_modules", - "!.svelte-kit", - "!packages/@uppy/components/src/input.css", - "!**/*.vue", - "!**/*.svelte" - ], "rules": { "recommended": true, "suspicious": { @@ -48,22 +40,23 @@ "useExhaustiveDependencies": "error", "useHookAtTopLevel": "error", "noUnusedFunctionParameters": "off", + "noUnusedImports": "error", + "noUnusedPrivateClassMembers": "error", "noUnusedVariables": { "level": "error", "options": { "ignoreRestSiblings": true } - } + }, + "noNestedComponentDefinitions": "error", + "noReactPropAssignments": "error" }, "style": { "noNonNullAssertion": "off" }, "a11y": { - "noSvgWithoutTitle": "off" - }, - "nursery": { - "noNestedComponentDefinitions": "error", - "noReactPropAssign": "error" + "noSvgWithoutTitle": "off", + "useSemanticElements": "off" } } }, @@ -80,5 +73,36 @@ "organizeImports": "on" } } - } + }, + "overrides": [ + { + "includes": ["packages/@uppy/companion/**"], + "linter": { + "rules": { + "complexity": { + "useLiteralKeys": "off" + } + } + } + }, + { + "includes": ["**/*.vue", "**/*.svelte", "packages/@uppy/vue/**/*.ts"], + "linter": { + "rules": { + "correctness": { + "useHookAtTopLevel": "off", + "useExhaustiveDependencies": "off" + } + } + } + }, + { + "includes": ["examples/nextjs/**/*.css"], + "css": { + "parser": { + "tailwindDirectives": true + } + } + } + ] } diff --git a/examples/aws-companion/index.html b/examples/aws-companion/index.html index 0b86787b7..01eacb7a8 100644 --- a/examples/aws-companion/index.html +++ b/examples/aws-companion/index.html @@ -1,5 +1,5 @@ - + diff --git a/examples/aws-companion/package.json b/examples/aws-companion/package.json index f061bbcdb..9c02f8a2c 100644 --- a/examples/aws-companion/package.json +++ b/examples/aws-companion/package.json @@ -11,11 +11,11 @@ }, "devDependencies": { "@uppy/companion": "workspace:*", - "body-parser": "^1.20.4", + "body-parser": "^2.2.2", "cookie-parser": "^1.4.7", "cors": "^2.8.5", - "dotenv": "^16.0.1", - "express": "^4.22.0", + "dotenv": "^17.4.2", + "express": "^5.2.1", "express-session": "^1.17.3", "npm-run-all": "^4.1.5", "vite": "^7.1.11" diff --git a/examples/aws-companion/server.cjs b/examples/aws-companion/server.cjs index a0edb6b16..bcbc1e025 100644 --- a/examples/aws-companion/server.cjs +++ b/examples/aws-companion/server.cjs @@ -66,4 +66,4 @@ const server = app.listen(3020, () => { console.log('listening on port 3020') }) -companion.socket(server) +companion.socket(server, options) diff --git a/examples/aws-nodejs/package.json b/examples/aws-nodejs/package.json index cfcbde2a1..bdc013ed0 100644 --- a/examples/aws-nodejs/package.json +++ b/examples/aws-nodejs/package.json @@ -15,6 +15,6 @@ "@aws-sdk/s3-request-presigner": "^3.338.0", "body-parser": "^1.20.4", "dotenv": "^16.0.0", - "express": "^4.22.0" + "express": "^5.2.1" } } diff --git a/examples/aws-nodejs/public/index.html b/examples/aws-nodejs/public/index.html index 1173b0c2c..2ff0ec921 100644 --- a/examples/aws-nodejs/public/index.html +++ b/examples/aws-nodejs/public/index.html @@ -1,5 +1,5 @@ - + Uppy – AWS S3 upload example diff --git a/examples/aws-php/index.html b/examples/aws-php/index.html index d5728c3da..b6e5b196b 100644 --- a/examples/aws-php/index.html +++ b/examples/aws-php/index.html @@ -1,5 +1,5 @@ - + diff --git a/examples/cdn/index.html b/examples/cdn/index.html index 5f66f2087..6a50ef3ba 100644 --- a/examples/cdn/index.html +++ b/examples/cdn/index.html @@ -11,14 +11,14 @@ - +
- + - +
diff --git a/examples/sveltekit/test/index.test.ts b/examples/sveltekit/test/index.test.ts index 3c33fd04b..b2c019428 100644 --- a/examples/sveltekit/test/index.test.ts +++ b/examples/sveltekit/test/index.test.ts @@ -1,16 +1,26 @@ -import { userEvent } from '@vitest/browser/context' -import { describe, expect, test } from 'vitest' +import { setupWorker } from 'msw/browser' +import { afterAll, beforeAll, describe, expect, test } from 'vitest' +import { userEvent } from 'vitest/browser' import { render } from 'vitest-browser-svelte' +import { tusHandlers } from '../../shared/tusHandlers.js' import PropsReactivity from '../src/components/test/props-reactivity.svelte' import App from '../src/routes/+page.svelte' +const worker = setupWorker(...tusHandlers) +beforeAll(async () => { + await worker.start({ onUnhandledRequest: 'error' }) +}) +afterAll(() => { + worker.stop() +}) + const createMockFile = (name: string, type: string, size: number = 1024) => { return new File(['test content'], name, { type }) } describe('App', () => { test('renders all main sections and upload button is initially disabled', async () => { - const screen = render(App) + const screen = await render(App) await expect.element(screen.getByText('With list')).toBeInTheDocument() await expect.element(screen.getByText('With grid')).toBeInTheDocument() @@ -24,7 +34,7 @@ describe('App', () => { }) test('can add and remove files and upload', async () => { - const screen = render(App) + const screen = await render(App) const fileInput = document.getElementById( 'uppy-dropzone-file-input-uppy', @@ -50,7 +60,7 @@ describe('App', () => { describe('ScreenCapture Component', () => { test('renders with title, control buttons, and close functionality works', async () => { - const screen = render(App) + const screen = await render(App) await screen .getByRole('button', { name: 'Screen Capture', exact: true }) @@ -83,7 +93,7 @@ describe('ScreenCapture Component', () => { describe('Webcam Component', () => { test('renders with title, control buttons, and close functionality works', async () => { - const screen = render(App) + const screen = await render(App) await screen.getByRole('button', { name: 'Webcam', exact: true }).click() @@ -114,7 +124,7 @@ describe('Webcam Component', () => { describe('RemoteSource Component', () => { test('renders login button and login interaction works', async () => { - const screen = render(App) + const screen = await render(App) await screen.getByRole('button', { name: 'Dropbox', exact: true }).click() @@ -122,12 +132,11 @@ describe('RemoteSource Component', () => { await expect.element(loginButton).toBeInTheDocument() await loginButton.click() - await expect.element(loginButton).toBeInTheDocument() }) }) test('Dashboard reacts to prop changes', async () => { - const screen = render(PropsReactivity) + const screen = await render(PropsReactivity) const toggleButton = screen.getByText('Toggle dashboard') const dashboard = screen.container.querySelector('.uppy-Dashboard') @@ -138,7 +147,7 @@ test('Dashboard reacts to prop changes', async () => { }) test('StatusBar reacts to prop changes', async () => { - const screen = render(PropsReactivity) + const screen = await render(PropsReactivity) const toggleButton = screen.getByText('Toggle statusbar') expect( diff --git a/examples/sveltekit/vitest.config.ts b/examples/sveltekit/vitest.config.ts index 924d3f7db..5a22254af 100644 --- a/examples/sveltekit/vitest.config.ts +++ b/examples/sveltekit/vitest.config.ts @@ -1,5 +1,6 @@ import { sveltekit } from '@sveltejs/kit/vite' import tailwindcss from '@tailwindcss/vite' +import { playwright } from '@vitest/browser-playwright' import { defineConfig } from 'vite' export default defineConfig({ @@ -7,7 +8,7 @@ export default defineConfig({ test: { browser: { enabled: true, - provider: 'playwright', + provider: playwright(), instances: [{ browser: 'chromium' }], }, }, diff --git a/examples/transloadit/index.html b/examples/transloadit/index.html index a3919ae1f..a9e0b9c1f 100644 --- a/examples/transloadit/index.html +++ b/examples/transloadit/index.html @@ -1,5 +1,5 @@ - + @@ -140,7 +140,7 @@ This API is a one-shot upload UI using a modal overlay. Call the function and receive a listen to an event with upload results ✌️

- +

uppy.upload()

An <input type=file> backed by uppy.upload():

diff --git a/examples/transloadit/main.js b/examples/transloadit/main.js index 7853376a3..88720ac57 100644 --- a/examples/transloadit/main.js +++ b/examples/transloadit/main.js @@ -50,9 +50,11 @@ const formUppy = new Uppy({ }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -100,9 +102,11 @@ const formUppyWithDashboard = new Uppy({ }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -129,9 +133,11 @@ const dashboard = new Uppy({ .use(ImageEditor, { target: Dashboard }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -151,9 +157,11 @@ const dashboardModal = new Uppy({ .use(ImageEditor, { target: Dashboard }) .use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) @@ -182,9 +190,11 @@ const uppyWithoutUI = new Uppy({ }, }).use(Transloadit, { waitForEncoding: true, - params: { - auth: { key: TRANSLOADIT_KEY }, - template_id: TEMPLATE_ID, + assemblyOptions: { + params: { + auth: { key: TRANSLOADIT_KEY }, + template_id: TEMPLATE_ID, + }, }, }) diff --git a/examples/transloadit/package.json b/examples/transloadit/package.json index 6072b43ab..bb08b521e 100644 --- a/examples/transloadit/package.json +++ b/examples/transloadit/package.json @@ -15,7 +15,7 @@ "@uppy/remote-sources": "workspace:*", "@uppy/transloadit": "workspace:*", "@uppy/webcam": "workspace:*", - "express": "^4.22.0", + "express": "^5.2.1", "he": "^1.2.0" }, "private": true, diff --git a/examples/transloadit/server.js b/examples/transloadit/server.js index 765301bd5..c71994b0e 100755 --- a/examples/transloadit/server.js +++ b/examples/transloadit/server.js @@ -36,7 +36,7 @@ function Footer() { } function FormFields(fields) { - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function Field([name, value]) { if (name === 'transloadit') return '' let isValueJSON = false @@ -76,7 +76,7 @@ function FormFields(fields) { } function UploadsList(uploads) { - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function Upload(upload) { return `
  • ${e(upload.name)}
  • ` } @@ -89,12 +89,12 @@ function UploadsList(uploads) { } function ResultsList(results) { - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function Result(result) { return `
  • ${e(result.name)} View
  • ` } - // biome-ignore lint/nursery/noNestedComponentDefinitions: not a react component + // biome-ignore lint/correctness/noNestedComponentDefinitions: not a react component function ResultsSection(stepName) { return `

    ${e(stepName)}

    diff --git a/examples/vue/package.json b/examples/vue/package.json index a0f42e3db..4d2c046b1 100644 --- a/examples/vue/package.json +++ b/examples/vue/package.json @@ -22,11 +22,13 @@ "devDependencies": { "@tailwindcss/vite": "^4.1.11", "@vitejs/plugin-vue": "^6.0.1", - "@vitest/browser": "^3.2.4", - "playwright": "1.57.0", + "@vitest/browser": "^4.1.6", + "@vitest/browser-playwright": "^4.1.6", + "msw": "^2.10.4", + "playwright": "1.60.0", "tailwindcss": "^4.0.0", "vite": "^7.1.11", - "vitest": "^3.2.4", - "vitest-browser-vue": "^1.0.0" + "vitest": "^4.1.6", + "vitest-browser-vue": "^2.1.0" } } diff --git a/examples/vue/src/Dropzone.vue b/examples/vue/src/Dropzone.vue index c36d0a9a9..4bb75fd80 100644 --- a/examples/vue/src/Dropzone.vue +++ b/examples/vue/src/Dropzone.vue @@ -7,7 +7,7 @@ >
    - - - -
    +
    - - - - -
    - - - -
    - - - - - -