Licence
MIT
Version
1.0.0
Deps
0
Size
6 kB
Vulns
0
Weekly
172
ghostapi
Mock http server with typed in-memory SQLite database. powered by Elysia. works with any Standard Schema library. uses Kysely for type-safe database queries.
bun add -d @lobomfz/ghostapiUsage
your app probably calls external APIs using a base URL from env:
// src/billing.ts
const STRIPE_API = process.env.STRIPE_API; // https://api.stripe.com in prod
export async function updateSubscription(customerId: string, plan: string) {
const res = await fetch(`${STRIPE_API}/customers/${customerId}/subscription`, {
method: "POST",
body: JSON.stringify({ plan }),
});
return res.json();
}create a mock that handles those routes:
import { Mock } from "@lobomfz/ghostapi";
import { type } from "arktype";
const schema = type({
id: "string",
plan: "string",
});
const stripeMock = new Mock(
{ customers: schema },
// db is fully typed based on your schemas
// app is a full elysia instance
(app, { db }) => {
app.post(
"/customers/:id/subscription",
async ({ params, body }) => {
await db
.updateTable("customers")
.set({ plan: body.plan })
.where("id", "=", params.id)
.execute();
return db
.selectFrom("customers")
.selectAll()
.where("id", "=", params.id)
.executeTakeFirst();
},
{ body: schema },
);
return {
seedCustomer: (id: string, plan: string) =>
db.insertInto("customers").values({ id, plan }).execute(),
};
},
);in tests, set STRIPE_API=http://localhost:4100 and your code calls the mock transparently:
import { test, expect } from "bun:test";
// your production code
import { updateSubscription } from "../src/billing";
stripeMock.listen(4100);
test("update subscription", async () => {
// seed data through helpers or directly via db
await stripeMock.helpers.seedCustomer("cus_123", "free");
const customer = await updateSubscription("cus_123", "pro");
expect(customer.plan).toBe("pro");
});API
new Mock<T, H>(schemas: T, setup: (app: Elysia, ctx: { db: Kysely<T>, schemas: T }) => H | void)
mock.db // Kysely client
mock.helpers // return value from setup function
mock.listen(port: number): void
mock.reset(table?: keyof T): voidNotes
- Booleans are stored as
0/1