Armazenamento e Arquivos
Visão Geral
Seção intitulada “Visão Geral”O módulo client.storage fornece métodos para gerenciamento de arquivos — envio, download, listagem e exclusão. Funciona tanto com disco local quanto com backends de armazenamento compatíveis com S3, dependendo da configuração do seu servidor.
Todos os métodos de armazenamento usam o transporte compartilhado, então os tokens de autenticação são injetados automaticamente.
Enviar um Arquivo
Seção intitulada “Enviar um Arquivo”Use putObject() para enviar um arquivo. Aceita um objeto File ou Blob junto com uma chave de armazenamento e metadados opcionais:
const result = await client.storage.putObject({ file: fileObject, // File or Blob key: "products/images/camera.jpg", // Storage path (optional) bucket: "uploads", // Bucket name (optional) public: false, // Store public (permanent token-less URL) — optional, default false metadata: { // Custom metadata (optional) description: "Product photo", uploadedBy: "user-123" }});
// result: { key: string; bucket: string; storageUrl: string }Um arquivo acima de 8 MiB é enviado pelo
endpoint retomável (TUS) do servidor, 8 MiB por requisição, em vez de como uma única requisição multipart que o servidor
processa por inteiro — de modo que um upload grande custa ao servidor um chunk de memória, não três
a cinco vezes o arquivo. Um chunk que falha no caminho é reenviado de onde
o servidor parou. O resultado, o objeto armazenado e as verificações do servidor são
os mesmos de qualquer forma. Quando o endpoint retomável não consegue receber o arquivo (um servidor
mais antigo, ou várias instâncias que não compartilham uploads), ele vai como um único
POST /api/storage/upload, e o mesmo vale para todo arquivo seguinte desse cliente. Veja
Uploads retomáveis (TUS).
A Partir de um Campo de Arquivo
Seção intitulada “A Partir de um Campo de Arquivo”const input = document.querySelector<HTMLInputElement>("#file-input");const file = input?.files?.[0];
if (file) { const result = await client.storage.putObject({ file, key: `avatars/${userId}/${file.name}` }); console.log("Uploaded to:", result.key);}Obter uma URL Assinada
Seção intitulada “Obter uma URL Assinada”Recupere uma URL de download e os metadados de um arquivo armazenado:
const { url, metadata, fileNotFound } = await client.storage.getSignedUrl( "products/images/camera.jpg");
if (url) { console.log("Download URL:", url); console.log("Content type:", metadata?.contentType);} else { console.log("File not found");}Com um bucket específico:
const { url } = await client.storage.getSignedUrl( "camera.jpg", "product-images" // bucket);O SDK armazena em cache as URLs assinadas para evitar chamadas redundantes ao servidor, até que o
token de download de cada uma expire. As consultas feitas juntas — uma página de pré-visualizações
chamando getSignedUrl() no mesmo tick — vão ao servidor como um único
POST /api/storage/metadata por 100 arquivos, que o limitador de taxa conta como um
décimo das requisições que ele substitui; um arquivo que um chamador não pode ler falha
apenas aquela chamada. O cache pertence à credencial que o pediu: quando
o token de acesso muda — um logout, outro usuário entrando, uma renovação — ele
recomeça do zero, de modo que um usuário nunca recebe uma URL emitida para outro.
URLs privadas vs. públicas
Seção intitulada “URLs privadas vs. públicas”- Arquivos privados recebem uma URL com um token de download de curta duração e restrito ao caminho (
?token=…, 5 minutos a menos que o servidor definaSTORAGE_DOWNLOAD_TOKEN_TTL, que a 0.23 não lê) — nunca seu token de acesso. Como ele expira, não persista uma URL privada; armazene o caminho do arquivo e chamegetSignedUrl()novamente ao renderizá-lo. - Arquivos públicos (armazenados sob o prefixo
public/— definastorage: { public: true }na propriedade, ou passepublic: trueparaputObject) recebem uma URL estável, sem token, permanente e cacheável por CDN, sem ida e volta ao servidor. São seguros para armazenar em um banco de dados e vincular diretamente.
Arquivos dentro de texto
Seção intitulada “Arquivos dentro de texto”Um texto que incorpora um arquivo — as imagens em um campo markdown — também
não pode conter uma URL privada, então ele contém uma referência de
storage: rebase-storage:posts/cover.png, com ?storageId=media quando o
arquivo está em uma fonte nomeada. É isso que o editor markdown do painel de
administração grava para uma imagem enviada. Troque as referências por URLs
ao renderizar o texto:
import { resolveStorageReferences } from "@rebasepro/client";
const post = await client.data.collection("posts").findById("post-1");const body = await resolveStorageReferences(String(post?.body ?? ""), client);// `body` is the same markdown, each reference replaced by a fresh URL.Cada objeto é assinado uma vez por chamada, a partir de sua própria fonte, então
uma imagem privada continua funcionando por mais tempo que tenha passado desde
o upload. Uma referência que nomeia um objeto que não existe mais é deixada
como está. storageReference(key, storageId?) constrói uma, para texto que
você mesmo escreve.
O texto salvo antes de as referências existirem guarda a própria URL de download de um arquivo privado,
…/storage/file/posts/cover.png?token=…, cujo token expirou minutos
depois de ser escrito. resolveStorageReferences renova essas também: o token
ainda nomeia o objeto, então a URL é substituída por uma nova. Para armazenar
referências em vez disso, reescreva o texto uma vez com
storageReferencesForDownloadUrls(text), que deixa todas as outras URLs
como estão.
Baixar um Arquivo
Seção intitulada “Baixar um Arquivo”Recupere um arquivo como um objeto File:
const file = await client.storage.getObject("products/images/camera.jpg");
if (file) { console.log("File name:", file.name); console.log("File type:", file.type); console.log("File size:", file.size);
// Create a download link const url = URL.createObjectURL(file); window.open(url);} else { console.log("File not found");}Com um bucket específico:
const file = await client.storage.getObject("camera.jpg", "product-images");Excluir um Arquivo
Seção intitulada “Excluir um Arquivo”await client.storage.deleteObject("products/images/camera.jpg");
// With bucketawait client.storage.deleteObject("camera.jpg", "product-images");Excluir um arquivo inexistente não lança um erro.
Listar Arquivos
Seção intitulada “Listar Arquivos”Liste arquivos por prefixo, com paginação opcional:
const result = await client.storage.listObjects("products/images/", { bucket: "uploads", maxResults: 50, pageToken: undefined // for pagination});
for (const item of result.items) { console.log(item.fullPath, item.name, item.size, item.updated, item.contentType);}
// Paginateif (result.nextPageToken) { const nextPage = await client.storage.listObjects("products/images/", { pageToken: result.nextPageToken });}Cada item carrega seu size em bytes e updated (um
timestamp ISO 8601) no armazenamento local, S3 e GCS, e seu contentType no armazenamento local
e no GCS — o suficiente para mostrar uma pasta sem um getSignedUrl() por arquivo. Uma
listagem do S3 não tem content type; as pastas (result.prefixes) não trazem nenhum dos
três.
Formatos de Chave de Armazenamento
Seção intitulada “Formatos de Chave de Armazenamento”O SDK lida de forma transparente com os prefixos das chaves de armazenamento. Você pode passar chaves com ou sem o prefixo de protocolo:
// All equivalent — the SDK strips the prefix internallyawait client.storage.getSignedUrl("local://products/image.jpg");await client.storage.getSignedUrl("s3://products/image.jpg");await client.storage.getSignedUrl("products/image.jpg");Referência da API
Seção intitulada “Referência da API”| Método | Descrição | Retorna |
|---|---|---|
putObject({ file, key?, bucket?, metadata? }) |
Enviar um arquivo | UploadFileResult |
getSignedUrl(key, bucket?) |
Obter URL de download + metadados | DownloadConfig |
getObject(key, bucket?) |
Baixar como objeto File |
File | null |
deleteObject(key, bucket?) |
Excluir um arquivo | void |
listObjects(prefix, options?) |
Listar arquivos por prefixo | StorageListResult |
Próximos Passos
Seção intitulada “Próximos Passos”- Configuração de Armazenamento — Configurar S3 ou armazenamento local no servidor
- Consultar Dados — Operações CRUD e construtor de consultas
- Autenticação — Login e gerenciamento de sessões