@kozojs/core 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +254 -0
- package/lib/index.d.ts +135 -0
- package/lib/index.js +694 -0
- package/lib/index.js.map +1 -0
- package/lib/middleware/index.d.ts +79 -0
- package/lib/middleware/index.js +135 -0
- package/lib/middleware/index.js.map +1 -0
- package/package.json +76 -0
package/README.md
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# @kozojs/core
|
|
2
|
+
|
|
3
|
+
🔥 **Kozo** - The fastest TypeScript framework that runs everywhere.
|
|
4
|
+
|
|
5
|
+
High-performance backend framework with native Zod validation, type-safe client generation, and edge runtime compatibility.
|
|
6
|
+
|
|
7
|
+
## 📊 Performance
|
|
8
|
+
|
|
9
|
+
- **10,503 req/s** with full Zod validation
|
|
10
|
+
- **83%** of Fastify performance on Node.js
|
|
11
|
+
- **Zero overhead** serialization with fast-json-stringify
|
|
12
|
+
- **Edge-ready**: Works on Node.js, Bun, Deno, and Cloudflare Workers
|
|
13
|
+
|
|
14
|
+
## ✨ Features
|
|
15
|
+
|
|
16
|
+
- 🎯 **Type-Safe Client Generation** - Auto-generate typed SDK from your API
|
|
17
|
+
- ⚡ **Zero Config** - No decorators, no boilerplate
|
|
18
|
+
- 🛡️ **Zod Native** - First-class Zod schema support
|
|
19
|
+
- 🌍 **Universal** - Runs on any JavaScript runtime
|
|
20
|
+
- 🚀 **Fast** - Optimized for performance with minimal overhead
|
|
21
|
+
|
|
22
|
+
## 🚀 Quick Start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @kozojs/core zod
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { createKozo } from '@kozojs/core';
|
|
30
|
+
import { z } from 'zod';
|
|
31
|
+
|
|
32
|
+
const app = createKozo({ port: 3000 });
|
|
33
|
+
|
|
34
|
+
// Define schema
|
|
35
|
+
const UserSchema = z.object({
|
|
36
|
+
id: z.string().uuid(),
|
|
37
|
+
email: z.string().email(),
|
|
38
|
+
name: z.string(),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Create route with validation
|
|
42
|
+
app.get('/users/:id', {
|
|
43
|
+
params: z.object({ id: z.string().uuid() }),
|
|
44
|
+
response: UserSchema,
|
|
45
|
+
}, (c) => {
|
|
46
|
+
return {
|
|
47
|
+
id: c.params.id,
|
|
48
|
+
email: 'user@example.com',
|
|
49
|
+
name: 'John Doe',
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
await app.listen(3000);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 🎯 Type-Safe Client Generation
|
|
57
|
+
|
|
58
|
+
Generate a fully typed client SDK with automatic type inference:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// server.ts
|
|
62
|
+
const app = createKozo();
|
|
63
|
+
|
|
64
|
+
app.get('/users', {
|
|
65
|
+
query: z.object({ page: z.number() }),
|
|
66
|
+
response: z.array(UserSchema),
|
|
67
|
+
}, handler);
|
|
68
|
+
|
|
69
|
+
// Generate client
|
|
70
|
+
const clientCode = app.generateClient({
|
|
71
|
+
baseUrl: 'https://api.example.com',
|
|
72
|
+
includeValidation: true, // Include Zod schemas for client-side validation
|
|
73
|
+
validateByDefault: false, // Opt-in validation
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Save to file
|
|
77
|
+
writeFileSync('./client/api.ts', clientCode);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Usage in Frontend:**
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { KozoClient } from './client/api';
|
|
84
|
+
|
|
85
|
+
const api = new KozoClient({
|
|
86
|
+
baseUrl: 'https://api.example.com',
|
|
87
|
+
validateRequests: true, // Enable runtime validation
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Fully typed! 🎉
|
|
91
|
+
const users = await api.users({ query: { page: 1 } });
|
|
92
|
+
// ^? User[]
|
|
93
|
+
|
|
94
|
+
// TypeScript catches errors at compile time
|
|
95
|
+
const user = await api.usersById({
|
|
96
|
+
params: { id: 'invalid' } // ❌ Type error: not a UUID
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 🛡️ Validation
|
|
101
|
+
|
|
102
|
+
Kozo uses Zod for schema validation with detailed error messages:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
app.post('/users', {
|
|
106
|
+
body: z.object({
|
|
107
|
+
email: z.string().email(),
|
|
108
|
+
name: z.string().min(2).max(50),
|
|
109
|
+
age: z.number().min(18),
|
|
110
|
+
}),
|
|
111
|
+
response: UserSchema,
|
|
112
|
+
}, (c) => {
|
|
113
|
+
// c.body is fully typed and validated
|
|
114
|
+
const { email, name, age } = c.body;
|
|
115
|
+
// Your logic here
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Error Response (auto-formatted):**
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"error": "Validation failed",
|
|
123
|
+
"details": [
|
|
124
|
+
{
|
|
125
|
+
"path": ["email"],
|
|
126
|
+
"message": "Invalid email"
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 🌍 Runtime Compatibility
|
|
133
|
+
|
|
134
|
+
Kozo runs on all modern JavaScript runtimes:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
// Node.js
|
|
138
|
+
import { createKozo } from '@kozojs/core';
|
|
139
|
+
const app = createKozo();
|
|
140
|
+
await app.listen(3000);
|
|
141
|
+
|
|
142
|
+
// Bun (faster JSON parsing)
|
|
143
|
+
const app = createKozo();
|
|
144
|
+
await app.listen(3000); // Automatically uses Bun optimizations
|
|
145
|
+
|
|
146
|
+
// Cloudflare Workers
|
|
147
|
+
export default {
|
|
148
|
+
fetch: app.fetch,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Deno
|
|
152
|
+
import { createKozo } from 'npm:@kozojs/core';
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## 📈 Performance Comparison
|
|
156
|
+
|
|
157
|
+
| Framework | Req/Sec | Notes |
|
|
158
|
+
|-----------|---------|-------|
|
|
159
|
+
| **Fastify** | 12,754 | Native Node.js, no edge support |
|
|
160
|
+
| **Rikta** | 11,919 | Fastify-based, no edge support |
|
|
161
|
+
| **Kozo** | **10,503** | ✅ Universal (Node, Bun, Edge) |
|
|
162
|
+
| **NestJS** | 8,500 | Heavy framework overhead |
|
|
163
|
+
|
|
164
|
+
**Why Kozo is slower on Node.js:**
|
|
165
|
+
- Built on Hono (universal runtime adapter)
|
|
166
|
+
- That 17% performance gap buys you: ✅ Edge compatibility ✅ Bun support ✅ Zero config DX
|
|
167
|
+
|
|
168
|
+
**Why choose Kozo:**
|
|
169
|
+
- If you need **edge deployment** → Kozo is your only option
|
|
170
|
+
- If you need **maximum Node.js speed** → Use Fastify/Rikta
|
|
171
|
+
- If you want **best DX + portability** → Kozo is the sweet spot
|
|
172
|
+
|
|
173
|
+
## 🔌 Middleware
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
app.use(async (c, next) => {
|
|
177
|
+
console.log(`${c.req.method} ${c.req.url}`);
|
|
178
|
+
await next();
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 🎨 Services (Dependency Injection)
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
const app = createKozo({
|
|
186
|
+
services: {
|
|
187
|
+
db: new DatabaseClient(),
|
|
188
|
+
cache: new RedisClient(),
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
app.get('/users', {}, (c) => {
|
|
193
|
+
const users = await c.services.db.users.findMany();
|
|
194
|
+
return users;
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## 📚 API Reference
|
|
199
|
+
|
|
200
|
+
### `createKozo(config?)`
|
|
201
|
+
|
|
202
|
+
Create a new Kozo application.
|
|
203
|
+
|
|
204
|
+
**Options:**
|
|
205
|
+
- `port?: number` - Server port (default: 3000)
|
|
206
|
+
- `services?: Services` - Dependency injection container
|
|
207
|
+
|
|
208
|
+
### `app.get(path, schema, handler)`
|
|
209
|
+
|
|
210
|
+
Define a GET route.
|
|
211
|
+
|
|
212
|
+
**Parameters:**
|
|
213
|
+
- `path: string` - Route path (supports `:param`)
|
|
214
|
+
- `schema: RouteSchema` - Zod schemas for validation
|
|
215
|
+
- `params?: ZodSchema` - Path parameters
|
|
216
|
+
- `query?: ZodSchema` - Query string
|
|
217
|
+
- `response?: ZodSchema` - Response body (enables fast serialization)
|
|
218
|
+
- `handler: (context) => any` - Route handler
|
|
219
|
+
|
|
220
|
+
### `app.generateClient(options?)`
|
|
221
|
+
|
|
222
|
+
Generate a type-safe client SDK.
|
|
223
|
+
|
|
224
|
+
**Options:**
|
|
225
|
+
- `baseUrl?: string` - API base URL
|
|
226
|
+
- `includeValidation?: boolean` - Include Zod schemas (default: true)
|
|
227
|
+
- `validateByDefault?: boolean` - Enable validation by default (default: false)
|
|
228
|
+
- `defaultHeaders?: Record<string, string>` - Default request headers
|
|
229
|
+
|
|
230
|
+
## 🏆 When to Use Kozo
|
|
231
|
+
|
|
232
|
+
**Use Kozo if you:**
|
|
233
|
+
- ✅ Need edge deployment (Cloudflare Workers, Vercel Edge)
|
|
234
|
+
- ✅ Want Bun compatibility
|
|
235
|
+
- ✅ Love Zod and want native integration
|
|
236
|
+
- ✅ Need type-safe client generation
|
|
237
|
+
- ✅ Want zero-config DX
|
|
238
|
+
|
|
239
|
+
**Don't use Kozo if you:**
|
|
240
|
+
- ❌ Only target Node.js and need absolute maximum speed
|
|
241
|
+
- ❌ Already have a complex Fastify/Express setup
|
|
242
|
+
- ❌ Don't care about type safety
|
|
243
|
+
|
|
244
|
+
## 📄 License
|
|
245
|
+
|
|
246
|
+
MIT
|
|
247
|
+
|
|
248
|
+
## 🤝 Contributing
|
|
249
|
+
|
|
250
|
+
Contributions welcome! See [CONTRIBUTING.md](../../CONTRIBUTING.md)
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
**Made with ⚡ by the Kozo team**
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as hono from 'hono';
|
|
2
|
+
import { Hono, Context } from 'hono';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export { z } from 'zod';
|
|
5
|
+
import { TSchema, Static } from '@sinclair/typebox';
|
|
6
|
+
|
|
7
|
+
type SchemaType = z.ZodType<any> | TSchema;
|
|
8
|
+
type RouteSchema = {
|
|
9
|
+
body?: SchemaType;
|
|
10
|
+
query?: SchemaType;
|
|
11
|
+
params?: SchemaType;
|
|
12
|
+
response?: SchemaType | Record<number, SchemaType>;
|
|
13
|
+
};
|
|
14
|
+
type InferSchema<T> = T extends z.ZodType<any> ? z.infer<T> : T extends TSchema ? Static<T> : unknown;
|
|
15
|
+
type KozoContext<S extends RouteSchema = {}> = {
|
|
16
|
+
services: Services;
|
|
17
|
+
body: InferSchema<S['body']>;
|
|
18
|
+
query: InferSchema<S['query']>;
|
|
19
|
+
params: InferSchema<S['params']>;
|
|
20
|
+
req: any;
|
|
21
|
+
json: (data: any) => Response;
|
|
22
|
+
text: (data: string, status?: number, headers?: any) => Response;
|
|
23
|
+
};
|
|
24
|
+
type KozoHandler<S extends RouteSchema = {}> = (ctx: KozoContext<S>) => any | Promise<any>;
|
|
25
|
+
interface Services {
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
interface OpenAPIConfigRef {
|
|
29
|
+
info: {
|
|
30
|
+
title: string;
|
|
31
|
+
version: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
};
|
|
34
|
+
servers?: Array<{
|
|
35
|
+
url: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
}>;
|
|
38
|
+
tags?: Array<{
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
interface KozoConfig {
|
|
44
|
+
routesDir?: string;
|
|
45
|
+
services?: Services;
|
|
46
|
+
port?: number;
|
|
47
|
+
mode?: 'safe' | 'turbo';
|
|
48
|
+
runtime?: 'node' | 'bun';
|
|
49
|
+
target?: 'node' | 'edge' | 'cloudflare' | 'vercel' | 'netlify';
|
|
50
|
+
monitoring?: {
|
|
51
|
+
enable: boolean;
|
|
52
|
+
metrics: ('req/sec' | 'latency' | 'errors')[];
|
|
53
|
+
port?: number;
|
|
54
|
+
};
|
|
55
|
+
basePath?: string;
|
|
56
|
+
openapi?: OpenAPIConfigRef;
|
|
57
|
+
onError?: (error: Error, ctx: any) => any;
|
|
58
|
+
onNotFound?: (ctx: any) => any;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Client Generator Options
|
|
63
|
+
*/
|
|
64
|
+
interface ClientGeneratorOptions {
|
|
65
|
+
/** Include Zod schemas for client-side validation (default: true) */
|
|
66
|
+
includeValidation?: boolean;
|
|
67
|
+
/** Base URL for the API (default: '') */
|
|
68
|
+
baseUrl?: string;
|
|
69
|
+
/** Enable runtime validation by default (default: false) */
|
|
70
|
+
validateByDefault?: boolean;
|
|
71
|
+
/** Custom headers to include in all requests */
|
|
72
|
+
defaultHeaders?: Record<string, string>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Route information for client generation
|
|
76
|
+
*/
|
|
77
|
+
interface RouteInfo {
|
|
78
|
+
method: string;
|
|
79
|
+
path: string;
|
|
80
|
+
schema: RouteSchema;
|
|
81
|
+
/** Optional: store the Zod schema instance for type extraction */
|
|
82
|
+
zodSchemas?: {
|
|
83
|
+
body?: any;
|
|
84
|
+
query?: any;
|
|
85
|
+
params?: any;
|
|
86
|
+
response?: any;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Generate typed client code from routes
|
|
91
|
+
*/
|
|
92
|
+
declare function generateTypedClient(routes: RouteInfo[], options?: ClientGeneratorOptions): string;
|
|
93
|
+
|
|
94
|
+
interface Plugin {
|
|
95
|
+
name: string;
|
|
96
|
+
version?: string;
|
|
97
|
+
install: (app: Kozo) => void | Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Kozo - High-performance TypeScript framework with Zod schemas
|
|
101
|
+
*/
|
|
102
|
+
declare class Kozo {
|
|
103
|
+
private app;
|
|
104
|
+
private services;
|
|
105
|
+
private routes;
|
|
106
|
+
constructor(config?: KozoConfig);
|
|
107
|
+
use(plugin: Plugin): this;
|
|
108
|
+
generateClient(baseUrl?: string): string;
|
|
109
|
+
generateClient(options?: ClientGeneratorOptions): string;
|
|
110
|
+
get<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S>): void;
|
|
111
|
+
post<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S>): void;
|
|
112
|
+
put<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S>): void;
|
|
113
|
+
patch<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S>): void;
|
|
114
|
+
delete<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S>): void;
|
|
115
|
+
private register;
|
|
116
|
+
listen(port?: number): Promise<void>;
|
|
117
|
+
getApp(): Hono;
|
|
118
|
+
get fetch(): (request: Request, Env?: unknown, executionCtx?: hono.ExecutionContext) => Response | Promise<Response>;
|
|
119
|
+
}
|
|
120
|
+
declare function createKozo(config?: KozoConfig): Kozo;
|
|
121
|
+
|
|
122
|
+
type UserHandler = (c: any) => any;
|
|
123
|
+
type CompiledRoute = {
|
|
124
|
+
validateBody?: (data: any) => boolean;
|
|
125
|
+
validateQuery?: (data: any) => boolean;
|
|
126
|
+
validateParams?: (data: any) => boolean;
|
|
127
|
+
serialize?: (data: any) => string;
|
|
128
|
+
errors?: any;
|
|
129
|
+
};
|
|
130
|
+
declare class SchemaCompiler {
|
|
131
|
+
static compile(schema: RouteSchema): CompiledRoute;
|
|
132
|
+
}
|
|
133
|
+
declare function compileRouteHandler(userHandler: UserHandler, schema: RouteSchema, services: any, compiled: CompiledRoute): (c: Context) => any;
|
|
134
|
+
|
|
135
|
+
export { type ClientGeneratorOptions, type CompiledRoute, Kozo, type KozoConfig, type KozoContext, type KozoHandler, type RouteInfo, type RouteSchema, SchemaCompiler, type Services, compileRouteHandler, createKozo, generateTypedClient };
|