API Reference

new Kizuna()

Bind one API surface, with its tags, identities, request contexts, and validation codes, and keep it as `k`.

new Kizuna() binds one API surface. Keep the instance as k, then use k.routes to define route groups and k.contract to assemble them. Construct it once and import k wherever you define routes.

pnpm add @ts-kizuna/core
bun add @ts-kizuna/core
npm install @ts-kizuna/core
import { Kizuna } from '@ts-kizuna/core';

Parameters

new Kizuna(config?: {
    identities?: Record<string, Identity>;
    requestContext?: Record<string, RequestContext>;
    tags?: TagSet;
    validation?: { issueCodes?: readonly string[] };
    plugins?: Record<string, ContractPlugin>;
    jobs?: JobsConfig;
}): K
FieldTypeDescription
identitiesRecord<string, Identity>Optional. The API's identities from the Kizuna.identity builders. The keys become the names the auth map and guards use.
requestContextRecord<string, RequestContext>Optional. Declarations from Kizuna.requestContext, the request-scoped values every handler receives.
tagsTagSetOptional. A tag set from Kizuna.tags. Its keys become the allowed group tags.
validation.issueCodesreadonly string[]Optional. Custom validation issue codes this API's handlers may emit via k.issue. Captured as a literal union.
pluginsRecord<string, ContractPlugin>Optional. The plugins this API declares. Their keys become the names server.api and handlers use. See Plugins.
jobsJobsConfigOptional. Settings shared by every job. The jobs themselves are declared with k.jobs. See Jobs.

Returns

The instance. Keep it as k, the authoring surface for this API:

MethodSignatureDescription
k.routes(tag, defs) => RoutesDefine a route group under one of the tag set's keys.
k.auth(routes, map) => AuthMapBuild the auth map, typed against the routes and identities.
k.jobs(identity, definitions) => JobsDeclare scheduled jobs and the identity they require.
k.contract({ routes, jobs, auth }) => ContractAssemble route groups into the contract shared everywhere.
k.issue(ctx, issue) => voidRaise a typed validation issue code inside a Zod refinement.

Example

Set the factory up once, usually in a k.ts file, then import k wherever you define routes.

// k.ts
import { Kizuna } from '@ts-kizuna/core';
import { tags } from './tags';
import { user, member } from './identities';
import { analytics } from './request-contexts';

export const k = new Kizuna({
    identities: {
        user,
        member,
    },
    requestContext: {
        analytics,
    },
    tags,
    validation: {
        issueCodes: ['invalid_phone_number'],
    },
});

Request context

requestContext registers declarations from Kizuna.requestContext, the request-scoped values like analytics ids or a logger. Every handler receives them typed under requestContext, keyed by their name; each is resolved per request by a server.requestContext resolver wired on server.api.

src/contract/request-contexts.ts
import { z } from 'zod';
import { Kizuna } from '@ts-kizuna/core';

export const analytics = Kizuna.requestContext(
    z.object({
        sessionId: z.string().nullable(),
    })
);
src/contract/k.ts
import { analytics } from './request-contexts';

export const k = new Kizuna({
    requestContext: {
        analytics,
    },
});
listUsers: ({ query, requestContext }) => {
    track(requestContext.analytics.sessionId, 'listUsers');
    // ...
},

See the Contract guide for response schemas, deprecation, typed response headers, and nesting.

On this page