Skip to content

feat(cloudflare): exportAs patch directive to hoist named union type aliases#381

Open
sam-goodwin wants to merge 1 commit into
mainfrom
claude/workers-named-binding-union
Open

feat(cloudflare): exportAs patch directive to hoist named union type aliases#381
sam-goodwin wants to merge 1 commit into
mainfrom
claude/workers-named-binding-union

Conversation

@sam-goodwin

Copy link
Copy Markdown
Collaborator

Adds an exportAs property-patch directive that hoists a well-known inline union into an exported named type alias, and applies it to the Workers script-upload binding union (previously repeated anonymously inline in ~8 request/response structs).

// patches/workers/putScript.json
"metadata.bindings[]": { "exportAs": "Binding" }

generates

export interface WorkersBindingKindD1 { ... }
export interface WorkersBindingKindDurableObjectNamespace2 { ... }
// ...one exported interface per variant
export type Binding = WorkersBindingKindAI | WorkersBindingKindD1 | ... | WorkerLoaderBinding | ArtifactsBinding | RatelimitBinding;

export interface PutScriptRequest {
  metadata: { bindings?: Binding[]; ... };
}

so consumers write workers.Binding instead of Exclude<workers.PutScriptRequest["metadata"]["bindings"], undefined>[number].

  • Variant naming is source-first: a structurally identical module-private def whose name came from the upstream SDK (WorkersBindingKindD1) is promoted to export interface rather than duplicated under a new name; suffixes (WorkersBindingKindDurableObjectNamespace2) now appear only where request and response shapes genuinely differ. Patch-appended variants without an upstream name get discriminant-derived names (WorkerLoaderBinding, ArtifactsBinding, RatelimitBinding).
  • The TS-type emitter still inlines module-private refs (public types stay self-contained); only exported refs render by name. The schema emitter's ref short-circuit is generalized so the union's schema const resolves by name too.
  • Misuse fails generation loudly: one exportAs name targeting two structurally different unions, or a name colliding with an existing top-level identifier, throws.
  • Directives applied: putScript request metadata.bindings[]Binding, getScriptScriptAndVersionSetting response bindings[]SettingsBinding. Only the workers service was regenerated (−590 lines from collapsing the repeated inline unions).

Verified with bun tsc -b from the alchemy workspace root and live WorkerEnv / WorkerBinding test suites (deploying real Workers through the regenerated putScript/settings schemas).

🤖 Generated with Claude Code

…aliases

Well-known inline discriminated unions (e.g. the Workers script-upload
binding union, repeated inline in ~8 request/response structs) can now be
named at their JSON path in a patch file:

  "metadata.bindings[]": { "exportAs": "Binding" }

The hoisting pass lifts the union into an exported top-level type alias
with one exported named interface per variant. Structurally identical
module-private defs with upstream-derived names are promoted (not
duplicated); unnamed patch-appended variants get discriminant-derived
names (WorkerLoaderBinding, ArtifactsBinding). Public request/response
interfaces reference the alias by name, so consumers write
workers.Binding instead of Exclude<...["bindings"], undefined>[number].

Applied to workers: putScript request bindings -> Binding,
getScriptScriptAndVersionSetting response bindings -> SettingsBinding.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alchemy-version-bot

Copy link
Copy Markdown
Contributor

Install the packages built from this commit:

@distilled.cloud/core

bun add @distilled.cloud/core@https://pkg.distilled.cloud/core/0d915a3

@distilled.cloud/cloudflare

bun add @distilled.cloud/cloudflare@https://pkg.distilled.cloud/cloudflare/0d915a3

@distilled.cloud/planetscale

bun add @distilled.cloud/planetscale@https://pkg.distilled.cloud/planetscale/0d915a3

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