Skip to content

feat: import consumer spec/FS types instead of replicating them (package mode)#18

Merged
vercel-eddie merged 1 commit into
mainfrom
feat/consumer-spec-imports
Jul 7, 2026
Merged

feat: import consumer spec/FS types instead of replicating them (package mode)#18
vercel-eddie merged 1 commit into
mainfrom
feat/consumer-spec-imports

Conversation

@vercel-eddie

Copy link
Copy Markdown
Collaborator

Why

In package mode (generators.types), each target kind's generated module replicates every consumer kind's Spec + FS interface inline (so its dependent-hook context/hook are concretely typed). A change to a widely-consumed spec — ServiceSpec, SubscriberSpec — therefore regenerates every kind that accepts it as a consumer: a one-field change (e.g. adding hpa to the subscriber spec) produces a ~12-file diff.

The shared ./host module already established the fix: emit an import instead of replicating.

What

dependentInterfaces (package mode) no longer inlines the consumer Spec/FS. VeilTypes instead emits, per consumer kind:

import type { ServiceSpec, FS as ServiceFS } from './service';
export type { ServiceSpec, ServiceFS };
  • import — local use in this module's *DependentHookContext / *DependentHook.
  • re-export — the consumer's generated dependent hooks import <Consumer>Spec / <Consumer>FS from this (target) module, so they must stay exported (an un-re-exported aliased import is TS2459).

Inline (single-file) mode is untouched — still replicates. The consumer's own module already exports its spec as <Consumer>Spec and FS as FS; veil's per-file tsc (--moduleResolution bundler) resolves the relative cross-module import, same as ./host.

Validation

  • New unit tests (pkg/build/graph_test.go): package mode imports + re-exports and does not replicate; inline mode still replicates; no-consumer kinds emit nothing.
  • Full go test ./... green.
  • Regenerated the entire vercel/api kind-type set with this build: platform/types/*.ts shrinks ~1,575 lines (12 files), the hook typecheck stays green, and every rendered _infra is byte-identical.

🤖 Generated with Claude Code

…age mode)

In package mode (`generators.types`), each target kind's generated module
replicated every consumer kind's Spec + FS interface inline, so a change to a
widely-consumed spec (e.g. ServiceSpec / SubscriberSpec) regenerated every kind
that accepts it as a consumer — a one-field change produced a many-file diff.

Instead, import each consumer's Spec + FS from the consumer's own module and
re-export them (so the consumer's dependent hooks keep importing
`<Consumer>Spec` / `<Consumer>FS` from the target module). Inline mode
(single-file output) is unchanged — it still replicates.

The consumer's own module already exports its spec as `<Consumer>Spec` and its
FS as `FS`; the per-file tsc (`--moduleResolution bundler`) resolves the
relative cross-module import, exactly like the shared `./host` module.

Verified against the api repo: regenerating all kind types shrinks them ~1575
lines with zero change to any rendered `_infra` and a green hook typecheck.
@vercel-eddie vercel-eddie marked this pull request as ready for review July 7, 2026 16:38
@vercel-eddie vercel-eddie merged commit be06f3c into main Jul 7, 2026
3 checks passed
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