Skip to content

fix: add AST extraction to serving type generator and move types to shared/#279

Merged
pkosiec merged 11 commits intomainfrom
pkosiec/serving-typegen
Apr 20, 2026
Merged

fix: add AST extraction to serving type generator and move types to shared/#279
pkosiec merged 11 commits intomainfrom
pkosiec/serving-typegen

Conversation

@pkosiec
Copy link
Copy Markdown
Member

@pkosiec pkosiec commented Apr 16, 2026

Summary

Move generated appkit-types/ from client/src/ to shared/ so both client and server can consume the generated types. Add AST-based endpoint discovery, server-side type-checking, and fix the serving plugin to work correctly with generated types.

What changed

  • Generated types → shared/: Output moved from client/src/appkit-types/ to shared/appkit-types/. Tsconfigs updated. Old files cleaned up automatically on first regeneration.
  • AST endpoint discovery: The serving type generator now parses server/index.ts to extract serving({ endpoints: {...} }) config — no manual config needed in vite.config.ts.
  • Server type-checking in template: build:server previously only ran tsdown (transpile-only, no type-checking), while the client already ran tsc -b before vite build. Added noEmit: true to tsconfig.server.json so tsc -b can type-check without emitting files — tsdown handles all JS output and only reads the tsconfig for path aliases and module resolution, ignoring emit options. Both sides are now symmetric: type-check (tsc -b) → bundle (tsdown/vite).
  • ServingFactory adapts to endpoint count: Single endpoint → alias optional. Multiple endpoints → alias required for disambiguation.
  • Unnamed serving mode registers both URL patterns: /api/serving/invoke (legacy) and /api/serving/default/invoke (type-generated clients) both work.
  • Auto-migration for existing apps: When type generation runs on an existing app with old-style configs, it automatically patches project files (see migration details below).

Auto-migration for existing apps

Existing apps scaffolded from older templates have config files that still reference the old client/src/appkit-types/ location. The type generator now automatically patches these on the next run:

File What changes Detection
tsconfig.client.json Adds "shared/appkit-types" to include Checks if already present
tsconfig.server.json Removes outDir/declaration/declarationMap/sourceMap, adds noEmit: true Checks if outDir exists
package.json Updates build:server and typecheck scripts to use tsc -b Exact-match on old script values

Characteristics:

  • Idempotent — each sub-migration checks current file state, skips if already migrated
  • Runs once per session — dedup flag prevents double execution when both analytics and serving generators fire
  • Best-effort — missing files or parse failures are silently skipped
  • Opt-out — set "appkit": { "autoMigrate": false } in package.json to disable

Note: JSONC comments in tsconfig files (/* Emit */, // comment) are stripped during migration since JSON.parse requires strict JSON. This only affects the one-time migration write-back.

Demo

Rough, but shows that everything works as it should. I also deployed those apps - no issues.

ms-demo-raw.mp4

(btw the second schema should be unresolved as that endpoint doesn't expose OpenAPI)

Type generation migration:

migration.mp4

@pkosiec pkosiec force-pushed the pkosiec/serving-typegen branch from 1cab794 to 6240b19 Compare April 16, 2026 10:25
@pkosiec pkosiec marked this pull request as ready for review April 16, 2026 14:55
@pkosiec pkosiec force-pushed the pkosiec/serving-typegen branch 3 times, most recently from 8c2ba06 to 3d80175 Compare April 20, 2026 10:15
Comment thread packages/appkit/src/type-generator/index.ts Outdated
Comment thread packages/appkit/src/type-generator/vite-plugin.ts
@pkosiec pkosiec enabled auto-merge (squash) April 20, 2026 17:08
@pkosiec pkosiec disabled auto-merge April 20, 2026 17:14
pkosiec added 11 commits April 20, 2026 19:30
…hared/

The CLI generate-types command was falling back to the DATABRICKS_SERVING_ENDPOINT_NAME
env var instead of extracting endpoint aliases from server.ts, producing a single
"default" key instead of the actual aliases (e.g., "first", "second", "third"). This
causes build failures when client code references typed endpoint aliases.

Additionally, generated type declarations are moved from client/src/appkit-types/ to
shared/appkit-types/ so both server and client tsconfigs can see the ServingEndpointRegistry
module augmentation (server tsconfig already includes shared/**/*).

Co-authored-by: Isaac
The outFile path changed from client/src/ to shared/ but the test
assertion was not updated.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
…r build

- Move serving types gitignore from client/src/ to shared/ (dev-playground + template)
- Add old file cleanup in generator to prevent duplicate module augmentation
- Add tsc -b to template build:server for type-checking parity with build:client
- Simplify template typecheck script to use tsc -b consistently

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
Mirror the serving types cleanup — remove stale
client/src/appkit-types/analytics.d.ts after generating at the new
shared/ location.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
- Extract removeOldGeneratedTypes into migration.ts to avoid duplication
  and circular dependency between index.ts and serving/generator.ts
- Add try-catch to resolveEndpointsFromServerFile so AST parse failures
  fall back gracefully to env var
- Remove unused root variable in analytics vite-plugin
- Clean up template tsconfig.server.json: remove dead emit options
  (outDir, declaration, declarationMap, sourceMap) since noEmit is set

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
ServingFactory now adapts based on endpoint count:
- Empty registry: alias optional, untyped
- Single key: alias optional, fully typed (defaults to the only endpoint)
- Multiple keys: alias required for disambiguation

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
… clients

When serving() is called without explicit endpoints (unnamed mode), the
type generator still creates a "default" alias. Client hooks then
construct /api/serving/default/invoke, but the server only had /invoke
registered — causing a 404.

Now unnamed mode registers both /invoke and /:alias/invoke (same for
stream) so both URL patterns work.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
When type generation runs, automatically patch existing apps' config
files to match the new shared/appkit-types/ output location:

- tsconfig.client.json: add "shared/appkit-types" to include
- tsconfig.server.json: switch from emit mode to noEmit
- package.json: update build:server and typecheck scripts

Each sub-migration is idempotent (content-based detection, no marker
files). Opt-out via "appkit": { "autoMigrate": false } in package.json.
Vite plugins now pass projectRoot explicitly to generators.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
- Log warnings on migration sub-function failures instead of silent catch
- Track migrated projects per-root (Set) instead of global boolean flag
- Validate resolveProjectRoot output by checking for package.json
- Add compile-time type tests for IsUnion and ServingFactory conditional
- Update CLI help text examples to reference shared/appkit-types/ paths

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
…Types.d.ts)

Target the actually shipped filenames for old type cleanup instead of
the intermediate appkit-types/ directory that was never released.
Fix outdated JSDoc comments referencing old paths.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
@pkosiec pkosiec force-pushed the pkosiec/serving-typegen branch from 089a8c9 to 3c4f218 Compare April 20, 2026 17:32
@pkosiec pkosiec enabled auto-merge (squash) April 20, 2026 17:32
@pkosiec pkosiec merged commit 422afb3 into main Apr 20, 2026
7 checks passed
@pkosiec pkosiec deleted the pkosiec/serving-typegen branch April 20, 2026 17:38
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.

2 participants