Skip to content
Draft

v4 #55

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
198 commits
Select commit Hold shift + click to select a range
4a8ccf3
support static, start supporting openapi, switch to zod, update examp…
alii Feb 5, 2025
8f522a4
transform, before, fix query parsing, faster route matching, fix brok…
alii Feb 5, 2025
3c15b60
o3-mini wrote some tests
alii Feb 5, 2025
be915ad
uws/getRemoteAddress refactor ( improve request metadata handling), u…
alii Feb 5, 2025
55a938c
fix: client types depended on sse response being structually differen…
alii Feb 5, 2025
ca049eb
fix: type errors
alii Feb 5, 2025
5d9efdb
big router
alii Feb 5, 2025
c8b13f9
fix client types
alii Feb 5, 2025
dd18b30
remove G
alii Feb 5, 2025
4c3544d
update
alii Feb 5, 2025
5fd3a6f
4.0.0-beta.2
alii Feb 5, 2025
b03c83c
remove trace method
alii Feb 5, 2025
f6fec66
feat: add performance tests on PR via oha (#56)
TheLDB Feb 5, 2025
dc84420
4.0.0-beta.3
alii Feb 6, 2025
841be9e
Merge branch 'v4' of github.com:kaito-http/kaito into v4
alii Feb 6, 2025
19f7e25
4.0.0-beta.4
alii Feb 8, 2025
275ee0b
beta.5
alii Feb 9, 2025
d4d1464
4.0.0-beta.5
alii Feb 9, 2025
5401708
changes
alii Feb 9, 2025
bfb1d1b
params() stuff
alii Feb 16, 2025
14aaa4e
fix
alii Feb 16, 2025
e285483
fix router tests
alii Feb 16, 2025
89ac5dc
v4 beta.6
alii Feb 16, 2025
57c2512
res => head
alii Feb 16, 2025
cbd4882
update getting-started
alii Feb 16, 2025
30c13d1
udate
alii Feb 16, 2025
3293f57
teh
alii Feb 16, 2025
333b974
update
alii Feb 16, 2025
79b5b47
import {Callout} from 'nextra/components';
alii Feb 16, 2025
7b6e5ea
move it
alii Feb 16, 2025
89c6414
change
alii Feb 16, 2025
302a124
update
alii Feb 16, 2025
407978e
update .through() docs
alii Feb 16, 2025
445365c
updates
alii Feb 16, 2025
e4161c4
Lol thanks claude
alii Feb 16, 2025
23caa9e
update
alii Feb 16, 2025
00e68cf
oh
alii Feb 16, 2025
d90eea0
ok
alii Feb 16, 2025
f79ffdc
fuck sake
alii Feb 16, 2025
5b3d334
fix
alii Feb 16, 2025
4e4f8be
Major grammatical improvements
alii Feb 16, 2025
335c1eb
this does not fuckin exist😭
alii Feb 16, 2025
8d2b301
FILENAME
alii Feb 16, 2025
c8453f1
make it more cloudflarey
alii Feb 16, 2025
cbc8817
update cors
alii Feb 16, 2025
0cceb4f
update cors docs
alii Feb 16, 2025
0a26c92
change cors stuff
alii Feb 16, 2025
fb00cdb
beta.4
alii Feb 16, 2025
ccf3527
changes
alii Feb 16, 2025
ee56d3a
once agian claude cooks
alii Feb 16, 2025
f366312
Landon
alii Feb 16, 2025
d68993d
Fixes+tests for nested routers where the parent or child is "/" (#57)
hiett Feb 21, 2025
c489586
200 > default
alii Feb 23, 2025
d8c2121
bump yarn
alii Mar 19, 2025
0634a8c
4.0.0-beta.9
alii Mar 19, 2025
c555182
cors dx
alii Mar 19, 2025
c26bc17
4.0.0-beta.11
alii Mar 22, 2025
d869587
feat: start new .params() proposal
alii Apr 16, 2025
a31d645
4.0.0-beta.12
alii Apr 16, 2025
d71563c
work on kschema (#58)
alii May 11, 2025
a4e6550
Merge branch 'main' of github.com:kaito-http/kaito into v4
alii May 11, 2025
4aa5192
yarn 4.9.1
alii May 11, 2025
3ff8355
beta.13
alii May 11, 2025
a4b6390
matrix
alii May 11, 2025
07a7406
mrege
alii May 11, 2025
c0ce229
drop warning timeout
alii May 11, 2025
7caf7b1
fix: uws support cancel for stream
alii May 11, 2025
a824ab4
bump actions/setup-node
alii May 11, 2025
5cec394
schema type fixes
alii May 11, 2025
15ae448
kschema changes
alii May 11, 2025
8b02b87
schema work
alii May 11, 2025
281e25e
schema
alii May 11, 2025
cc7949f
schema
alii May 11, 2025
2317329
schema
alii May 11, 2025
4d3cc14
schema
alii May 11, 2025
ea27198
formar
alii May 11, 2025
77b5b48
KUnion
alii May 12, 2025
f878fa3
fix
alii May 12, 2025
6dce768
schema
alii May 12, 2025
ae4d8e3
router
alii May 12, 2025
b3e425c
rm for now
alii May 12, 2025
9935ff5
fix client
alii May 12, 2025
d7630ee
docs
alii May 12, 2025
1627bc8
LAndon
alii May 13, 2025
964b9a4
woops
alii May 13, 2025
478bd61
perms
alii May 30, 2025
9cf118d
export kschema
alii Jun 3, 2025
43f2ec1
Merge branch 'v4' of github.com:kaito-http/kaito into v4
alii Jun 3, 2025
d8d4a83
Merge branch 'main' of github.com:kaito-http/kaito into v4
alii Jun 3, 2025
e590fb1
Update dependencies and improve router functionality
alii Sep 20, 2025
89931d4
fix: implement an objectFromURLSearchParams schema for faster queryst…
alii Sep 20, 2025
429d56e
make all the tests pass
alii Sep 20, 2025
93c93fe
fix: simplify some of the schemas/tests
alii Sep 20, 2025
1a96410
tests: a bunch more valid/invalid uris
alii Sep 20, 2025
fb7f067
format the file
alii Sep 20, 2025
1c2e555
feat: add startsWith and endsWith validation for strings
alii Sep 20, 2025
cdccfcf
chore: use typescript@5.9.2
alii Sep 20, 2025
b03254c
use 4.10.2 stable
alii Sep 20, 2025
5ffa2ba
dont vendor yarn
alii Sep 20, 2025
2e1f0bb
test in both bun & node
alii Sep 20, 2025
60842c0
I couldn't get catalogs to work in yarn
alii Sep 20, 2025
2e66863
test
alii Sep 20, 2025
930ceab
Merge main into v4, keeping v4 content
alii Sep 20, 2025
1ed6f56
k.literal()
alii Sep 20, 2025
919fbea
feat: enhance README and improve server functionality
alii Sep 20, 2025
880c4c6
feat: enable clean build option in tsup configuration
alii Sep 20, 2025
5c97289
update docs
alii Jun 3, 2025
c71bbe0
improve streaming body test
alii Jun 3, 2025
3997370
bump uws.js
alii Jun 3, 2025
96bbc09
uws: Remove mention of ASL (slow + faster alternative now)
alii Sep 20, 2025
21787d4
const → using
alii Sep 20, 2025
feeb80c
Refactor ServeOptions interface and comment out static handling logic…
alii Sep 20, 2025
12e2b37
remove static routes test
alii Sep 20, 2025
bd1b979
move Symbol.dispose
alii Sep 20, 2025
2f324f5
fix: ReadableStream is strictly an ArrayBuffer backed Uint8Array
alii Sep 20, 2025
4d3d699
corepack in ci
alii Sep 20, 2025
a41cca1
test
alii Sep 20, 2025
451e690
refactor: change KaitoConfig from type to interface and update Route …
alii Sep 20, 2025
b6f097b
types
alii Sep 21, 2025
44eb76a
refactor: enhance Route and Router types for improved input handling
alii Sep 21, 2025
9f75d50
4.0.0-beta.14
alii Sep 21, 2025
3f04afe
update test suite
alii Sep 21, 2025
8cd3697
fix: update bytes method to return Uint8Array<ArrayBuffer> for improv…
alii Sep 21, 2025
da3572a
make sseEventToString() use a list of lines
alii Sep 21, 2025
8d22e05
fix: remediate broken client types in both client & core
alii Sep 21, 2025
bbb1750
4.0.0-beta.15
alii Sep 21, 2025
2238703
update example
alii Sep 21, 2025
6435479
feat(beta.16): ensure OpenAPI schema examples and descriptions are de…
alii Sep 21, 2025
dfafceb
beta.17
alii Sep 21, 2025
4b972c0
fix: Fix a subtle type error in openapi response schema definition
alii Sep 21, 2025
8b1558c
beta.18
alii Sep 21, 2025
3e9f40c
k.scalar() support in openapi schema
alii Sep 21, 2025
49f7827
fix: Client couldn't find routes that extend AnyRoute
alii Sep 21, 2025
20dfa36
4 beta 20
alii Sep 21, 2025
7a67bc1
I broke the client again
alii Sep 21, 2025
abde41a
fix: parse SSE result in client properly in the types
alii Sep 21, 2025
4ee1085
fix: async run() broke in the previous beta
alii Sep 21, 2025
59a50c0
fix: KObject output does not necessarily need to be JSON
alii Sep 21, 2025
b64408e
beta.21
alii Sep 21, 2025
21c33f0
KRef does not need a JSONValue output
alii Sep 21, 2025
1f114eb
copy in example/description from base schema in scalar
alii Sep 21, 2025
b29f9d2
.22
alii Sep 21, 2025
b6afe4a
Implement OpenAPI schema generation for KRef and enhance BaseSchema w…
alii Sep 21, 2025
0e51e81
fix: KRef output schema constructor type parameter doesn't have to be…
alii Sep 21, 2025
6974a80
beta.24
alii Sep 21, 2025
42bae31
router.openapi() jsdoc
alii Sep 21, 2025
3dc6875
rearrange
alii Sep 22, 2025
c81ecbe
uws rename KaitoServer → Server
alii Sep 22, 2025
c835d06
⚠️remove success and data fields from responses!!⚠️
alii Sep 22, 2025
66f1adc
.25
alii Sep 22, 2025
4306dda
fix: header cloning
alii Sep 22, 2025
1f233af
internal client error types
alii Sep 22, 2025
b00607d
k.record()
alii Sep 22, 2025
9a22469
beta.26
alii Sep 22, 2025
96058a9
tests for k.record()
alii Sep 22, 2025
903fe57
k.json() and k.lazy()
alii Sep 22, 2025
1595c53
import type
alii Sep 22, 2025
3323236
chagne
alii Sep 22, 2025
aa28df7
beta.27
alii Sep 22, 2025
64bdf06
4.0.0-beta.27
alii Sep 22, 2025
2adf161
fix: `void` run function should serialize as null.
alii Nov 24, 2025
808ae1f
beta.28
alii Nov 24, 2025
c76de0d
beta.29
alii Nov 24, 2025
f6c2f7a
Implement k.enum
alii Mar 7, 2026
fb2a739
Fix SSE types
alii Mar 7, 2026
d4e9127
beta.30
alii Mar 7, 2026
742806e
fix ci
alii Mar 7, 2026
3ab710f
fix
alii Mar 7, 2026
0f20dfe
fix
alii Mar 7, 2026
ceb87bb
fix
alii Mar 7, 2026
c4dc0b5
fix type errors
alii Mar 7, 2026
74d7673
vendor yarn
alii Mar 7, 2026
5ae983a
lol
alii Mar 7, 2026
feea3be
fix
alii Mar 7, 2026
58f96ec
docs → v4
alii Mar 7, 2026
d90545f
Docs updates
alii Mar 7, 2026
da21cf8
fix pagebuild
alii Mar 7, 2026
f448593
Improve the voice of the documentation
alii Mar 7, 2026
2a512bb
fix scalars
alii Mar 9, 2026
803da26
undo fmt
alii Mar 9, 2026
cfbf06c
fix regression
alii Mar 9, 2026
0fb4502
fix route type arity in tests
alii Mar 9, 2026
c19f327
4.0.0-beta.31
alii Mar 9, 2026
121c624
fix output schema inference site conformance
alii Mar 9, 2026
1a234aa
4.0.0-beta.32
alii Mar 9, 2026
1dd9279
useless
alii Mar 9, 2026
d30cba2
specify buffer backing
alii Mar 9, 2026
52e491f
unify abortion
alii Mar 9, 2026
2e9e945
tidy
alii Mar 12, 2026
7344366
route request, head into through()
alii Mar 12, 2026
4981766
Plugins
alii Mar 12, 2026
b20ead9
4.0.0-beta.33
alii Mar 12, 2026
51e34c1
talk about request and head
alii Mar 12, 2026
0ad829c
Dead code
alii Mar 12, 2026
5c64445
Pipes page
alii Mar 12, 2026
a1da994
docs(cookies): add fami example(s)
pxseu Mar 14, 2026
d2f007c
Update fami docs to use new pipe-based API
alii Mar 14, 2026
f3806a9
Update fami example to use object syntax
alii Mar 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node: ['20.x', '22.x', '23.x', '24.x']
node: ['20.x', '22.x', '24.x']
os: [ubuntu-latest, windows-latest]

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Install Node ${{ matrix.node }}
uses: actions/setup-node@v2
uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node }}
cache: yarn

- name: Install dependencies
run: yarn
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ dist
!.yarn/plugins
!.yarn/sdks

# Pagefind search index
_pagefind/

# Environment variables
.env
.env.local
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
"typescript.tsdk": "node_modules/typescript/lib"
}
940 changes: 940 additions & 0 deletions .yarn/releases/yarn-4.13.0.cjs

Large diffs are not rendered by default.

925 changes: 0 additions & 925 deletions .yarn/releases/yarn-4.5.0.cjs

This file was deleted.

3 changes: 2 additions & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-4.5.0.cjs

yarnPath: .yarn/releases/yarn-4.13.0.cjs
4 changes: 4 additions & 0 deletions .zed/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"formatter": "prettier",
"format_on_save": "on",
}
10 changes: 10 additions & 0 deletions apps/docs/mdx-components.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {useMDXComponents as getDocsMDXComponents} from 'nextra-theme-docs';

const docsComponents = getDocsMDXComponents();

export function useMDXComponents(components?: Record<string, React.ComponentType>) {
return {
...docsComponents,
...components,
};
}
3 changes: 2 additions & 1 deletion apps/docs/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
3 changes: 1 addition & 2 deletions apps/docs/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import nextra from 'nextra';

const withNextra = nextra({
theme: 'nextra-theme-docs',
themeConfig: './src/theme.config.tsx',
contentDirBasePath: '/',
});

export default withNextra({
Expand Down
14 changes: 7 additions & 7 deletions apps/docs/package.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
{
"name": "@kaito-http/docs",
"private": true,
"version": "3.2.1",
"version": "4.0.0-beta.33",
"author": "Alistair Smith <hi@alistair.sh>",
"license": "MIT",
"dependencies": {
"es-urlcat": "^1.0.0",
"next": "^15.1.4",
"nextra": "3.3.1",
"nextra-theme-docs": "3.3.1",
"next": "^15.3.3",
"nextra": "^4",
"nextra-theme-docs": "^4",
"pathcat": "^1.4.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"scripts": {
"dev": "next",
"start": "next start",
"build": "next build"
"build": "next build && pagefind --site .next/server/app --output-path public/_pagefind"
},
"devDependencies": {
"@types/node": "^22.10.5",
"@types/react": "^19.0.5",
"@types/react-dom": "^19.0.3",
"typescript": "^5.7.3"
"pagefind": "^1",
"typescript": "5.9.2"
},
"description": "Functional HTTP Framework for TypeScript",
"homepage": "https://github.com/kaito-http/kaito",
Expand Down
23 changes: 23 additions & 0 deletions apps/docs/src/app/[[...mdxPath]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {generateStaticParamsFor, importPage} from 'nextra/pages';
import {useMDXComponents as getMDXComponents} from '../../../mdx-components';

export const generateStaticParams = generateStaticParamsFor('mdxPath');

export async function generateMetadata(props: {params: Promise<{mdxPath?: string[]}>}) {
const params = await props.params;
const {metadata} = await importPage(params.mdxPath);
return metadata;
}

const Wrapper = getMDXComponents().wrapper!;

export default async function Page(props: {params: Promise<{mdxPath?: string[]}>}) {
const params = await props.params;
const {default: MDXContent, toc, metadata, sourceCode} = await importPage(params.mdxPath);

return (
<Wrapper toc={toc} metadata={metadata} sourceCode={sourceCode}>
<MDXContent {...props} params={params} />
</Wrapper>
);
}
48 changes: 48 additions & 0 deletions apps/docs/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {Footer, Layout, Navbar} from 'nextra-theme-docs';
import {Head, Search} from 'nextra/components';
import {getPageMap} from 'nextra/page-map';
import 'nextra-theme-docs/style.css';
import type {ReactNode} from 'react';

export const metadata = {
title: {
default: 'Kaito',
template: '%s — Kaito',
},
description: 'Kaito: An HTTP framework for TypeScript',
twitter: {
card: 'summary_large_image',
site: '@alistaiir',
},
};

export default async function RootLayout({children}: {children: ReactNode}) {
return (
<html lang="en" dir="ltr" suppressHydrationWarning>
<Head faviconGlyph="✦" />
<body>
<Layout
navbar={
<Navbar
logo={<span>Kaito</span>}
projectLink="https://github.com/kaito-http/kaito"
chatLink="https://discord.gg/PeEPDMKBEn"
/>
}
pageMap={await getPageMap()}
docsRepositoryBase="https://github.com/kaito-http/kaito/blob/main/apps/docs"
editLink="Edit this page on GitHub"
feedback={{labels: 'docs-feedback', content: 'Feedback'}}
footer={
<Footer>
An open-source project by <a href="https://alistair.sh">Alistair Smith</a>
</Footer>
}
search={<Search />}
>
{children}
</Layout>
</body>
</html>
);
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import type {Meta} from 'nextra';
const meta: Meta = {
context: 'Context',
routes: 'Routes',
routers: 'Routers',
handler: 'Handler',
'router-basics': 'Router Basics',
'advanced-routing': 'Advanced Routing',
pipes: 'Pipes',
client: 'Client',
streaming: 'Streaming',
'error-handling': 'Error Handling',
Expand Down
77 changes: 77 additions & 0 deletions apps/docs/src/content/documentation/advanced-routing.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: Advanced Routing
description: Learn about advanced routing features in Kaito, including router merging, params, and middleware patterns
---

import {Callout} from 'nextra/components';

# Advanced Routing

## Router Merging

Routers can be merged, which brings one router's routes into another, with a prefix. This is incredibly useful for larger apps, for example when you have multiple versions of an API.

```ts filename="api.ts"
import {v1} from './routers/v1.ts';
import {v2} from './routers/v2.ts';

export const api = router.merge('/v1', v1).merge('/v2', v2);
```

All type information, route names, and correct prefixes are preserved during merging.

## Router Parameters

The `.params()` method lets you declare what URL parameters a router expects when it gets merged. Pass the param names as a type argument, like `.params<'userId'>()` — no runtime validation needed, params are always strings extracted from the URL. This only matters when the router is merged somewhere that provides those parameters.

### Basic Parameters

```ts
// Declare that this router needs a userId parameter
const userRouter = router.params<'userId'>().get('/', async ({params}) => {
// params.userId is guaranteed to exist and is a string
return {id: params.userId};
});

// This works - we're mounting at a path that provides userId
const app = router.merge('/users/:userId', userRouter);

// This would be a type error - we're not providing userId
const badApp = router.merge('/users', userRouter);
```

### Nested Parameters

Parameters become especially powerful with deeply nested routers:

```ts
// This router needs both userId and postId
const commentsRouter = router.params<'userId' | 'postId'>().pipe(async (ctx, params) => {
const [user, post] = await Promise.all([db.users.findById(params.userId), db.posts.findById(params.postId)]);

if (!user || !post) {
throw new KaitoError(404, 'Not found');
}

return {
...ctx,
user,
post,
};
});

// This router provides postId and forwards userId
const postsRouter = router.params<'userId'>().merge('/posts/:postId/comments', commentsRouter);

// Finally, we provide userId at the top level
const app = router.merge('/users/:userId', postsRouter);
```

<Callout>
You can only call `.params()` once on a router. Multiple calls will result in a type error to prevent breaking
existing routes.
</Callout>

## Pipes

Kaito uses `.pipe()` instead of traditional middleware to transform context before routes run. Pipes are type-safe, composable, and chainable. See the dedicated [Pipes](/documentation/pipes) page for full documentation, including chaining, plugins, reusable routers, and advanced generic patterns.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {Callout} from 'nextra/components';

# Client

<Callout>
The Kaito client is a recent addition to the Kaito ecosystem. It's still in the early stages of development. While we
think it's definitely stable, there may be missing features or unexpected behaviours.
think it's definitely stable, there may be missing features or unexpected behaviors.
</Callout>

# Client

Kaito provides a strongly-typed HTTP client that seamlessly integrates with your Kaito server. The client supports all HTTP methods, streaming responses, and Server-Sent Events (SSE) out of the box.

To ensure compatibility, always use matching versions of the client and server packages, as they are released together.
Expand All @@ -20,12 +20,9 @@ bun i @kaito-http/client
Create a client instance by providing your API's type and base URL:

```ts filename="api/index.ts"
const app = router().merge('/v1', v1);
const app = router.merge('/v1', v1);

const handler = createKaitoHTTPHandler({
router: app,
// ...
});
const handle = app.serve();

export type App = typeof app;
```
Expand Down Expand Up @@ -68,8 +65,8 @@ await api.post('/v1/users/@me', {

### Non-JSON Responses

For endpoints that return a `Response` instance, you must pass `response: true` to the request options. This is enforced for you at a compile time type level, so you
can't accidentally forget to pass it. The option is needed so the runtime JavaScript doesn't assume the response is JSON.
For endpoints that return a `Response` instance, you must pass `response: true` to the request options. This is enforced at a compile time type level, so you
cannot accidentally forget to pass it. The option is needed so the runtime JavaScript does not assume the response is JSON.

```ts
const response = await api.get('/v1/response/', {
Expand Down
70 changes: 70 additions & 0 deletions apps/docs/src/content/documentation/context.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: Context
description: Context is a way to pass common data to all routes
---

import {Callout} from 'nextra/components';

# Context

In Kaito, context is information shared across every single route. You provide it at the root of your application, and Kaito generates it on every single request.

Below is an example of things that you could include, but it's really up to you and what you would find useful to include in your app.

In the documentation about routers, you'll learn about how routers can create their own context for enabling powerful separation of concerns. See [Pipes](/documentation/pipes) for how to transform and enrich context per-router.

<Callout>
Passing the request/response objects to context is ok, but we firmly recommend you read the
[routes](/documentation/routes) documentation for information on the Request/Response model.
</Callout>

```ts filename="context.ts"
import {create} from '@kaito-http/core';
import {db} from './db.ts';

// Create a new router with context
export const router = create({
getContext: async (req, head) => {
return {
req,
head,
time: new Date(),

searchForUser: async (query: string) => {
return await db.users.search(query);
},

// This is just an example
getSession: async () => {
const cookies = req.headers.get('cookie');

// this is bad code, use a cookie parser library! npmjs.com/package/cookie is a good one
const token = cookies
?.split(';')
.find(cookie => cookie.startsWith('token='))
?.split('=')[1];

return await db.sessions.findByToken(token);
},
};
},
});
```

You can then use this context, when setup correctly with a router, inside every single route. E.g.

```ts filename="routes/users.ts"
import {k} from '@kaito-http/core';
import {router} from '../context.ts';

export const users = router.get('/users/search', {
query: {
search: k.string().max(200),
},

async run({ctx, query}) {
const users = await ctx.searchForUser(query.search);
return users;
},
});
```
Loading
Loading