@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.
Files changed (49) hide show
  1. package/dist/index.js +137 -3
  2. package/package.json +8 -2
  3. package/templates/hono/CLAUDE.md +53 -326
  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 +49 -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 +24 -122
  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 +64 -320
  26. package/templates/hono/docs/library/zod/index.md +53 -257
  27. package/templates/npx/CLAUDE.md +58 -276
  28. package/templates/npx/docs/references/patterns.md +160 -0
  29. package/templates/tanstack-start/CLAUDE.md +0 -4
  30. package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
  31. package/templates/tanstack-start/docs/design/index.md +119 -12
  32. package/templates/tanstack-start/docs/guides/conventions.md +103 -0
  33. package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
  34. package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
  35. package/templates/tanstack-start/docs/guides/hooks.md +166 -0
  36. package/templates/tanstack-start/docs/guides/routes.md +166 -0
  37. package/templates/tanstack-start/docs/guides/services.md +143 -0
  38. package/templates/tanstack-start/docs/library/tanstack-query/index.md +18 -2
  39. package/templates/tanstack-start/docs/library/zod/index.md +16 -1
  40. package/templates/tanstack-start/docs/design/accessibility.md +0 -163
  41. package/templates/tanstack-start/docs/design/color.md +0 -93
  42. package/templates/tanstack-start/docs/design/spacing.md +0 -122
  43. package/templates/tanstack-start/docs/design/typography.md +0 -80
  44. package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
  45. package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
  46. package/templates/tanstack-start/docs/guides/prettier.md +0 -189
  47. package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
  48. package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -48
  49. package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -74
@@ -1,12 +1,10 @@
1
1
  # Zod v4 - Schema Validation
2
2
 
3
- > TypeScript-first 스키마 선언 및 검증 라이브러리
3
+ > TypeScript-first 스키마 검증
4
4
 
5
5
  ---
6
6
 
7
- ## ⚠️ 버전 주의
8
-
9
- 이 문서는 **Zod v4** 기준입니다. v3과 API가 다릅니다.
7
+ ## 버전 주의
10
8
 
11
9
  ```typescript
12
10
  // ✅ v4 문법
@@ -17,7 +15,6 @@ z.uuid()
17
15
  // ❌ v3 문법 (사용 금지)
18
16
  z.string().email()
19
17
  z.string().url()
20
- z.string().uuid()
21
18
  ```
22
19
 
23
20
  ---
@@ -32,76 +29,40 @@ npm install zod
32
29
 
33
30
  ## 기본 타입
34
31
 
35
- ### Primitives
36
-
37
32
  ```typescript
38
33
  import { z } from 'zod'
39
34
 
40
- // 문자열
41
- const stringSchema = z.string()
42
-
43
- // 숫자
44
- const numberSchema = z.number()
45
-
46
- // 불리언
47
- const booleanSchema = z.boolean()
48
-
49
- // BigInt
50
- const bigintSchema = z.bigint()
51
-
52
- // Date
53
- const dateSchema = z.date()
54
-
55
- // Undefined / Null
56
- const undefinedSchema = z.undefined()
57
- const nullSchema = z.null()
35
+ z.string()
36
+ z.number()
37
+ z.boolean()
38
+ z.date()
39
+ z.undefined()
40
+ z.null()
58
41
  ```
59
42
 
60
- ### 문자열 검증 (v4)
43
+ ### 문자열 (v4)
61
44
 
62
45
  ```typescript
63
- // ✅ v4 전용 메서드
64
46
  z.email() // 이메일
65
47
  z.url() // URL
66
48
  z.uuid() // UUID
67
- z.cuid() // CUID
68
- z.ulid() // ULID
69
- z.ip() // IP 주소
70
-
71
- // 문자열 + 체이닝
72
- z.string().min(1) // 최소 길이
73
- z.string().max(100) // 최대 길이
74
- z.string().length(10) // 정확한 길이
75
- z.string().trim() // 앞뒤 공백 제거
76
- z.string().toLowerCase() // 소문자 변환
77
- z.string().toUpperCase() // 대문자 변환
78
- z.string().startsWith('a') // 접두사
79
- z.string().endsWith('z') // 접미사
80
- z.string().includes('test') // 포함
49
+ z.string().min(1).max(100) // 길이
50
+ z.string().trim() // 공백 제거
81
51
  z.string().regex(/^[a-z]+$/) // 정규식
82
52
  ```
83
53
 
84
- ### 숫자 검증
54
+ ### 숫자
85
55
 
86
56
  ```typescript
87
- z.number().int() // 정수
88
- z.number().positive() // 양수
89
- z.number().negative() // 음수
90
- z.number().nonnegative() // 0 이상
91
- z.number().nonpositive() // 0 이하
92
- z.number().min(1) // 최소값
93
- z.number().max(100) // 최대값
94
- z.number().multipleOf(5) // 배수
95
- z.number().finite() // 유한수
96
- z.number().safe() // 안전한 정수 범위
57
+ z.number().int() // 정수
58
+ z.number().positive() // 양수
59
+ z.number().min(1).max(100)
97
60
  ```
98
61
 
99
62
  ---
100
63
 
101
64
  ## 객체
102
65
 
103
- ### 기본 객체
104
-
105
66
  ```typescript
106
67
  const userSchema = z.object({
107
68
  id: z.string(),
@@ -111,137 +72,45 @@ const userSchema = z.object({
111
72
  })
112
73
 
113
74
  type User = z.infer<typeof userSchema>
114
- // { id: string; email: string; name: string; age: number }
115
75
  ```
116
76
 
117
77
  ### Optional / Nullable
118
78
 
119
79
  ```typescript
120
- const schema = z.object({
121
- required: z.string(),
122
- optional: z.string().optional(), // string | undefined
123
- nullable: z.string().nullable(), // string | null
124
- nullish: z.string().nullish(), // string | null | undefined
125
- })
80
+ z.string().optional() // string | undefined
81
+ z.string().nullable() // string | null
82
+ z.string().nullish() // string | null | undefined
126
83
  ```
127
84
 
128
85
  ### 기본값
129
86
 
130
87
  ```typescript
131
- const schema = z.object({
132
- name: z.string().default('Anonymous'),
133
- role: z.enum(['user', 'admin']).default('user'),
134
- active: z.boolean().default(true),
135
- })
88
+ z.string().default('Anonymous')
89
+ z.enum(['user', 'admin']).default('user')
136
90
  ```
137
91
 
138
- ### Partial / Required
92
+ ### Partial / Pick / Omit
139
93
 
140
94
  ```typescript
141
- const userSchema = z.object({
142
- name: z.string(),
143
- email: z.email(),
144
- })
145
-
146
- // 모든 필드 optional
147
- const partialSchema = userSchema.partial()
148
- // { name?: string; email?: string }
149
-
150
- // 모든 필드 required
151
- const requiredSchema = partialSchema.required()
152
- // { name: string; email: string }
153
-
154
- // 특정 필드만 partial
155
- const mixedSchema = userSchema.partial({ email: true })
156
- // { name: string; email?: string }
157
- ```
158
-
159
- ### Pick / Omit
160
-
161
- ```typescript
162
- const userSchema = z.object({
163
- id: z.string(),
164
- name: z.string(),
165
- email: z.email(),
166
- password: z.string(),
167
- })
168
-
169
- // 특정 필드만 선택
170
- const publicSchema = userSchema.pick({ id: true, name: true })
171
- // { id: string; name: string }
172
-
173
- // 특정 필드 제외
174
- const createSchema = userSchema.omit({ id: true })
175
- // { name: string; email: string; password: string }
176
- ```
177
-
178
- ### Extend / Merge
179
-
180
- ```typescript
181
- const baseSchema = z.object({
182
- id: z.string(),
183
- createdAt: z.date(),
184
- })
185
-
186
- // 확장
187
- const userSchema = baseSchema.extend({
188
- name: z.string(),
189
- email: z.email(),
190
- })
191
-
192
- // 병합
193
- const anotherSchema = z.object({
194
- updatedAt: z.date(),
195
- })
196
- const mergedSchema = baseSchema.merge(anotherSchema)
197
- ```
198
-
199
- ---
200
-
201
- ## 배열
202
-
203
- ```typescript
204
- // 기본 배열
205
- z.array(z.string())
206
-
207
- // 길이 제한
208
- z.array(z.string()).min(1)
209
- z.array(z.string()).max(10)
210
- z.array(z.string()).length(5)
211
- z.array(z.string()).nonempty()
212
-
213
- // 중복 제거 (unique는 없음, transform 사용)
214
- z.array(z.string()).transform((arr) => [...new Set(arr)])
95
+ userSchema.partial() // 모든 필드 optional
96
+ userSchema.partial({ email: true }) // 특정 필드만
97
+ userSchema.pick({ id: true, name: true })
98
+ userSchema.omit({ password: true })
215
99
  ```
216
100
 
217
101
  ---
218
102
 
219
103
  ## Enum / Union
220
104
 
221
- ### Enum
222
-
223
105
  ```typescript
224
- // Zod enum
225
- const statusSchema = z.enum(['pending', 'active', 'completed'])
226
- type Status = z.infer<typeof statusSchema>
227
- // 'pending' | 'active' | 'completed'
228
-
229
- // TypeScript enum 사용
230
- enum Role {
231
- User = 'user',
232
- Admin = 'admin',
233
- }
234
- const roleSchema = z.nativeEnum(Role)
235
- ```
236
-
237
- ### Union
106
+ // Enum
107
+ z.enum(['pending', 'active', 'completed'])
238
108
 
239
- ```typescript
240
- // 기본 union
241
- const stringOrNumber = z.union([z.string(), z.number()])
109
+ // Union
110
+ z.union([z.string(), z.number()])
242
111
 
243
- // Discriminated union
244
- const responseSchema = z.discriminatedUnion('type', [
112
+ // Discriminated Union
113
+ z.discriminatedUnion('type', [
245
114
  z.object({ type: z.literal('success'), data: z.unknown() }),
246
115
  z.object({ type: z.literal('error'), message: z.string() }),
247
116
  ])
@@ -252,12 +121,9 @@ const responseSchema = z.discriminatedUnion('type', [
252
121
  ## Coerce (타입 변환)
253
122
 
254
123
  ```typescript
255
- // Query parameter 등에서 유용
256
- z.coerce.string() // any → string
257
124
  z.coerce.number() // string → number
258
- z.coerce.boolean() // 'true'/'false' → boolean
125
+ z.coerce.boolean() // 'true' → boolean
259
126
  z.coerce.date() // string → Date
260
- z.coerce.bigint() // string → bigint
261
127
  ```
262
128
 
263
129
  ---
@@ -265,67 +131,27 @@ z.coerce.bigint() // string → bigint
265
131
  ## Transform
266
132
 
267
133
  ```typescript
268
- // 변환
269
- const schema = z.string().transform((val) => val.toUpperCase())
270
-
271
- // 타입 변환
272
- const numberToString = z.number().transform((n) => String(n))
273
-
274
- // 복합 변환
275
- const userSchema = z.object({
276
- email: z.email().transform((e) => e.toLowerCase()),
277
- name: z.string().transform((n) => n.trim()),
278
- tags: z.string().transform((s) => s.split(',').map((t) => t.trim())),
279
- })
134
+ z.email().transform((e) => e.toLowerCase())
135
+ z.string().transform((s) => s.split(','))
280
136
  ```
281
137
 
282
138
  ---
283
139
 
284
140
  ## Refine (커스텀 검증)
285
141
 
286
- ### 단일 필드
287
-
288
142
  ```typescript
289
- const passwordSchema = z.string().refine(
290
- (password) => password.length >= 8 && /[A-Z]/.test(password),
291
- { message: '8자 이상, 대문자 포함 필요' }
292
- )
293
- ```
294
-
295
- ### 객체 전체
143
+ // 단일 필드
144
+ z.string().refine((val) => val.length >= 8, {
145
+ message: '8자 이상 필요',
146
+ })
296
147
 
297
- ```typescript
298
- const schema = z.object({
148
+ // 객체 전체
149
+ z.object({
299
150
  password: z.string().min(8),
300
151
  confirmPassword: z.string(),
301
- }).refine(
302
- (data) => data.password === data.confirmPassword,
303
- {
304
- message: '비밀번호가 일치하지 않습니다',
305
- path: ['confirmPassword'], // 에러 위치 지정
306
- }
307
- )
308
- ```
309
-
310
- ### SuperRefine (고급)
311
-
312
- ```typescript
313
- const schema = z.string().superRefine((val, ctx) => {
314
- if (val.length < 8) {
315
- ctx.addIssue({
316
- code: z.ZodIssueCode.too_small,
317
- minimum: 8,
318
- type: 'string',
319
- inclusive: true,
320
- message: '8자 이상 입력하세요',
321
- })
322
- }
323
- if (!/[A-Z]/.test(val)) {
324
- ctx.addIssue({
325
- code: z.ZodIssueCode.custom,
326
- message: '대문자를 포함하세요',
327
- })
328
- }
152
+ }).refine((data) => data.password === data.confirmPassword, {
153
+ message: '비밀번호 불일치',
154
+ path: ['confirmPassword'],
329
155
  })
330
156
  ```
331
157
 
@@ -333,68 +159,40 @@ const schema = z.string().superRefine((val, ctx) => {
333
159
 
334
160
  ## 에러 처리
335
161
 
336
- ### safeParse
337
-
338
162
  ```typescript
339
- const schema = z.object({
340
- email: z.email(),
341
- age: z.number().min(0),
342
- })
343
-
344
163
  const result = schema.safeParse(input)
345
164
 
346
165
  if (result.success) {
347
- console.log(result.data) // 검증된 데이터
166
+ console.log(result.data)
348
167
  } else {
349
168
  console.log(result.error.flatten())
350
- // {
351
- // formErrors: [],
352
- // fieldErrors: {
353
- // email: ['Invalid email'],
354
- // age: ['Number must be greater than or equal to 0']
355
- // }
356
- // }
169
+ // { fieldErrors: { email: ['Invalid email'] } }
357
170
  }
358
171
  ```
359
172
 
360
- ### 커스텀 에러 메시지
173
+ ### 커스텀 에러
361
174
 
362
175
  ```typescript
363
- const schema = z.object({
364
- email: z.email({ message: '올바른 이메일을 입력하세요' }),
365
- name: z.string().min(1, { message: '이름을 입력하세요' }),
366
- age: z.number()
367
- .min(0, { message: '나이는 0 이상이어야 합니다' })
368
- .max(150, { message: '나이는 150 이하여야 합니다' }),
369
- })
176
+ z.email({ message: '올바른 이메일 입력' })
177
+ z.string().min(1, { message: '필수 입력' })
370
178
  ```
371
179
 
372
180
  ---
373
181
 
374
- ## Hono와 함께 사용
182
+ ## Hono와 함께
375
183
 
376
184
  ```typescript
377
- import { Hono } from 'hono'
378
185
  import { zValidator } from '@hono/zod-validator'
379
- import { z } from 'zod'
380
186
 
381
- const app = new Hono()
382
-
383
- // ✅ v4 문법 사용
384
- const createUserSchema = z.object({
187
+ const schema = z.object({
385
188
  email: z.email(),
386
189
  name: z.string().min(1).trim(),
387
- website: z.url().optional(),
388
190
  })
389
191
 
390
- app.post(
391
- '/users',
392
- zValidator('json', createUserSchema, (result, c) => {
192
+ app.post('/users',
193
+ zValidator('json', schema, (result, c) => {
393
194
  if (!result.success) {
394
- return c.json(
395
- { errors: result.error.flatten().fieldErrors },
396
- 400
397
- )
195
+ return c.json({ errors: result.error.flatten().fieldErrors }, 400)
398
196
  }
399
197
  }),
400
198
  (c) => {
@@ -409,5 +207,3 @@ app.post(
409
207
  ## 관련 문서
410
208
 
411
209
  - [Hono 검증](../hono/validation.md)
412
- - [복잡한 타입](./complex-types.md)
413
- - [Transform](./transforms.md)