diff --git a/packages/http-client-csharp/emitter/src/lib/client-converter.ts b/packages/http-client-csharp/emitter/src/lib/client-converter.ts index 52586f2ddf0..2dd4c81a2cf 100644 --- a/packages/http-client-csharp/emitter/src/lib/client-converter.ts +++ b/packages/http-client-csharp/emitter/src/lib/client-converter.ts @@ -107,10 +107,16 @@ function fromSdkClient( ); } // fill children + // TODO: remove deduplication once https://github.com/Azure/typespec-azure/issues/4251 is fixed if (client.children) { - inputClient.children = client.children.map((c) => - diagnostics.pipe(fromSdkClient(sdkContext, c, rootApiVersions)), - ); + const seen = new Set(); + const children: InputClient[] = []; + for (const child of client.children) { + if (seen.has(child)) continue; + seen.add(child); + children.push(diagnostics.pipe(fromSdkClient(sdkContext, child, rootApiVersions))); + } + inputClient.children = children; } return diagnostics.wrap(inputClient); diff --git a/packages/http-client-csharp/emitter/test/Unit/client-converter.test.ts b/packages/http-client-csharp/emitter/test/Unit/client-converter.test.ts index 77c21d09e02..9d5a1b36c03 100644 --- a/packages/http-client-csharp/emitter/test/Unit/client-converter.test.ts +++ b/packages/http-client-csharp/emitter/test/Unit/client-converter.test.ts @@ -458,3 +458,88 @@ describe("client name suffix", () => { } }); }); + +describe("client children deduplication", () => { + let runner: TestHost; + + beforeEach(async () => { + runner = await createEmitterTestHost(); + }); + + it("should not have duplicate children in the code model", async () => { + const program = await typeSpecCompile( + ` + @service(#{ + title: "Test Service", + }) + @server( + "{endpoint}/client/structure/{client}", + "", + { + endpoint: url, + client: string, + } + ) + namespace TestService { + @route("/one") + @post + op one(): void; + + @route("/two") + @post + op two(): void; + + interface Foo { + @route("/three") + @post + three(): void; + } + + interface Bar { + @route("/four") + @post + four(): void; + } + } + + @client({ + name: "FirstClient", + service: TestService, + }) + namespace TestClientNs { + op one is TestService.one; + + @client + interface Group3 { + two is TestService.two; + three is TestService.Foo.three; + } + + @client + interface Group4 { + four is TestService.Bar.four; + } + } + `, + runner, + { IsNamespaceNeeded: false, IsTCGCNeeded: true }, + ); + const context = createEmitterContext(program); + const sdkContext = await createCSharpSdkContext(context); + const [root] = createModel(sdkContext); + + const client = root.clients[0]; + ok(client, "Client should exist"); + + if (client.children && client.children.length > 0) { + // Verify no duplicates by checking unique crossLanguageDefinitionIds + const childIds = client.children.map((c) => c.crossLanguageDefinitionId); + const uniqueIds = new Set(childIds); + strictEqual( + childIds.length, + uniqueIds.size, + `Client children should have no duplicates. Found: [${childIds.join(", ")}]`, + ); + } + }); +});