Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
SdkClientType,
SdkEnumType,
SdkHttpOperation,
UsageFlags,
} from "@azure-tools/typespec-client-generator-core";
import { CSharpEmitterContext } from "../sdk-context.js";
import { CodeModel } from "../type/code-model.js";
Expand All @@ -14,11 +13,7 @@ import { fromSdkClients } from "./client-converter.js";
import { fromSdkNamespaces } from "./namespace-converter.js";
import { processServiceAuthentication } from "./service-authentication.js";
import { fromSdkType } from "./type-converter.js";
import {
containsMultiServiceClient,
firstLetterToUpperCase,
getClientNamespaceString,
} from "./utils.js";
import { firstLetterToUpperCase, getClientNamespaceString } from "./utils.js";

/**
* Creates the code model from the SDK context.
Expand Down Expand Up @@ -75,15 +70,7 @@ function parseApiVersions(
enums: SdkEnumType[],
rootClients: SdkClientType<SdkHttpOperation>[],
): string[] {
if (containsMultiServiceClient(rootClients)) {
return rootClients[0]?.apiVersions ?? [];
}

const apiVersionEnum = enums.find((e) => (e.usage & UsageFlags.ApiVersionEnum) !== 0);
if (apiVersionEnum) {
return apiVersionEnum.values.map((v) => v.value as string);
}

// Always use client.apiVersions as the source of truth.
return rootClients[0]?.apiVersions ?? [];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,4 +440,68 @@ describe("parseApiVersions", () => {
ok(barClient.apiVersions.includes("bv1"), "Bar client should include bv1");
ok(barClient.apiVersions.includes("bv2"), "Bar client should include bv2");
});

it("should include all API versions from @versioned enum", async () => {
const program = await typeSpecCompile(
`
@service(#{
title: "Test Service",
})
@versioned(Versions)
namespace TestService;

enum Versions {
v1: "v1",
v2: "v2",
v3: "v3",
}

@route("/test")
op test(): void;
`,
runner,
{ IsNamespaceNeeded: false },
);
const context = createEmitterContext(program);
const sdkContext = await createCSharpSdkContext(context);
const root = createModel(sdkContext);

// Verify all three versions are present in the root apiVersions
strictEqual(root.apiVersions.length, 3, "Should have 3 apiVersions");
ok(root.apiVersions.includes("v1"), "Should include v1");
ok(root.apiVersions.includes("v2"), "Should include v2");
ok(root.apiVersions.includes("v3"), "Should include v3");
});

it("should preserve version order from TCGC", async () => {
const program = await typeSpecCompile(
`
@service(#{
title: "Test Service",
})
@versioned(Versions)
namespace TestService;

enum Versions {
"2023-01-01",
"2024-01-01",
"2025-01-01",
}

@route("/test")
op test(): void;
`,
runner,
{ IsNamespaceNeeded: false },
);
const context = createEmitterContext(program);
const sdkContext = await createCSharpSdkContext(context);
const root = createModel(sdkContext);

// Verify versions are in the order TCGC provides them
strictEqual(root.apiVersions.length, 3, "Should have 3 apiVersions");
strictEqual(root.apiVersions[0], "2023-01-01", "First version should be 2023-01-01");
strictEqual(root.apiVersions[1], "2024-01-01", "Second version should be 2024-01-01");
strictEqual(root.apiVersions[2], "2025-01-01", "Third version should be 2025-01-01");
});
});