refactor(utils): replace 'data: any' on server functions with their validated shapes - #1117
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
tanstack-com | 71181d1 | Commit Preview URL Branch Preview URL |
Aug 05 2026, 04:51 AM |
📝 WalkthroughWalkthroughChangesThe PR replaces untyped server-function payloads with explicit TypeScript input contracts. Runtime behavior remains unchanged. Typed server utility inputs
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
34bc342 to
27d661f
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
27d661f to
71181d1
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
CLAUDE.md says type safety is paramount and to fix at the source rather than cast. Fourteen server functions took
{ data: any }, which drops every guarantee at the boundary where it matters most — admin mutations readingdata.userId,data.capabilities, and so on with no check that those fields exist or hold the right type.users.server.tsintent-admin.server.tsstats-admin.server.tsstats.server.tsWhere the types came from
Not guessed. Each
*.server.tsfunction has a sibling in*.functions.tsthat validates the call against a valibot schema before delegating, so the schema is already the contract — these annotations just state it:For each function I pulled the fields it actually reads out of the body (
rg -o "data\.\w+") and matched them against that schema. That caughtretryIntentVersion, whoseversionIdisv.number()— annotating itstringby eye would have compiled and been wrong.listUsersreads ten fields, so it gets a namedListUsersInput. The rest are inline, matchingrequireCapabilityin the same file.They are deliberately looser than the schemas in two places, both noted in a comment on
ListUsersInput:maxLength,minValue,uuid) have no type-level equivalent.useEffectiveCapabilitiesisv.optional(v.boolean(), true), so post-validation it is always aboolean— but the annotation keeps it optional, becauselistUsersguards it with?? trueand tightening the type would make that guard dead code.Nothing is re-checked at runtime and no behaviour changes.
Note
fetchNpmDownloadChunk(stats.server.ts) is exported but has zero call sites anywhere insrc/,scripts/, ortests/. It is typed here rather than deleted so this PR stays one thing; removing it is worth doing separately.Testing
tscclean andoxlint --type-awarereports 0 errors across 916 files. Types-only change — no runtime code was touched.Summary by CodeRabbit