Generate TS API from Go source - #4915
Conversation
There was a problem hiding this comment.
Pull request overview
Generates TypeScript API protocol types from Go definitions and uses them to strongly type API requests.
Changes:
- Adds the Go-to-TypeScript protocol generator and generated definitions.
- Migrates async/sync clients to generated request and response mappings.
- Integrates generation into API tooling and tests.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
internal/core/projectreference.go |
Adds generated API documentation. |
internal/core/compileroptions.go |
Marks options as API-exposed. |
internal/api/session.go |
Adds generator result/nullability annotations. |
internal/api/proto.go |
Adds generation metadata and non-null annotations. |
Herebyfile.mjs |
Adds API generation task. |
.github/copilot-instructions.md |
Documents API test requirements. |
_tools/gen-proto/main.go |
Implements protocol type generation. |
_tools/gen-proto/main_test.go |
Tests generated output. |
_packages/native-preview/test/compilerOptions.test.ts |
Removes manual synchronization tests. |
_packages/native-preview/src/api/sync/client.ts |
Types synchronous requests. |
_packages/native-preview/src/api/sync/api.ts |
Adopts generated protocol types. |
_packages/native-preview/src/api/proto.ts |
Re-exports and augments generated types. |
_packages/native-preview/src/api/proto.generated.ts |
Contains generated protocol definitions. |
_packages/native-preview/src/api/compilerOptions.ts |
Removes manual compiler-option definitions. |
_packages/native-preview/src/api/async/client.ts |
Types asynchronous requests. |
_packages/native-preview/src/api/async/api.ts |
Adopts generated protocol types. |
Suppressed comments (2)
_packages/native-preview/src/api/async/client.ts:201
- Every binary method currently requires request parameters, but this optional argument allows calls with no payload and defeats the generated request checking.
async apiRequestBinary<K extends SourceFileResponseMethod>(method: K, params?: APIMethodInfo[K]["params"]): Promise<Uint8Array | undefined> {
_packages/native-preview/src/api/sync/client.ts:104
- Every binary method currently requires request parameters, but this optional argument allows calls with no payload and defeats the generated request checking.
apiRequestBinary<K extends SourceFileResponseMethod>(method: K, params?: APIMethodInfo[K]["params"]): Uint8Array | undefined {
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
How do we want to reconcile this and #4712; that PR first? |
|
Can we wait to do this after the repo move? |
I should just be able to merge and regen the API, so in theory not bad, unless the new APIs need some extra annotations for API tests against the autogenerated types to pass. I imagine Andrew Branch (@andrewbranch) wants to give this a review before we merge it though. |
Andrew Branch (andrewbranch)
left a comment
There was a problem hiding this comment.
This is great! I wanted to do this from the beginning but it's been super backburnered. Thank you!
|
If you can be quick then yeah we can do this now! |
|
Content mappers doesn't actually add any new API endpoints so... maybe no merge conflicts? Let's find out. |
Jake Bailey (jakebailey)
left a comment
There was a problem hiding this comment.
Hope it doesn't hang again?
| // MethodResetServerTiming clears the server's collected timing totals and | ||
| // recent-request ring buffer. Like MethodGetServerTiming, it is handled by | ||
| // the connection itself and is not recorded. | ||
| MethodResetServerTiming Method = "resetServerTiming" |
There was a problem hiding this comment.
These got pushed into the connection instead of the API client, and the generator errors on them - appropriately, since they're unused in the actual Session API. So they're gone now.
And strongly type the API Client's
apiRequestmethod based on those autogenerated type mappings.The code generator works by reading the
HandleRequestmethod ofSessionand just following the type information from that to generate the types for the TS side of the API - so in the common case you just write the API backend first, and the API frontend should appear for "free" with a simplenpx hereby generate:api.There are a trio of new annotations/comments introduced in
proto.goandsession.goto support this that slightly adjust the emit on a per-field/method basis.nonnil:"true"for struct members to removenullfrom the TS type for nil-ablegotypes, and// @gen-proto-nullableand// @gen-proto-result: Tfor explicitly addingnull-ability to API methods or outright overriding their TS types (mostly to replace ananyrequired by the sync/async split onSourceFileResponsetypes with the specific type). Most of these should be made redundant by Gabriela Araujo Britto (@gabritto)'s annotations eventually, but they work for now.