@kood/claude-code 0.1.6 → 0.1.9

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 (107) hide show
  1. package/dist/index.js +109 -216
  2. package/package.json +8 -2
  3. package/templates/hono/CLAUDE.md +59 -328
  4. package/templates/hono/docs/architecture/architecture.md +93 -747
  5. package/templates/hono/docs/deployment/cloudflare.md +59 -513
  6. package/templates/hono/docs/deployment/docker.md +41 -356
  7. package/templates/hono/docs/deployment/index.md +54 -190
  8. package/templates/hono/docs/deployment/railway.md +36 -306
  9. package/templates/hono/docs/deployment/vercel.md +49 -434
  10. package/templates/hono/docs/library/ai-sdk/index.md +53 -290
  11. package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
  12. package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
  13. package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
  14. package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
  15. package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
  16. package/templates/hono/docs/library/hono/env-setup.md +24 -313
  17. package/templates/hono/docs/library/hono/error-handling.md +34 -295
  18. package/templates/hono/docs/library/hono/index.md +29 -121
  19. package/templates/hono/docs/library/hono/middleware.md +21 -188
  20. package/templates/hono/docs/library/hono/rpc.md +40 -341
  21. package/templates/hono/docs/library/hono/validation.md +35 -195
  22. package/templates/hono/docs/library/pino/index.md +42 -333
  23. package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
  24. package/templates/hono/docs/library/prisma/config.md +19 -260
  25. package/templates/hono/docs/library/prisma/index.md +67 -320
  26. package/templates/hono/docs/library/zod/index.md +53 -257
  27. package/templates/npx/CLAUDE.md +62 -274
  28. package/templates/npx/docs/references/patterns.md +160 -0
  29. package/templates/tanstack-start/CLAUDE.md +100 -256
  30. package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
  31. package/templates/tanstack-start/docs/deployment/cloudflare.md +37 -424
  32. package/templates/tanstack-start/docs/deployment/index.md +57 -286
  33. package/templates/tanstack-start/docs/deployment/nitro.md +36 -318
  34. package/templates/tanstack-start/docs/deployment/railway.md +40 -409
  35. package/templates/tanstack-start/docs/deployment/vercel.md +43 -465
  36. package/templates/tanstack-start/docs/design/components.md +77 -311
  37. package/templates/tanstack-start/docs/design/index.md +113 -69
  38. package/templates/tanstack-start/docs/design/safe-area.md +51 -250
  39. package/templates/tanstack-start/docs/design/tailwind-setup.md +45 -359
  40. package/templates/tanstack-start/docs/guides/conventions.md +103 -0
  41. package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
  42. package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
  43. package/templates/tanstack-start/docs/guides/hooks.md +166 -0
  44. package/templates/tanstack-start/docs/guides/routes.md +166 -0
  45. package/templates/tanstack-start/docs/guides/services.md +143 -0
  46. package/templates/tanstack-start/docs/library/better-auth/2fa.md +27 -115
  47. package/templates/tanstack-start/docs/library/better-auth/advanced.md +22 -105
  48. package/templates/tanstack-start/docs/library/better-auth/index.md +17 -66
  49. package/templates/tanstack-start/docs/library/better-auth/plugins.md +11 -88
  50. package/templates/tanstack-start/docs/library/better-auth/session.md +12 -92
  51. package/templates/tanstack-start/docs/library/better-auth/setup.md +9 -91
  52. package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +30 -358
  53. package/templates/tanstack-start/docs/library/prisma/config.md +27 -327
  54. package/templates/tanstack-start/docs/library/prisma/crud.md +46 -174
  55. package/templates/tanstack-start/docs/library/prisma/index.md +23 -113
  56. package/templates/tanstack-start/docs/library/prisma/relations.md +31 -153
  57. package/templates/tanstack-start/docs/library/prisma/schema.md +40 -217
  58. package/templates/tanstack-start/docs/library/prisma/setup.md +12 -112
  59. package/templates/tanstack-start/docs/library/prisma/transactions.md +20 -110
  60. package/templates/tanstack-start/docs/library/tanstack-query/index.md +26 -97
  61. package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +28 -107
  62. package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +44 -146
  63. package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +33 -127
  64. package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +49 -149
  65. package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +19 -112
  66. package/templates/tanstack-start/docs/library/tanstack-start/index.md +33 -80
  67. package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +28 -106
  68. package/templates/tanstack-start/docs/library/tanstack-start/routing.md +21 -118
  69. package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +34 -246
  70. package/templates/tanstack-start/docs/library/tanstack-start/setup.md +6 -39
  71. package/templates/tanstack-start/docs/library/zod/complex-types.md +32 -156
  72. package/templates/tanstack-start/docs/library/zod/index.md +31 -144
  73. package/templates/tanstack-start/docs/library/zod/transforms.md +20 -129
  74. package/templates/tanstack-start/docs/library/zod/validation.md +39 -155
  75. package/templates/hono/docs/commands/git.md +0 -145
  76. package/templates/hono/docs/mcp/context7.md +0 -106
  77. package/templates/hono/docs/mcp/index.md +0 -176
  78. package/templates/hono/docs/mcp/sequential-thinking.md +0 -101
  79. package/templates/hono/docs/mcp/serena.md +0 -269
  80. package/templates/hono/docs/mcp/sgrep.md +0 -105
  81. package/templates/hono/docs/skills/gemini-review/SKILL.md +0 -220
  82. package/templates/hono/docs/skills/gemini-review/references/checklists.md +0 -136
  83. package/templates/hono/docs/skills/gemini-review/references/prompt-templates.md +0 -303
  84. package/templates/npx/docs/commands/git.md +0 -145
  85. package/templates/npx/docs/mcp/index.md +0 -60
  86. package/templates/npx/docs/skills/gemini-review/SKILL.md +0 -220
  87. package/templates/npx/docs/skills/gemini-review/references/checklists.md +0 -134
  88. package/templates/npx/docs/skills/gemini-review/references/prompt-templates.md +0 -301
  89. package/templates/tanstack-start/docs/commands/git.md +0 -145
  90. package/templates/tanstack-start/docs/design/accessibility.md +0 -433
  91. package/templates/tanstack-start/docs/design/color.md +0 -235
  92. package/templates/tanstack-start/docs/design/spacing.md +0 -341
  93. package/templates/tanstack-start/docs/design/typography.md +0 -324
  94. package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
  95. package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
  96. package/templates/tanstack-start/docs/guides/prettier.md +0 -189
  97. package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
  98. package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -107
  99. package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -186
  100. package/templates/tanstack-start/docs/mcp/context7.md +0 -204
  101. package/templates/tanstack-start/docs/mcp/index.md +0 -177
  102. package/templates/tanstack-start/docs/mcp/sequential-thinking.md +0 -180
  103. package/templates/tanstack-start/docs/mcp/serena.md +0 -269
  104. package/templates/tanstack-start/docs/mcp/sgrep.md +0 -174
  105. package/templates/tanstack-start/docs/skills/gemini-review/SKILL.md +0 -220
  106. package/templates/tanstack-start/docs/skills/gemini-review/references/checklists.md +0 -144
  107. package/templates/tanstack-start/docs/skills/gemini-review/references/prompt-templates.md +0 -292
@@ -6,16 +6,10 @@
6
6
 
7
7
  ## HTTPException
8
8
 
9
- ### 기본 사용
10
-
11
9
  ```typescript
12
- import { Hono } from 'hono'
13
10
  import { HTTPException } from 'hono/http-exception'
14
11
 
15
- const app = new Hono()
16
-
17
12
  app.get('/users/:id', async (c) => {
18
- const id = c.req.param('id')
19
13
  const user = await prisma.user.findUnique({ where: { id } })
20
14
 
21
15
  if (!user) {
@@ -26,49 +20,22 @@ app.get('/users/:id', async (c) => {
26
20
  })
27
21
  ```
28
22
 
29
- ### HTTPException 옵션
23
+ ### 일반적인 상태 코드
30
24
 
31
25
  ```typescript
32
- throw new HTTPException(400, {
33
- message: 'Invalid request', // 에러 메시지
34
- cause: originalError, // 원인 에러
35
- })
36
- ```
37
-
38
- ### 일반적인 HTTP 상태 코드
39
-
40
- ```typescript
41
- // 400 Bad Request - 잘못된 요청
42
- throw new HTTPException(400, { message: 'Invalid input' })
43
-
44
- // 401 Unauthorized - 인증 필요
45
- throw new HTTPException(401, { message: 'Authentication required' })
46
-
47
- // 403 Forbidden - 권한 없음
48
- throw new HTTPException(403, { message: 'Access denied' })
49
-
50
- // 404 Not Found - 리소스 없음
51
- throw new HTTPException(404, { message: 'Resource not found' })
52
-
53
- // 409 Conflict - 충돌
54
- throw new HTTPException(409, { message: 'Resource already exists' })
55
-
56
- // 422 Unprocessable Entity - 검증 실패
57
- throw new HTTPException(422, { message: 'Validation failed' })
58
-
59
- // 429 Too Many Requests - 요청 제한 초과
60
- throw new HTTPException(429, { message: 'Rate limit exceeded' })
61
-
62
- // 500 Internal Server Error - 서버 에러
63
- throw new HTTPException(500, { message: 'Internal server error' })
26
+ throw new HTTPException(400, { message: 'Invalid input' }) // Bad Request
27
+ throw new HTTPException(401, { message: 'Unauthorized' }) // 인증 필요
28
+ throw new HTTPException(403, { message: 'Access denied' }) // 권한 없음
29
+ throw new HTTPException(404, { message: 'Not found' }) // 리소스 없음
30
+ throw new HTTPException(409, { message: 'Already exists' }) // 충돌
31
+ throw new HTTPException(422, { message: 'Validation failed' }) // 검증 실패
32
+ throw new HTTPException(429, { message: 'Rate limit exceeded' })// 요청 제한
64
33
  ```
65
34
 
66
35
  ---
67
36
 
68
37
  ## 글로벌 에러 핸들러
69
38
 
70
- ### onError
71
-
72
39
  ```typescript
73
40
  import { Hono } from 'hono'
74
41
  import { HTTPException } from 'hono/http-exception'
@@ -76,144 +43,45 @@ import { HTTPException } from 'hono/http-exception'
76
43
  const app = new Hono()
77
44
 
78
45
  app.onError((err, c) => {
79
- console.error(`${err}`)
80
-
81
- // HTTPException 처리
82
- if (err instanceof HTTPException) {
83
- return c.json(
84
- {
85
- error: err.message,
86
- status: err.status,
87
- },
88
- err.status
89
- )
90
- }
91
-
92
- // 기타 에러
93
- return c.json(
94
- {
95
- error: 'Internal Server Error',
96
- message: err.message,
97
- },
98
- 500
99
- )
100
- })
101
- ```
102
-
103
- ### 상세 에러 응답
104
-
105
- ```typescript
106
- app.onError((err, c) => {
107
- const requestId = c.get('requestId')
46
+ console.error(err)
108
47
 
109
- // HTTPException
110
48
  if (err instanceof HTTPException) {
111
- return c.json(
112
- {
113
- success: false,
114
- error: {
115
- code: err.status,
116
- message: err.message,
117
- requestId,
118
- },
119
- },
120
- err.status
121
- )
49
+ return c.json({ error: err.message, status: err.status }, err.status)
122
50
  }
123
51
 
124
- // Zod 검증 에러 (이미 zValidator에서 처리된 경우)
125
- if (err.name === 'ZodError') {
126
- return c.json(
127
- {
128
- success: false,
129
- error: {
130
- code: 400,
131
- message: 'Validation failed',
132
- details: err.flatten(),
133
- requestId,
134
- },
135
- },
136
- 400
137
- )
138
- }
139
-
140
- // 개발 환경에서만 스택 트레이스 포함
141
- const isDev = c.env.NODE_ENV === 'development'
142
-
143
- return c.json(
144
- {
145
- success: false,
146
- error: {
147
- code: 500,
148
- message: 'Internal Server Error',
149
- ...(isDev && { stack: err.stack }),
150
- requestId,
151
- },
152
- },
153
- 500
154
- )
52
+ return c.json({ error: 'Internal Server Error' }, 500)
155
53
  })
156
- ```
157
54
 
158
- ---
159
-
160
- ## 404 핸들러
161
-
162
- ### notFound
163
-
164
- ```typescript
165
55
  app.notFound((c) => {
166
- return c.json(
167
- {
168
- error: 'Not Found',
169
- path: c.req.path,
170
- method: c.req.method,
171
- },
172
- 404
173
- )
56
+ return c.json({ error: 'Not Found', path: c.req.path }, 404)
174
57
  })
175
58
  ```
176
59
 
177
60
  ---
178
61
 
179
- ## 라우트별 에러 핸들러
62
+ ## 상세 에러 응답
180
63
 
181
64
  ```typescript
182
- const api = new Hono()
183
-
184
- // API 전용 에러 핸들러 (우선순위 높음)
185
- api.onError((err, c) => {
186
- console.log('API-specific error handler')
65
+ app.onError((err, c) => {
66
+ const requestId = c.get('requestId')
67
+ const isDev = c.env.NODE_ENV === 'development'
187
68
 
188
69
  if (err instanceof HTTPException) {
189
- return c.json({ apiError: err.message }, err.status)
70
+ return c.json({
71
+ success: false,
72
+ error: { status: err.status, message: err.message, requestId },
73
+ }, err.status)
190
74
  }
191
75
 
192
- return c.json({ apiError: err.message }, 500)
193
- })
194
-
195
- api.get('/error', () => {
196
- throw new Error('API error')
197
- })
198
-
199
- app.route('/api', api)
200
- ```
201
-
202
- ---
203
-
204
- ## 미들웨어에서 에러 접근
205
-
206
- ### c.error 사용
207
-
208
- ```typescript
209
- app.use(async (c, next) => {
210
- await next()
211
-
212
- // 핸들러에서 발생한 에러 접근
213
- if (c.error) {
214
- // 로깅, 모니터링 등
215
- console.error('Error occurred:', c.error)
216
- }
76
+ return c.json({
77
+ success: false,
78
+ error: {
79
+ status: 500,
80
+ message: 'Internal Server Error',
81
+ requestId,
82
+ ...(isDev && { stack: err.stack }),
83
+ },
84
+ }, 500)
217
85
  })
218
86
  ```
219
87
 
@@ -221,7 +89,7 @@ app.use(async (c, next) => {
221
89
 
222
90
  ## 커스텀 에러 클래스
223
91
 
224
- ### errors.ts
92
+ ### lib/errors.ts
225
93
 
226
94
  ```typescript
227
95
  import { HTTPException } from 'hono/http-exception'
@@ -238,18 +106,6 @@ export class UnauthorizedError extends HTTPException {
238
106
  }
239
107
  }
240
108
 
241
- export class ForbiddenError extends HTTPException {
242
- constructor(message = 'Access denied') {
243
- super(403, { message })
244
- }
245
- }
246
-
247
- export class ValidationError extends HTTPException {
248
- constructor(message: string, public details?: unknown) {
249
- super(422, { message })
250
- }
251
- }
252
-
253
109
  export class ConflictError extends HTTPException {
254
110
  constructor(resource: string) {
255
111
  super(409, { message: `${resource} already exists` })
@@ -264,137 +120,20 @@ import { NotFoundError, ConflictError } from '@/lib/errors'
264
120
 
265
121
  app.get('/users/:id', async (c) => {
266
122
  const user = await prisma.user.findUnique({ where: { id } })
267
-
268
- if (!user) {
269
- throw new NotFoundError('User')
270
- }
271
-
123
+ if (!user) throw new NotFoundError('User')
272
124
  return c.json({ user })
273
125
  })
274
126
 
275
127
  app.post('/users', async (c) => {
276
- const data = c.req.valid('json')
277
- const existing = await prisma.user.findUnique({
278
- where: { email: data.email },
279
- })
280
-
281
- if (existing) {
282
- throw new ConflictError('User with this email')
283
- }
284
-
285
- const user = await prisma.user.create({ data })
286
- return c.json({ user }, 201)
287
- })
288
- ```
289
-
290
- ---
291
-
292
- ## 스트리밍 에러 처리
293
-
294
- ```typescript
295
- import { stream } from 'hono/streaming'
296
-
297
- app.get('/stream', (c) => {
298
- return stream(
299
- c,
300
- async (stream) => {
301
- stream.onAbort(() => {
302
- console.log('Stream aborted')
303
- })
304
-
305
- await stream.write(new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]))
306
- },
307
- // 에러 핸들러 (선택적)
308
- (err, stream) => {
309
- stream.writeln('An error occurred!')
310
- console.error(err)
311
- }
312
- )
128
+ const existing = await prisma.user.findUnique({ where: { email } })
129
+ if (existing) throw new ConflictError('User with this email')
130
+ // ...
313
131
  })
314
132
  ```
315
133
 
316
134
  ---
317
135
 
318
- ## 완전한 에러 처리 설정
319
-
320
- ```typescript
321
- import { Hono } from 'hono'
322
- import { HTTPException } from 'hono/http-exception'
323
- import { logger } from 'hono/logger'
324
- import { requestId } from 'hono/request-id'
325
-
326
- type Env = {
327
- Bindings: {
328
- NODE_ENV: string
329
- }
330
- Variables: {
331
- requestId: string
332
- }
333
- }
334
-
335
- const app = new Hono<Env>()
336
-
337
- // 미들웨어
338
- app.use(logger())
339
- app.use(requestId())
340
-
341
- // 글로벌 에러 핸들러
342
- app.onError((err, c) => {
343
- const reqId = c.get('requestId')
344
- const isDev = c.env.NODE_ENV === 'development'
345
-
346
- console.error(`[${reqId}] Error:`, err)
347
-
348
- if (err instanceof HTTPException) {
349
- return c.json(
350
- {
351
- success: false,
352
- error: {
353
- status: err.status,
354
- message: err.message,
355
- requestId: reqId,
356
- },
357
- },
358
- err.status
359
- )
360
- }
361
-
362
- return c.json(
363
- {
364
- success: false,
365
- error: {
366
- status: 500,
367
- message: 'Internal Server Error',
368
- requestId: reqId,
369
- ...(isDev && { stack: err.stack }),
370
- },
371
- },
372
- 500
373
- )
374
- })
375
-
376
- // 404 핸들러
377
- app.notFound((c) => {
378
- return c.json(
379
- {
380
- success: false,
381
- error: {
382
- status: 404,
383
- message: 'Not Found',
384
- path: c.req.path,
385
- },
386
- },
387
- 404
388
- )
389
- })
390
-
391
- export default app
392
- ```
393
-
394
- ---
395
-
396
136
  ## 관련 문서
397
137
 
398
138
  - [기본 사용법](./index.md)
399
139
  - [미들웨어](./middleware.md)
400
- - [Zod 검증](./validation.md)
@@ -1,73 +1,32 @@
1
1
  # Hono - Web Framework
2
2
 
3
- > Web Standards 기반 초경량, 초고속 서버 프레임워크
3
+ > Web Standards 기반 초경량 서버 프레임워크
4
4
 
5
- ---
6
-
7
- ## 개요
8
-
9
- Hono는 Cloudflare Workers, Deno, Bun, Node.js 등 모든 JavaScript 런타임에서 동작하는 서버 프레임워크입니다.
5
+ @env-setup.md
6
+ @middleware.md
7
+ @validation.md
8
+ @error-handling.md
9
+ @rpc.md
10
10
 
11
11
  ---
12
12
 
13
13
  ## 설치
14
14
 
15
15
  ```bash
16
- # npm
17
16
  npm install hono
18
-
19
- # bun
20
- bun add hono
21
-
22
- # yarn
23
- yarn add hono
24
17
  ```
25
18
 
26
19
  ---
27
20
 
28
21
  ## 기본 사용법
29
22
 
30
- ### App 생성
31
-
32
23
  ```typescript
33
24
  import { Hono } from 'hono'
34
25
 
35
26
  const app = new Hono()
36
27
 
37
- app.get('/', (c) => {
38
- return c.text('Hello Hono!')
39
- })
40
-
41
- export default app
42
- ```
43
-
44
- ### HTTP 메서드
45
-
46
- ```typescript
47
- const app = new Hono()
48
-
49
- app.get('/', (c) => c.text('GET /'))
28
+ app.get('/', (c) => c.text('Hello Hono!'))
50
29
  app.post('/', (c) => c.text('POST /'))
51
- app.put('/', (c) => c.text('PUT /'))
52
- app.delete('/', (c) => c.text('DELETE /'))
53
- app.patch('/', (c) => c.text('PATCH /'))
54
-
55
- // 모든 메서드
56
- app.all('/hello', (c) => c.text('Any Method /hello'))
57
-
58
- // 여러 메서드
59
- app.on(['PUT', 'DELETE'], '/post', (c) => c.text('PUT or DELETE /post'))
60
- ```
61
-
62
- ---
63
-
64
- ## 라우팅
65
-
66
- ### 기본 라우팅
67
-
68
- ```typescript
69
- // 정적 경로
70
- app.get('/users', (c) => c.json({ users: [] }))
71
30
 
72
31
  // 동적 파라미터
73
32
  app.get('/users/:id', (c) => {
@@ -80,34 +39,22 @@ app.get('/posts/:postId/comments/:commentId', (c) => {
80
39
  const { postId, commentId } = c.req.param()
81
40
  return c.json({ postId, commentId })
82
41
  })
83
- ```
84
42
 
85
- ### 와일드카드
86
-
87
- ```typescript
88
- // 와일드카드 매칭
89
- app.get('/wild/*/card', (c) => {
90
- return c.text('GET /wild/*/card')
91
- })
92
-
93
- // 모든 하위 경로
94
- app.get('/api/*', (c) => {
95
- return c.text('API catch-all')
96
- })
43
+ export default app
97
44
  ```
98
45
 
99
- ### 라우트 그룹화
46
+ ---
47
+
48
+ ## 라우트 그룹화
100
49
 
101
50
  ```typescript
102
51
  const app = new Hono()
103
52
 
104
- // 서브 라우트
105
53
  const users = new Hono()
106
54
  users.get('/', (c) => c.json({ users: [] }))
107
55
  users.get('/:id', (c) => c.json({ id: c.req.param('id') }))
108
56
  users.post('/', (c) => c.json({ created: true }, 201))
109
57
 
110
- // 마운트
111
58
  app.route('/users', users)
112
59
  ```
113
60
 
@@ -115,26 +62,16 @@ app.route('/users', users)
115
62
 
116
63
  ## Context (c)
117
64
 
118
- ### Request 정보
65
+ ### Request
119
66
 
120
67
  ```typescript
121
68
  app.get('/info', (c) => {
122
- // URL 정보
123
69
  const url = c.req.url
124
70
  const path = c.req.path
125
71
  const method = c.req.method
126
-
127
- // 파라미터
128
72
  const id = c.req.param('id')
129
- const params = c.req.param() // 모든 파라미터
130
-
131
- // 쿼리 스트링
132
73
  const page = c.req.query('page')
133
- const queries = c.req.query() // 모든 쿼리
134
-
135
- // 헤더
136
74
  const auth = c.req.header('Authorization')
137
-
138
75
  return c.json({ url, path, method })
139
76
  })
140
77
  ```
@@ -142,86 +79,57 @@ app.get('/info', (c) => {
142
79
  ### Request Body
143
80
 
144
81
  ```typescript
145
- // JSON
146
82
  app.post('/json', async (c) => {
147
83
  const body = await c.req.json()
148
84
  return c.json(body)
149
85
  })
150
86
 
151
- // Form Data
152
87
  app.post('/form', async (c) => {
153
88
  const body = await c.req.parseBody()
154
89
  return c.json(body)
155
90
  })
156
-
157
- // Raw Text
158
- app.post('/text', async (c) => {
159
- const text = await c.req.text()
160
- return c.text(text)
161
- })
162
91
  ```
163
92
 
164
- ### Response 메서드
93
+ ### Response
165
94
 
166
95
  ```typescript
167
- // Text
168
- app.get('/text', (c) => c.text('Hello'))
169
-
170
- // JSON
171
- app.get('/json', (c) => c.json({ message: 'Hello' }))
172
-
173
- // JSON with status
174
- app.post('/created', (c) => c.json({ id: 1 }, 201))
175
-
176
- // HTML
177
- app.get('/html', (c) => c.html('<h1>Hello</h1>'))
178
-
179
- // Redirect
180
- app.get('/old', (c) => c.redirect('/new'))
181
-
182
- // Not Found
183
- app.get('/404', (c) => c.notFound())
96
+ c.text('Hello') // Text
97
+ c.json({ message: 'Hello' }) // JSON
98
+ c.json({ id: 1 }, 201) // JSON + status
99
+ c.html('<h1>Hello</h1>') // HTML
100
+ c.redirect('/new') // Redirect
101
+ c.notFound() // 404
184
102
  ```
185
103
 
186
104
  ---
187
105
 
188
- ## 환경 변수 (Bindings)
106
+ ## Bindings & Variables
189
107
 
190
108
  ```typescript
191
109
  type Bindings = {
192
110
  DATABASE_URL: string
193
111
  JWT_SECRET: string
194
- MY_BUCKET: R2Bucket // Cloudflare R2
195
112
  }
196
113
 
197
- const app = new Hono<{ Bindings: Bindings }>()
198
-
199
- app.get('/', (c) => {
200
- const dbUrl = c.env.DATABASE_URL
201
- const secret = c.env.JWT_SECRET
202
- return c.json({ connected: true })
203
- })
204
- ```
205
-
206
- ---
207
-
208
- ## Variables (상태 공유)
209
-
210
- ```typescript
211
114
  type Variables = {
212
115
  userId: string
213
116
  user: { id: string; name: string }
214
117
  }
215
118
 
216
- const app = new Hono<{ Variables: Variables }>()
119
+ const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()
120
+
121
+ // 환경 변수 접근
122
+ app.get('/', (c) => {
123
+ const dbUrl = c.env.DATABASE_URL
124
+ return c.json({ connected: true })
125
+ })
217
126
 
218
- // 미들웨어에서 설정
127
+ // Variables 설정/사용
219
128
  app.use(async (c, next) => {
220
129
  c.set('userId', '123')
221
130
  await next()
222
131
  })
223
132
 
224
- // 핸들러에서 사용
225
133
  app.get('/me', (c) => {
226
134
  const userId = c.get('userId')
227
135
  return c.json({ userId })
@@ -232,7 +140,7 @@ app.get('/me', (c) => {
232
140
 
233
141
  ## 관련 문서
234
142
 
235
- - [환경 변수 설정](./env-setup.md) - .env.development, .env.production 설정 ⭐
143
+ - [환경 변수 설정](./env-setup.md)
236
144
  - [미들웨어](./middleware.md)
237
145
  - [Zod 검증](./validation.md)
238
146
  - [에러 처리](./error-handling.md)