Skip to content

Commit

Permalink
[tcgc] only expose top level client in SdkPackage (#1033)
Browse files Browse the repository at this point in the history
resolve: #1040
  • Loading branch information
tadelesh authored Jun 20, 2024
1 parent 1e14af8 commit eae81f8
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 32 deletions.
7 changes: 7 additions & 0 deletions .chronus/changes/client_hierarchy-2024-5-18-18-19-30.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: breaking
packages:
- "@azure-tools/typespec-client-generator-core"
---

only expose top level client in `SdkPackage`
1 change: 0 additions & 1 deletion packages/typespec-client-generator-core/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export interface SdkContext<
> extends TCGCContext {
emitContext: EmitContext<TOptions>;
experimental_sdkPackage: SdkPackage<TServiceOperation>;
__clients?: SdkClientType<TServiceOperation>[];
}

export interface SdkEmitterOptions {
Expand Down
7 changes: 1 addition & 6 deletions packages/typespec-client-generator-core/src/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,6 @@ function createSdkClientType<
// eslint-disable-next-line deprecation/deprecation
arm: client.kind === "SdkClient" ? client.arm : false,
};
context.__clients!.push(sdkClientType);
return diagnostics.wrap(sdkClientType);
}

Expand Down Expand Up @@ -613,17 +612,13 @@ export function getSdkPackage<
TServiceOperation extends SdkServiceOperation,
>(context: SdkContext<TOptions, TServiceOperation>): SdkPackage<TServiceOperation> {
const diagnostics = createDiagnosticCollector();
context.__clients = new Array<SdkClientType<TServiceOperation>>();
populateApiVersionInformation(context);
const modelsAndEnums = diagnostics.pipe(getAllModelsWithDiagnostics(context));
for (const client of listClients(context)) {
createSdkClientType(context, client);
}
const crossLanguagePackageId = diagnostics.pipe(getCrossLanguagePackageId(context));
return {
name: getClientNamespaceString(context)!,
rootNamespace: getClientNamespaceString(context)!,
clients: Array.from(context.__clients.values()),
clients: listClients(context).map((c) => diagnostics.pipe(createSdkClientType(context, c))),
models: modelsAndEnums.filter((x): x is SdkModelType => x.kind === "model"),
enums: modelsAndEnums.filter((x): x is SdkEnumType => x.kind === "enum"),
diagnostics: diagnostics.diagnostics,
Expand Down
13 changes: 10 additions & 3 deletions packages/typespec-client-generator-core/test/decorators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ import {
shouldGenerateConvenient,
shouldGenerateProtocol,
} from "../src/decorators.js";
import { SdkMethodResponse, SdkOperationGroup, UsageFlags } from "../src/interfaces.js";
import {
SdkClientType,
SdkHttpOperation,
SdkMethodResponse,
SdkOperationGroup,
UsageFlags,
} from "../src/interfaces.js";
import { getCrossLanguageDefinitionId, getCrossLanguagePackageId } from "../src/public-utils.js";
import { getAllModels } from "../src/types.js";
import { SdkTestRunner, createSdkContextTestHelper, createSdkTestRunner } from "./test-host.js";
Expand Down Expand Up @@ -3284,7 +3290,7 @@ describe("typespec-client-generator-core: decorators", () => {
`
);
const sdkPackage = runner.context.experimental_sdkPackage;
strictEqual(sdkPackage.clients.length, 2);
strictEqual(sdkPackage.clients.length, 1);
const versioningClient = sdkPackage.clients.find((x) => x.name === "VersioningClient");
ok(versioningClient);
strictEqual(versioningClient.methods.length, 2);
Expand All @@ -3306,7 +3312,8 @@ describe("typespec-client-generator-core: decorators", () => {
strictEqual(clientAccessor.name, "getInterfaceV2");
deepStrictEqual(clientAccessor.apiVersions, ["v2"]);

const interfaceV2 = sdkPackage.clients.find((x) => x.name === "InterfaceV2");
const interfaceV2 = versioningClient.methods.find((x) => x.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
ok(interfaceV2);
strictEqual(interfaceV2.methods.length, 1);

Expand Down
55 changes: 35 additions & 20 deletions packages/typespec-client-generator-core/test/package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ApiKeyAuth, OAuth2Flow, Oauth2Auth } from "@typespec/http";
import { deepStrictEqual, ok, strictEqual } from "assert";
import { beforeEach, describe, it } from "vitest";
import {
SdkClientType,
SdkCredentialParameter,
SdkCredentialType,
SdkEndpointParameter,
Expand Down Expand Up @@ -577,10 +578,11 @@ describe("typespec-client-generator-core: package", () => {
}
`);
const sdkPackage = runner.context.experimental_sdkPackage;
strictEqual(sdkPackage.clients.length, 2);
strictEqual(sdkPackage.clients.length, 1);

const mainClient = sdkPackage.clients.find((c) => c.name === "TestServiceClient");
const operationGroup = sdkPackage.clients.find((c) => c.name === "MyOperationGroup");
const operationGroup = mainClient?.methods.find((c) => c.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
ok(mainClient && operationGroup);

strictEqual(mainClient.methods.length, 1);
Expand Down Expand Up @@ -620,12 +622,17 @@ describe("typespec-client-generator-core: package", () => {
}
`);
const sdkPackage = runner.context.experimental_sdkPackage;
strictEqual(sdkPackage.clients.length, 4);
strictEqual(sdkPackage.clients.length, 1);

const mainClient = sdkPackage.clients.find((c) => c.name === "TestServiceClient");
const fooClient = sdkPackage.clients.find((c) => c.name === "Foo");
const fooBarClient = sdkPackage.clients.filter((c) => c.name === "Bar")![0];
const barClient = sdkPackage.clients.filter((c) => c.name === "Bar")![1];
const mainClient = sdkPackage.clients[0];
const fooClient = mainClient.methods.find(
(m) => m.kind === "clientaccessor" && m.name === "getFoo"
)?.response as SdkClientType<SdkHttpOperation>;
const fooBarClient = fooClient.methods.find((m) => m.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
const barClient = mainClient.methods.find(
(m) => m.kind === "clientaccessor" && m.name === "getBar"
)?.response as SdkClientType<SdkHttpOperation>;
ok(mainClient && fooClient && fooBarClient && barClient);

strictEqual(mainClient.methods.length, 2);
Expand Down Expand Up @@ -2449,12 +2456,11 @@ describe("typespec-client-generator-core: package", () => {
`
);
const sdkPackage = runnerWithCore.context.experimental_sdkPackage;
strictEqual(sdkPackage.clients.length, 2);
const client = sdkPackage.clients.find((c) => c.initialization.access === "internal");
strictEqual(sdkPackage.clients.length, 1);
const parentClient = sdkPackage.clients[0];
const client = parentClient.methods.find((x) => x.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
ok(client);
const parentClient = sdkPackage.clients.filter(
(c) => c.initialization.access === "public"
)[0];
strictEqual(client.methods.length, 2);

// TEST GET STATUS
Expand Down Expand Up @@ -2671,10 +2677,11 @@ describe("typespec-client-generator-core: package", () => {
`
);
const sdkPackage = runnerWithCore.context.experimental_sdkPackage;
strictEqual(sdkPackage.clients.length, 2);
strictEqual(sdkPackage.clients.length, 1);
strictEqual(sdkPackage.models.length, 1);
strictEqual(sdkPackage.models[0].name, "Manufacturer");
const widgetClient = sdkPackage.clients.find((c) => c.name === "Widgets");
const widgetClient = sdkPackage.clients[0].methods.find((x) => x.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
ok(widgetClient);
strictEqual(widgetClient.initialization.properties.length, 3);
strictEqual(widgetClient.initialization.access, "internal");
Expand Down Expand Up @@ -2953,7 +2960,9 @@ describe("typespec-client-generator-core: package", () => {
sdkPackage.models.map((x) => x.name).sort(),
["CheckupCollectionWithNextLink", "Checkup", "PetStoreError", "CheckupUpdate"].sort()
);
const createOrUpdate = sdkPackage.clients[0].methods[0];
const client = sdkPackage.clients[0].methods.find((x) => x.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
const createOrUpdate = client.methods[0];
strictEqual(createOrUpdate.kind, "basic");
strictEqual(createOrUpdate.name, "createOrUpdate");
strictEqual(createOrUpdate.parameters.length, 5);
Expand Down Expand Up @@ -3048,7 +3057,10 @@ describe("typespec-client-generator-core: package", () => {
const sdkPackage = runnerWithCore.context.experimental_sdkPackage;
strictEqual(sdkPackage.models.length, 2);

const createOrReplace = sdkPackage.clients[0].methods[1];
const client = sdkPackage.clients[0].methods.find((x) => x.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;

const createOrReplace = client.methods[1];
strictEqual(createOrReplace.kind, "basic");
strictEqual(createOrReplace.name, "createOrReplaceDataConnection");
strictEqual(createOrReplace.parameters.length, 5);
Expand Down Expand Up @@ -3215,7 +3227,9 @@ describe("typespec-client-generator-core: package", () => {
`);

const sdkPackage = runner.context.experimental_sdkPackage;
strictEqual(sdkPackage.clients[0].methods[0].parameters[0].clientDefaultValue, "v2");
const client = sdkPackage.clients[0].methods.find((x) => x.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
strictEqual(client.methods[0].parameters[0].clientDefaultValue, "v2");
});

it("default api version for operation is", async () => {
Expand Down Expand Up @@ -3350,9 +3364,10 @@ function getServiceMethodOfClient(
numMethods: number = 1,
methodIndex: number = 0
): SdkServiceMethod<SdkHttpOperation> {
let client = sdkPackage.clients.filter((c) => c.initialization.access === "internal")[0];
if (!client) {
client = sdkPackage.clients.filter((c) => c.initialization.access === "public")[0];
let client = sdkPackage.clients[0];
if (client.methods.some((x) => x.kind === "clientaccessor")) {
client = client.methods.find((x) => x.kind === "clientaccessor")
?.response as SdkClientType<SdkHttpOperation>;
}
strictEqual(client.methods.length, numMethods);
const method = client.methods[methodIndex];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { expectDiagnostics } from "@typespec/compiler/testing";
import { ok, strictEqual } from "assert";
import { beforeEach, describe, it } from "vitest";
import { UsageFlags } from "../../src/interfaces.js";
import { SdkClientType, SdkHttpOperation, UsageFlags } from "../../src/interfaces.js";
import { getAllModelsWithDiagnostics } from "../../src/types.js";
import { SdkTestRunner, createSdkTestRunner } from "../test-host.js";

Expand Down Expand Up @@ -208,7 +208,10 @@ describe("typespec-client-generator-core: multipart types", () => {
upload(...WidgetForm): Widget;
}
`);
const formDataMethod = runner.context.experimental_sdkPackage.clients[0].methods[0];
const client = runner.context.experimental_sdkPackage.clients[0].methods.find(
(x) => x.kind === "clientaccessor"
)?.response as SdkClientType<SdkHttpOperation>;
const formDataMethod = client.methods[0];
strictEqual(formDataMethod.kind, "basic");
strictEqual(formDataMethod.name, "upload");
strictEqual(formDataMethod.parameters.length, 3);
Expand Down

0 comments on commit eae81f8

Please sign in to comment.