Skip to content

Commit 4c750ee

Browse files
committed
chore(ui/dependencies): update zod to version 4.3.5 and refactor API data parsing
1 parent 28f015e commit 4c750ee

File tree

8 files changed

+53
-22
lines changed

8 files changed

+53
-22
lines changed

ui-ssr/bun.lock

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ui-ssr/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"tailwindcss": "^4.0.6",
6464
"tw-animate-css": "^1.3.6",
6565
"vite-tsconfig-paths": "^5.1.4",
66-
"zod": "^3.22.4"
66+
"zod": "^4.3.5"
6767
},
6868
"devDependencies": {
6969
"@tanstack/devtools-event-client": "^0.3.2",

ui-ssr/src/api/bookmarks.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createServerFn } from '@tanstack/react-start'
33
import camelcaseKeys from 'camelcase-keys'
44
import type { z } from 'zod'
55
import { FeatureCompactSchema } from '@/types/feature'
6+
import { parseWithPrettify } from '@/utils/zod'
67

78
export interface Bookmark {
89
saeName: string
@@ -49,7 +50,10 @@ export const fetchBookmarks = createServerFn({ method: 'GET' })
4950
// Validate and parse feature data if present
5051
const bookmarks = camelCased.bookmarks.map((bookmark: any) => {
5152
if (bookmark.feature) {
52-
bookmark.feature = FeatureCompactSchema.parse(bookmark.feature)
53+
bookmark.feature = parseWithPrettify(
54+
FeatureCompactSchema,
55+
bookmark.feature,
56+
)
5357
}
5458
return bookmark
5559
})

ui-ssr/src/api/circuits.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createServerFn } from '@tanstack/react-start'
33
import camelcaseKeys from 'camelcase-keys'
44
import { z } from 'zod'
55
import type { CircuitData } from '@/types/circuit'
6+
import { parseWithPrettify } from '@/utils/zod'
67
import { CircuitDataSchema } from '@/types/circuit'
78

89
export type CircuitStatus = 'pending' | 'running' | 'completed' | 'failed'
@@ -109,7 +110,7 @@ export const fetchSaeSets = createServerFn({ method: 'GET' }).handler(
109110
async () => {
110111
const response = await fetch(`${process.env.BACKEND_URL}/sae-sets`)
111112
const data = await response.json()
112-
return z.array(z.string()).parse(data)
113+
return parseWithPrettify(z.array(z.string()), data)
113114
},
114115
)
115116

@@ -242,7 +243,7 @@ export const fetchCircuit = createServerFn({ method: 'GET' })
242243
deep: true,
243244
}) as FetchCircuitResponse
244245

245-
result.graphData = CircuitDataSchema.parse(result.graphData)
246+
result.graphData = parseWithPrettify(CircuitDataSchema, result.graphData)
246247

247248
return result
248249
},

ui-ssr/src/api/features.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { decode } from '@msgpack/msgpack'
22
import camelcaseKeys from 'camelcase-keys'
33
import { z } from 'zod'
44
import { createServerFn } from '@tanstack/react-start'
5+
import { parseWithPrettify } from '@/utils/zod'
56
import {
67
FeatureCompactSchema,
78
FeatureSampleCompactSchema,
@@ -12,7 +13,7 @@ export const fetchDictionaries = createServerFn({ method: 'GET' }).handler(
1213
async () => {
1314
const response = await fetch(`${process.env.BACKEND_URL}/dictionaries`)
1415
const data = await response.json()
15-
return z.array(z.string()).parse(data)
16+
return parseWithPrettify(z.array(z.string()), data)
1617
},
1718
)
1819

@@ -23,7 +24,8 @@ export const fetchMetrics = createServerFn({ method: 'GET' })
2324
`${process.env.BACKEND_URL}/dictionaries/${dictionary}/metrics`,
2425
)
2526
const data = await response.json()
26-
return z.object({ metrics: z.array(z.string()) }).parse(data).metrics
27+
return parseWithPrettify(z.object({ metrics: z.array(z.string()) }), data)
28+
.metrics
2729
})
2830

2931
export type MetricFilters = Record<string, { min?: number; max?: number }>
@@ -81,7 +83,7 @@ export const fetchFeature = createServerFn({ method: 'GET' })
8183
],
8284
})
8385

84-
return FeatureSchema.parse(camelCased)
86+
return parseWithPrettify(FeatureSchema, camelCased)
8587
})
8688

8789
export const fetchSamplings = createServerFn({ method: 'GET' })
@@ -100,9 +102,10 @@ export const fetchSamplings = createServerFn({ method: 'GET' })
100102
deep: true,
101103
})
102104

103-
return z
104-
.array(z.object({ name: z.string(), length: z.number() }))
105-
.parse(camelCased)
105+
return parseWithPrettify(
106+
z.array(z.object({ name: z.string(), length: z.number() })),
107+
camelCased,
108+
)
106109
})
107110

108111
export const fetchSamples = createServerFn({ method: 'GET' })
@@ -150,7 +153,7 @@ export const fetchSamples = createServerFn({ method: 'GET' })
150153
const decoded = decode(new Uint8Array(arrayBuffer)) as any
151154
const camelCased = camelcaseKeys(decoded)
152155

153-
return z.array(FeatureSampleCompactSchema).parse(camelCased)
156+
return parseWithPrettify(z.array(FeatureSampleCompactSchema), camelCased)
154157
},
155158
)
156159

@@ -188,7 +191,7 @@ export const countFeatures = createServerFn({ method: 'GET' })
188191
}
189192

190193
const data = await response.json()
191-
return z.object({ count: z.number() }).parse(data).count
194+
return parseWithPrettify(z.object({ count: z.number() }), data).count
192195
})
193196

194197
export const fetchFeatures = createServerFn({ method: 'GET' })
@@ -224,7 +227,7 @@ export const fetchFeatures = createServerFn({ method: 'GET' })
224227
],
225228
})
226229

227-
return z.array(FeatureCompactSchema).parse(camelCased)
230+
return parseWithPrettify(z.array(FeatureCompactSchema), camelCased)
228231
})
229232

230233
export const submitCustomInput = createServerFn({ method: 'POST' })
@@ -257,7 +260,7 @@ export const submitCustomInput = createServerFn({ method: 'POST' })
257260
stopPaths: ['context'],
258261
})
259262

260-
return FeatureSampleCompactSchema.parse(camelCased)
263+
return parseWithPrettify(FeatureSampleCompactSchema, camelCased)
261264
})
262265

263266
export const toggleBookmark = createServerFn({ method: 'POST' })
@@ -343,12 +346,13 @@ export const dictionaryInference = createServerFn({ method: 'POST' })
343346
],
344347
})
345348

346-
return z
347-
.array(
349+
return parseWithPrettify(
350+
z.array(
348351
z.object({
349352
feature: FeatureCompactSchema,
350353
inference: FeatureSampleCompactSchema,
351354
}),
352-
)
353-
.parse(camelCased)
355+
),
356+
camelCased,
357+
)
354358
})

ui-ssr/src/routes/circuit.$id.index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { AlertCircle, Loader2 } from 'lucide-react'
99
import { useCallback, useMemo, useState } from 'react'
1010
import { z } from 'zod'
1111
import type { CircuitData, FeatureNode, VisState } from '@/types/circuit'
12+
import { parseWithPrettify } from '@/utils/zod'
1213
import {
1314
circuitQueryOptions,
1415
circuitStatusQueryOptions,
@@ -35,7 +36,7 @@ const searchParamsSchema = z.object({
3536
})
3637

3738
export const Route = createFileRoute('/circuit/$id/')({
38-
validateSearch: searchParamsSchema,
39+
validateSearch: (search) => parseWithPrettify(searchParamsSchema, search),
3940
staticData: {
4041
fullScreen: true,
4142
},

ui-ssr/src/routes/dictionaries.$dictionaryName.features.$featureIndex.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Link, createFileRoute, useNavigate } from '@tanstack/react-router'
22
import { useEffect, useState } from 'react'
33
import { z } from 'zod'
44
import { ChevronLeft, ChevronRight } from 'lucide-react'
5+
import { parseWithPrettify } from '@/utils/zod'
56
import { Button } from '@/components/ui/button'
67
import { FeatureBookmarkButton } from '@/components/feature/bookmark-button'
78
import { FeatureCard } from '@/components/feature/feature-card'
@@ -28,7 +29,7 @@ const searchParamsSchema = z.object({
2829
export const Route = createFileRoute(
2930
'/dictionaries/$dictionaryName/features/$featureIndex',
3031
)({
31-
validateSearch: searchParamsSchema,
32+
validateSearch: (search) => parseWithPrettify(searchParamsSchema, search),
3233
staticData: {
3334
fullScreen: true,
3435
},

ui-ssr/src/utils/zod.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { z } from 'zod'
2+
3+
export function parseWithPrettify<T>(schema: z.ZodType<T>, data: unknown): T {
4+
try {
5+
return schema.parse(data)
6+
} catch (error) {
7+
if (error instanceof z.ZodError) {
8+
// Use built-in prettifyError from Zod 4
9+
const message = z.prettifyError(error)
10+
throw new Error(message)
11+
}
12+
throw error
13+
}
14+
}

0 commit comments

Comments
 (0)