-
Notifications
You must be signed in to change notification settings - Fork 71
[tcgc] one client multiple services #3460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
70cf314
a76ed5e
c7a60a6
e078c04
6c70802
88af780
fa746ed
5ddb972
00d990c
224d610
05ed64b
d3c20dd
4b7a6b7
9623302
4bf90bb
2a73a95
bb9a49b
d0742e2
e274d6b
8e6339b
7b81398
a1d7664
59b92a6
9ed2b77
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| changeKind: feature | ||
| packages: | ||
| - "@azure-tools/typespec-client-generator-core" | ||
| --- | ||
|
|
||
| Add support to define one client from multiple services. Api versions for services will rest on the subclient |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,13 @@ | ||
| import { createDiagnosticCollector, Diagnostic, getDoc, getSummary } from "@typespec/compiler"; | ||
| import { | ||
| createDiagnosticCollector, | ||
| Diagnostic, | ||
| getDoc, | ||
| getSummary, | ||
| listServices, | ||
| } from "@typespec/compiler"; | ||
| import { $ } from "@typespec/compiler/typekit"; | ||
| import { getServers, HttpServer } from "@typespec/http"; | ||
| import { getVersionDependencies } from "@typespec/versioning"; | ||
| import { | ||
| getClientInitializationOptions, | ||
| getClientNameOverride, | ||
|
|
@@ -17,6 +24,7 @@ import { | |
| SdkEndpointParameter, | ||
| SdkEndpointType, | ||
| SdkHttpOperation, | ||
| SdkMethodParameter, | ||
| SdkOperationGroup, | ||
| SdkPathParameter, | ||
| SdkServiceOperation, | ||
|
|
@@ -190,6 +198,14 @@ export function createSdkClientType<TServiceOperation extends SdkServiceOperatio | |
| name = override; | ||
| } | ||
| } | ||
| if (!parent && client.kind === "SdkClient" && client.parent) { | ||
| const parentRaw = context.__rawClientsOperationGroupsCache?.get(client.parent) as | ||
| | SdkClient | ||
| | undefined; | ||
| parent = context.__clientTypesCache?.find((c) => c.__raw === parentRaw) as | ||
| | SdkClientType<TServiceOperation> | ||
| | undefined; | ||
| } | ||
|
Comment on lines
+201
to
+208
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't prefer to mix the client hierarchy build into the SDK type creation section. It's better to do it in the cache process. |
||
| const sdkClientType: SdkClientType<TServiceOperation> = { | ||
| __raw: client, | ||
| kind: "client", | ||
|
|
@@ -213,7 +229,8 @@ export function createSdkClientType<TServiceOperation extends SdkServiceOperatio | |
| ); | ||
| addDefaultClientParameters(context, sdkClientType); | ||
| // update initialization model properties | ||
|
|
||
| context.__clientTypesCache = context.__clientTypesCache || []; | ||
| context.__clientTypesCache.push(sdkClientType); | ||
| return diagnostics.wrap(sdkClientType); | ||
| } | ||
|
|
||
|
|
@@ -239,6 +256,48 @@ function addDefaultClientParameters< | |
| if (apiVersionParam) break; | ||
| } | ||
| } | ||
|
|
||
| // Check for multi-service scenario with @useDependency | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering why the API parameter no longer poped up from the operation level's parameter for multi-service cases? I believe only the top-level client should have special logic. |
||
| if (!apiVersionParam && client.__raw.kind === "SdkClient") { | ||
| const services = listServices(context.program); | ||
| if (services.length > 1 && client.__raw.type?.kind === "Namespace") { | ||
| // Check if this is a multi-service client with @useDependency | ||
| const versionDependencies = getVersionDependencies(context.program, client.__raw.type); | ||
| if (versionDependencies && versionDependencies.size > 0) { | ||
| // Create an API version parameter for multi-service clients with @useDependency | ||
| const stringType = context.program.checker.getStdType("string"); | ||
|
|
||
| // Create a SdkMethodParameter for the API version | ||
| const apiVersionMethodParam: SdkMethodParameter = { | ||
| __raw: undefined, | ||
| kind: "method", | ||
| name: "apiVersion", | ||
| isGeneratedName: false, | ||
| doc: "The API version to use for the operation", | ||
| type: getSdkBuiltInType(context, stringType), | ||
| optional: false, | ||
| isApiVersionParam: true, | ||
| onClient: true, | ||
| apiVersions: context.getApiVersionsForType(client.__raw.type ?? client.__raw.service), | ||
| clientDefaultValue: undefined, | ||
| decorators: [], | ||
| crossLanguageDefinitionId: `${client.crossLanguageDefinitionId}.apiVersion`, | ||
| access: "public", | ||
| flatten: false, | ||
| }; | ||
|
|
||
| // Add to cache | ||
| let clientParams = context.__clientParametersCache.get(client.__raw); | ||
| if (!clientParams) { | ||
| clientParams = []; | ||
| context.__clientParametersCache.set(client.__raw, clientParams); | ||
| } | ||
| clientParams.push(apiVersionMethodParam); | ||
| apiVersionParam = apiVersionMethodParam; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (apiVersionParam) { | ||
| defaultClientParamters.push(apiVersionParam); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a bug from TypeSpec? This seems a hack to get back the operations that raw type graph does not have. If it only happens when having versioning, I doubt if it is a versioning mutator issue.