Skip to content

Conversation

@FionaBronwen
Copy link

@FionaBronwen FionaBronwen commented Jan 5, 2026

Summary

This PR introduces a GraphQL mutation engine that leverages the @typespec/mutator-framework to transform TypeSpec types for GraphQL schema generation. This PR establishes the foundation with name sanitization, but the architecture will support additional transformations (e.g., input/output type splitting, visibility filtering) in future PRs.

What it does

The mutation engine wraps the mutator-framework's MutationEngine with GraphQL-specific mutation classes. These classes intercept type graph traversal to apply GraphQL-specific transformations.

Current transformation: Name sanitization ensures all type, field, and member names are valid GraphQL identifiers (e.g., $Invalid$_Invalid_, my-fieldmy_field).

Future transformations (not in this PR):

  • Input/output type splitting based on usage
  • Custom scalar mapping
  • and more :)

Architecture

Class Purpose
GraphQLMutationEngine Core engine wrapping MutationEngine
GraphQLEnumMutation Transforms enum types
GraphQLEnumMemberMutation Transforms enum members
GraphQLModelMutation Transforms model types
GraphQLModelPropertyMutation Transforms model properties
GraphQLOperationMutation Transforms operations
GraphQLScalarMutation Transforms scalar types

Changes

New Files:

  • src/mutation-engine/engine.ts - Core engine wrapping MutationEngine
  • src/mutation-engine/options.ts - GraphQL-specific mutation options
  • src/mutation-engine/mutations/*.ts - 6 mutation classes for different type kinds
  • test/mutation-engine/graphql-mutation-engine.test.ts - unit tests

Usage

import { createGraphQLMutationEngine } from "@typespec/graphql";

const engine = createGraphQLMutationEngine(program, namespace);

const enumMutation = engine.mutateEnum(myEnum);
const modelMutation = engine.mutateModel(myModel);

// Access the transformed type
console.log(enumMutation.mutatedType.name);

@FionaBronwen FionaBronwen force-pushed the fionabronwen/type-utils branch 4 times, most recently from 65f55e7 to 0bc74f1 Compare January 7, 2026 19:59
@FionaBronwen FionaBronwen force-pushed the fionabronwen/mutation-engine branch 7 times, most recently from 9f878e2 to 17e8959 Compare January 7, 2026 21:59
@FionaBronwen FionaBronwen force-pushed the fionabronwen/mutation-engine branch from 17e8959 to e651f96 Compare January 7, 2026 22:00
@FionaBronwen FionaBronwen marked this pull request as ready for review January 7, 2026 22:04
@FionaBronwen FionaBronwen removed the request for review from swatkatz January 7, 2026 22:04
],
"peerDependencies": {
"@typespec/compiler": "workspace:~",
"@typespec/emitter-framework": "^0.5.0",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably this should be workspace:~ as well?

* GraphQL mutation engine that applies GraphQL-specific transformations
* to TypeSpec types, such as name sanitization.
*/
export class GraphQLMutationEngine {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand the implementation of the mutation framework, a MutationEngine should capture the mutations for one type of transformation; i.e., we should have a specific GraphQLNamingMutationEngine, and other engines that capture the various different transformations we want to run, rather than a global "GraphQL" engine.

I'm using the HttpCanonicalizer engine as the reference point here — it implements a very specific type of transformation rather than "HTTP" transformations broadly.

It also seems that SimpleMutationEngine might be sufficient for what we need here.

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.

3 participants