TypeScript SDK
@jaina/sdk — typed client for Node and the browser.
Install
npm install @jaina/sdk
Quickstart
import { JainaClient } from '@jaina/sdk';
const jaina = new JainaClient({
apiKey: process.env.JAINA_API_KEY!,
});
const projects = await jaina.projects.list();
console.log(projects.items);
Resources
The client mirrors the REST API surface:
jaina.projects— list, get, create, update, deletejaina.schemas—(projectSlug)→ list/get/create/update/deletejaina.packages—(projectSlug)→ list/get/create/update/deletejaina.records—(projectSlug, schemaSlug)→ list/get/create/update/deletejaina.files—(projectSlug)→ upload/get/deletejaina.actions— define and execute actionsjaina.webhooks— register, list, test
Typed records
Pass a type parameter for full type safety on data:
interface Enemy {
name: string;
hp: number;
attack: number;
sprite: string;
rarity: 'common' | 'uncommon' | 'rare' | 'mythic';
}
const enemies = await jaina.records.list<Enemy>('my-game', 'enemy', {
filter: { 'data.hp': { gte: 50 } },
});
enemies.items.forEach((e) => {
// e.data.name, e.data.hp are typed
});
Generate the interface from your schema with jaina codegen --lang typescript.
Error handling
import { JainaError } from '@jaina/sdk';
try {
await jaina.records.create('my-game', 'enemy', { /* ... */ });
} catch (err) {
if (err instanceof JainaError) {
console.error(err.status, err.code, err.message);
if (err.code === 'validation_failed') {
console.error(err.issues);
}
} else {
throw err;
}
}
Pagination helper
for await (const page of jaina.records.paginate('my-game', 'enemy')) {
for (const record of page.items) {
/* ... */
}
}
Browser usage
The SDK works in browsers if you wrap it with an authenticated proxy on your backend. Never put jn_live_... tokens in client-side bundles.
