Official Node.js client library for the RaidFrame API.
npm install @raidframe/sdk
import { RaidFrame } from "@raidframe/sdk";
const rf = new RaidFrame({
token: process.env.RAIDFRAME_TOKEN,
project: "my-saas", // optional, auto-detected from raidframe.yaml
});
const projects = await rf.projects.list();
const project = await rf.projects.get("my-saas");
const newProject = await rf.projects.create({ name: "new-app", region: "us-east-1" });
await rf.projects.delete("old-app");
const services = await rf.services.list();
const api = await rf.services.get("api");
// Scale
await rf.services.scale("api", { min: 4, max: 20 });
// Restart
await rf.services.restart("api");
// Create
await rf.services.create({
name: "worker",
type: "worker",
command: "node worker.js",
});
// Trigger deploy
const deployment = await rf.deploy({ watch: true });
console.log(`Deployed: ${deployment.id} (${deployment.version})`);
// List deployments
const deployments = await rf.deployments.list({ limit: 10 });
// Rollback
await rf.deployments.rollback();
// Or to specific version
await rf.deployments.rollback("dep_abc123");
// Provision
await rf.databases.create({ engine: "postgres", name: "main", plan: "pro" });
// Query
const result = await rf.databases.query("main", "SELECT count(*) FROM users");
console.log(result.rows[0].count);
// Backup
await rf.databases.backup("main", { name: "before-migration" });
// Branch
await rf.databases.branch("main", { name: "feature-x" });
// Set
await rf.env.set({ STRIPE_KEY: "sk_live_xxx", API_SECRET: "secret" });
// Get
const value = await rf.env.get("STRIPE_KEY");
// List
const vars = await rf.env.list();
// Delete
await rf.env.delete("OLD_KEY");
// Query logs
const logs = await rf.logs.query({
service: "api",
since: "1h",
level: "error",
search: "timeout",
limit: 50,
});
// Stream logs
const stream = rf.logs.stream({ service: "api" });
stream.on("log", (entry) => {
console.log(`[${entry.service}] ${entry.message}`);
});
stream.on("error", (err) => console.error(err));
// Stop streaming
stream.close();
const metrics = await rf.metrics.get({
service: "api",
metrics: ["cpu_percent", "response_time_p99"],
period: "24h",
});
console.log(`CPU: ${metrics.cpu_percent.avg}%`);
console.log(`P99: ${metrics.response_time_p99.avg}ms`);
import { Queue, Worker } from "@raidframe/sdk";
// Publish
const queue = new Queue("tasks");
await queue.publish({ type: "send-email", to: "[email protected]" });
// Consume
const worker = new Worker("tasks", async (job) => {
await sendEmail(job.data.to);
});
worker.start({ concurrency: 10 });
import { KV } from "@raidframe/sdk";
const kv = new KV();
await kv.set("feature:dark-mode", "true", { ttl: 3600 });
const value = await kv.get("feature:dark-mode");
await kv.delete("feature:dark-mode");
const count = await kv.incr("rate:ip:192.168.1.1");
import { Email } from "@raidframe/sdk";
const email = new Email();
await email.send({
from: "[email protected]",
to: "[email protected]",
subject: "Welcome",
template: "welcome",
data: { name: "Alice" },
});
import { RaidFrameError, NotFoundError, RateLimitError } from "@raidframe/sdk";
try {
await rf.services.get("nonexistent");
} catch (err) {
if (err instanceof NotFoundError) {
console.log("Service not found");
} else if (err instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${err.retryAfter}s`);
} else {
throw err;
}
}
The SDK is fully typed. All methods, parameters, and responses have TypeScript definitions:
import type { Service, Deployment, Database, LogEntry } from "@raidframe/sdk";
const service: Service = await rf.services.get("api");
const deployment: Deployment = await rf.deploy();