Commit graph

6 commits

Author SHA1 Message Date
Merlijn Vos
5684efa64e
Introduce @uppy/image-generator (#6056)
Closes #5378 

- Introduce `@uppy/image-generator`, a new plugin to generate images
based on a prompt via Transloadit
- until we have "golden templates" the idea is to just send
[steps](https://transloadit.com/docs/topics/templates/#overruling-templates-at-runtime)
- because we must send steps and since we must use signature
authentication for security, which is signed based on the params we
send, we can't reuse the `assemblyOptions` the consumers is already
passing to `@uppy/transloadit` (if they use that uploaders, not needed).
- Remove `SearchInput` (this component was trying to be too many things,
all with conditional boolean props, which is bad practise) in favor of
`useSearchForm` and reuse this hook in two new components `SearchView`
and `FilterInput`
- Reuse all the styles from `SearchProviderView`. This deviates from the
design in #5378. It felt too inconsistent to me to do another UI here
again. For the initial version, I think it's best to stay consistent and
then redesign with search providers taken into account too.
- Because the service is so slow, I went a bit further with the loading
state to show funny messages that rotate while loading mostly because
users will start thinking it is broken after 5 seconds while it fact we
are still loading. But open to ideas here.

This unfortunately means the integration for the consumer is not as lean
and pretty as you would hope. On the upside, it does give them complete
freedom.

```ts
.use(ImageGenerator, {
  assemblyOptions: async (prompt) => {
    const res = await fetch(`/assembly-options?prompt=${encodeURIComponent(prompt)}`)
    return res.json()
  }
})
```

on the consumer's server:

```ts
import crypto from 'node:crypto'

const utcDateString = (ms) => {
  return new Date(ms)
    .toISOString()
    .replace(/-/g, '/')
    .replace(/T/, ' ')
    .replace(/\.\d+Z$/, '+00:00')
}

// expire 1 hour from now (this must be milliseconds)
const expires = utcDateString(Date.now() + 1 * 60 * 60 * 1000)
const authKey = 'YOUR_TRANSLOADIT_KEY'
const authSecret = 'YOUR_TRANSLOADIT_SECRET'

const params = JSON.stringify({
  auth: {
    key: authKey,
    expires,
  },
  // can not contain any more steps, the only step must be /image/generate
  steps: {
    generated_image: { // can be named different
      robot: '/image/generate',
      result: true, // mandatory
      aspect_ratio: '2:3', // up to them
      model: 'flux-1.1-pro-ultra', // up to them
      prompt, // mandatory
      num_outputs: 2, // up to them
    },
  },
})
const signatureBytes = crypto.createHmac('sha384', authSecret).update(Buffer.from(params, 'utf-8'))
// The final signature needs the hash name in front, so
// the hashing algorithm can be updated in a backwards-compatible
// way when old algorithms become insecure.
const signature = `sha384:${signatureBytes.digest('hex')}`

// respond with { params, signature } JSON to the client
```


https://github.com/user-attachments/assets/9217e457-b38b-48ac-81f0-37a417309e98



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds AI image generation plugin using Transloadit, exports low-level
Transloadit APIs, and replaces SearchInput with new
FilterInput/SearchView + useSearchForm across provider views.
> 
> - **New plugin: `@uppy/image-generator`**
> - UI plugin to generate images from a prompt via Transloadit
(`src/index.tsx`, styles, locale, build configs).
> - Integrated into dev Dashboard and included in `uppy` bundle and
global styles.
> - **Provider Views refactor**
> - Remove `SearchInput`; introduce `useSearchForm`, `SearchView`, and
`FilterInput` components.
> - Update `ProviderView`, `SearchProviderView`, and `Webdav` to use new
components; export them from `@uppy/provider-views`.
> - **Transloadit updates**
> - Export `Assembly`, `AssemblyError`, and `Client` from
`@uppy/transloadit`.
>   - Minor internal change: normalize `assemblyOptions.fields`.
> - **Locales**
> - Add strings for image generation and minor additions (e.g.,
`chooseFiles`).
>   - Ensure locales build depends on `@uppy/image-generator`.
> - **Build config**
> - Turborepo: add `uppy#build:css` and hook `image-generator` into
locales build.
> - **Changesets**
> - `@uppy/image-generator` major; `@uppy/transloadit` minor;
`@uppy/locales` and `uppy` minor; `@uppy/provider-views` and
`@uppy/webdav` patch.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4b1b729069. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Prakash <qxprakash@gmail.com>
2025-12-03 11:59:52 +01:00
Mikael Finstad
1fbb95da2b
improve test scripts (#6016)
1. don't run browser tests in `headless` mode by default when running
tests individually. because when writing/running tests, i usually want
to see/debug using the browser. if one still wants headless, it's as
easy as: `yarn workspace @uppy/xyz test --browser.headless`. instead
append the `headless` mode when running all tests together - it doesn't
make sense to run all projects' tests without headless mode.
2. don't always run browser tests with `watch`: watch doesn't make sense
when running multiple projects in turbo (one project just blocks the
rest watching for changes). if one still wants to run a single test with
watch mode, it's as easy as: `yarn workspace @uppy/xyz test --watch`
3. don't cache test runs: if I run the `test` command. most of the time
I want to actually run tests (not skip them if they already ran last
time)
4. output logs when running tests. it's nice to see that the tests have
actually run (also on CI)
5. when running all tests, use concurrency=1, because the tests also
includes e2e tests, running multiple browsers in parallel really just
makes the test fail on my computer (and uses a lot of memory)

current output is not very informative:

<img width="840" height="410" alt="Screenshot 2025-10-17 at 17 09 55"
src="https://github.com/user-attachments/assets/9ca8278c-f160-478c-87e2-2ef861ba4bb1"
/>

with this PR:

<img width="672" height="495" alt="Screenshot 2025-10-17 at 17 20 49"
src="https://github.com/user-attachments/assets/1339c96b-d0c1-42e1-8fa1-d5a4a36ea42a"
/>
2025-10-17 22:07:01 +08:00
Mikael Finstad
8df48060fa
Fix turbo scripts (#5859)
[always run yarn build before
watch](2507302e29)

or else everything doesn't get built
closes https://github.com/transloadit/uppy/issues/5858
2025-07-30 18:42:48 +02:00
Merlijn Vos
0525a2c91a
Fix turbo race condition (#5839)
Closes #5822 

- `"^build"` makes sure dependencies of the package are build first.
- Make dependencies of @uppy/components actually dependencies
- Remove concurrency setting. It was too high for computers with low
RAM.
2025-07-23 10:49:11 +02:00
Merlijn Vos
7c609a56d9
Use turbo for all unit tests (#5815)
- Upgrade vitest from 1.x to 3.x.
  - Fix some tests that now became more strict and started failing
-  Add test command to all packages + needed dependencies
- Add turbo config for running tests

Another PR will completely redo the e2e test suite.
2025-07-12 13:21:35 +02:00
Merlijn Vos
271db86ad0
Use turbo for building and watching concurrently (#5808)
- Add `typecheck` command to all packages.
- Use turbo to build and watch concurrently with caches.
- Remove root `bin/` folder with last global scripts
- `bin/companion.sh` -> `@uppy/companion/start-dev` (`yarn
start:companion` still works)
- `bin/build-components.mjs` -> `@uppy/components/migrate.mjs` (`yarn
migrate:components` can be used to run it). This only needs to be ran
for new components, not changing existing ones, so that's why it's not
part of the build process.

turbo is smart enough to build dependencies within a package first
before building the package itself (e.g if wanting to build @uppy/audio,
build @uppy/utils first). Unfortunately @uppy/core is a peer dep
everywhere turbo does not take it into account, yet it must be build
first to avoid race conditions. Therefor I added a turbo.json to each
package, which you normally never need, but this is an odd case I
suppose. Other solutions ran into cyclic dep errors.

Another PR would move over the test commands to turbo too.
2025-07-10 13:21:18 +02:00