Skip to content

Commit dac5789

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 ede2951 commit dac5789

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

@@ -211,15 +212,18 @@ export class GraphQLUnionMutation extends UnionMutation<MutationOptions, any, Mu
211212
const properties: Record<string, ReturnType<typeof tk.modelProperty.create>> = {};
212213
for (const variant of flattenedVariants) {
213214
const fieldName = sanitizeNameForGraphQL(variantNameToString(variant.name));
215+
// Mutate the variant type with the same options (preserving input context)
216+
// so that model variants get their Input suffix.
217+
const variantMutation = this.engine.mutate(variant.type, this.options);
214218
properties[fieldName] = tk.modelProperty.create({
215219
name: fieldName,
216-
type: variant.type,
220+
type: variantMutation.mutationNode.mutatedType,
217221
optional: true, // oneOf: exactly one must be provided
218222
});
219223
}
220224

221225
const unionName = getUnionName(this.sourceType, program);
222-
const modelName = sanitizeNameForGraphQL(unionName) + "Input";
226+
const modelName = withInputSuffix(sanitizeNameForGraphQL(unionName));
223227

224228
const oneOfModel = tk.model.create({
225229
name: modelName,

0 commit comments

Comments
 (0)