-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat: generate schemas from types, improve type definitions #1292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
ochafik
wants to merge
5
commits into
main
Choose a base branch
from
ochafik/ts2zod-library-approach
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit: |
b093040 to
400cfa6
Compare
9c79016 to
2ca16dc
Compare
This refactors the type generation approach to use the ts-to-zod library
for converting TypeScript types to Zod schemas, replacing the previous
manual schema generation.
Key changes:
- Add scripts/generate-schemas.ts using ts-to-zod as a library with:
- Custom pre-processing to inject SDK-specific features (Base64 validation,
description JSDoc tags, RELATED_TASK_META_KEY)
- Post-processing transforms for strict() mode, discriminatedUnions, enums
- AST-based schema post-processing with ts-morph for robust transformations
- Generate src/generated/sdk.types.ts (pre-processed TypeScript types)
- Generate src/generated/sdk.schemas.ts (Zod schemas with SDK conventions)
- Refactor src/types.ts to re-export most schemas from generated code
- Convert Request/Notification/Result from intersection to union types
for better type narrowing in switch statements
- Add union types: McpRequest, McpNotification, McpResult for type guards
- Fix test files for union type compatibility and new schema structures
- Add comprehensive schema comparison tests
The generated schemas maintain full compatibility with the existing API
while improving type safety and reducing manual maintenance burden.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
0e236d5 to
ac367a9
Compare
- Generate schemas during `npm run build` - Add `npm run check:schemas` script to verify generated files are in sync - Run schema sync check in CI after build to catch uncommitted changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ac367a9 to
ff03e42
Compare
Replace manual BASE_TO_UNION_CONFIG (46 items) with auto-discovery that: - Finds interfaces transitively extending Request/Notification/Result - Finds type aliases referencing the base type (e.g., EmptyResult = Result) - Filters by naming convention (*Request, *Notification, *Result) - Excludes abstract bases via small exclusion list (4 items) This eliminates maintenance burden when spec adds new request/result types. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add --if-changed flag that skips regeneration if outputs are newer than inputs - Use this flag in build script for faster incremental builds - Move prettier formatting inside the script for cleaner integration Benchmarks: - Full generation: ~5.3s - With --if-changed (skip): ~1.0s (tsx startup only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
68a830e to
2421901
Compare
Restructure generate-schemas.ts with clear separation of concerns: - TYPE_TRANSFORMS: Adapt spec types for SDK (extends clauses, extensions) - TYPE_CLEANUP_TRANSFORMS: Prepare for export (remove index sigs, create unions) - SCHEMA_TRANSFORMS: Post-process ts-to-zod output for Zod v4 Key improvements: - `named()` helper creates programmatic names for parameterized transforms (e.g., `extendsClause(JSONRPCRequest→Request)`) - `applyTransforms()` runs pipelines with consistent logging - Transforms are declarative arrays, easy to reorder/add/remove - Clear 3-phase pipeline visible in main() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
2421901 to
1ebf506
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds auto-generated Zod schemas and types from
spec.types.tsusing ts-to-zod + AST-based refactorings (for complete backwards compatibility), plus discriminated union types (McpRequest,McpNotification,McpResult) for better TypeScript type narrowing.See Reviewer Verification section below for scripts to compare exports between branches.
Key Features
1. Schema Generation Pipeline
2. Discriminated Union Types for Type Narrowing
3. Naming Scheme
Request,Notification,ResultMcpRequest,McpNotification,McpResult4. Client/Server Use Union Types by Default
ClientandServernow default to union types for better type narrowing out of the box:Note: This is technically a breaking change if you explicitly annotated variables with the old defaults (e.g.,
Client<Request, Notification, Result>), but this is unlikely since those were the defaults and writing them explicitly would be redundant.Schema Post-Processing
The script applies several transforms for SDK compatibility:
"zod"→"zod/v4"z.record().and(z.object())→z.looseObject().int()to ProgressTokenSchema, RequestIdSchema.default([])to content arrays for backwards compat.passthrough()to ToolSchema.outputSchemaConfiguration-Driven Transforms
Transforms are declaratively configured:
Generated Files
sdk.types.tssdk.schemas.tssdk.schemas.zod.test.tstypes.ts: Now a Thin Re-export Layer
src/types.tsis now primarily a re-export layer from the generated files:Test Results
Reviewer Verification
export-symbols.ts
Expected: Only additions (5 new exports), no removals:
McpRequest,McpNotification,McpResult- new union types for type narrowingElicitationCapabilitySchema,ErrorSchema- new schemasexport-schemas-to-json.ts
🤖 Generated with Claude Code