Skip to content

Commit 27ee72a

Browse files
committed
Fix double-suffix and oneOf variant mutation bugs
- Add withInputSuffix helper to prevent "PetInput" → "PetInputInput" - Fix oneOf input unions to mutate variant types with input context (model variants now correctly get their Input suffix, e.g. Cat → CatInput) - Refactor model.ts to use shared withInputSuffix helper
1 parent 664706d commit 27ee72a

3 files changed

Lines changed: 13 additions & 5 deletions

File tree

packages/graphql/src/lib/type-utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ export function sanitizeNameForGraphQL(name: string, prefix: string = ""): strin
113113
return name;
114114
}
115115

116+
/** Add "Input" suffix to a name if it doesn't already have one. */
117+
export function withInputSuffix(name: string): string {
118+
return name.endsWith("Input") ? name : name + "Input";
119+
}
116120

117121
/** Convert a name to CONSTANT_CASE for GraphQL enum members. */
118122
export function toEnumMemberName(enumName: string, name: string) {

packages/graphql/src/mutation-engine/mutations/model.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
type SimpleMutationOptions,
77
type SimpleMutations,
88
} from "@typespec/mutator-framework";
9-
import { sanitizeNameForGraphQL } from "../../lib/type-utils.js";
9+
import { sanitizeNameForGraphQL, withInputSuffix } from "../../lib/type-utils.js";
1010
import { GraphQLMutationOptions, GraphQLTypeContext } from "../options.js";
1111

1212
/**
@@ -38,8 +38,8 @@ export class GraphQLModelMutation extends SimpleModelMutation<SimpleMutationOpti
3838
// Apply GraphQL name sanitization
3939
model.name = sanitizeNameForGraphQL(model.name);
4040
// Input models get "Input" suffix (unless they already have it)
41-
if (this.typeContext === GraphQLTypeContext.Input && !model.name.endsWith("Input")) {
42-
model.name = model.name + "Input";
41+
if (this.typeContext === GraphQLTypeContext.Input) {
42+
model.name = withInputSuffix(model.name);
4343
}
4444
});
4545
super.mutate();

packages/graphql/src/mutation-engine/mutations/union.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
sanitizeNameForGraphQL,
1919
stripNullVariants,
2020
toTypeName,
21+
withInputSuffix,
2122
} from "../../lib/type-utils.js";
2223
import { GraphQLMutationOptions, GraphQLTypeContext } from "../options.js";
2324

@@ -196,15 +197,18 @@ export class GraphQLUnionMutation extends UnionMutation<MutationOptions, any, Mu
196197
const properties: Record<string, ReturnType<typeof tk.modelProperty.create>> = {};
197198
for (const variant of flattenedVariants) {
198199
const fieldName = sanitizeNameForGraphQL(variantNameToString(variant.name));
200+
// Mutate the variant type with the same options (preserving input context)
201+
// so that model variants get their Input suffix.
202+
const variantMutation = this.engine.mutate(variant.type, this.options);
199203
properties[fieldName] = tk.modelProperty.create({
200204
name: fieldName,
201-
type: variant.type,
205+
type: variantMutation.mutationNode.mutatedType,
202206
optional: true, // oneOf: exactly one must be provided
203207
});
204208
}
205209

206210
const unionName = getUnionName(this.sourceType, program);
207-
const modelName = sanitizeNameForGraphQL(unionName) + "Input";
211+
const modelName = withInputSuffix(sanitizeNameForGraphQL(unionName));
208212

209213
const oneOfModel = tk.model.create({
210214
name: modelName,

0 commit comments

Comments
 (0)