Convex
@transloadit/convex es un componente de Convex que hace que Transloadit se sienta nativo. Firma las opciones de subida
en el servidor, verifica webhooks y almacena los resultados en Convex para que tu interfaz pueda actualizarse en
tiempo real.
Instala
npm i @transloadit/convex @uppy/core @uppy/transloadit
Configuración
- Registra el 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
- Configura la autenticación de Convex para tu aplicación.
Establece las credenciales del servidor y el
tokenIdentifierdel único usuario que tiene permitido probar este flujo de subida. Recupera ese identificador desde un contexto de servidor autenticado y de confianza mediantectx.auth.getUserIdentity(), no a partir de datos introducidos en el 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'
- Expón solo una acción de firma autorizada. Los wrappers
makeTransloaditAPIdel componente no incorporan autorización a nivel de aplicación. Este ejemplo no acepta parámetros del cliente y firma únicamente el Job de redimensionamiento que se muestra a continuación, para una única subida esperada y con un plazo de expiración de 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 una aplicación multiusuario, reemplaza la lista de acceso para un único usuario por tus propias comprobaciones de pertenencia y de cupo de subidas antes de firmar. Mantén las Instructions permitidas en el servidor. Las consultas de resultados y la recepción de webhooks necesitan sus propios controles de acceso; consulta la documentación del componente sobre backend y webhooks.
Cliente de Uppy
Pasa el ConvexClient autenticado de tu aplicación a esta función de fábrica.
Configura el setAuth() del cliente con tu
proveedor de autenticación antes de subir archivos. El callback llama a la acción a través de ese
cliente y devuelve su resultado { params, signature, fields } directamente a 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, {}),
})
}
Usa la instancia de Uppy devuelta con tu selector de archivos y luego llama a
uppy.upload(). Las restricciones del selector ayudan al usuario a seleccionar un
archivo; la acción del servidor aplica los controles de autorización y limita el procesamiento al
Job permitido. Sigue la guía de Uppy para integrar la interfaz de usuario.
Aplicación de demostración
Consulta la demostración integral de una galería de bodas en convex-demo.transload.it y el código fuente completo en el repositorio de GitHub.