Skip to content

feat: move TypeScript client codegen into the SDK module#9

Draft
TomChv wants to merge 1 commit into
mainfrom
feat/extract-client-codegen-in-typescript-sdk
Draft

feat: move TypeScript client codegen into the SDK module#9
TomChv wants to merge 1 commit into
mainfrom
feat/extract-client-codegen-in-typescript-sdk

Conversation

@TomChv

@TomChv TomChv commented Jul 6, 2026

Copy link
Copy Markdown
Member

Summary

Moves TypeScript client generation out of dagger/dagger's engine runtime and into this SDK module, so the module can generate a typed client for a bound module without the engine driving codegen or opening a nested engine session. The SDK receives the schema + module metadata as plain data and runs codegen in an ordinary container.

Pairs with the engine-side proposal in dagger/dagger (hack/designs/client-codegen-workflow.md), which makes client generation a normal @generate rollup generator owned by the SDK. Full design rationale lives in design/client-gen.md.

What's in it

helpers/codegen — the TypeScript client generator, ported from dagger/dagger's cmd/codegen as a standalone Go module:

  • Zero dagger.io/dagger dependency (deps: strcase, memfs, golang.org/x/mod). Engine-free: reads a pre-computed introspection schema + a meta.json (module name, engine version, dependencies) and emits client.gen.ts plus per-dependency <dep>.gen.ts files.
  • Replaces upstream's live --module-source-id GraphQL query (which needed a nested engine) with the meta.json file input.
  • DIR_SOURCE fail-closed: only GIT_SOURCE/LOCAL_SOURCE deps can be served by a generated client; anything else errors rather than silently producing an unservable client.
  • Upstream golden tests ported (dep-splitting, objects, types) to guard fidelity.

helpers/config-updator — new client config writers for the scoped-package model:

  • client-package-json: type: module, SDK-owned @dagger.io/dagger pinned to the engine version, typescript pin, and a scoped name (@dagger.io/<sanitized>-client) when unnamed.
  • client-tsconfig / client-deno-config (deno writes the npm:@dagger.io/dagger@<v> import).

typescript-sdk.dang — the dang wiring:

  • codegenBuilder / configUpdatorBuilder containers (compile the Go helpers, same pattern as moduleConfigBuilder).
  • generateClient(ws, module, path) — the workspace analogue of mod(ws, path).generate(ws).
  • generateAllClient(ws) @generate — regenerates every client registered in workspace config (currentModule.asSDK.clients).
  • Renamed generateAllgenerateAllModule for symmetry with generateAllClient.

e2egenerateClientCheck and generateAllClientCheck (client analogues of generateCheck/generateAllCheck), plus a registered client fixture in dagger.toml.

Design decisions

  • Always Remote / scoped package. A generated client is a standalone npm package that depends on @dagger.io/dagger; no bundled library is vendored here.
  • Portable + workspace. Clients must run both inside a workspace and as standalone packages, so git dependency provenance (source + refPin) is embedded into the generated serveModuleDependencies; local deps take the workspace-only guarded serve.

Testing

  • dagger --x-release=v1.0.0-beta.5 check13/13 green, including the two new client checks. The Go helpers are also independently covered (go test ./... in each).
  • More tests and manual tests to come

Known limitations / follow-ups

  • Schema source (temporary): beta.5 doesn't yet expose the engine's client-facing ModuleSource.clientSchemaIntrospectionJSON or CurrentModuleAsSDKClient.moduleSource. Until they ship, the module resolves via the polyfill and uses the module-facing introspectionSchemaJSON. Swap both in once the engine primitives land — the client is otherwise generated from a schema that hides some core types and omits self-bindings.
  • Deno client config exists in config-updator but isn't wired into clientDirectory yet.
  • The passing fixture (generate/app) has no dependencies, so serveModuleDependencies isn't yet exercised end-to-end — a dependency-bearing client fixture is a good next addition.

Add plumbing to handle client generation directly inside the typescript-sdk module.
Move the client codegen binary as a helper of this codegen.

Signed-off-by: Vasek - Tom C <tom@dagger.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant