@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,15 +1,5 @@
1
- import {
2
- BodyParameter,
3
- Client,
4
- ModularCodeModel,
5
- Operation,
6
- Parameter
7
- } from "./modularCodeModel.js";
8
- import {
9
- NameType,
10
- clearImportSets,
11
- normalizeName
12
- } from "@azure-tools/rlc-common";
1
+ import { ModularEmitterOptions } from "./interfaces.js";
2
+ import { NameType, normalizeName } from "@azure-tools/rlc-common";
13
3
  import { Project, SourceFile } from "ts-morph";
14
4
  import {
15
5
  getDeserializePrivateFunction,
@@ -25,9 +15,22 @@ import { SdkContext } from "../utils/interfaces.js";
25
15
  import { addImportBySymbol } from "../utils/importHelper.js";
26
16
  import { getDocsFromDescription } from "./helpers/docsHelpers.js";
27
17
  import { getOperationName } from "./helpers/namingHelpers.js";
28
- import { isRLCMultiEndpoint } from "../utils/clientUtils.js";
18
+ import {
19
+ getModularClientOptions,
20
+ isRLCMultiEndpoint
21
+ } from "../utils/clientUtils.js";
29
22
  import { getTypeExpression } from "./type-expressions/get-type-expression.js";
30
- import { buildType } from "./helpers/typeHelpers.js";
23
+ import {
24
+ SdkClientType,
25
+ SdkMethodParameter,
26
+ SdkServiceOperation
27
+ } from "@azure-tools/typespec-client-generator-core";
28
+ import {
29
+ getMethodHierarchiesMap,
30
+ ServiceOperation
31
+ } from "../utils/operationUtil.js";
32
+ import { resolveReference } from "../framework/reference.js";
33
+ import { useDependencies } from "../framework/hooks/useDependencies.js";
31
34
 
32
35
  /**
33
36
  * This function creates a file under /api for each operation group.
@@ -35,20 +38,23 @@ import { buildType } from "./helpers/typeHelpers.js";
35
38
  * file called operations.ts where all operations are generated.
36
39
  */
37
40
  export function buildOperationFiles(
38
- client: Client,
39
41
  dpgContext: SdkContext,
40
- codeModel: ModularCodeModel
42
+ client: SdkClientType<SdkServiceOperation>,
43
+ emitterOptions: ModularEmitterOptions
41
44
  ) {
42
- const operationFiles = [];
45
+ const operationFiles: Set<SourceFile> = new Set();
46
+ const { subfolder, rlcClientName } = getModularClientOptions(
47
+ dpgContext,
48
+ client
49
+ );
43
50
  const isMultiEndpoint = isRLCMultiEndpoint(dpgContext);
44
- const clientType = isMultiEndpoint
45
- ? `Client.${client.rlcClientName}`
46
- : "Client";
47
- for (const operationGroup of client.operationGroups) {
48
- clearImportSets(codeModel.runtimeImports);
51
+ const clientType = isMultiEndpoint ? `Client.${rlcClientName}` : "Client";
52
+ const methodMap = getMethodHierarchiesMap(dpgContext, client);
53
+ for (const [prefixKey, operations] of methodMap) {
54
+ const prefixes = prefixKey.split("/");
49
55
  const operationFileName =
50
- operationGroup.className && operationGroup.namespaceHierarchies.length > 0
51
- ? `${operationGroup.namespaceHierarchies
56
+ prefixes.length > 0 && prefixKey !== ""
57
+ ? `${prefixes
52
58
  .map((hierarchy) => {
53
59
  return normalizeName(hierarchy, NameType.File);
54
60
  })
@@ -57,55 +63,48 @@ export function buildOperationFiles(
57
63
  // into a nameless operation group. We'll call this operations.
58
64
  "operations";
59
65
 
60
- const subfolder = client.subfolder;
61
- const srcPath = codeModel.modularOptions.sourceRoot;
62
- const operationGroupFile = codeModel.project.createSourceFile(
63
- `${srcPath}/${
64
- subfolder && subfolder !== "" ? subfolder + "/" : ""
65
- }api/${operationFileName}.ts`
66
- );
66
+ const srcPath = emitterOptions.modularOptions.sourceRoot;
67
+ const filepath = `${srcPath}/${
68
+ subfolder && subfolder !== "" ? subfolder + "/" : ""
69
+ }api/${operationFileName}.ts`;
67
70
 
71
+ const operationGroupFile =
72
+ emitterOptions.project.createSourceFile(filepath);
68
73
  // Import the deserializeUtils
69
74
  importDeserializeUtils(
70
75
  srcPath,
71
76
  operationGroupFile,
72
- codeModel.project,
77
+ emitterOptions.project,
73
78
  "deserialize",
74
79
  subfolder,
75
- operationGroup.namespaceHierarchies.length
80
+ prefixes.length
76
81
  );
77
82
 
78
83
  // Import the serializeUtils
79
84
  importDeserializeUtils(
80
85
  srcPath,
81
86
  operationGroupFile,
82
- codeModel.project,
87
+ emitterOptions.project,
83
88
  "serialize",
84
89
  subfolder,
85
- operationGroup.namespaceHierarchies.length
90
+ prefixes.length
86
91
  );
87
92
 
88
- const indexPathPrefix =
89
- "../".repeat(operationGroup.namespaceHierarchies.length) || "./";
90
- operationGroupFile.addImportDeclaration({
91
- namedImports: [`${client.rlcClientName} as Client`],
92
- moduleSpecifier: `${indexPathPrefix}index.js`
93
- });
94
-
95
- operationGroup.operations.forEach((o) => {
93
+ operations.forEach((op) => {
96
94
  const operationDeclaration = getOperationFunction(
97
95
  dpgContext,
98
- o,
96
+ [prefixes, op],
99
97
  clientType
100
98
  );
101
99
  const sendOperationDeclaration = getSendPrivateFunction(
102
100
  dpgContext,
103
- o,
101
+ client,
102
+ [prefixes, op],
104
103
  clientType
105
104
  );
106
105
  const deserializeOperationDeclaration = getDeserializePrivateFunction(
107
106
  dpgContext,
108
- o
107
+ op
109
108
  );
110
109
  operationGroupFile.addFunctions([
111
110
  sendOperationDeclaration,
@@ -114,13 +113,18 @@ export function buildOperationFiles(
114
113
  ]);
115
114
  });
116
115
 
117
- // addImportsToFiles(codeModel.runtimeImports, operationGroupFile);
118
- operationGroupFile.fixUnusedIdentifiers();
116
+ const indexPathPrefix =
117
+ "../".repeat(prefixKey === "" ? 0 : prefixes.length) || "./";
118
+ operationGroupFile.addImportDeclaration({
119
+ namedImports: [`${rlcClientName} as Client`],
120
+ moduleSpecifier: `${indexPathPrefix}index.js`
121
+ });
119
122
  addImportBySymbol("serializeRecord", operationGroupFile);
123
+ operationGroupFile.fixUnusedIdentifiers();
120
124
 
121
- operationFiles.push(operationGroupFile);
125
+ operationFiles.add(operationGroupFile);
122
126
  }
123
- return operationFiles;
127
+ return Array.from(operationFiles);
124
128
  }
125
129
 
126
130
  export function importDeserializeUtils(
@@ -160,15 +164,24 @@ export function importDeserializeUtils(
160
164
  */
161
165
  export function buildOperationOptions(
162
166
  context: SdkContext,
163
- operation: Operation,
167
+ method: [string[], ServiceOperation],
164
168
  sourceFile: SourceFile
165
169
  ) {
170
+ const dependencies = useDependencies();
171
+ const operation = method[1];
166
172
  const optionalParameters = operation.parameters
167
- .filter((p) => p.implementation === "Method")
173
+ .filter(
174
+ (p) =>
175
+ p.onClient === false &&
176
+ !(
177
+ p.isGeneratedName &&
178
+ (p.name === "contentType" || p.name !== "accept")
179
+ )
180
+ )
168
181
  .filter((p) => p.optional || p.clientDefaultValue);
169
- const options: (BodyParameter | Parameter)[] = [...optionalParameters];
182
+ const options: SdkMethodParameter[] = [...optionalParameters];
170
183
 
171
- const name = getOperationOptionsName(operation, true);
184
+ const name = getOperationOptionsName(method, true);
172
185
  const lroOptions = {
173
186
  name: "updateIntervalInMs",
174
187
  type: "number",
@@ -177,27 +190,24 @@ export function buildOperationOptions(
177
190
  };
178
191
 
179
192
  // handle optional body parameter
180
- if (operation.bodyParameter?.optional === true) {
181
- options.push(operation.bodyParameter);
182
- }
183
-
193
+ // if (operation.operation.bodyParam?.optional === true) {
194
+ // options.push(operation.operation.bodyParam);
195
+ // }
196
+ const operationOptionsReference = resolveReference(
197
+ dependencies.OperationOptions
198
+ );
184
199
  sourceFile.addInterface({
185
200
  name,
186
201
  isExported: true,
187
- extends: ["OperationOptions"],
202
+ extends: [operationOptionsReference],
188
203
  properties: (isLroOnlyOperation(operation) ? [lroOptions] : []).concat(
189
204
  options.map((p) => {
190
205
  return {
191
- docs: getDocsFromDescription(p.description),
206
+ docs: getDocsFromDescription(p.doc),
192
207
  hasQuestionToken: true,
193
- ...(p.type.tcgcType
194
- ? {
195
- type: getTypeExpression(context, p.type.tcgcType),
196
- name: p.clientName
197
- }
198
- : {
199
- ...buildType(p.clientName, p.type, p.format)
200
- })
208
+
209
+ type: getTypeExpression(context, p.type),
210
+ name: normalizeName(p.name, NameType.Parameter)
201
211
  };
202
212
  })
203
213
  ),
@@ -208,21 +218,24 @@ export function buildOperationOptions(
208
218
  /**
209
219
  * This function creates a map of operation file path to operation names.
210
220
  */
211
- export function buildLroDeserDetailMap(client: Client) {
221
+ export function buildLroDeserDetailMap(
222
+ context: SdkContext,
223
+ client: SdkClientType<SdkServiceOperation>
224
+ ) {
212
225
  const map = new Map<string, OperationPathAndDeserDetails[]>();
213
226
  const existingNames = new Set<string>();
214
- for (const operationGroup of client.operationGroups) {
215
- const operations = operationGroup.operations.filter((o) =>
216
- isLroOnlyOperation(o)
217
- );
227
+ const methodMap = getMethodHierarchiesMap(context, client);
228
+ for (const [prefixKey, operations] of methodMap) {
229
+ const prefixes = prefixKey.split("/");
230
+ const lroOperations = operations.filter((o) => isLroOnlyOperation(o));
218
231
  // skip this operation group if it has no LRO operations
219
- if (operations.length === 0) {
232
+ if (lroOperations.length === 0) {
220
233
  continue;
221
234
  }
222
235
 
223
236
  const operationFileName =
224
- operationGroup.className && operationGroup.namespaceHierarchies.length > 0
225
- ? `${operationGroup.namespaceHierarchies
237
+ prefixes.length > 0 && prefixKey !== ""
238
+ ? `${prefixes
226
239
  .map((hierarchy) => {
227
240
  return normalizeName(hierarchy, NameType.File);
228
241
  })
@@ -232,7 +245,7 @@ export function buildLroDeserDetailMap(client: Client) {
232
245
  "operations";
233
246
  map.set(
234
247
  `./api/${operationFileName}.js`,
235
- operations.map((o) => {
248
+ lroOperations.map((o) => {
236
249
  const { name } = getOperationName(o);
237
250
  const deserName = `_${name}Deserialize`;
238
251
  let renamedDeserName = undefined;
@@ -245,7 +258,7 @@ export function buildLroDeserDetailMap(client: Client) {
245
258
  }
246
259
  existingNames.add(deserName);
247
260
  return {
248
- path: `${o.method.toUpperCase()} ${o.url}`,
261
+ path: `${o.operation.verb.toUpperCase()} ${o.operation.path}`,
249
262
  expectedStatusesExpression: getExpectedStatuses(o),
250
263
  deserName,
251
264
  renamedDeserName
@@ -1,20 +1,21 @@
1
- import { NameType, normalizeName } from "@azure-tools/rlc-common";
1
+ import { NameType } from "@azure-tools/rlc-common";
2
2
 
3
- import { ModularCodeModel } from "./modularCodeModel.js";
3
+ import { ModularEmitterOptions } from "./interfaces.js";
4
4
  import { getClassicalLayerPrefix } from "./helpers/namingHelpers.js";
5
+ import { SdkContext } from "@azure-tools/typespec-client-generator-core";
6
+ import { getModularClientOptions } from "../utils/clientUtils.js";
7
+ import { getMethodHierarchiesMap } from "../utils/operationUtil.js";
5
8
 
6
9
  function buildExportsForMultiClient(
7
- codeModel: ModularCodeModel,
10
+ context: SdkContext,
11
+ emitterOptions: ModularEmitterOptions,
8
12
  packageInfo: any
9
13
  ) {
10
- if (codeModel.clients.length > 1) {
14
+ if (context.sdkPackage.clients.length > 1) {
11
15
  delete packageInfo.exports["./api"];
12
16
  delete packageInfo.exports["./models"];
13
- for (const client of codeModel.clients) {
14
- const subfolder = normalizeName(
15
- client.name.replace("Client", ""),
16
- NameType.File
17
- );
17
+ for (const client of context.sdkPackage.clients) {
18
+ const { subfolder } = getModularClientOptions(context, client);
18
19
  packageInfo.exports[`./${subfolder}`] = `./src/${subfolder}/index.ts`;
19
20
 
20
21
  packageInfo.exports[`./${subfolder}/api`] =
@@ -23,18 +24,17 @@ function buildExportsForMultiClient(
23
24
  `./src/${subfolder}/models/index.ts`;
24
25
  }
25
26
  }
26
- if (codeModel.options.hierarchyClient) {
27
- for (const client of codeModel.clients) {
28
- for (const operationGroup of client.operationGroups) {
29
- if (operationGroup.namespaceHierarchies.length === 0) {
27
+ if (emitterOptions.options.hierarchyClient) {
28
+ for (const client of context.sdkPackage.clients) {
29
+ const { subfolder } = getModularClientOptions(context, client);
30
+ const methodMap = getMethodHierarchiesMap(context, client);
31
+ for (const [prefixKey, _] of methodMap) {
32
+ const prefixes = prefixKey.split("/");
33
+ if (prefixKey === "") {
30
34
  continue;
31
35
  }
32
- const subfolder =
33
- codeModel.clients.length > 1
34
- ? normalizeName(client.name.replace("Client", ""), NameType.File)
35
- : undefined;
36
36
  const subApiPath = `api/${getClassicalLayerPrefix(
37
- operationGroup,
37
+ prefixes,
38
38
  NameType.File,
39
39
  "/"
40
40
  )}`;
@@ -48,16 +48,19 @@ function buildExportsForMultiClient(
48
48
  return packageInfo.exports;
49
49
  }
50
50
 
51
- export function getModuleExports(codeModel: ModularCodeModel) {
51
+ export function getModuleExports(
52
+ context: SdkContext,
53
+ emitterOptions: ModularEmitterOptions
54
+ ) {
52
55
  const exports: Record<string, any> = {
53
56
  exports: {
54
57
  ".": "./src/index.ts",
55
58
  "./models": "./src/models/index.ts"
56
59
  }
57
60
  };
58
- if (!codeModel.options.azureArm) {
61
+ if (!emitterOptions.options.azureArm) {
59
62
  exports["exports"]["./api"] = "./src/api/index.ts";
60
63
  }
61
64
 
62
- return buildExportsForMultiClient(codeModel, exports);
65
+ return buildExportsForMultiClient(context, emitterOptions, exports);
63
66
  }
@@ -1,35 +1,43 @@
1
1
  import { SourceFile } from "ts-morph";
2
2
  import { isLroOnlyOperation } from "./helpers/operationHelpers.js";
3
- import { ModularCodeModel, Client } from "./modularCodeModel.js";
3
+ import { ModularEmitterOptions } from "./interfaces.js";
4
4
  import path from "path";
5
5
  import { buildLroDeserDetailMap } from "./buildOperations.js";
6
6
  import { getClientName } from "./helpers/namingHelpers.js";
7
7
  import { NameType, normalizeName } from "@azure-tools/rlc-common";
8
8
  import { resolveReference } from "../framework/reference.js";
9
- import {
10
- AzureCoreDependencies,
11
- AzurePollingDependencies
12
- } from "./external-dependencies.js";
9
+ import { AzurePollingDependencies } from "./external-dependencies.js";
13
10
  import { PollingHelpers } from "./static-helpers-metadata.js";
11
+ import {
12
+ SdkClientType,
13
+ SdkServiceOperation
14
+ } from "@azure-tools/typespec-client-generator-core";
15
+ import { getMethodHierarchiesMap } from "../utils/operationUtil.js";
16
+ import { getModularClientOptions } from "../utils/clientUtils.js";
17
+ import { SdkContext } from "../utils/interfaces.js";
18
+ import { useDependencies } from "../framework/hooks/useDependencies.js";
14
19
 
15
20
  export function buildRestorePoller(
16
- codeModel: ModularCodeModel,
17
- client: Client
21
+ context: SdkContext,
22
+ client: SdkClientType<SdkServiceOperation>,
23
+ emitterOptions: ModularEmitterOptions
18
24
  ) {
19
- const lros = client.operationGroups
20
- .flatMap((op) => op.operations)
21
- .filter(isLroOnlyOperation);
22
- if (lros.length === 0) {
25
+ const dependencies = useDependencies();
26
+ const { subfolder } = getModularClientOptions(context, client);
27
+ const methodMap = getMethodHierarchiesMap(context, client);
28
+ const hasLro = Array.from(methodMap.values()).some((operations) => {
29
+ return operations.some(isLroOnlyOperation);
30
+ });
31
+ if (!hasLro) {
23
32
  return;
24
33
  }
25
- const srcPath = codeModel.modularOptions.sourceRoot;
26
- const subfolder = client.subfolder ?? "";
34
+ const srcPath = emitterOptions.modularOptions.sourceRoot;
27
35
  const filePath = path.join(
28
36
  `${srcPath}/${
29
- subfolder !== "" ? subfolder + "/" : ""
37
+ subfolder && subfolder !== "" ? subfolder + "/" : ""
30
38
  }restorePollerHelpers.ts`
31
39
  );
32
- const restorePollerFile = codeModel.project.createSourceFile(
40
+ const restorePollerFile = emitterOptions.project.createSourceFile(
33
41
  filePath,
34
42
  undefined,
35
43
  {
@@ -38,9 +46,13 @@ export function buildRestorePoller(
38
46
  );
39
47
 
40
48
  const clientNames = importClassicalClient(client, restorePollerFile);
41
- const deserializeMap = importDeserializeHelpers(client, restorePollerFile);
49
+ const deserializeMap = importDeserializeHelpers(
50
+ context,
51
+ client,
52
+ restorePollerFile
53
+ );
42
54
  const pathUncheckedReference = resolveReference(
43
- AzureCoreDependencies.PathUncheckedResponse
55
+ dependencies.PathUncheckedResponse
44
56
  );
45
57
  const pollerLikeReference = resolveReference(
46
58
  AzurePollingDependencies.PollerLike
@@ -49,7 +61,7 @@ export function buildRestorePoller(
49
61
  AzurePollingDependencies.OperationState
50
62
  );
51
63
  const operationOptionsReference = resolveReference(
52
- AzureCoreDependencies.OperationOptions
64
+ dependencies.OperationOptions
53
65
  );
54
66
  const deserializeStateReference = resolveReference(
55
67
  AzurePollingDependencies.DeserializeState
@@ -64,7 +76,7 @@ export function buildRestorePoller(
64
76
  /**
65
77
  * The signal which can be used to abort requests.
66
78
  */
67
- abortSignal?: ${resolveReference(AzureCoreDependencies.AbortSignalLike)};
79
+ abortSignal?: ${resolveReference(dependencies.AbortSignalLike)};
68
80
  /** Deserialization function for raw response body */
69
81
  processResponseBody?: (result: TResponse) => Promise<TResult>;
70
82
  }
@@ -203,8 +215,12 @@ export function buildRestorePoller(
203
215
  restorePollerFile.addStatements(restorePollerHelperContent);
204
216
  }
205
217
 
206
- function importDeserializeHelpers(client: Client, sourceFile: SourceFile) {
207
- const deserializeDetails = buildLroDeserDetailMap(client);
218
+ function importDeserializeHelpers(
219
+ context: SdkContext,
220
+ client: SdkClientType<SdkServiceOperation>,
221
+ sourceFile: SourceFile
222
+ ) {
223
+ const deserializeDetails = buildLroDeserDetailMap(context, client);
208
224
  const deserializeMap: string[] = [];
209
225
  for (const [key, value] of deserializeDetails.entries()) {
210
226
  sourceFile.addImportDeclaration({
@@ -227,10 +243,10 @@ function importDeserializeHelpers(client: Client, sourceFile: SourceFile) {
227
243
  }
228
244
 
229
245
  function importClassicalClient(
230
- client: Client,
246
+ client: SdkClientType<SdkServiceOperation>,
231
247
  sourceFile: SourceFile
232
248
  ): string[] {
233
- const classicalClientName = `${getClientName(client.tcgcClient)}Client`;
249
+ const classicalClientName = `${getClientName(client)}Client`;
234
250
  sourceFile.addImportDeclaration({
235
251
  namedImports: [`${classicalClientName}`],
236
252
  moduleSpecifier: `./${normalizeName(classicalClientName, NameType.File)}.js`
@@ -4,21 +4,29 @@ import {
4
4
  getClassicalClientName,
5
5
  getClientName
6
6
  } from "./helpers/namingHelpers.js";
7
- import { Client, ModularCodeModel } from "./modularCodeModel.js";
7
+ import { ModularEmitterOptions } from "./interfaces.js";
8
8
  import { resolveReference } from "../framework/reference.js";
9
9
  import { PagingHelpers } from "./static-helpers-metadata.js";
10
+ import {
11
+ SdkClientType,
12
+ SdkContext,
13
+ SdkServiceOperation
14
+ } from "@azure-tools/typespec-client-generator-core";
15
+ import { getModularClientOptions } from "../utils/clientUtils.js";
16
+ import { getMethodHierarchiesMap } from "../utils/operationUtil.js";
10
17
 
11
18
  export function buildRootIndex(
12
- client: Client,
13
- codeModel: ModularCodeModel,
19
+ context: SdkContext,
20
+ client: SdkClientType<SdkServiceOperation>,
21
+ emitterOptions: ModularEmitterOptions,
14
22
  rootIndexFile: SourceFile
15
23
  ) {
16
- const { project } = codeModel;
17
- const srcPath = codeModel.modularOptions.sourceRoot;
18
- const subfolder = client.subfolder ?? "";
19
- const clientName = `${getClassicalClientName(client.tcgcClient)}`;
24
+ const { project } = emitterOptions;
25
+ const srcPath = emitterOptions.modularOptions.sourceRoot;
26
+ const { subfolder } = getModularClientOptions(context, client);
27
+ const clientName = `${getClassicalClientName(client)}`;
20
28
  const clientFile = project.getSourceFile(
21
- `${srcPath}/${subfolder !== "" ? subfolder + "/" : ""}${normalizeName(
29
+ `${srcPath}/${subfolder && subfolder !== "" ? subfolder + "/" : ""}${normalizeName(
22
30
  clientName,
23
31
  NameType.File
24
32
  )}.ts`
@@ -33,7 +41,7 @@ export function buildRootIndex(
33
41
  );
34
42
  }
35
43
 
36
- exportClassicalClient(client, rootIndexFile, subfolder);
44
+ exportClassicalClient(client, rootIndexFile, subfolder ?? "");
37
45
  exportRestoreHelpers(
38
46
  rootIndexFile,
39
47
  project,
@@ -62,17 +70,14 @@ export function buildRootIndex(
62
70
  isTopLevel: true
63
71
  });
64
72
 
65
- exportPagingTypes(codeModel, rootIndexFile);
73
+ exportPagingTypes(context, rootIndexFile);
66
74
  }
67
75
 
68
76
  /**
69
77
  * This is a temporary solution for adding paging exports. Eventually we will have the binder generate the exports automatically.
70
78
  */
71
- function exportPagingTypes(
72
- codeModel: ModularCodeModel,
73
- rootIndexFile: SourceFile
74
- ) {
75
- if (!hasPaging(codeModel)) {
79
+ function exportPagingTypes(context: SdkContext, rootIndexFile: SourceFile) {
80
+ if (!hasPaging(context)) {
76
81
  return;
77
82
  }
78
83
 
@@ -90,15 +95,18 @@ function exportPagingTypes(
90
95
  }
91
96
  }
92
97
 
93
- function hasPaging(codeModel: ModularCodeModel): boolean {
94
- return codeModel.clients.some((c) =>
95
- c.operationGroups.some((og) =>
96
- og.operations.some(
97
- (op) =>
98
- op.discriminator === "paging" || op.discriminator === "lropaging"
99
- )
100
- )
101
- );
98
+ function hasPaging(context: SdkContext): boolean {
99
+ return context.sdkPackage.clients.some((client) => {
100
+ const methodMap = getMethodHierarchiesMap(context, client);
101
+ for (const [_, operations] of methodMap) {
102
+ if (
103
+ operations.some((op) => op.kind === "paging" || op.kind === "lropaging")
104
+ ) {
105
+ return true;
106
+ }
107
+ }
108
+ return false;
109
+ });
102
110
  }
103
111
 
104
112
  function getExistingExports(rootIndexFile: SourceFile): Set<string> {
@@ -139,7 +147,7 @@ function exportRestoreHelpers(
139
147
  ) {
140
148
  const helperFile = project.getSourceFile(
141
149
  `${srcPath}/${
142
- subfolder !== "" ? subfolder + "/" : ""
150
+ subfolder && subfolder !== "" ? subfolder + "/" : ""
143
151
  }restorePollerHelpers.ts`
144
152
  );
145
153
  if (!helperFile) {
@@ -155,7 +163,7 @@ function exportRestoreHelpers(
155
163
  }
156
164
  );
157
165
  const moduleSpecifier = `./${
158
- isTopLevel && subfolder !== "" ? subfolder + "/" : ""
166
+ isTopLevel && subfolder && subfolder !== "" ? subfolder + "/" : ""
159
167
  }restorePollerHelpers.js`;
160
168
  indexFile.addExportDeclaration({
161
169
  moduleSpecifier,
@@ -164,16 +172,16 @@ function exportRestoreHelpers(
164
172
  }
165
173
 
166
174
  function exportClassicalClient(
167
- client: Client,
175
+ client: SdkClientType<SdkServiceOperation>,
168
176
  indexFile: SourceFile,
169
177
  subfolder: string,
170
178
  isSubClient: boolean = false
171
179
  ) {
172
- const clientName = `${getClientName(client.tcgcClient)}Client`;
180
+ const clientName = `${getClientName(client)}Client`;
173
181
  indexFile.addExportDeclaration({
174
182
  namedExports: [clientName],
175
183
  moduleSpecifier: `./${
176
- subfolder !== "" && !isSubClient ? subfolder + "/" : ""
184
+ subfolder && subfolder !== "" && !isSubClient ? subfolder + "/" : ""
177
185
  }${normalizeName(clientName, NameType.File)}.js`
178
186
  });
179
187
  }
@@ -248,37 +256,38 @@ function exportModules(
248
256
  }
249
257
 
250
258
  export function buildSubClientIndexFile(
251
- client: Client,
252
- codeModel: ModularCodeModel
259
+ context: SdkContext,
260
+ client: SdkClientType<SdkServiceOperation>,
261
+ emitterOptions: ModularEmitterOptions
253
262
  ) {
254
- const subfolder = client.subfolder ?? "";
255
- const srcPath = codeModel.modularOptions.sourceRoot;
256
- const subClientIndexFile = codeModel.project.createSourceFile(
257
- `${srcPath}/${subfolder !== "" ? subfolder + "/" : ""}index.ts`,
263
+ const { subfolder } = getModularClientOptions(context, client);
264
+ const srcPath = emitterOptions.modularOptions.sourceRoot;
265
+ const subClientIndexFile = emitterOptions.project.createSourceFile(
266
+ `${srcPath}/${subfolder && subfolder !== "" ? subfolder + "/" : ""}index.ts`,
258
267
  undefined,
259
268
  { overwrite: true }
260
269
  );
261
- const clientName = `${getClientName(client.tcgcClient)}Client`;
270
+ const clientName = `${getClientName(client)}Client`;
262
271
  const clientFilePath = `${srcPath}/${
263
- subfolder !== "" ? subfolder + "/" : ""
272
+ subfolder && subfolder !== "" ? subfolder + "/" : ""
264
273
  }${normalizeName(clientName, NameType.File)}.ts`;
265
- const clientFile = codeModel.project.getSourceFile(clientFilePath);
274
+ const clientFile = emitterOptions.project.getSourceFile(clientFilePath);
266
275
 
267
276
  if (!clientFile) {
268
277
  throw new Error(`Couldn't find client file: ${clientFilePath}`);
269
278
  }
270
279
 
271
- exportClassicalClient(client, subClientIndexFile, subfolder, true);
280
+ exportClassicalClient(client, subClientIndexFile, subfolder ?? "", true);
272
281
  exportRestoreHelpers(
273
282
  subClientIndexFile,
274
- codeModel.project,
283
+ emitterOptions.project,
275
284
  srcPath,
276
285
  clientName,
277
286
  subfolder
278
287
  );
279
288
  exportModules(
280
289
  subClientIndexFile,
281
- codeModel.project,
290
+ emitterOptions.project,
282
291
  srcPath,
283
292
  clientName,
284
293
  "api",
@@ -289,7 +298,7 @@ export function buildSubClientIndexFile(
289
298
  );
290
299
  exportModules(
291
300
  subClientIndexFile,
292
- codeModel.project,
301
+ emitterOptions.project,
293
302
  srcPath,
294
303
  clientName,
295
304
  "classic",