@kroombase/client
v1.0.0
Published
KroomBase client for JavaScript and TypeScript — typed access to your hosted PostgreSQL backend over REST.
Downloads
186
Maintainers
Readme
@kroombase/client
Typed JavaScript and TypeScript client for KroomBase — a hosted PostgreSQL backend. It talks to the REST API, so anything that can make an HTTP request can use the same backend; this package is the ergonomic path for JS/TS.
Install
npm install @kroombase/clientQuick start
import { KroomBase } from "@kroombase/client";
const db = new KroomBase({ apiKey: "kb_your_api_key" });
const rows = await db.from("orders").select(["id", "total"]).where("status", "=", "paid").limit(10);
const [created] = await db.insert("orders", { customer_id: 1, total: 42 });
await db.update("orders", created.id, { status: "shipped" });
await db.delete("orders", created.id);Configuration
new KroomBase({
apiKey: "kb_...", // data access — no raw SQL
// token: "eyJ...", // session token — also enables sql()
url: "https://kroombase.kroombox.com", // optional, this is the default
fetch: customFetch, // optional, e.g. for tests or a proxy
timeoutMs: 30000, // optional, 0 disables the timeout
});One of apiKey / token is required. The constructor throws if neither is given, rather than
failing later with a 401.
Methods
| Method | Needs | Returns |
| --- | --- | --- |
| listTables() | apiKey | table names |
| from(table).select(cols?) | apiKey | rows; chainable with .where(), .order(), .limit(), .offset() |
| insert(table, data) | apiKey | the inserted row(s) |
| update(table, id, data) | apiKey | the updated row; throws if nothing matched |
| delete(table, id) | apiKey | { message } |
| sql(projectId, query) | token | one entry per statement, each with rows and rowCount |
| createBucket(name) | token | the new bucket |
| listBuckets() | token | your buckets |
| uploadFile(bucketId, path, file) | token | the stored object |
| listFiles(bucketId, path?) | token | folder entries |
| deleteFile(bucketId, path) | token | confirmation |
The query builder is awaitable directly — await db.from("t").limit(1) works without calling
.run().
Errors
Every non-2xx response throws KroomBaseError with status, body, and message:
import { KroomBaseError } from "@kroombase/client";
try {
await db.update("orders", 999, { status: "x" });
} catch (err) {
if (err instanceof KroomBaseError) console.error(err.status, err.message);
}Honest limits
These are properties of the REST API this client wraps, documented so you are not surprised:
delete()cannot confirm a deletion.DELETE /rest/:table/:idanswers{message:"row deleted"}whether or not a row matched. Read first, or usesql()withDELETE ... RETURNING, when that matters.update()throws on a missing row. The route itself answers200 []; this client turns that into a 404 error, because a write that silently did nothing is worse than a failure.- Raw SQL needs a session token. API keys are refused by
/query; that is deliberate, so a leaked key cannot drop tables.
Other languages
The SDK is a convenience, not a requirement. The REST API is one header and plain JSON:
curl "https://kroombase.kroombox.com/rest/orders?limit=5" -H "apikey: kb_your_api_key"See the docs in the app for Python and raw curl equivalents.
