Convex
@transloadit/convex é um componente do Convex que faz a Transloadit parecer nativa.
Ele assina opções de upload no servidor, verifica webhooks e armazena os resultados no Convex para
que sua interface possa ser atualizada em tempo real.
Instalar
npm i @transloadit/convex @uppy/core @uppy/transloadit
Configuração
- Registre o componente:
// convex/convex.config.ts
import { defineApp } from 'convex/server'
import transloadit from '@transloadit/convex/convex.config'
const app = defineApp()
app.use(transloadit)
export default app
- Configure a autenticação do Convex para seu aplicativo. Defina as
credenciais do servidor e o
tokenIdentifierdo único usuário autorizado a experimentar esse fluxo de upload. Obtenha esse identificador em um contexto confiável e autenticado do servidor usandoctx.auth.getUserIdentity(), e não a partir de dados fornecidos pelo navegador:
npx convex env set TRANSLOADIT_KEY 'YOUR_AUTH_KEY'
npx convex env set TRANSLOADIT_SECRET 'YOUR_AUTH_SECRET'
npx convex env set TRANSLOADIT_UPLOADER_TOKEN_IDENTIFIER 'YOUR_APPROVED_TOKEN_IDENTIFIER'
- Exponha apenas uma ação autorizada de assinatura. Os wrappers
makeTransloaditAPIdo componente não adicionam autorização no nível da aplicação. Este exemplo não aceita parâmetros do cliente e assina apenas o Job de redimensionamento abaixo, para um upload esperado, com expiração em cinco minutos:
// convex/transloadit.ts
import { Transloadit } from '@transloadit/convex'
import { ConvexError } from 'convex/values'
import { components } from './_generated/api'
import { action } from './_generated/server'
const transloadit = new Transloadit(components.transloadit)
export const createAssemblyOptions = action({
args: {},
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity()
if (identity === null) {
throw new ConvexError('Sign in to upload files.')
}
const allowedUploader = process.env.TRANSLOADIT_UPLOADER_TOKEN_IDENTIFIER
if (!allowedUploader || identity.tokenIdentifier !== allowedUploader) {
throw new ConvexError('Uploads are not enabled for this account.')
}
return transloadit.createAssemblyOptions(ctx, {
steps: {
resized: {
use: ':original',
robot: '/image/resize',
width: 800,
},
},
numExpectedUploadFiles: 1,
// Whole-second UTC avoids ambiguity in API date parsing.
expires: new Date(Date.now() + 5 * 60 * 1000).toISOString().replace(/\.\d{3}Z$/, 'Z'),
})
},
})
Para um aplicativo com vários usuários, substitua a lista de permissões de um único usuário pelas suas próprias verificações de associação e de cota de upload antes de assinar. Mantenha as Instructions permitidas no servidor. As consultas de resultados e a ingestão de webhooks precisam de seus próprios controles de acesso; consulte a documentação de backend e webhooks do componente.
Cliente Uppy
Passe o ConvexClient autenticado do seu aplicativo para esta função de fábrica.
Configure o setAuth() do cliente com seu provedor
de autenticação antes de fazer o upload. O callback chama a ação por meio desse cliente e retorna o
resultado { params, signature, fields } da ação diretamente ao Uppy:
// src/uploader.ts
import Uppy from '@uppy/core'
import Transloadit from '@uppy/transloadit'
import type { ConvexClient } from 'convex/browser'
import { api } from '../convex/_generated/api'
export function createUploader(convex: ConvexClient): Uppy {
return new Uppy({
restrictions: { maxNumberOfFiles: 1, allowedFileTypes: ['image/*'] },
}).use(Transloadit, {
waitForEncoding: true,
assemblyOptions: () => convex.action(api.transloadit.createAssemblyOptions, {}),
})
}
Use a instância do Uppy retornada com seu seletor de arquivos e, em seguida, chame
uppy.upload(). As restrições do seletor ajudam o usuário a selecionar um arquivo;
a autorização e o Job de processamento permitido são impostos pela ação do servidor. Siga o
guia do Uppy para integrações de interface.
Aplicativo de demonstração
Veja a demonstração de ponta a ponta de uma galeria de casamento em convex-demo.transload.it e o código-fonte completo no repositório do GitHub.