Queries
Select, insert, update and delete with a client typed from your schema.
The client
import { createClient } from "@shipmantis/sdk";
import schema from "../mantis/schema";
export const mantis = createClient({
url: process.env.MANTIS_URL!,
key: process.env.MANTIS_SECRET_KEY!,
schema,
});| Option | What it does |
|---|---|
url | https://data.shipmantis.com, written to .env.local by init. |
key | The secret key on a server, the publishable key in a browser. |
schema | Your schema. It is only used for types, so tables, columns and rows are checked. |
branch | The branch to query. Default: main. |
userToken | A function that returns the signed-in user's token, for access rules. |
mantis.from(table) gives you the table's client. Every call returns the rows it read or
changed, typed from the schema.
Select
const todos = mantis.from("todos");
const open = await todos.select({
columns: ["id", "title"],
where: { done: false, dueAt: { lt: new Date().toISOString() } },
orderBy: [{ column: "dueAt", direction: "asc" }],
limit: 20,
offset: 40,
});
// ^? { id: string; title: string }[]columnspicks the columns to return. Leave it out for all of them.orderBysorts by one or more columns,ascby default. Rows are always sorted byidlast, so pages are stable. WithoutorderBy, rows come oldest first.limitis 100 by default and at most 1000.offsetskips rows.
Where
Every key in where must hold, so the conditions are joined with AND. A plain value means
equal; an object compares:
| Operator | Means |
|---|---|
eq, ne | equal, not equal |
lt, lte, gt, gte | less than, at most, greater than, at least |
in | equal to one of a list |
await todos.select({ where: { listId: { in: [inbox, today] }, title: { ne: "" } } });null asks for an empty column: { dueAt: null } and { dueAt: { eq: null } } both mean
is null, and { dueAt: { ne: null } } means is not null. A ne with a value keeps the rows
where the column is empty.
Insert
const [todo] = await todos.insert({ title: "Ship it", listId: inbox });
await todos.insert([{ title: "One", listId: inbox }, { title: "Two", listId: inbox }]);Pass one row or an array of up to 1000. Columns that are optional or have a default can be left
out. The rows come back with id and createdAt filled.
Update and delete
await todos.update({ set: { done: true }, where: { id: todo.id } });
await todos.delete({ where: { done: true } });Both need a where, so a missing filter can't change every row by accident. To mean every row,
say so with where: {}.
Errors
A refused call throws a MantisError with the HTTP status and a list of reasons:
import { MantisError } from "@shipmantis/sdk";
try {
await todos.insert({ title: "No list" } as never);
} catch (error) {
if (error instanceof MantisError) {
console.log(error.status, error.reasons);
// 422 [ ... ]
}
}| Status | When |
|---|---|
| 401 | The user token is not valid for the project, or the schema has no auth to check it. |
| 402 | The team's plan is out of room. Delete rows or move to Pro. |
| 403 | The access rules refuse the call. |
| 422 | The query is not valid, or Postgres refused a value or a constraint. Nothing was changed. |
Every write is recorded, so anything a query does can be rewound.