@kood/claude-code 0.1.7 → 0.1.10
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/dist/index.js +137 -3
- package/package.json +8 -2
- package/templates/hono/CLAUDE.md +53 -326
- package/templates/hono/docs/architecture/architecture.md +93 -747
- package/templates/hono/docs/deployment/cloudflare.md +59 -513
- package/templates/hono/docs/deployment/docker.md +41 -356
- package/templates/hono/docs/deployment/index.md +49 -190
- package/templates/hono/docs/deployment/railway.md +36 -306
- package/templates/hono/docs/deployment/vercel.md +49 -434
- package/templates/hono/docs/library/ai-sdk/index.md +53 -290
- package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
- package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
- package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
- package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
- package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
- package/templates/hono/docs/library/hono/env-setup.md +24 -313
- package/templates/hono/docs/library/hono/error-handling.md +34 -295
- package/templates/hono/docs/library/hono/index.md +24 -122
- package/templates/hono/docs/library/hono/middleware.md +21 -188
- package/templates/hono/docs/library/hono/rpc.md +40 -341
- package/templates/hono/docs/library/hono/validation.md +35 -195
- package/templates/hono/docs/library/pino/index.md +42 -333
- package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
- package/templates/hono/docs/library/prisma/config.md +19 -260
- package/templates/hono/docs/library/prisma/index.md +64 -320
- package/templates/hono/docs/library/zod/index.md +53 -257
- package/templates/npx/CLAUDE.md +58 -276
- package/templates/npx/docs/references/patterns.md +160 -0
- package/templates/tanstack-start/CLAUDE.md +0 -4
- package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
- package/templates/tanstack-start/docs/design/index.md +119 -12
- package/templates/tanstack-start/docs/guides/conventions.md +103 -0
- package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
- package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
- package/templates/tanstack-start/docs/guides/hooks.md +166 -0
- package/templates/tanstack-start/docs/guides/routes.md +166 -0
- package/templates/tanstack-start/docs/guides/services.md +143 -0
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +18 -2
- package/templates/tanstack-start/docs/library/zod/index.md +16 -1
- package/templates/tanstack-start/docs/design/accessibility.md +0 -163
- package/templates/tanstack-start/docs/design/color.md +0 -93
- package/templates/tanstack-start/docs/design/spacing.md +0 -122
- package/templates/tanstack-start/docs/design/typography.md +0 -80
- package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
- package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
- package/templates/tanstack-start/docs/guides/prettier.md +0 -189
- package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
- package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -48
- package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -74
|
@@ -4,9 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
### 미들웨어 등록
|
|
7
|
+
## 기본 사용법
|
|
10
8
|
|
|
11
9
|
```typescript
|
|
12
10
|
import { Hono } from 'hono'
|
|
@@ -15,15 +13,8 @@ import { cors } from 'hono/cors'
|
|
|
15
13
|
|
|
16
14
|
const app = new Hono()
|
|
17
15
|
|
|
18
|
-
// 모든
|
|
19
|
-
app.use(
|
|
20
|
-
app.use(cors())
|
|
21
|
-
|
|
22
|
-
// 특정 경로에 적용
|
|
23
|
-
app.use('/api/*', cors())
|
|
24
|
-
|
|
25
|
-
// 특정 메서드 + 경로
|
|
26
|
-
app.post('/api/*', someMiddleware())
|
|
16
|
+
app.use(logger()) // 모든 라우트
|
|
17
|
+
app.use('/api/*', cors()) // 특정 경로
|
|
27
18
|
```
|
|
28
19
|
|
|
29
20
|
### 실행 순서
|
|
@@ -40,24 +31,19 @@ app.use(async (c, next) => {
|
|
|
40
31
|
await next()
|
|
41
32
|
console.log('3. 응답 후')
|
|
42
33
|
})
|
|
43
|
-
|
|
44
34
|
// 출력: 1 → 2 → handler → 3 → 4
|
|
45
35
|
```
|
|
46
36
|
|
|
47
37
|
---
|
|
48
38
|
|
|
49
|
-
## 커스텀 미들웨어
|
|
50
|
-
|
|
51
|
-
### createMiddleware 사용
|
|
39
|
+
## 커스텀 미들웨어
|
|
52
40
|
|
|
53
41
|
```typescript
|
|
54
42
|
import { createMiddleware } from 'hono/factory'
|
|
55
43
|
import { HTTPException } from 'hono/http-exception'
|
|
56
44
|
|
|
57
45
|
type Env = {
|
|
58
|
-
Variables: {
|
|
59
|
-
userId: string
|
|
60
|
-
}
|
|
46
|
+
Variables: { userId: string }
|
|
61
47
|
}
|
|
62
48
|
|
|
63
49
|
export const authMiddleware = createMiddleware<Env>(async (c, next) => {
|
|
@@ -67,29 +53,15 @@ export const authMiddleware = createMiddleware<Env>(async (c, next) => {
|
|
|
67
53
|
throw new HTTPException(401, { message: 'Unauthorized' })
|
|
68
54
|
}
|
|
69
55
|
|
|
70
|
-
// 토큰 검증 (예시)
|
|
71
56
|
const payload = await verifyJWT(token)
|
|
72
57
|
c.set('userId', payload.sub)
|
|
73
|
-
|
|
74
58
|
await next()
|
|
75
59
|
})
|
|
76
|
-
```
|
|
77
60
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
// 특정 라우트에 적용
|
|
61
|
+
// 사용
|
|
82
62
|
app.get('/me', authMiddleware, (c) => {
|
|
83
|
-
|
|
84
|
-
return c.json({ userId })
|
|
63
|
+
return c.json({ userId: c.get('userId') })
|
|
85
64
|
})
|
|
86
|
-
|
|
87
|
-
// 그룹에 적용
|
|
88
|
-
const api = new Hono()
|
|
89
|
-
api.use(authMiddleware)
|
|
90
|
-
api.get('/profile', (c) => c.json({ id: c.get('userId') }))
|
|
91
|
-
|
|
92
|
-
app.route('/api', api)
|
|
93
65
|
```
|
|
94
66
|
|
|
95
67
|
---
|
|
@@ -100,13 +72,7 @@ app.route('/api', api)
|
|
|
100
72
|
|
|
101
73
|
```typescript
|
|
102
74
|
import { logger } from 'hono/logger'
|
|
103
|
-
|
|
104
75
|
app.use(logger())
|
|
105
|
-
|
|
106
|
-
// 커스텀 로거
|
|
107
|
-
app.use(logger((message, ...rest) => {
|
|
108
|
-
console.log(message, ...rest)
|
|
109
|
-
}))
|
|
110
76
|
```
|
|
111
77
|
|
|
112
78
|
### CORS
|
|
@@ -114,111 +80,29 @@ app.use(logger((message, ...rest) => {
|
|
|
114
80
|
```typescript
|
|
115
81
|
import { cors } from 'hono/cors'
|
|
116
82
|
|
|
117
|
-
// 기본
|
|
118
|
-
app.use('/api/*', cors())
|
|
119
|
-
|
|
120
|
-
// 설정
|
|
121
83
|
app.use('/api/*', cors({
|
|
122
|
-
origin: 'https://example.com',
|
|
84
|
+
origin: ['https://example.com'],
|
|
123
85
|
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
124
86
|
allowHeaders: ['Content-Type', 'Authorization'],
|
|
125
87
|
credentials: true,
|
|
126
|
-
maxAge: 86400,
|
|
127
|
-
}))
|
|
128
|
-
|
|
129
|
-
// 여러 origin
|
|
130
|
-
app.use('/api/*', cors({
|
|
131
|
-
origin: ['https://example.com', 'https://app.example.com'],
|
|
132
88
|
}))
|
|
133
89
|
```
|
|
134
90
|
|
|
135
|
-
### Basic Auth
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
import { basicAuth } from 'hono/basic-auth'
|
|
139
|
-
|
|
140
|
-
app.use(
|
|
141
|
-
'/admin/*',
|
|
142
|
-
basicAuth({
|
|
143
|
-
username: 'admin',
|
|
144
|
-
password: 'secret',
|
|
145
|
-
})
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
// 여러 사용자
|
|
149
|
-
app.use(
|
|
150
|
-
'/admin/*',
|
|
151
|
-
basicAuth({
|
|
152
|
-
username: 'admin1',
|
|
153
|
-
password: 'secret1',
|
|
154
|
-
}, {
|
|
155
|
-
username: 'admin2',
|
|
156
|
-
password: 'secret2',
|
|
157
|
-
})
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
// 커스텀 검증
|
|
161
|
-
app.use(
|
|
162
|
-
'/admin/*',
|
|
163
|
-
basicAuth({
|
|
164
|
-
verifyUser: async (username, password, c) => {
|
|
165
|
-
return username === 'admin' && password === 'secret'
|
|
166
|
-
},
|
|
167
|
-
})
|
|
168
|
-
)
|
|
169
|
-
```
|
|
170
|
-
|
|
171
91
|
### Bearer Auth
|
|
172
92
|
|
|
173
93
|
```typescript
|
|
174
94
|
import { bearerAuth } from 'hono/bearer-auth'
|
|
175
95
|
|
|
176
|
-
app.use(
|
|
177
|
-
'
|
|
178
|
-
|
|
179
|
-
token: 'my-secret-token',
|
|
180
|
-
})
|
|
181
|
-
)
|
|
182
|
-
|
|
183
|
-
// 커스텀 검증
|
|
184
|
-
app.use(
|
|
185
|
-
'/api/*',
|
|
186
|
-
bearerAuth({
|
|
187
|
-
verifyToken: async (token, c) => {
|
|
188
|
-
return token === 'valid-token'
|
|
189
|
-
},
|
|
190
|
-
})
|
|
191
|
-
)
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### ETag
|
|
195
|
-
|
|
196
|
-
```typescript
|
|
197
|
-
import { etag } from 'hono/etag'
|
|
198
|
-
|
|
199
|
-
app.use('/static/*', etag())
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Compress
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
import { compress } from 'hono/compress'
|
|
206
|
-
|
|
207
|
-
app.use(compress())
|
|
96
|
+
app.use('/api/*', bearerAuth({
|
|
97
|
+
verifyToken: async (token) => token === 'valid-token',
|
|
98
|
+
}))
|
|
208
99
|
```
|
|
209
100
|
|
|
210
101
|
### Secure Headers
|
|
211
102
|
|
|
212
103
|
```typescript
|
|
213
104
|
import { secureHeaders } from 'hono/secure-headers'
|
|
214
|
-
|
|
215
105
|
app.use(secureHeaders())
|
|
216
|
-
|
|
217
|
-
// 설정
|
|
218
|
-
app.use(secureHeaders({
|
|
219
|
-
xFrameOptions: 'DENY',
|
|
220
|
-
xXssProtection: '1',
|
|
221
|
-
}))
|
|
222
106
|
```
|
|
223
107
|
|
|
224
108
|
### Request ID
|
|
@@ -229,54 +113,15 @@ import { requestId } from 'hono/request-id'
|
|
|
229
113
|
app.use('*', requestId())
|
|
230
114
|
|
|
231
115
|
app.get('/', (c) => {
|
|
232
|
-
|
|
233
|
-
return c.text(`Request ID: ${id}`)
|
|
234
|
-
})
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### Timing
|
|
238
|
-
|
|
239
|
-
```typescript
|
|
240
|
-
import { timing, startTime, endTime } from 'hono/timing'
|
|
241
|
-
|
|
242
|
-
app.use(timing())
|
|
243
|
-
|
|
244
|
-
app.get('/', async (c) => {
|
|
245
|
-
startTime(c, 'db')
|
|
246
|
-
await db.query()
|
|
247
|
-
endTime(c, 'db')
|
|
248
|
-
|
|
249
|
-
return c.json({ data: [] })
|
|
116
|
+
return c.text(`Request ID: ${c.get('requestId')}`)
|
|
250
117
|
})
|
|
251
118
|
```
|
|
252
119
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
## 미들웨어 조합
|
|
120
|
+
### Compress
|
|
256
121
|
|
|
257
122
|
```typescript
|
|
258
|
-
import {
|
|
259
|
-
|
|
260
|
-
import { cors } from 'hono/cors'
|
|
261
|
-
import { secureHeaders } from 'hono/secure-headers'
|
|
262
|
-
import { requestId } from 'hono/request-id'
|
|
263
|
-
|
|
264
|
-
const app = new Hono()
|
|
265
|
-
|
|
266
|
-
// 공통 미들웨어
|
|
267
|
-
app.use(logger())
|
|
268
|
-
app.use(requestId())
|
|
269
|
-
app.use(secureHeaders())
|
|
270
|
-
|
|
271
|
-
// API 전용
|
|
272
|
-
app.use('/api/*', cors())
|
|
273
|
-
|
|
274
|
-
// 인증 필요
|
|
275
|
-
app.use('/api/protected/*', authMiddleware)
|
|
276
|
-
|
|
277
|
-
// 라우트
|
|
278
|
-
app.get('/api/public', (c) => c.json({ public: true }))
|
|
279
|
-
app.get('/api/protected/data', (c) => c.json({ secret: 'data' }))
|
|
123
|
+
import { compress } from 'hono/compress'
|
|
124
|
+
app.use(compress())
|
|
280
125
|
```
|
|
281
126
|
|
|
282
127
|
---
|
|
@@ -287,40 +132,29 @@ app.get('/api/protected/data', (c) => c.json({ secret: 'data' }))
|
|
|
287
132
|
import { Hono } from 'hono'
|
|
288
133
|
import { createMiddleware } from 'hono/factory'
|
|
289
134
|
|
|
290
|
-
// 환경 타입 정의
|
|
291
135
|
type Env = {
|
|
292
|
-
Bindings: {
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
Variables: {
|
|
296
|
-
db: Database
|
|
297
|
-
user: User | null
|
|
298
|
-
}
|
|
136
|
+
Bindings: { DATABASE_URL: string }
|
|
137
|
+
Variables: { db: Database; user: User | null }
|
|
299
138
|
}
|
|
300
139
|
|
|
301
|
-
// 타입 안전 미들웨어
|
|
302
140
|
const dbMiddleware = createMiddleware<Env>(async (c, next) => {
|
|
303
|
-
|
|
304
|
-
c.set('db', db)
|
|
141
|
+
c.set('db', new Database(c.env.DATABASE_URL))
|
|
305
142
|
await next()
|
|
306
143
|
})
|
|
307
144
|
|
|
308
145
|
const authMiddleware = createMiddleware<Env>(async (c, next) => {
|
|
309
146
|
const token = c.req.header('Authorization')
|
|
310
|
-
|
|
311
|
-
c.set('user', user)
|
|
147
|
+
c.set('user', token ? await verifyToken(token) : null)
|
|
312
148
|
await next()
|
|
313
149
|
})
|
|
314
150
|
|
|
315
|
-
// App에서 사용
|
|
316
151
|
const app = new Hono<Env>()
|
|
317
|
-
|
|
318
152
|
app.use(dbMiddleware)
|
|
319
153
|
app.use(authMiddleware)
|
|
320
154
|
|
|
321
155
|
app.get('/users', (c) => {
|
|
322
|
-
const db = c.get('db')
|
|
323
|
-
const user = c.get('user')
|
|
156
|
+
const db = c.get('db') // Database 타입
|
|
157
|
+
const user = c.get('user') // User | null 타입
|
|
324
158
|
return c.json({ users: [] })
|
|
325
159
|
})
|
|
326
160
|
```
|
|
@@ -330,5 +164,4 @@ app.get('/users', (c) => {
|
|
|
330
164
|
## 관련 문서
|
|
331
165
|
|
|
332
166
|
- [기본 사용법](./index.md)
|
|
333
|
-
- [Zod 검증](./validation.md)
|
|
334
167
|
- [에러 처리](./error-handling.md)
|