new Kizuna()
The authoring surface for one API, typed by the Config that kizuna generate writes.
new Kizuna<Config>() is what you declare routes with. It takes nothing at runtime: its type parameter is the Config generated from your kizuna.config.ts, and that is what types everything a handler receives and checks every name you write.
Keep the instance as k, usually in src/k.ts, and import it wherever you declare.
pnpm add kizunajs@betabun add kizunajs@betanpm install kizunajs@betaimport { Kizuna } from 'kizunajs';
import type { Config } from '../kizuna.types';
export const k = new Kizuna<Config>();What it gives you
| Member | Signature | Description |
|---|---|---|
k.route | (definition) => RouteBuilder | Declare one route and the handler that answers it. |
k.routes | (tag, defs) => Routes | Group routes under one of the tag set's keys. |
k.tags | (tags) => TagSet | Declare the OpenAPI tags routes are grouped under. |
k.identity | .bearer, .apiKey, .basic, .oauth2, .openIdConnect, .custom | Declare an identity and the guard that authenticates it. |
k.requestContext | (config) => RequestContextBuilder | Declare a request-scoped value and the handler that fills it. |
k.job | (definition) => JobBuilder | Declare one job and the handler that runs it. |
k.jobs | (identity, definitions) => Jobs | Group jobs and name the identity they require. |
k.issue | (ctx, issue) => void | Raise a typed validation code inside a Zod refinement. |
Statics
Some declarations are shared across APIs rather than bound to one, so they stay on the class:
| Member | Description |
|---|---|
Kizuna.model | Name a schema so every client reuses one type. |
Kizuna.permissions | Declare a permission catalog. |
Kizuna.roles | Declare the roles callers hold. |
What Config carries
kizuna.types.ts is written by kizuna generate from your config. Every name you write against k is checked against it, and everything a handler receives comes from it.
export interface Config {
adapter: ReturnType<typeof expressAdapter>;
tags: typeof tags;
auth: {
identities: {
user: typeof user;
member: typeof member;
};
};
requestContext: {
analytics: typeof analytics;
};
validation: {
issueCodes: 'invalid_phone_number';
};
jobs: typeof jobs;
}So a route's auth only accepts a declared identity, k.routes('users', ...) only accepts a declared tag, and a handler reads auth.user, requestContext.analytics, jobs.indexUser and your framework's own request without importing any of them.
Example
import { z } from 'zod';
import { k } from '../k';
export const usersRoutes = k.routes('users', {
getUser: k
.route({
method: 'GET',
path: '/users/:id',
auth: 'user',
responses: {
200: UserSchema,
},
})
.handler(async ({ params, auth, req }) => ({
status: 200,
body: await db.users.find(params.id, auth.user.userId),
})),
});Assemble them with defineConfig. See the Config guide for response schemas, deprecation, typed response headers, and nesting.