Alloy infrastructure, mutation pipeline, and simple type components#90
Merged
swatkatz merged 13 commits intoJun 9, 2026
Merged
Conversation
- Build: @alloy-js/graphql (linked local), JSX transpilation via alloy build, rollup plugin for vitest - Context: GraphQLSchemaContext provider with TypeGraph from mutation engine (single source of truth, no duplicate interface) - Components: Field and OperationField — thin translators from mutated types to Alloy GraphQL SDL components. Use resolveGraphQLTypeName for type names and decorator-based nullable state. No type-expression render-prop indirection (mutation pipeline handles all transforms). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Delete legacy emitter infrastructure (graphql-emitter.ts, registry.ts, schema-emitter.ts, type-maps.ts, types.d.ts) - New $onEmit: type-usage → mutation engine → buildTypeGraph → render (stub) - Add schema-mutator.ts: walks namespace, mutates all types via engine, produces TypeGraph. No pre-classified buckets — renderer classifies at render time using decorators and typeUsage. - Add empty-schema diagnostic when no operations exist - Emitter test updated to verify pipeline runs (rendering TBD) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests verify: - Mutated models/enums/scalars/unions/operations appear in TypeGraph - Unreachable types are excluded when omitUnreachableTypes is true - All declared types included when omitUnreachableTypes is false - T | null unions are not registered in the TypeGraph - Union wrapper models (scalar variants) are included - Array models are skipped (they're list types, not object types) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The mutation engine already handles T | null unions correctly (replaces with inner type). The pre-check was a premature optimization that added code without benefit — engine.mutate() is cached. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without this, navigateTypesInNamespace on the global namespace visits built-in TypeSpec scalars (string, int32, etc.) from the TypeSpec sub-namespace, adding them to the TypeGraph unnecessarily. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After creating synthetic wrapper models for scalar union variants, replace the variant's type reference with the wrapper model. This makes the union self-contained — all variant types are now Models, so the renderer can use variant.type.name uniformly without reconstructing wrapper names. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Thin rendering components that consume mutated types from the TypeGraph and delegate to @alloy-js/graphql. No render-time name logic — all names come from type.name (set by the mutation engine). Includes test infrastructure: renderToSDL helper and vitest config for deduping @alloy-js/core and graphql across linked packages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Models used as operation parameters now get a second mutation pass with GraphQLTypeContext.Input, producing the Input-suffixed variant (e.g., BookInput) alongside the Output variant in the TypeGraph. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only produce an Output mutation for models actually used as output (or unreferenced models defaulting to output). Input-only models now only get an Input mutation, preventing spurious output types in the TypeGraph. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When two different TypeSpec types produce the same GraphQL name (e.g., explicit model BookInput + model Book used as input both yielding "BookInput"), report an error diagnostic instead of silently overwriting in the TypeGraph. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When creating a synthetic flattened union (after null-stripping or scalar wrapping), clone the source union instead of creating from scratch. This preserves decorators and the AST node, so getDoc/getDeprecationDetails work on the flattened result. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- GraphQLUnion narrows Union.name to string (mutation engine guarantee) - $.model.is() typekit guard for variant types (established repo pattern) - No runtime throws — type safety from interface contract + narrowing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add simple type components (Enum, Scalar, Union) and input model splitting
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merge PRs #77, #83, and #79 into the feature/graphql branch.
These branches were stacked and accidentally merged into each other instead of feature/graphql.