Files
Folders in the schema, uploads straight to storage, and short-lived links to read them.
Files live in folders you declare in the schema, next to the tables. Each folder sets the largest file it takes, the content types it accepts and who may read, upload and delete.
import { defineSchema, fileRule, t, table } from "@shipmantis/sdk";
export default defineSchema(
{
profiles: table({ name: t.text() }),
},
{
storage: {
avatars: {
maxBytes: 2 * 1024 * 1024,
types: ["image/*"],
rules: {
read: fileRule.public(),
insert: fileRule.signedIn(),
delete: fileRule.uploader(),
},
},
},
},
);| Field | What it does |
|---|---|
maxBytes | The largest file, in bytes. Default 50 MB, at most 5 GB. |
types | The content types it accepts, like image/png or image/*. Leave it out for any type. |
rules | Who may read, insert and delete. See below. |
A folder's name is lowercase letters, digits, _ and -, starting with a letter. Push the
schema to create it.
Upload, link, list, remove
const file = await mantis.storage.upload(`avatars/${userId}.webp`, blob);
// { path, size, contentType, owner, createdAt }
const url = await mantis.storage.url(file.path);
const files = await mantis.storage.list("avatars/");
await mantis.storage.remove(file.path);- Paths start with the folder:
avatars/me.webp. They take letters, digits,.,_and-between single slashes, up to 512 characters. upload(path, body, { contentType })takes aBlob, anArrayBufferor aUint8Array. The content type comes from the blob unless you pass one. The file goes straight to storage in 16 MB parts, four at a time, and never passes through your server. A path that already holds a file is refused: remove it first, or upload under another name.url(path)returns a signed link that works for five minutes. Ask for a new one each time you show the file.list(prefix)returns up to 100 files whose path starts with the prefix, in path order, and only the ones the caller may read.
File rules
| Rule | Allows |
|---|---|
fileRule.public() | Anyone with the publishable key. |
fileRule.signedIn() | Any signed-in user. |
fileRule.uploader() | The user who uploaded the file. |
fileRule.role("admin") | Users with that role. |
fileRule.any(...), fileRule.all(...) | Any one of the rules, or all of them. |
An operation with no rule is refused for the publishable key; only the secret key may do it. The
secret key skips the rules altogether. Rules about users need auth in
the schema.
Like table rules, a file rule that lets more people in is held on main for a person's approval,
and one that lets fewer in applies at once.
Files and branches
Files belong to the project, not to a branch. Every branch reads main's files, and uploads and
removes made with a branch selected are refused, so testing on a branch can't change what users
see.