@smicolon/ai-kit 0.3.1 → 0.4.0

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.
Files changed (156) hide show
  1. package/README.md +73 -40
  2. package/dist/index.js +260 -126
  3. package/package.json +5 -5
  4. package/.claude-plugin/marketplace.json +0 -373
  5. package/packs/architect/CHANGELOG.md +0 -17
  6. package/packs/architect/README.md +0 -58
  7. package/packs/architect/agents/system-architect.md +0 -768
  8. package/packs/architect/commands/diagram-create.md +0 -300
  9. package/packs/better-auth/.mcp.json +0 -14
  10. package/packs/better-auth/CHANGELOG.md +0 -26
  11. package/packs/better-auth/README.md +0 -125
  12. package/packs/better-auth/agents/auth-architect.md +0 -278
  13. package/packs/better-auth/commands/auth-provider-add.md +0 -265
  14. package/packs/better-auth/commands/auth-setup.md +0 -298
  15. package/packs/better-auth/skills/auth-security/SKILL.md +0 -425
  16. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +0 -455
  17. package/packs/dev-loop/CHANGELOG.md +0 -69
  18. package/packs/dev-loop/README.md +0 -155
  19. package/packs/dev-loop/commands/cancel-dev.md +0 -21
  20. package/packs/dev-loop/commands/dev-loop.md +0 -72
  21. package/packs/dev-loop/commands/dev-plan.md +0 -351
  22. package/packs/dev-loop/hooks/hooks.json +0 -15
  23. package/packs/dev-loop/hooks/stop-hook.sh +0 -178
  24. package/packs/dev-loop/scripts/setup-dev-loop.sh +0 -194
  25. package/packs/dev-loop/skills/tdd-planner/SKILL.md +0 -249
  26. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +0 -874
  27. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +0 -260
  28. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +0 -275
  29. package/packs/django/CHANGELOG.md +0 -39
  30. package/packs/django/README.md +0 -92
  31. package/packs/django/agents/django-architect.md +0 -182
  32. package/packs/django/agents/django-builder.md +0 -250
  33. package/packs/django/agents/django-feature-based.md +0 -420
  34. package/packs/django/agents/django-reviewer.md +0 -253
  35. package/packs/django/agents/django-tester.md +0 -230
  36. package/packs/django/commands/api-endpoint.md +0 -285
  37. package/packs/django/commands/model-create.md +0 -178
  38. package/packs/django/commands/test-generate.md +0 -325
  39. package/packs/django/rules/migrations.md +0 -138
  40. package/packs/django/rules/models.md +0 -167
  41. package/packs/django/rules/serializers.md +0 -126
  42. package/packs/django/rules/services.md +0 -131
  43. package/packs/django/rules/tests.md +0 -140
  44. package/packs/django/rules/views.md +0 -102
  45. package/packs/django/skills/import-convention-enforcer/SKILL.md +0 -226
  46. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +0 -343
  47. package/packs/django/skills/migration-safety-checker/SKILL.md +0 -375
  48. package/packs/django/skills/model-entity-validator/SKILL.md +0 -298
  49. package/packs/django/skills/performance-optimizer/SKILL.md +0 -447
  50. package/packs/django/skills/red-phase-verifier/SKILL.md +0 -180
  51. package/packs/django/skills/security-first-validator/SKILL.md +0 -435
  52. package/packs/django/skills/test-coverage-advisor/SKILL.md +0 -394
  53. package/packs/django/skills/test-validity-checker/SKILL.md +0 -194
  54. package/packs/failure-log/CHANGELOG.md +0 -20
  55. package/packs/failure-log/README.md +0 -168
  56. package/packs/failure-log/commands/failure-add.md +0 -106
  57. package/packs/failure-log/commands/failure-list.md +0 -89
  58. package/packs/failure-log/hooks/hooks.json +0 -16
  59. package/packs/failure-log/hooks/scripts/inject-failures.sh +0 -64
  60. package/packs/failure-log/skills/failure-log-manager/SKILL.md +0 -164
  61. package/packs/flutter/CHANGELOG.md +0 -19
  62. package/packs/flutter/README.md +0 -170
  63. package/packs/flutter/agents/flutter-architect.md +0 -166
  64. package/packs/flutter/agents/flutter-builder.md +0 -303
  65. package/packs/flutter/agents/release-manager.md +0 -355
  66. package/packs/flutter/commands/fastlane-setup.md +0 -188
  67. package/packs/flutter/commands/flutter-build.md +0 -90
  68. package/packs/flutter/commands/flutter-deploy.md +0 -133
  69. package/packs/flutter/commands/flutter-test.md +0 -117
  70. package/packs/flutter/commands/signing-setup.md +0 -209
  71. package/packs/flutter/hooks/hooks.json +0 -17
  72. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +0 -193
  73. package/packs/flutter/skills/flutter-architecture/SKILL.md +0 -127
  74. package/packs/flutter/skills/store-publishing/SKILL.md +0 -163
  75. package/packs/hono/CHANGELOG.md +0 -19
  76. package/packs/hono/README.md +0 -143
  77. package/packs/hono/agents/hono-architect.md +0 -240
  78. package/packs/hono/agents/hono-builder.md +0 -285
  79. package/packs/hono/agents/hono-reviewer.md +0 -279
  80. package/packs/hono/agents/hono-tester.md +0 -346
  81. package/packs/hono/commands/middleware-create.md +0 -223
  82. package/packs/hono/commands/project-init.md +0 -306
  83. package/packs/hono/commands/route-create.md +0 -153
  84. package/packs/hono/commands/rpc-client.md +0 -263
  85. package/packs/hono/hooks/hooks.json +0 -4
  86. package/packs/hono/skills/cloudflare-bindings/SKILL.md +0 -408
  87. package/packs/hono/skills/hono-patterns/SKILL.md +0 -309
  88. package/packs/hono/skills/rpc-typesafe/SKILL.md +0 -388
  89. package/packs/hono/skills/zod-validation/SKILL.md +0 -332
  90. package/packs/nestjs/CHANGELOG.md +0 -29
  91. package/packs/nestjs/README.md +0 -75
  92. package/packs/nestjs/agents/nestjs-architect.md +0 -402
  93. package/packs/nestjs/agents/nestjs-builder.md +0 -301
  94. package/packs/nestjs/agents/nestjs-tester.md +0 -437
  95. package/packs/nestjs/commands/module-create.md +0 -369
  96. package/packs/nestjs/rules/controllers.md +0 -92
  97. package/packs/nestjs/rules/dto.md +0 -124
  98. package/packs/nestjs/rules/entities.md +0 -102
  99. package/packs/nestjs/rules/services.md +0 -106
  100. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +0 -389
  101. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +0 -365
  102. package/packs/nextjs/CHANGELOG.md +0 -36
  103. package/packs/nextjs/README.md +0 -76
  104. package/packs/nextjs/agents/frontend-tester.md +0 -680
  105. package/packs/nextjs/agents/frontend-visual.md +0 -820
  106. package/packs/nextjs/agents/nextjs-architect.md +0 -331
  107. package/packs/nextjs/agents/nextjs-modular.md +0 -433
  108. package/packs/nextjs/commands/component-create.md +0 -398
  109. package/packs/nextjs/rules/api-routes.md +0 -129
  110. package/packs/nextjs/rules/components.md +0 -106
  111. package/packs/nextjs/rules/hooks.md +0 -132
  112. package/packs/nextjs/skills/accessibility-validator/SKILL.md +0 -445
  113. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +0 -399
  114. package/packs/nextjs/skills/react-form-validator/SKILL.md +0 -569
  115. package/packs/nuxtjs/CHANGELOG.md +0 -30
  116. package/packs/nuxtjs/README.md +0 -56
  117. package/packs/nuxtjs/agents/frontend-tester.md +0 -680
  118. package/packs/nuxtjs/agents/frontend-visual.md +0 -820
  119. package/packs/nuxtjs/agents/nuxtjs-architect.md +0 -537
  120. package/packs/nuxtjs/commands/component-create.md +0 -223
  121. package/packs/nuxtjs/rules/components.md +0 -101
  122. package/packs/nuxtjs/rules/composables.md +0 -118
  123. package/packs/nuxtjs/rules/server-routes.md +0 -127
  124. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +0 -183
  125. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +0 -196
  126. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +0 -190
  127. package/packs/onboard/CHANGELOG.md +0 -22
  128. package/packs/onboard/README.md +0 -103
  129. package/packs/onboard/agents/onboard-guide.md +0 -118
  130. package/packs/onboard/commands/onboard.md +0 -313
  131. package/packs/onboard/skills/onboard-context-provider/SKILL.md +0 -98
  132. package/packs/tanstack-router/CHANGELOG.md +0 -30
  133. package/packs/tanstack-router/README.md +0 -113
  134. package/packs/tanstack-router/agents/tanstack-architect.md +0 -173
  135. package/packs/tanstack-router/agents/tanstack-builder.md +0 -360
  136. package/packs/tanstack-router/agents/tanstack-tester.md +0 -454
  137. package/packs/tanstack-router/commands/form-create.md +0 -313
  138. package/packs/tanstack-router/commands/query-create.md +0 -263
  139. package/packs/tanstack-router/commands/route-create.md +0 -190
  140. package/packs/tanstack-router/commands/table-create.md +0 -413
  141. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +0 -370
  142. package/packs/tanstack-router/skills/db-patterns/SKILL.md +0 -346
  143. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +0 -415
  144. package/packs/tanstack-router/skills/form-patterns/SKILL.md +0 -425
  145. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +0 -341
  146. package/packs/tanstack-router/skills/query-patterns/SKILL.md +0 -359
  147. package/packs/tanstack-router/skills/router-patterns/SKILL.md +0 -285
  148. package/packs/tanstack-router/skills/store-patterns/SKILL.md +0 -351
  149. package/packs/tanstack-router/skills/table-patterns/SKILL.md +0 -531
  150. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +0 -428
  151. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +0 -490
  152. package/packs/worktree/CHANGELOG.md +0 -45
  153. package/packs/worktree/README.md +0 -219
  154. package/packs/worktree/commands/wt.md +0 -93
  155. package/packs/worktree/scripts/wt.sh +0 -957
  156. package/packs/worktree/skills/worktree-manager/SKILL.md +0 -113
@@ -1,408 +0,0 @@
1
- ---
2
- name: cloudflare-bindings
3
- description: This skill activates when working with Cloudflare Workers bindings like D1, KV, R2, Durable Objects, or environment variables. It provides patterns for database access, caching, file storage, and secrets management.
4
- ---
5
-
6
- # Cloudflare Bindings
7
-
8
- Patterns for Cloudflare Workers bindings in Hono.
9
-
10
- ## Type Definitions
11
-
12
- Define all bindings in a central type:
13
-
14
- ```typescript
15
- // types/bindings.ts
16
- export type Env = {
17
- Bindings: {
18
- // D1 Database
19
- DB: D1Database
20
-
21
- // KV Namespace
22
- KV: KVNamespace
23
-
24
- // R2 Bucket
25
- BUCKET: R2Bucket
26
-
27
- // Durable Object
28
- COUNTER: DurableObjectNamespace
29
-
30
- // Environment Variables
31
- ENVIRONMENT: 'development' | 'staging' | 'production'
32
- API_KEY: string
33
- JWT_SECRET: string
34
- }
35
- Variables: {
36
- user: User
37
- requestId: string
38
- }
39
- }
40
- ```
41
-
42
- ## D1 Database
43
-
44
- ### Basic Queries
45
-
46
- ```typescript
47
- app.get('/users', async (c) => {
48
- const db = c.env.DB
49
-
50
- // Select all
51
- const { results } = await db
52
- .prepare('SELECT * FROM users WHERE deleted_at IS NULL')
53
- .all()
54
-
55
- return c.json({ data: results })
56
- })
57
-
58
- app.get('/users/:id', async (c) => {
59
- const db = c.env.DB
60
- const id = c.req.param('id')
61
-
62
- // Select one
63
- const user = await db
64
- .prepare('SELECT * FROM users WHERE id = ?')
65
- .bind(id)
66
- .first()
67
-
68
- if (!user) {
69
- return c.json({ error: 'User not found' }, 404)
70
- }
71
-
72
- return c.json({ data: user })
73
- })
74
- ```
75
-
76
- ### Insert and Update
77
-
78
- ```typescript
79
- app.post('/users', async (c) => {
80
- const db = c.env.DB
81
- const { email, name } = c.req.valid('json')
82
- const id = crypto.randomUUID()
83
-
84
- const result = await db
85
- .prepare('INSERT INTO users (id, email, name) VALUES (?, ?, ?)')
86
- .bind(id, email, name)
87
- .run()
88
-
89
- return c.json({ data: { id, email, name } }, 201)
90
- })
91
-
92
- app.put('/users/:id', async (c) => {
93
- const db = c.env.DB
94
- const id = c.req.param('id')
95
- const { name } = c.req.valid('json')
96
-
97
- await db
98
- .prepare('UPDATE users SET name = ?, updated_at = datetime("now") WHERE id = ?')
99
- .bind(name, id)
100
- .run()
101
-
102
- return c.json({ data: { id, name } })
103
- })
104
- ```
105
-
106
- ### Transactions (Batch)
107
-
108
- ```typescript
109
- app.post('/transfer', async (c) => {
110
- const db = c.env.DB
111
- const { fromId, toId, amount } = c.req.valid('json')
112
-
113
- // D1 batch for transaction-like behavior
114
- const results = await db.batch([
115
- db.prepare('UPDATE accounts SET balance = balance - ? WHERE id = ?')
116
- .bind(amount, fromId),
117
- db.prepare('UPDATE accounts SET balance = balance + ? WHERE id = ?')
118
- .bind(amount, toId),
119
- db.prepare('INSERT INTO transfers (from_id, to_id, amount) VALUES (?, ?, ?)')
120
- .bind(fromId, toId, amount)
121
- ])
122
-
123
- return c.json({ success: true })
124
- })
125
- ```
126
-
127
- ### Pagination
128
-
129
- ```typescript
130
- app.get('/users', async (c) => {
131
- const db = c.env.DB
132
- const { page, limit } = c.req.valid('query')
133
- const offset = (page - 1) * limit
134
-
135
- const [users, countResult] = await Promise.all([
136
- db.prepare('SELECT * FROM users LIMIT ? OFFSET ?')
137
- .bind(limit, offset)
138
- .all(),
139
- db.prepare('SELECT COUNT(*) as total FROM users')
140
- .first<{ total: number }>()
141
- ])
142
-
143
- return c.json({
144
- data: users.results,
145
- meta: {
146
- page,
147
- limit,
148
- total: countResult?.total || 0
149
- }
150
- })
151
- })
152
- ```
153
-
154
- ## KV Namespace
155
-
156
- ### Basic Operations
157
-
158
- ```typescript
159
- // Get
160
- app.get('/cache/:key', async (c) => {
161
- const kv = c.env.KV
162
- const key = c.req.param('key')
163
-
164
- const value = await kv.get(key)
165
-
166
- if (!value) {
167
- return c.json({ error: 'Not found' }, 404)
168
- }
169
-
170
- return c.json({ data: value })
171
- })
172
-
173
- // Get as JSON
174
- const data = await kv.get('config', 'json')
175
-
176
- // Get with metadata
177
- const { value, metadata } = await kv.getWithMetadata('key')
178
-
179
- // Put
180
- await kv.put('key', 'value')
181
-
182
- // Put with TTL (seconds)
183
- await kv.put('session', token, { expirationTtl: 3600 })
184
-
185
- // Put with expiration (Unix timestamp)
186
- await kv.put('temp', data, { expiration: Date.now() / 1000 + 3600 })
187
-
188
- // Put with metadata
189
- await kv.put('user:123', JSON.stringify(user), {
190
- metadata: { createdAt: Date.now() }
191
- })
192
-
193
- // Delete
194
- await kv.delete('key')
195
-
196
- // List keys
197
- const { keys } = await kv.list({ prefix: 'user:' })
198
- ```
199
-
200
- ### Caching Pattern
201
-
202
- ```typescript
203
- app.get('/expensive-data', async (c) => {
204
- const kv = c.env.KV
205
- const cacheKey = 'expensive-data'
206
-
207
- // Try cache first
208
- const cached = await kv.get(cacheKey, 'json')
209
- if (cached) {
210
- return c.json({ data: cached, cached: true })
211
- }
212
-
213
- // Compute expensive data
214
- const data = await computeExpensiveData()
215
-
216
- // Cache for 5 minutes
217
- await kv.put(cacheKey, JSON.stringify(data), { expirationTtl: 300 })
218
-
219
- return c.json({ data, cached: false })
220
- })
221
- ```
222
-
223
- ### Rate Limiting
224
-
225
- ```typescript
226
- const rateLimiter = createMiddleware<Env>(async (c, next) => {
227
- const kv = c.env.KV
228
- const ip = c.req.header('CF-Connecting-IP') || 'unknown'
229
- const key = `ratelimit:${ip}`
230
-
231
- const count = parseInt(await kv.get(key) || '0')
232
-
233
- if (count >= 100) {
234
- return c.json({ error: 'Rate limit exceeded' }, 429)
235
- }
236
-
237
- await kv.put(key, String(count + 1), { expirationTtl: 60 })
238
-
239
- await next()
240
- })
241
- ```
242
-
243
- ## R2 Bucket
244
-
245
- ### Upload Files
246
-
247
- ```typescript
248
- app.post('/upload', async (c) => {
249
- const bucket = c.env.BUCKET
250
- const body = await c.req.parseBody()
251
- const file = body['file'] as File
252
-
253
- if (!file) {
254
- return c.json({ error: 'No file provided' }, 400)
255
- }
256
-
257
- const key = `uploads/${crypto.randomUUID()}-${file.name}`
258
-
259
- await bucket.put(key, file.stream(), {
260
- httpMetadata: {
261
- contentType: file.type
262
- },
263
- customMetadata: {
264
- originalName: file.name,
265
- uploadedAt: new Date().toISOString()
266
- }
267
- })
268
-
269
- return c.json({ key }, 201)
270
- })
271
- ```
272
-
273
- ### Download Files
274
-
275
- ```typescript
276
- app.get('/files/:key', async (c) => {
277
- const bucket = c.env.BUCKET
278
- const key = c.req.param('key')
279
-
280
- const object = await bucket.get(key)
281
-
282
- if (!object) {
283
- return c.json({ error: 'File not found' }, 404)
284
- }
285
-
286
- const headers = new Headers()
287
- headers.set('Content-Type', object.httpMetadata?.contentType || 'application/octet-stream')
288
- headers.set('Content-Length', String(object.size))
289
-
290
- return new Response(object.body, { headers })
291
- })
292
- ```
293
-
294
- ### List Files
295
-
296
- ```typescript
297
- app.get('/files', async (c) => {
298
- const bucket = c.env.BUCKET
299
- const prefix = c.req.query('prefix') || ''
300
-
301
- const listed = await bucket.list({
302
- prefix,
303
- limit: 100
304
- })
305
-
306
- return c.json({
307
- data: listed.objects.map(obj => ({
308
- key: obj.key,
309
- size: obj.size,
310
- uploaded: obj.uploaded
311
- }))
312
- })
313
- })
314
- ```
315
-
316
- ### Delete Files
317
-
318
- ```typescript
319
- app.delete('/files/:key', async (c) => {
320
- const bucket = c.env.BUCKET
321
- const key = c.req.param('key')
322
-
323
- await bucket.delete(key)
324
-
325
- return c.body(null, 204)
326
- })
327
- ```
328
-
329
- ## Environment Variables
330
-
331
- ### Access in Handlers
332
-
333
- ```typescript
334
- app.get('/config', (c) => {
335
- const env = c.env.ENVIRONMENT
336
-
337
- return c.json({
338
- environment: env,
339
- features: {
340
- debug: env === 'development'
341
- }
342
- })
343
- })
344
- ```
345
-
346
- ### Secrets in Middleware
347
-
348
- ```typescript
349
- const authMiddleware = createMiddleware<Env>(async (c, next) => {
350
- const token = c.req.header('Authorization')?.replace('Bearer ', '')
351
-
352
- if (!token) {
353
- throw new HTTPException(401, { message: 'Missing token' })
354
- }
355
-
356
- // Use secret from environment
357
- const payload = await verify(token, c.env.JWT_SECRET)
358
- c.set('user', payload)
359
-
360
- await next()
361
- })
362
- ```
363
-
364
- ## wrangler.toml Configuration
365
-
366
- ```toml
367
- name = "my-app"
368
- main = "src/index.ts"
369
- compatibility_date = "2024-01-01"
370
-
371
- [vars]
372
- ENVIRONMENT = "production"
373
-
374
- [[d1_databases]]
375
- binding = "DB"
376
- database_name = "my-app-db"
377
- database_id = "xxxx-xxxx-xxxx"
378
-
379
- [[kv_namespaces]]
380
- binding = "KV"
381
- id = "xxxx-xxxx-xxxx"
382
-
383
- [[r2_buckets]]
384
- binding = "BUCKET"
385
- bucket_name = "my-app-bucket"
386
-
387
- # Secrets are set via wrangler secret put
388
- # wrangler secret put JWT_SECRET
389
- ```
390
-
391
- ## Local Development
392
-
393
- **.dev.vars** (for local secrets):
394
- ```
395
- JWT_SECRET=dev-secret-key
396
- API_KEY=dev-api-key
397
- ```
398
-
399
- ```bash
400
- # Run with local D1
401
- wrangler d1 create my-app-db --local
402
-
403
- # Run with local KV
404
- wrangler kv:namespace create KV --local
405
-
406
- # Start dev server
407
- wrangler dev
408
- ```
@@ -1,309 +0,0 @@
1
- ---
2
- name: hono-patterns
3
- description: This skill activates when writing Hono routes, handlers, middleware, or discussing Hono application architecture. It provides patterns for routing, middleware composition, error handling, and TypeScript integration.
4
- ---
5
-
6
- # Hono Patterns
7
-
8
- Core patterns for building Hono applications.
9
-
10
- ## Routing Patterns
11
-
12
- ### Modular Route Organization
13
-
14
- Organize routes in separate files and compose with `app.route()`:
15
-
16
- ```typescript
17
- // routes/users.ts
18
- import { Hono } from 'hono'
19
- import type { Env } from '../types/bindings'
20
-
21
- const users = new Hono<Env>()
22
-
23
- users.get('/', (c) => c.json({ users: [] }))
24
- users.get('/:id', (c) => c.json({ id: c.req.param('id') }))
25
- users.post('/', (c) => c.json({ created: true }, 201))
26
-
27
- export { users }
28
-
29
- // index.ts
30
- import { users } from './routes/users'
31
- import { posts } from './routes/posts'
32
-
33
- app.route('/api/users', users)
34
- app.route('/api/posts', posts)
35
- ```
36
-
37
- ### Route Groups with Shared Middleware
38
-
39
- ```typescript
40
- const api = new Hono<Env>()
41
-
42
- // Apply auth to all /api routes
43
- api.use('*', authMiddleware)
44
-
45
- api.route('/users', users)
46
- api.route('/posts', posts)
47
-
48
- app.route('/api', api)
49
-
50
- // Public routes remain unprotected
51
- app.get('/health', (c) => c.json({ status: 'ok' }))
52
- ```
53
-
54
- ### Chained Route Definition (for RPC)
55
-
56
- ```typescript
57
- // Chain routes for proper type inference
58
- const routes = app
59
- .get('/users', (c) => c.json({ users: [] }))
60
- .post('/users', (c) => c.json({ created: true }, 201))
61
- .get('/users/:id', (c) => c.json({ id: c.req.param('id') }))
62
-
63
- export type AppType = typeof routes
64
- ```
65
-
66
- ## Handler Patterns
67
-
68
- ### Basic Handler
69
-
70
- ```typescript
71
- app.get('/users', async (c) => {
72
- const users = await fetchUsers()
73
- return c.json(users)
74
- })
75
- ```
76
-
77
- ### Handler with Validation
78
-
79
- ```typescript
80
- import { zValidator } from '@hono/zod-validator'
81
- import { z } from 'zod'
82
-
83
- app.post('/users',
84
- zValidator('json', z.object({
85
- email: z.string().email(),
86
- name: z.string().min(1)
87
- })),
88
- async (c) => {
89
- const data = c.req.valid('json')
90
- return c.json({ id: crypto.randomUUID(), ...data }, 201)
91
- }
92
- )
93
- ```
94
-
95
- ### Factory Pattern for External Handlers
96
-
97
- Use when handlers need to be defined outside route files:
98
-
99
- ```typescript
100
- import { createFactory } from 'hono/factory'
101
- import type { Env } from '../types/bindings'
102
-
103
- const factory = createFactory<Env>()
104
-
105
- // Define handler with proper types
106
- export const listUsers = factory.createHandlers(
107
- zValidator('query', paginationSchema),
108
- async (c) => {
109
- const { page, limit } = c.req.valid('query')
110
- return c.json({ users: [], page, limit })
111
- }
112
- )
113
-
114
- // Use in routes
115
- users.get('/', ...listUsers)
116
- ```
117
-
118
- ## Middleware Patterns
119
-
120
- ### Creating Typed Middleware
121
-
122
- ```typescript
123
- import { createMiddleware } from 'hono/factory'
124
- import type { Env } from '../types/bindings'
125
-
126
- export const loggerMiddleware = createMiddleware<Env>(async (c, next) => {
127
- const start = Date.now()
128
- await next()
129
- console.log(`${c.req.method} ${c.req.url} - ${Date.now() - start}ms`)
130
- })
131
- ```
132
-
133
- ### Middleware with Variables
134
-
135
- ```typescript
136
- // Update types/bindings.ts
137
- type Env = {
138
- Variables: {
139
- user: { id: string; email: string }
140
- }
141
- }
142
-
143
- // Middleware sets variable
144
- const authMiddleware = createMiddleware<Env>(async (c, next) => {
145
- const user = await validateToken(c.req.header('Authorization'))
146
- c.set('user', user) // Type-safe!
147
- await next()
148
- })
149
-
150
- // Handler accesses variable
151
- app.get('/profile', authMiddleware, (c) => {
152
- const user = c.get('user') // Type-safe!
153
- return c.json(user)
154
- })
155
- ```
156
-
157
- ### Configurable Middleware Factory
158
-
159
- ```typescript
160
- interface CacheOptions {
161
- maxAge: number
162
- public?: boolean
163
- }
164
-
165
- export const cache = (options: CacheOptions) => {
166
- return createMiddleware<Env>(async (c, next) => {
167
- await next()
168
-
169
- const directive = options.public ? 'public' : 'private'
170
- c.header('Cache-Control', `${directive}, max-age=${options.maxAge}`)
171
- })
172
- }
173
-
174
- // Usage
175
- app.get('/static/*', cache({ maxAge: 86400, public: true }))
176
- ```
177
-
178
- ## Error Handling
179
-
180
- ### HTTPException
181
-
182
- ```typescript
183
- import { HTTPException } from 'hono/http-exception'
184
-
185
- app.get('/users/:id', async (c) => {
186
- const user = await getUser(c.req.param('id'))
187
-
188
- if (!user) {
189
- throw new HTTPException(404, { message: 'User not found' })
190
- }
191
-
192
- return c.json(user)
193
- })
194
- ```
195
-
196
- ### Global Error Handler
197
-
198
- ```typescript
199
- app.onError((err, c) => {
200
- if (err instanceof HTTPException) {
201
- return c.json({ error: err.message }, err.status)
202
- }
203
-
204
- console.error(err)
205
- return c.json({ error: 'Internal server error' }, 500)
206
- })
207
- ```
208
-
209
- ### Custom Error Classes
210
-
211
- ```typescript
212
- class NotFoundError extends HTTPException {
213
- constructor(resource: string) {
214
- super(404, { message: `${resource} not found` })
215
- }
216
- }
217
-
218
- class ValidationError extends HTTPException {
219
- constructor(errors: Record<string, string>) {
220
- super(400, { message: 'Validation failed', cause: errors })
221
- }
222
- }
223
- ```
224
-
225
- ## Response Patterns
226
-
227
- ### JSON Responses
228
-
229
- ```typescript
230
- // Success
231
- c.json({ data: users })
232
- c.json({ data: user }, 200)
233
- c.json({ data: newUser }, 201)
234
-
235
- // Errors
236
- c.json({ error: 'Not found' }, 404)
237
- c.json({ error: 'Validation failed', details: errors }, 400)
238
-
239
- // No content
240
- c.body(null, 204)
241
- ```
242
-
243
- ### Consistent Response Format
244
-
245
- ```typescript
246
- interface ApiResponse<T> {
247
- data?: T
248
- error?: string
249
- meta?: {
250
- page?: number
251
- limit?: number
252
- total?: number
253
- }
254
- }
255
-
256
- // Helper
257
- function success<T>(c: Context, data: T, status = 200) {
258
- return c.json({ data } as ApiResponse<T>, status)
259
- }
260
-
261
- function error(c: Context, message: string, status = 400) {
262
- return c.json({ error: message } as ApiResponse<never>, status)
263
- }
264
- ```
265
-
266
- ## Context Access
267
-
268
- ### Request Data
269
-
270
- ```typescript
271
- // Path params
272
- const id = c.req.param('id')
273
- const { id, slug } = c.req.param()
274
-
275
- // Query params
276
- const page = c.req.query('page')
277
- const { page, limit } = c.req.query()
278
-
279
- // Headers
280
- const auth = c.req.header('Authorization')
281
-
282
- // Body (validated)
283
- const data = c.req.valid('json')
284
- const form = c.req.valid('form')
285
- const query = c.req.valid('query')
286
- ```
287
-
288
- ### Environment and Bindings
289
-
290
- ```typescript
291
- // Environment variables
292
- const secret = c.env.JWT_SECRET
293
-
294
- // Cloudflare bindings
295
- const db = c.env.DB
296
- const kv = c.env.KV
297
- const bucket = c.env.BUCKET
298
- ```
299
-
300
- ## Best Practices
301
-
302
- 1. **Always type your app**: `new Hono<Env>()`
303
- 2. **Validate all inputs** with Zod
304
- 3. **Use `createMiddleware`** for type-safe middleware
305
- 4. **Export `AppType`** for RPC client
306
- 5. **Handle errors** with HTTPException
307
- 6. **Use proper status codes**: 200, 201, 204, 400, 401, 404, 500
308
- 7. **Organize routes** in separate files
309
- 8. **Keep handlers small** - delegate to services