@azure-tools/typespec-ts 0.36.0 → 0.37.0-alpha.20241230.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/src/contextManager.d.ts +1 -2
  3. package/dist/src/contextManager.d.ts.map +1 -1
  4. package/dist/src/contextManager.js.map +1 -1
  5. package/dist/src/framework/load-static-helpers.d.ts +2 -1
  6. package/dist/src/framework/load-static-helpers.d.ts.map +1 -1
  7. package/dist/src/framework/load-static-helpers.js +17 -0
  8. package/dist/src/framework/load-static-helpers.js.map +1 -1
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +31 -29
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/lib.js +1 -1
  13. package/dist/src/lib.js.map +1 -1
  14. package/dist/src/metaTree.d.ts +0 -5
  15. package/dist/src/metaTree.d.ts.map +1 -1
  16. package/dist/src/modular/buildClassicalClient.d.ts +3 -2
  17. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
  18. package/dist/src/modular/buildClassicalClient.js +64 -62
  19. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  20. package/dist/src/modular/buildClassicalOperationGroups.d.ts +3 -2
  21. package/dist/src/modular/buildClassicalOperationGroups.d.ts.map +1 -1
  22. package/dist/src/modular/buildClassicalOperationGroups.js +35 -27
  23. package/dist/src/modular/buildClassicalOperationGroups.js.map +1 -1
  24. package/dist/src/modular/buildClientContext.d.ts +4 -3
  25. package/dist/src/modular/buildClientContext.d.ts.map +1 -1
  26. package/dist/src/modular/buildClientContext.js +84 -35
  27. package/dist/src/modular/buildClientContext.js.map +1 -1
  28. package/dist/src/modular/buildModularOptions.d.ts +7 -0
  29. package/dist/src/modular/buildModularOptions.d.ts.map +1 -0
  30. package/dist/src/modular/buildModularOptions.js +16 -0
  31. package/dist/src/modular/buildModularOptions.js.map +1 -0
  32. package/dist/src/modular/buildOperations.d.ts +6 -4
  33. package/dist/src/modular/buildOperations.d.ts.map +1 -1
  34. package/dist/src/modular/buildOperations.js +56 -55
  35. package/dist/src/modular/buildOperations.js.map +1 -1
  36. package/dist/src/modular/buildProjectFiles.d.ts +3 -2
  37. package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
  38. package/dist/src/modular/buildProjectFiles.js +18 -16
  39. package/dist/src/modular/buildProjectFiles.js.map +1 -1
  40. package/dist/src/modular/buildRestorePoller.d.ts +4 -2
  41. package/dist/src/modular/buildRestorePoller.d.ts.map +1 -1
  42. package/dist/src/modular/buildRestorePoller.js +22 -18
  43. package/dist/src/modular/buildRestorePoller.js.map +1 -1
  44. package/dist/src/modular/buildRootIndex.d.ts +4 -3
  45. package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
  46. package/dist/src/modular/buildRootIndex.js +40 -31
  47. package/dist/src/modular/buildRootIndex.js.map +1 -1
  48. package/dist/src/modular/buildSubpathIndex.d.ts +4 -2
  49. package/dist/src/modular/buildSubpathIndex.d.ts.map +1 -1
  50. package/dist/src/modular/buildSubpathIndex.js +8 -5
  51. package/dist/src/modular/buildSubpathIndex.js.map +1 -1
  52. package/dist/src/modular/emitLoggerFile.d.ts +2 -3
  53. package/dist/src/modular/emitLoggerFile.d.ts.map +1 -1
  54. package/dist/src/modular/emitLoggerFile.js +4 -4
  55. package/dist/src/modular/emitLoggerFile.js.map +1 -1
  56. package/dist/src/modular/emitModels.d.ts +1 -2
  57. package/dist/src/modular/emitModels.d.ts.map +1 -1
  58. package/dist/src/modular/emitModels.js +10 -3
  59. package/dist/src/modular/emitModels.js.map +1 -1
  60. package/dist/src/modular/emitModelsOptions.d.ts +3 -24
  61. package/dist/src/modular/emitModelsOptions.d.ts.map +1 -1
  62. package/dist/src/modular/emitModelsOptions.js +10 -86
  63. package/dist/src/modular/emitModelsOptions.js.map +1 -1
  64. package/dist/src/modular/emitSamples.js +2 -1
  65. package/dist/src/modular/emitSamples.js.map +1 -1
  66. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts +3 -3
  67. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts.map +1 -1
  68. package/dist/src/modular/helpers/classicalOperationHelpers.js +40 -50
  69. package/dist/src/modular/helpers/classicalOperationHelpers.js.map +1 -1
  70. package/dist/src/modular/helpers/clientHelpers.d.ts +11 -8
  71. package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
  72. package/dist/src/modular/helpers/clientHelpers.js +87 -60
  73. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  74. package/dist/src/modular/helpers/namingHelpers.d.ts +4 -7
  75. package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
  76. package/dist/src/modular/helpers/namingHelpers.js +3 -26
  77. package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
  78. package/dist/src/modular/helpers/operationHelpers.d.ts +21 -20
  79. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  80. package/dist/src/modular/helpers/operationHelpers.js +336 -291
  81. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  82. package/dist/src/modular/helpers/typeHelpers.d.ts +4 -25
  83. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
  84. package/dist/src/modular/helpers/typeHelpers.js +6 -218
  85. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  86. package/dist/src/modular/interfaces.d.ts +15 -8
  87. package/dist/src/modular/interfaces.d.ts.map +1 -1
  88. package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
  89. package/dist/src/modular/serialization/buildDeserializerFunction.js +1 -2
  90. package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
  91. package/dist/src/modular/serialization/buildSerializerFunction.d.ts.map +1 -1
  92. package/dist/src/modular/serialization/buildSerializerFunction.js +1 -2
  93. package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
  94. package/dist/src/modular/serialization/serializeUtils.d.ts +8 -5
  95. package/dist/src/modular/serialization/serializeUtils.d.ts.map +1 -1
  96. package/dist/src/modular/serialization/serializeUtils.js +22 -22
  97. package/dist/src/modular/serialization/serializeUtils.js.map +1 -1
  98. package/dist/src/utils/clientUtils.d.ts +3 -1
  99. package/dist/src/utils/clientUtils.d.ts.map +1 -1
  100. package/dist/src/utils/clientUtils.js +10 -0
  101. package/dist/src/utils/clientUtils.js.map +1 -1
  102. package/dist/src/utils/operationUtil.d.ts +6 -2
  103. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  104. package/dist/src/utils/operationUtil.js +66 -7
  105. package/dist/src/utils/operationUtil.js.map +1 -1
  106. package/dist/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +3 -3
  108. package/src/contextManager.ts +1 -2
  109. package/src/framework/load-static-helpers.ts +24 -1
  110. package/src/index.ts +65 -37
  111. package/src/lib.ts +1 -1
  112. package/src/metaTree.ts +0 -6
  113. package/src/modular/buildClassicalClient.ts +97 -99
  114. package/src/modular/buildClassicalOperationGroups.ts +53 -47
  115. package/src/modular/buildClientContext.ts +101 -44
  116. package/src/modular/buildModularOptions.ts +27 -0
  117. package/src/modular/buildOperations.ts +91 -78
  118. package/src/modular/buildProjectFiles.ts +24 -21
  119. package/src/modular/buildRestorePoller.ts +39 -23
  120. package/src/modular/buildRootIndex.ts +51 -42
  121. package/src/modular/buildSubpathIndex.ts +16 -7
  122. package/src/modular/emitLoggerFile.ts +12 -10
  123. package/src/modular/emitModels.ts +15 -7
  124. package/src/modular/emitModelsOptions.ts +18 -125
  125. package/src/modular/emitSamples.ts +2 -3
  126. package/src/modular/helpers/classicalOperationHelpers.ts +50 -75
  127. package/src/modular/helpers/clientHelpers.ts +107 -73
  128. package/src/modular/helpers/namingHelpers.ts +6 -65
  129. package/src/modular/helpers/operationHelpers.ts +506 -384
  130. package/src/modular/helpers/typeHelpers.ts +11 -267
  131. package/src/modular/interfaces.ts +16 -8
  132. package/src/modular/serialization/buildDeserializerFunction.ts +1 -6
  133. package/src/modular/serialization/buildSerializerFunction.ts +1 -2
  134. package/src/modular/serialization/serializeUtils.ts +31 -30
  135. package/src/utils/clientUtils.ts +23 -1
  136. package/src/utils/operationUtil.ts +106 -14
  137. package/dist/src/modular/buildCodeModel.d.ts +0 -34
  138. package/dist/src/modular/buildCodeModel.d.ts.map +0 -1
  139. package/dist/src/modular/buildCodeModel.js +0 -1489
  140. package/dist/src/modular/buildCodeModel.js.map +0 -1
  141. package/dist/src/modular/modularCodeModel.d.ts +0 -166
  142. package/dist/src/modular/modularCodeModel.d.ts.map +0 -1
  143. package/dist/src/modular/modularCodeModel.js +0 -2
  144. package/dist/src/modular/modularCodeModel.js.map +0 -1
  145. package/src/modular/buildCodeModel.ts +0 -1965
  146. package/src/modular/modularCodeModel.ts +0 -211
@@ -1,6 +1,12 @@
1
- import { Client, ModularCodeModel } from "./modularCodeModel.js";
1
+ import {
2
+ SdkClientType,
3
+ SdkServiceOperation
4
+ } from "@azure-tools/typespec-client-generator-core";
5
+ import { ModularEmitterOptions } from "./interfaces.js";
2
6
 
3
7
  import { join } from "path";
8
+ import { SdkContext } from "../utils/interfaces.js";
9
+ import { getModularClientOptions } from "../utils/clientUtils.js";
4
10
 
5
11
  export interface buildSubpathIndexFileOptions {
6
12
  exportIndex?: boolean;
@@ -8,17 +14,20 @@ export interface buildSubpathIndexFileOptions {
8
14
  }
9
15
 
10
16
  export function buildSubpathIndexFile(
11
- codeModel: ModularCodeModel,
17
+ context: SdkContext,
18
+ emitterOptions: ModularEmitterOptions,
12
19
  subpath: string,
13
- client?: Client,
20
+ client?: SdkClientType<SdkServiceOperation>,
14
21
  options: buildSubpathIndexFileOptions = {}
15
22
  ) {
16
- const subfolder = client?.subfolder ?? "";
17
- const srcPath = codeModel.modularOptions.sourceRoot;
23
+ const subfolder = client
24
+ ? (getModularClientOptions(context, client).subfolder ?? "")
25
+ : "";
26
+ const srcPath = emitterOptions.modularOptions.sourceRoot;
18
27
  // Skip to export these files because they are used internally.
19
28
  const skipFiles = ["pagingHelpers.ts", "pollingHelpers.ts"];
20
29
  const apiFilePattern = join(srcPath, subfolder, subpath);
21
- const apiFiles = codeModel.project.getSourceFiles().filter((file) => {
30
+ const apiFiles = emitterOptions.project.getSourceFiles().filter((file) => {
22
31
  return file
23
32
  .getFilePath()
24
33
  .replace(/\\/g, "/")
@@ -27,7 +36,7 @@ export function buildSubpathIndexFile(
27
36
  if (apiFiles.length === 0) {
28
37
  return;
29
38
  }
30
- const indexFile = codeModel.project.createSourceFile(
39
+ const indexFile = emitterOptions.project.createSourceFile(
31
40
  `${srcPath}/${subfolder}/${subpath}/index.ts`
32
41
  );
33
42
  for (const file of apiFiles) {
@@ -1,18 +1,20 @@
1
- import { Project } from "ts-morph";
2
- import { ModularCodeModel } from "./modularCodeModel.js";
1
+ import { ModularEmitterOptions } from "./interfaces.js";
3
2
 
4
3
  export function emitLoggerFile(
5
- codeModel: ModularCodeModel,
6
- project: Project,
4
+ emitterOptions: ModularEmitterOptions,
7
5
  srcPath: string = "src"
8
6
  ) {
9
- if (codeModel.options.flavor !== "azure") {
7
+ if (emitterOptions.options.flavor !== "azure") {
10
8
  return;
11
9
  }
12
10
 
13
- const sourceFile = project.createSourceFile(`${srcPath}/logger.ts`, "", {
14
- overwrite: true
15
- });
11
+ const sourceFile = emitterOptions.project.createSourceFile(
12
+ `${srcPath}/logger.ts`,
13
+ "",
14
+ {
15
+ overwrite: true
16
+ }
17
+ );
16
18
 
17
19
  sourceFile.addImportDeclaration({
18
20
  namedImports: ["createClientLogger"],
@@ -20,8 +22,8 @@ export function emitLoggerFile(
20
22
  });
21
23
 
22
24
  const name =
23
- codeModel.options.packageDetails?.nameWithoutScope ??
24
- codeModel.options.packageDetails?.name;
25
+ emitterOptions.options.packageDetails?.nameWithoutScope ??
26
+ emitterOptions.options.packageDetails?.name;
25
27
  sourceFile.addStatements(
26
28
  `export const logger = createClientLogger("${name}");`
27
29
  );
@@ -22,6 +22,7 @@ import {
22
22
  SdkModelType,
23
23
  SdkNullableType,
24
24
  SdkServiceMethod,
25
+ SdkServiceOperation,
25
26
  SdkType,
26
27
  SdkUnionType,
27
28
  UsageFlags,
@@ -346,7 +347,7 @@ function emitEnumMember(member: SdkEnumValueType): EnumMemberStructure {
346
347
  return memberStructure;
347
348
  }
348
349
 
349
- export function buildModelInterface(
350
+ function buildModelInterface(
350
351
  context: SdkContext,
351
352
  type: SdkModelType
352
353
  ): InterfaceDeclarationStructure {
@@ -408,6 +409,13 @@ function addExtendedDictInfo(
408
409
  }
409
410
  modelInterface.extends.push(`Record<string, any>`);
410
411
  } else {
412
+ reportDiagnostic(context.program, {
413
+ code: "compatible-additional-properties",
414
+ format: {
415
+ modelName: modelInterface?.name ?? ""
416
+ },
417
+ target: NoTarget
418
+ });
411
419
  modelInterface.properties?.push({
412
420
  name: "additionalProperties",
413
421
  docs: ["Additional properties"],
@@ -557,7 +565,7 @@ export function visitPackageTypes(context: SdkContext) {
557
565
 
558
566
  function visitClient(
559
567
  context: SdkContext,
560
- client: SdkClientType<SdkHttpOperation>
568
+ client: SdkClientType<SdkServiceOperation>
561
569
  ) {
562
570
  // Comment this out for now, as client initialization is not used in the generated code
563
571
  // visitType(client.initialization, emitQueue);
@@ -634,32 +642,32 @@ function visitType(context: SdkContext, type: SdkType | undefined) {
634
642
  visitType(context, type.additionalProperties);
635
643
  }
636
644
  for (const property of type.properties) {
637
- if (!emitQueue.has(property.type as any)) {
645
+ if (!emitQueue.has(property.type)) {
638
646
  visitType(context, property.type);
639
647
  }
640
648
  }
641
649
  if (type.discriminatedSubtypes) {
642
650
  for (const subType of Object.values(type.discriminatedSubtypes)) {
643
- if (!emitQueue.has(subType as any)) {
651
+ if (!emitQueue.has(subType)) {
644
652
  visitType(context, subType);
645
653
  }
646
654
  }
647
655
  }
648
656
  }
649
657
  if (type.kind === "array") {
650
- if (!emitQueue.has(type.valueType as any)) {
658
+ if (!emitQueue.has(type.valueType)) {
651
659
  visitType(context, type.valueType);
652
660
  }
653
661
  }
654
662
  if (type.kind === "dict") {
655
- if (!emitQueue.has(type.valueType as any)) {
663
+ if (!emitQueue.has(type.valueType)) {
656
664
  visitType(context, type.valueType);
657
665
  }
658
666
  }
659
667
  if (type.kind === "union") {
660
668
  emitQueue.add(type);
661
669
  for (const value of type.variantTypes) {
662
- if (!emitQueue.has(value as any)) {
670
+ if (!emitQueue.has(value)) {
663
671
  visitType(context, value);
664
672
  }
665
673
  }
@@ -1,128 +1,28 @@
1
1
  import * as path from "path";
2
2
 
3
- import {
4
- Client,
5
- ModularCodeModel,
6
- Type as ModularType
7
- } from "./modularCodeModel.js";
8
- import { InterfaceDeclarationStructure, OptionalKind } from "ts-morph";
3
+ import { ModularEmitterOptions } from "./interfaces.js";
9
4
 
10
5
  import { buildOperationOptions } from "./buildOperations.js";
11
- import { getDocsFromDescription } from "./helpers/docsHelpers.js";
12
- import { getImportSpecifier } from "@azure-tools/rlc-common";
13
- import { getType } from "./helpers/typeHelpers.js";
14
6
  import { SdkContext } from "../utils/interfaces.js";
7
+ import {
8
+ SdkClientType,
9
+ SdkServiceOperation
10
+ } from "@azure-tools/typespec-client-generator-core";
11
+ import { getMethodHierarchiesMap } from "../utils/operationUtil.js";
12
+ import { getModularClientOptions } from "../utils/clientUtils.js";
15
13
 
16
14
  // ====== UTILITIES ======
17
15
 
18
- function isAzureCoreErrorSdkType(t: ModularType) {
19
- return (
20
- t.name &&
21
- ["error", "errormodel", "innererror", "errorresponse"].includes(
22
- t.name.toLowerCase()
23
- ) &&
24
- t.coreTypeInfo === "ErrorType"
25
- );
26
- }
27
-
28
- function isAzureCoreLroSdkType(t: ModularType) {
29
- return (
30
- t.name &&
31
- ["operationstate"].includes(t.name.toLowerCase()) &&
32
- t.coreTypeInfo === "LroType"
33
- );
34
- }
35
-
36
- export function isModelWithAdditionalProperties(t: ModularType) {
37
- return t.type === "dict" && t.name !== "Record";
38
- }
39
-
40
- function getCoreClientErrorType(name: string, coreClientTypes: Set<string>) {
41
- const coreClientType: string = name === "Error" ? "ErrorModel" : name;
42
- coreClientTypes.add(coreClientType);
43
- return coreClientType;
44
- }
45
-
46
- function getCoreLroType(name: string, coreLroTypes: Set<string>) {
47
- const coreLroType = name === "OperationState" ? "CoreOperationStatus" : name;
48
- coreLroTypes.add(coreLroType);
49
- return coreLroType;
50
- }
51
-
52
- /**
53
- * Extracts all the aliases from the code model
54
- * 1. alias from polymorphic base model, where we need to use typescript union to combine all the sub models
55
- * 2. alias from unions, where we also need to use typescript union to combine all the union variants
56
- */
57
- export function extractAliases(codeModel: ModularCodeModel): ModularType[] {
58
- const models = codeModel.types.filter(
59
- (t) =>
60
- ((t.type === "model" || t.type === "combined") &&
61
- t.alias &&
62
- t.aliasType) ||
63
- (isModelWithAdditionalProperties(t) && t.alias && t.aliasType)
64
- );
65
- return models;
66
- }
67
-
68
- type InterfaceStructure = OptionalKind<InterfaceDeclarationStructure> & {
69
- extends: string[];
70
- };
71
-
72
- export function buildModelInterface(
73
- model: ModularType,
74
- cache: { coreClientTypes: Set<string>; coreLroTypes: Set<string> }
75
- ): InterfaceStructure {
76
- const modelProperties = model.properties ?? [];
77
- const modelInterface = {
78
- name: model.alias ?? model.name ?? "FIXMYNAME",
79
- isExported: true,
80
- docs: getDocsFromDescription(model.description),
81
- extends: [] as string[],
82
- properties: (modelProperties ?? []).map((p) => {
83
- const propertyMetadata = getType(p.type, p.format);
84
- let propertyTypeName = propertyMetadata.name;
85
- if (isAzureCoreErrorSdkType(p.type)) {
86
- propertyTypeName = getCoreClientErrorType(
87
- propertyTypeName,
88
- cache.coreClientTypes
89
- );
90
- }
91
- if (isAzureCoreLroSdkType(p.type)) {
92
- propertyTypeName = getCoreLroType(propertyTypeName, cache.coreLroTypes);
93
- }
94
-
95
- return {
96
- name: `"${p.clientName}"`,
97
- docs: getDocsFromDescription(p.description),
98
- hasQuestionToken: p.optional,
99
- isReadonly: p.readonly,
100
- type: propertyTypeName
101
- };
102
- })
103
- };
104
-
105
- return modelInterface;
106
- }
107
-
108
- export function buildModelTypeAlias(model: ModularType) {
109
- return {
110
- name: model.name!,
111
- isExported: true,
112
- docs: ["Alias for " + model.name],
113
- type: model.aliasType!
114
- };
115
- }
116
-
117
16
  export function buildApiOptions(
118
17
  context: SdkContext,
119
- client: Client,
120
- codeModel: ModularCodeModel
18
+ client: SdkClientType<SdkServiceOperation>,
19
+ emitterOptions: ModularEmitterOptions
121
20
  ) {
122
- const modelOptionsFile = codeModel.project.createSourceFile(
21
+ const { subfolder } = getModularClientOptions(context, client);
22
+ const modelOptionsFile = emitterOptions.project.createSourceFile(
123
23
  path.join(
124
- codeModel.modularOptions.sourceRoot,
125
- client.subfolder ?? "",
24
+ emitterOptions.modularOptions.sourceRoot,
25
+ subfolder ?? "",
126
26
  `api/options.ts`
127
27
  ),
128
28
  undefined,
@@ -130,20 +30,13 @@ export function buildApiOptions(
130
30
  overwrite: true
131
31
  }
132
32
  );
133
- for (const operationGroup of client.operationGroups) {
134
- operationGroup.operations.forEach((o) => {
135
- buildOperationOptions(context, o, modelOptionsFile);
33
+ const methodMap = getMethodHierarchiesMap(context, client);
34
+ for (const [prefixKey, operations] of methodMap) {
35
+ const prefixes = prefixKey.split("/");
36
+ operations.forEach((o) => {
37
+ buildOperationOptions(context, [prefixes, o], modelOptionsFile);
136
38
  });
137
39
  }
138
- modelOptionsFile.addImportDeclarations([
139
- {
140
- moduleSpecifier: getImportSpecifier(
141
- "restClient",
142
- codeModel.runtimeImports
143
- ),
144
- namedImports: ["OperationOptions"]
145
- }
146
- ]);
147
40
 
148
41
  modelOptionsFile
149
42
  .getImportDeclarations()
@@ -243,9 +243,8 @@ function buildParameterValueMap(example: SdkHttpOperationExample) {
243
243
  const parameterMap: Record<string, SdkHttpParameterExampleValue> = {};
244
244
  example.parameters.forEach(
245
245
  (param) =>
246
- (parameterMap[
247
- (param.parameter as any).serializedName ?? param.parameter.name
248
- ] = param)
246
+ (parameterMap[param.parameter.serializedName ?? param.parameter.name] =
247
+ param)
249
248
  );
250
249
  return parameterMap;
251
250
  }
@@ -6,50 +6,42 @@ import {
6
6
  SourceFile,
7
7
  StructureKind
8
8
  } from "ts-morph";
9
- import { Client, OperationGroup } from "../modularCodeModel.js";
10
- import { getClassicalLayerPrefix, getClientName } from "./namingHelpers.js";
9
+ import { getClassicalLayerPrefix } from "./namingHelpers.js";
11
10
  import { getOperationFunction } from "./operationHelpers.js";
12
11
  import { SdkContext } from "../../utils/interfaces.js";
12
+ import {
13
+ SdkClientType,
14
+ SdkServiceOperation
15
+ } from "@azure-tools/typespec-client-generator-core";
16
+ import { getModularClientOptions } from "../../utils/clientUtils.js";
17
+ import { ServiceOperation } from "../../utils/operationUtil.js";
13
18
 
14
- export function shouldPromoteSubscriptionId(
15
- dpgContext: SdkContext,
16
- operationGroup: OperationGroup
17
- ) {
18
- const hasSubscriptionIdParameter = operationGroup.operations.some((op) =>
19
- op.parameters.some((p) => p.clientName === "subscriptionId")
20
- );
21
- return dpgContext?.rlcOptions?.azureArm && hasSubscriptionIdParameter;
22
- }
23
19
  export function getClassicalOperation(
24
20
  dpgContext: SdkContext,
25
- client: Client,
21
+ client: SdkClientType<SdkServiceOperation>,
26
22
  classicFile: SourceFile,
27
- operationGroup: OperationGroup,
28
- layer: number = operationGroup.namespaceHierarchies.length - 1
23
+ operationGroup: [string[], ServiceOperation[]],
24
+ layer: number = operationGroup[0].length - 1
29
25
  ) {
30
- // TODO: remove this logic once client-level parameter design is finalized
31
- // https://github.com/Azure/autorest.typescript/issues/2618
32
- const hasSubscriptionIdPromoted = shouldPromoteSubscriptionId(
33
- dpgContext,
34
- operationGroup
35
- );
36
- const modularClientName = `${getClientName(client.tcgcClient)}Context`;
26
+ const prefixes = operationGroup[0];
27
+ const operations = operationGroup[1];
28
+ const { rlcClientName } = getModularClientOptions(dpgContext, client);
37
29
  const hasClientContextImport = classicFile
38
30
  .getImportDeclarations()
39
31
  .filter((i) => {
40
32
  return (
41
33
  i.getModuleSpecifierValue() ===
42
34
  `${"../".repeat(layer + 2)}api/${normalizeName(
43
- modularClientName,
35
+ rlcClientName,
44
36
  NameType.File
45
37
  )}.js`
46
38
  );
47
39
  });
48
40
  if (!hasClientContextImport || hasClientContextImport.length === 0) {
49
41
  classicFile.addImportDeclaration({
50
- namedImports: [client.rlcClientName],
42
+ namedImports: [rlcClientName],
51
43
  moduleSpecifier: `${"../".repeat(layer + 2)}api/${normalizeName(
52
- modularClientName,
44
+ rlcClientName,
53
45
  NameType.File
54
46
  )}.js`
55
47
  });
@@ -60,18 +52,18 @@ export function getClassicalOperation(
60
52
  string | undefined
61
53
  >();
62
54
  const operationDeclarations: OptionalKind<FunctionDeclarationStructure>[] =
63
- operationGroup.operations.map((operation) => {
55
+ operations.map((operation) => {
64
56
  const declarations = getOperationFunction(
65
57
  dpgContext,
66
- operation,
67
- modularClientName
58
+ [prefixes, operation],
59
+ rlcClientName
68
60
  );
69
61
  operationMap.set(declarations, operation.oriName);
70
62
  return declarations;
71
63
  });
72
64
 
73
65
  const interfaceNamePrefix = getClassicalLayerPrefix(
74
- operationGroup,
66
+ prefixes,
75
67
  NameType.Interface,
76
68
  "",
77
69
  layer
@@ -81,18 +73,17 @@ export function getClassicalOperation(
81
73
  .getInterfaces()
82
74
  .filter((i) => i.getName() === interfaceName)[0];
83
75
  const properties: OptionalKind<PropertySignatureStructure>[] = [];
84
- if (layer !== operationGroup.namespaceHierarchies.length - 1) {
76
+ if (layer !== prefixes.length - 1) {
85
77
  properties.push({
86
78
  kind: StructureKind.PropertySignature,
87
- name:
88
- normalizeName(
89
- (layer === operationGroup.namespaceHierarchies.length - 1
90
- ? operationGroup.namespaceHierarchies[layer]
91
- : operationGroup.namespaceHierarchies[layer + 1]) ?? "",
92
- NameType.Property
93
- ) ?? operationGroup.propertyName,
79
+ name: normalizeName(
80
+ (layer === prefixes.length - 1
81
+ ? prefixes[layer]
82
+ : prefixes[layer + 1]) ?? "",
83
+ NameType.Property
84
+ ),
94
85
  type: `${getClassicalLayerPrefix(
95
- operationGroup,
86
+ prefixes,
96
87
  NameType.Interface,
97
88
  "",
98
89
  layer + 1
@@ -105,9 +96,6 @@ export function getClassicalOperation(
105
96
  name: getClassicalMethodName(d),
106
97
  type: `(${d.parameters
107
98
  ?.filter((p) => p.name !== "context")
108
- ?.filter(
109
- (p) => !(hasSubscriptionIdPromoted && p.name === "subscriptionId")
110
- )
111
99
  .map(
112
100
  (p) =>
113
101
  p.name +
@@ -134,10 +122,10 @@ export function getClassicalOperation(
134
122
  });
135
123
  }
136
124
 
137
- if (layer === operationGroup.namespaceHierarchies.length - 1) {
125
+ if (layer === prefixes.length - 1) {
138
126
  classicFile.addFunction({
139
127
  name: `get${getClassicalLayerPrefix(
140
- operationGroup,
128
+ prefixes,
141
129
  NameType.Interface,
142
130
  "",
143
131
  layer
@@ -146,21 +134,14 @@ export function getClassicalOperation(
146
134
  parameters: [
147
135
  {
148
136
  name: "context",
149
- type: client.rlcClientName
150
- },
151
- ...(hasSubscriptionIdPromoted
152
- ? [{ name: "subscriptionId", type: "string" }]
153
- : [])
137
+ type: rlcClientName
138
+ }
154
139
  ],
155
140
  statements: `return {
156
141
  ${operationDeclarations
157
142
  .map((d) => {
158
143
  return `${getClassicalMethodName(d)}: (${d.parameters
159
144
  ?.filter((p) => p.name !== "context")
160
- ?.filter(
161
- (p) =>
162
- !(hasSubscriptionIdPromoted && p.name === "subscriptionId")
163
- )
164
145
  .map(
165
146
  (p) =>
166
147
  p.name +
@@ -184,7 +165,7 @@ export function getClassicalOperation(
184
165
  }
185
166
 
186
167
  const operationFunctionName = `get${getClassicalLayerPrefix(
187
- operationGroup,
168
+ prefixes,
188
169
  NameType.Interface,
189
170
  "",
190
171
  layer
@@ -197,57 +178,50 @@ export function getClassicalOperation(
197
178
  if (returnStatement) {
198
179
  let statement = `,
199
180
  ...get${getClassicalLayerPrefix(
200
- operationGroup,
181
+ prefixes,
201
182
  NameType.Interface,
202
183
  "",
203
184
  layer + 1
204
- )}Operations(context${
205
- hasSubscriptionIdPromoted ? ", subscriptionId" : ""
206
- })}`;
207
- if (layer !== operationGroup.namespaceHierarchies.length - 1) {
185
+ )}Operations(context)}`;
186
+ if (layer !== prefixes.length - 1) {
208
187
  statement = `,
209
188
  ${normalizeName(
210
- operationGroup.namespaceHierarchies[layer + 1] ?? "FIXME",
189
+ prefixes[layer + 1] ?? "FIXME",
211
190
  NameType.Property
212
191
  )}: get${getClassicalLayerPrefix(
213
- operationGroup,
192
+ prefixes,
214
193
  NameType.Interface,
215
194
  "",
216
195
  layer + 1
217
- )}Operations(context${
218
- hasSubscriptionIdPromoted ? ", subscriptionId" : ""
219
- })}`;
196
+ )}Operations(context)}`;
220
197
  }
221
198
  const newReturnStatement = returnStatement.replace(/}$/, statement);
222
199
  existFunction.setBodyText(newReturnStatement);
223
200
  }
224
201
  } else {
225
- classicFile.addFunction({
202
+ const functions = {
226
203
  name: operationFunctionName,
227
204
  isExported: true,
228
205
  parameters: [
229
206
  {
230
207
  name: "context",
231
- type: client.rlcClientName
232
- },
233
- ...(hasSubscriptionIdPromoted
234
- ? [{ name: "subscriptionId", type: "string" }]
235
- : [])
208
+ type: rlcClientName
209
+ }
236
210
  ],
237
211
  returnType: `${getClassicalLayerPrefix(
238
- operationGroup,
212
+ prefixes,
239
213
  NameType.Interface,
240
214
  "",
241
215
  layer
242
216
  )}Operations`,
243
217
  statements:
244
- layer !== operationGroup.namespaceHierarchies.length - 1
218
+ layer !== prefixes.length - 1
245
219
  ? `return {
246
220
  ${normalizeName(
247
- operationGroup.namespaceHierarchies[layer + 1] ?? "FIXME",
221
+ prefixes[layer + 1] ?? "FIXME",
248
222
  NameType.Property
249
223
  )}: get${getClassicalLayerPrefix(
250
- operationGroup,
224
+ prefixes,
251
225
  NameType.Interface,
252
226
  "",
253
227
  layer + 1
@@ -255,13 +229,14 @@ export function getClassicalOperation(
255
229
  }`
256
230
  : `return {
257
231
  ...get${getClassicalLayerPrefix(
258
- operationGroup,
232
+ prefixes,
259
233
  NameType.Interface,
260
234
  "",
261
235
  layer
262
- )}(context${hasSubscriptionIdPromoted ? ", subscriptionId" : ""})
236
+ )}(context)
263
237
  }`
264
- });
238
+ };
239
+ classicFile.addFunction(functions);
265
240
  }
266
241
 
267
242
  function getClassicalMethodName(