@golive/storage
Guarda e serve ficheiros do teu projecto — uploads dos utilizadores, imagens, PDFs — directamente do browser ou da edge, com links temporários ou URLs públicos permanentes.
Instalar
$ npm i https://golive.co.ao/sdk/golive-storage-0.1.1.tgz
Ou por URL, sem passo de build:
import { GoLiveStorage } from "https://golive.co.ao/sdk/storage.js";
Início rápido
No browser os ficheiros ficam no espaço do utilizador autenticado — passa o token do @golive/auth:
import { GoLiveStorage } from "@golive/storage";
const storage = new GoLiveStorage({
projectId: "a1b2c3d4",
apiKey,
getToken: () => auth.getIdToken(),
});
// input type="file"
const { path, url, error } = await storage.uploadFile("recibos/maio.pdf", ficheiro);
if (error) console.error(error.message);
Este SDK nunca lança — devolve sempre { …, error }. Verifica o error. (O @golive/auth é o oposto: lança.)
Configuração
| Opção | Tipo | O que faz |
|---|---|---|
projectId | string | Id do projecto GoLive. Obrigatório. |
apiKey | string | Chave pública (a mesma do @golive/auth). Obrigatória. |
getToken | função | JWT do utilizador final (sync ou async). Obrigatório no browser. |
serviceKey | string | Chave de serviço (edge/backend): acesso total, sem scope users/{uid}. Necessária para escrever em public/. Nunca no browser. |
endpoint | string | URL da API de storage. Omissão: control plane. Dev Pack: http://localhost:18321/__golive/storage. |
publicFilesBase | string | Base dos ficheiros públicos. Omissão: …/v1/public/files/{projectId}. |
upload(path, body, opts?)
Envia conteúdo para um caminho. body aceita Blob, ArrayBuffer, Uint8Array ou string. Devolve UploadResult.
await storage.upload("notas/ola.txt", "Olá mundo", { contentType: "text/plain" });
const { path, size, url, error } = await storage.upload("img/logo.png", blob, {
contentType: "image/png",
forceUrl: true, // devolve já um URL temporário
});
Limite do upload directo: 8 MB por ficheiro (MAX_DIRECT_UPLOAD_BYTES).
uploadFile(path, file)
Atalho para um File vindo de um <input type="file"> — usa o file.type como content-type.
<input type="file" onChange={async (e) => {
const f = e.target.files[0];
const { path, error } = await storage.uploadFile(`uploads/${f.name}`, f);
}} />
list(prefix?)
Lista pastas e objectos sob um prefixo. Devolve { data: StorageList | null, error }.
const { data } = await storage.list("recibos/");
data.folders; // ["recibos/2026/"]
data.objects; // [{ path, name, size, contentType, updatedAt }]
download(path)
Descarrega o conteúdo como Blob.
const { data: blob, error } = await storage.download("recibos/maio.pdf");
if (blob) window.open(URL.createObjectURL(blob));
getDownloadUrl(path, opts?)
URL temporário (~1 hora). inline: true (omissão) serve para usar em <img src>; false força descarregar.
const { url } = await storage.getDownloadUrl("img/foto.jpg");
<img src={url} />
Se um <img> falhar por o link ter expirado, pede outro com refreshDownloadUrl(path, opts?) (mesma assinatura). Para assets estáveis, usa antes ficheiros públicos.
remove(path)
const { error } = await storage.remove("recibos/maio.pdf");
usage()
Quanto espaço o projecto ocupa — útil para mostrares o consumo ao utilizador.
const { data } = await storage.usage();
data.bytes; // total em bytes
data.count; // número de ficheiros
Ficheiros públicos (public/)
Os links normais expiram. Para assets estáveis — logos, CSS, imagens de marketing — usa a pasta public/: o URL é permanente e não precisa de token.
// escrever em public/ exige serviceKey → faz isto na edge/backend const admin = new GoLiveStorage({ projectId, apiKey, serviceKey: env.GOLIVE_SERVICE_KEY }); const { publicUrl } = await admin.uploadPublic("logo.png", blob, { contentType: "image/png" }); // no browser, só precisas do URL (nenhuma chamada de rede) const url = storage.getPublicUrl("logo.png"); <img src={url} />
| Método | O que faz |
|---|---|
uploadPublic(name, body, opts?) | Envia para public/<name> e devolve publicUrl. Requer serviceKey. |
getPublicUrl(path) | URL permanente do ficheiro público. Síncrono, sem rede. |
publicPath(name) | Normaliza o caminho para public/<name>. |
Sem serviceKey, o uploadPublic falha de propósito: o ficheiro iria para o espaço privado do utilizador e o publicUrl devolveria 404.
Tipos
interface StorageObject {
path: string; name: string; size: number;
contentType: string; updatedAt?: string;
}
interface StorageList {
prefix: string; folders: string[]; objects: StorageObject[];
}
interface StorageUsage { bytes: number; count: number; }
interface UploadResult {
path: string; size?: number; url?: string;
error: GoLiveStorageError | null;
}
Erros
Nunca lança — o erro vem no campo error, como GoLiveStorageError com .code e .message.
const { path, error } = await storage.uploadFile(nome, ficheiro);
if (error) {
if (error.code === "storage_quota_exceeded") mostrar("Sem espaço no plano.");
else if (error.code === "too_large") mostrar("Ficheiro acima de 8 MB.");
else mostrar(error.message);
}
Segurança
- Nunca ponhas a
serviceKeyno browser — dá acesso a todos os ficheiros do projecto. É para edge functions e backends (injectada porgolive env). - No browser usa
getToken: cada utilizador só vê e escreve no seu espaço (users/{uid}/…). - Tudo o que puseres em
public/fica acessível a quem tiver o URL — não guardes lá nada sensível. - Valida tipo e tamanho do ficheiro no cliente antes de enviar (o limite é 8 MB por upload).
Dev Pack (local)
Com o Storage ligado no Dev Pack (golive dev init):
const storage = new GoLiveStorage({
projectId: "dev",
apiKey: "dev",
endpoint: "http://localhost:18321/__golive/storage",
getToken: () => auth.getIdToken(),
});
Os ficheiros ficam em .golive/dev/storage (não commites a pasta .golive/) e podes navegá-los no painel /__golive/, separador Storage.