@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,12 +1,3 @@
1
- import {
2
- BodyParameter,
3
- Client,
4
- ModularCodeModel,
5
- Operation,
6
- Parameter,
7
- Property,
8
- Type
9
- } from "../modularCodeModel.js";
10
1
  import {
11
2
  FunctionDeclarationStructure,
12
3
  OptionalKind,
@@ -14,11 +5,17 @@ import {
14
5
  } from "ts-morph";
15
6
  import { NoTarget, Program } from "@typespec/compiler";
16
7
  import { PagingHelpers, PollingHelpers } from "../static-helpers-metadata.js";
17
- import { getType, isTypeNullable } from "./typeHelpers.js";
8
+ import {
9
+ getNullableValidType,
10
+ isSpreadBodyParameter,
11
+ isTypeNullable
12
+ } from "./typeHelpers.js";
18
13
  import { getClassicalLayerPrefix, getOperationName } from "./namingHelpers.js";
19
14
  import {
20
15
  getCollectionFormatHelper,
21
- hasCollectionFormatInfo
16
+ hasCollectionFormatInfo,
17
+ isBinaryPayload,
18
+ ServiceOperation
22
19
  } from "../../utils/operationUtil.js";
23
20
  import {
24
21
  isNormalUnion,
@@ -31,7 +28,7 @@ import {
31
28
  import { toPascalCase } from "../../utils/casingUtils.js";
32
29
 
33
30
  import { AzurePollingDependencies } from "../external-dependencies.js";
34
- import { NameType } from "@azure-tools/rlc-common";
31
+ import { NameType, normalizeName } from "@azure-tools/rlc-common";
35
32
  import { buildModelDeserializer } from "../serialization/buildDeserializerFunction.js";
36
33
  import { buildModelSerializer } from "../serialization/buildSerializerFunction.js";
37
34
  import { refkey } from "../../framework/refkey.js";
@@ -40,17 +37,38 @@ import { resolveReference } from "../../framework/reference.js";
40
37
  import { useDependencies } from "../../framework/hooks/useDependencies.js";
41
38
  import { useSdkTypes } from "../../framework/hooks/sdkTypes.js";
42
39
  import { isAzureCoreErrorType } from "../../utils/modelUtils.js";
43
- import { getTypeExpression } from "../type-expressions/get-type-expression.js";
40
+ import {
41
+ getTypeExpression,
42
+ normalizeModelPropertyName
43
+ } from "../type-expressions/get-type-expression.js";
44
44
  import { SdkContext } from "../../utils/interfaces.js";
45
+ import {
46
+ isReadOnly,
47
+ SdkBodyParameter,
48
+ SdkClientType,
49
+ SdkConstantType,
50
+ SdkHttpOperation,
51
+ SdkHttpParameter,
52
+ SdkLroPagingServiceMethod,
53
+ SdkLroServiceMethod,
54
+ SdkMethod,
55
+ SdkModelPropertyType,
56
+ SdkModelType,
57
+ SdkPagingServiceMethod,
58
+ SdkServiceParameter,
59
+ SdkType
60
+ } from "@azure-tools/typespec-client-generator-core";
45
61
 
46
62
  export function getSendPrivateFunction(
47
63
  dpgContext: SdkContext,
48
- operation: Operation,
64
+ client: SdkClientType<SdkHttpOperation>,
65
+ method: [string[], ServiceOperation],
49
66
  clientType: string
50
67
  ): OptionalKind<FunctionDeclarationStructure> {
68
+ const operation = method[1];
51
69
  const parameters = getOperationSignatureParameters(
52
70
  dpgContext,
53
- operation,
71
+ method,
54
72
  clientType
55
73
  );
56
74
  const { name } = getOperationName(operation);
@@ -64,20 +82,31 @@ export function getSendPrivateFunction(
64
82
  returnType: resolveReference(dependencies.StreamableMethod)
65
83
  };
66
84
 
67
- const operationPath = operation.url;
68
- const operationMethod = operation.method.toLowerCase();
69
- const optionalParamName = parameters.filter((p) =>
70
- p.type?.toString().endsWith("OptionalParams")
71
- )[0]?.name;
72
-
85
+ const operationPath = operation.operation.path;
86
+ const operationMethod = operation.operation.verb.toLowerCase();
87
+ const optionalParamName = getOptionalParamsName(parameters);
88
+ const hasQueryApiVersion = operation.operation.parameters.some(
89
+ (p) => p.isApiVersionParam && p.onClient && p.kind === "query"
90
+ );
91
+ const hasClientApiVersion = client.initialization.properties.some(
92
+ (p) => p.isApiVersionParam && p.onClient && p.kind === "method"
93
+ );
73
94
  const statements: string[] = [];
95
+ if (hasClientApiVersion && !hasQueryApiVersion) {
96
+ statements.push(
97
+ `context.pipeline.removePolicy({ name: "ClientApiVersionPolicy"});`
98
+ );
99
+ }
100
+
74
101
  statements.push(
75
102
  `return context.path("${operationPath}", ${getPathParameters(
76
103
  dpgContext,
77
- operation
104
+ operation,
105
+ optionalParamName
78
106
  )}).${operationMethod}({...${resolveReference(dependencies.operationOptionsToRequestParameters)}(${optionalParamName}), ${getRequestParameters(
79
107
  dpgContext,
80
- operation
108
+ operation,
109
+ optionalParamName
81
110
  )}});`
82
111
  );
83
112
 
@@ -89,7 +118,7 @@ export function getSendPrivateFunction(
89
118
 
90
119
  export function getDeserializePrivateFunction(
91
120
  context: SdkContext,
92
- operation: Operation
121
+ operation: ServiceOperation
93
122
  ): OptionalKind<FunctionDeclarationStructure> {
94
123
  const { name } = getOperationName(operation);
95
124
  const dependencies = useDependencies();
@@ -108,14 +137,15 @@ export function getDeserializePrivateFunction(
108
137
 
109
138
  // TODO: Support operation overloads
110
139
  // TODO: Support multiple responses
111
- const response = operation.responses[0]!;
140
+ const response = operation.response;
141
+ const restResponse = operation.operation.responses[0];
112
142
  let returnType;
113
- if (isLroOnly && operation.method.toLowerCase() !== "patch") {
143
+ if (isLroOnly && operation.operation.verb.toLowerCase() !== "patch") {
114
144
  returnType = buildLroReturnType(context, operation);
115
- } else if (response?.type?.type) {
145
+ } else if (response.type && restResponse) {
116
146
  returnType = {
117
- name: response.type.name,
118
- type: getTypeExpression(context, response.type.tcgcType!)
147
+ name: (restResponse as any).name ?? "",
148
+ type: getTypeExpression(context, restResponse.type!)
119
149
  };
120
150
  } else {
121
151
  returnType = { name: "", type: "void" };
@@ -142,16 +172,18 @@ export function getDeserializePrivateFunction(
142
172
  "}"
143
173
  );
144
174
  const deserializedType = isLroOnly
145
- ? operation?.lroMetadata?.finalResult
146
- : response.type;
147
- const hasLroSubPath = operation?.lroMetadata?.finalResultPath !== undefined;
175
+ ? operation?.lroMetadata?.finalResponse?.result
176
+ : restResponse
177
+ ? restResponse.type
178
+ : response.type;
179
+ const lroSubPath = isLroOnly
180
+ ? operation?.lroMetadata?.finalResponse?.resultPath
181
+ : undefined;
148
182
 
149
183
  const deserializePrefix = "result.body";
150
184
 
151
- const deserializedRoot = hasLroSubPath
152
- ? `${deserializePrefix}.${operation?.lroMetadata?.finalResultPath}`
153
- : `${deserializePrefix}`;
154
- if (isLroOnly && hasLroSubPath) {
185
+ const deserializedRoot = `${deserializePrefix}${lroSubPath ? "." + lroSubPath : ""}`;
186
+ if (isLroOnly && lroSubPath) {
155
187
  statements.push(
156
188
  `if(${deserializedRoot.split(".").join("?.")} === undefined) {
157
189
  throw createRestError(\`Expected a result in the response at position "${deserializedRoot}"\`, result);
@@ -160,10 +192,11 @@ export function getDeserializePrivateFunction(
160
192
  );
161
193
  }
162
194
 
163
- if (deserializedType?.tcgcType) {
195
+ if (deserializedType) {
196
+ const contentTypes = operation.operation.responses[0]?.contentTypes;
164
197
  const deserializeFunctionName = buildModelDeserializer(
165
198
  context,
166
- deserializedType.tcgcType,
199
+ deserializedType,
167
200
  false,
168
201
  true
169
202
  );
@@ -177,21 +210,14 @@ export function getDeserializePrivateFunction(
177
210
  context,
178
211
  deserializedType,
179
212
  deserializedRoot,
180
- response.isBinaryPayload ? "binary" : deserializedType.format
213
+ isBinaryPayload(context, response.type!.__raw!, contentTypes!)
214
+ ? "binary"
215
+ : getEncodeForType(deserializedType)
181
216
  )}`
182
217
  );
183
218
  }
184
219
  } else if (returnType.type === "void") {
185
220
  statements.push("return;");
186
- } else if (deserializedType) {
187
- statements.push(
188
- `return ${deserializeResponseValue(
189
- context,
190
- deserializedType,
191
- deserializedRoot,
192
- response.isBinaryPayload ? "binary" : deserializedType.format
193
- )}`
194
- );
195
221
  } else {
196
222
  statements.push("return;");
197
223
  }
@@ -202,12 +228,22 @@ export function getDeserializePrivateFunction(
202
228
  };
203
229
  }
204
230
 
231
+ function getOptionalParamsName(
232
+ parameters: OptionalKind<ParameterDeclarationStructure>[]
233
+ ) {
234
+ return (
235
+ parameters.filter((p) => p.type?.toString().endsWith("OptionalParams"))[0]
236
+ ?.name ?? "options"
237
+ );
238
+ }
239
+
205
240
  function getOperationSignatureParameters(
206
241
  context: SdkContext,
207
- operation: Operation,
242
+ method: [string[], ServiceOperation],
208
243
  clientType: string
209
244
  ): OptionalKind<ParameterDeclarationStructure>[] {
210
- const optionsType = getOperationOptionsName(operation, true);
245
+ const operation = method[1];
246
+ const optionsType = getOperationOptionsName(method, true);
211
247
  const parameters: Map<
212
248
  string,
213
249
  OptionalKind<ParameterDeclarationStructure>
@@ -216,30 +252,31 @@ function getOperationSignatureParameters(
216
252
  operation.parameters
217
253
  .filter(
218
254
  (p) =>
219
- p.implementation === "Method" &&
220
- p.type.type !== "constant" &&
255
+ p.onClient === false &&
256
+ p.type.kind !== "constant" &&
257
+ operation.operation.parameters.filter((param) => {
258
+ return (
259
+ param.correspondingMethodParams.length === 1 &&
260
+ param.correspondingMethodParams[0] === p
261
+ );
262
+ })[0]?.kind !== "cookie" &&
221
263
  p.clientDefaultValue === undefined &&
222
- !p.optional
264
+ !p.optional &&
265
+ !(
266
+ p.isGeneratedName &&
267
+ (p.name === "contentType" || p.name === "accept")
268
+ ) // skip tcgc generated contentType and accept header parameter
223
269
  )
224
270
  .map((p) => {
225
271
  return {
226
- name: p.clientName,
227
- type: getTypeExpression(context, p.tcgcType ?? p.type.tcgcType!)
272
+ name: p.name,
273
+ type: getTypeExpression(context, p.type)
228
274
  };
229
275
  })
230
276
  .forEach((p) => {
231
277
  parameters.set(p.name, p);
232
278
  });
233
279
 
234
- if (operation.bodyParameter && operation.bodyParameter.optional === false) {
235
- parameters.set(operation.bodyParameter?.clientName, {
236
- hasQuestionToken: operation.bodyParameter.optional,
237
- ...{
238
- name: operation.bodyParameter.clientName,
239
- type: getTypeExpression(context, operation.bodyParameter.type.tcgcType!)
240
- }
241
- });
242
- }
243
280
  // Add context as the first parameter
244
281
  const contextParam = { name: "context", type: clientType };
245
282
 
@@ -260,47 +297,54 @@ function getOperationSignatureParameters(
260
297
  */
261
298
  export function getOperationFunction(
262
299
  context: SdkContext,
263
- operation: Operation,
300
+ method: [string[], ServiceOperation],
264
301
  clientType: string
265
302
  ): OptionalKind<FunctionDeclarationStructure> & { propertyName?: string } {
303
+ const operation = method[1];
304
+ // Extract required parameters
305
+ const parameters: OptionalKind<ParameterDeclarationStructure>[] =
306
+ getOperationSignatureParameters(context, method, clientType);
307
+ const optionalParamName = getOptionalParamsName(parameters);
266
308
  if (isPagingOnlyOperation(operation)) {
267
309
  // Case 1: paging-only operation
268
- return getPagingOnlyOperationFunction(context, operation, clientType);
310
+ return getPagingOnlyOperationFunction(
311
+ context,
312
+ [method[0], operation],
313
+ clientType
314
+ );
269
315
  } else if (isLroOnlyOperation(operation)) {
270
316
  // Case 2: lro-only operation
271
- return getLroOnlyOperationFunction(context, operation, clientType);
317
+ return getLroOnlyOperationFunction(
318
+ context,
319
+ [method[0], operation],
320
+ clientType,
321
+ optionalParamName
322
+ );
272
323
  } else if (isLroAndPagingOperation(operation)) {
273
324
  // Case 3: both paging + lro operation is not supported yet so handle them as normal operation and customization may be needed
274
325
  // https://github.com/Azure/autorest.typescript/issues/2313
275
326
  }
276
327
 
277
- if (operation.name === "floatSeconds") {
278
- operation;
279
- }
280
- // Extract required parameters
281
- const parameters: OptionalKind<ParameterDeclarationStructure>[] =
282
- getOperationSignatureParameters(context, operation, clientType);
283
328
  // TODO: Support operation overloads
284
- const response = operation.responses[0]!;
329
+ const response = operation.response;
285
330
  let returnType = { name: "", type: "void" };
286
- if (response.type?.type) {
287
- const type =
288
- extractPagingType(response.type, operation.itemName) ?? response.type;
331
+ if (response.type) {
332
+ const type = response.type;
289
333
  returnType = {
290
- name: type.name ?? "",
291
- type: getTypeExpression(context, type.tcgcType!)
334
+ name: (type as any).name ?? "",
335
+ type: getTypeExpression(context, type!)
292
336
  };
293
337
  }
294
338
  const { name, fixme = [] } = getOperationName(operation);
295
339
  const functionStatement = {
296
340
  docs: [
297
- ...getDocsFromDescription(operation.description),
341
+ ...getDocsFromDescription(operation.doc),
298
342
  ...getFixmeForMultilineDocs(fixme)
299
343
  ],
300
344
  isAsync: true,
301
345
  isExported: true,
302
346
  name,
303
- propertyName: operation.name,
347
+ propertyName: normalizeName(operation.name, NameType.Property),
304
348
  parameters,
305
349
  returnType: `Promise<${returnType.type}>`
306
350
  };
@@ -321,12 +365,14 @@ export function getOperationFunction(
321
365
 
322
366
  function getLroOnlyOperationFunction(
323
367
  context: SdkContext,
324
- operation: Operation,
325
- clientType: string
368
+ method: [string[], SdkLroServiceMethod<SdkHttpOperation>],
369
+ clientType: string,
370
+ optionalParamName: string = "options"
326
371
  ) {
372
+ const operation = method[1];
327
373
  // Extract required parameters
328
374
  const parameters: OptionalKind<ParameterDeclarationStructure>[] =
329
- getOperationSignatureParameters(context, operation, clientType);
375
+ getOperationSignatureParameters(context, method, clientType);
330
376
  const returnType = buildLroReturnType(context, operation);
331
377
  const { name, fixme = [] } = getOperationName(operation);
332
378
  const pollerLikeReference = resolveReference(
@@ -337,13 +383,13 @@ function getLroOnlyOperationFunction(
337
383
  );
338
384
  const functionStatement = {
339
385
  docs: [
340
- ...getDocsFromDescription(operation.description),
386
+ ...getDocsFromDescription(operation.doc),
341
387
  ...getFixmeForMultilineDocs(fixme)
342
388
  ],
343
389
  isAsync: false,
344
390
  isExported: true,
345
391
  name,
346
- propertyName: operation.name,
392
+ propertyName: normalizeName(operation.name, NameType.Property),
347
393
  parameters,
348
394
  returnType: `${pollerLikeReference}<${operationStateReference}<${returnType.type}>, ${returnType.type}>`
349
395
  };
@@ -351,17 +397,29 @@ function getLroOnlyOperationFunction(
351
397
  const getLongRunningPollerReference = resolveReference(
352
398
  PollingHelpers.GetLongRunningPoller
353
399
  );
354
- const resourceLocationConfig = operation.lroMetadata?.finalStateVia
355
- ? `resourceLocationConfig: "${operation.lroMetadata?.finalStateVia}"`
356
- : "";
400
+ const lroMetadata =
401
+ operation.kind === "lro" || operation.kind === "lropaging"
402
+ ? operation.lroMetadata
403
+ : undefined;
404
+ const allowedFinalLocation = [
405
+ "azure-async-operation",
406
+ "location",
407
+ "original-uri",
408
+ "operation-location"
409
+ ];
410
+ const resourceLocationConfig =
411
+ lroMetadata?.finalStateVia &&
412
+ allowedFinalLocation.includes(lroMetadata?.finalStateVia)
413
+ ? `resourceLocationConfig: "${lroMetadata?.finalStateVia}"`
414
+ : "";
357
415
  const statements: string[] = [];
358
416
  statements.push(`
359
417
 
360
418
  return ${getLongRunningPollerReference}(context, _${name}Deserialize, ${getExpectedStatuses(
361
419
  operation
362
420
  )}, {
363
- updateIntervalInMs: options?.updateIntervalInMs,
364
- abortSignal: options?.abortSignal,
421
+ updateIntervalInMs: ${optionalParamName}?.updateIntervalInMs,
422
+ abortSignal: ${optionalParamName}?.abortSignal,
365
423
  getInitialResponse: () => _${name}Send(${parameters
366
424
  .map((p) => p.name)
367
425
  .join(", ")}),
@@ -377,13 +435,16 @@ function getLroOnlyOperationFunction(
377
435
  };
378
436
  }
379
437
 
380
- function buildLroReturnType(context: SdkContext, operation: Operation) {
438
+ function buildLroReturnType(
439
+ context: SdkContext,
440
+ operation: SdkLroServiceMethod<SdkHttpOperation>
441
+ ) {
381
442
  const metadata = operation.lroMetadata;
382
- if (metadata !== undefined && metadata.finalResult !== undefined) {
383
- const type = metadata.finalResult;
443
+ if (metadata !== undefined && metadata.finalResponse !== undefined) {
444
+ const type = metadata.finalResponse.result;
384
445
  return {
385
446
  name: type.name,
386
- type: getTypeExpression(context, type.tcgcType!)
447
+ type: getTypeExpression(context, type)
387
448
  };
388
449
  }
389
450
  return { name: "", type: "void" };
@@ -391,22 +452,22 @@ function buildLroReturnType(context: SdkContext, operation: Operation) {
391
452
 
392
453
  function getPagingOnlyOperationFunction(
393
454
  context: SdkContext,
394
- operation: Operation,
455
+ method: [string[], SdkPagingServiceMethod<SdkHttpOperation>],
395
456
  clientType: string
396
457
  ) {
458
+ const operation = method[1];
397
459
  // Extract required parameters
398
460
  const parameters: OptionalKind<ParameterDeclarationStructure>[] =
399
- getOperationSignatureParameters(context, operation, clientType);
461
+ getOperationSignatureParameters(context, method, clientType);
400
462
 
401
463
  // TODO: Support operation overloads
402
- const response = operation.responses[0]!;
464
+ const response = operation.response;
403
465
  let returnType = { name: "", type: "void" };
404
- if (response.type?.type) {
405
- const type =
406
- extractPagingType(response.type, operation.itemName) ?? response.type;
466
+ if (response.type && response.type.kind === "array") {
467
+ const type = response.type;
407
468
  returnType = {
408
- name: type.name ?? "",
409
- type: getTypeExpression(context, type.tcgcType!)
469
+ name: (type.valueType as any).name ?? "",
470
+ type: getTypeExpression(context, type.valueType)
410
471
  };
411
472
  }
412
473
  const { name, fixme = [] } = getOperationName(operation);
@@ -418,24 +479,33 @@ function getPagingOnlyOperationFunction(
418
479
  );
419
480
  const functionStatement = {
420
481
  docs: [
421
- ...getDocsFromDescription(operation.description),
482
+ ...getDocsFromDescription(operation.doc),
422
483
  ...getFixmeForMultilineDocs(fixme)
423
484
  ],
424
485
  isAsync: false,
425
486
  isExported: true,
426
487
  name,
427
- propertyName: operation.name,
488
+ propertyName: normalizeName(operation.name, NameType.Property),
428
489
  parameters,
429
490
  returnType: `${pagedAsyncIterableIteratorReference}<${returnType.type}>`
430
491
  };
431
492
 
432
493
  const statements: string[] = [];
433
494
  const options = [];
434
- if (operation.itemName) {
435
- options.push(`itemName: "${operation.itemName}"`);
495
+ // TODO pending tcgc issue to fix https://github.com/Azure/typespec-azure/issues/1985
496
+ const itemName =
497
+ operation.response.resultPath !== "" && operation.response.resultPath
498
+ ? operation.response.resultPath
499
+ : operation.__raw_paged_metadata?.itemsSegments
500
+ ? operation.__raw_paged_metadata.itemsSegments[0]
501
+ : undefined;
502
+ if (itemName) {
503
+ options.push(`itemName: "${itemName}"`);
436
504
  }
437
- if (operation.continuationTokenName) {
438
- options.push(`nextLinkName: "${operation.continuationTokenName}"`);
505
+ if (operation.__raw_paged_metadata?.nextLinkSegments) {
506
+ options.push(
507
+ `nextLinkName: "${operation.__raw_paged_metadata.nextLinkSegments[0]}"`
508
+ );
439
509
  }
440
510
  statements.push(
441
511
  `return ${buildPagedAsyncIteratorReference}(
@@ -453,31 +523,15 @@ function getPagingOnlyOperationFunction(
453
523
  };
454
524
  }
455
525
 
456
- function extractPagingType(type: Type, itemName?: string): Type | undefined {
457
- if (!itemName) {
458
- return undefined;
459
- }
460
- const allProperties = [
461
- ...(type.properties ?? []),
462
- ...(type.parents ?? []).flatMap((p) => p.properties ?? [])
463
- ];
464
- const prop = allProperties
465
- .filter((prop) => prop.restApiName === itemName)
466
- .map((prop) => prop.type);
467
- if (prop.length === 0) {
468
- return undefined;
469
- }
470
- return prop[0]?.type === "list" && prop[0].elementType
471
- ? prop[0].elementType
472
- : undefined;
473
- }
474
526
  export function getOperationOptionsName(
475
- operation: Operation,
527
+ method: [string[], ServiceOperation],
476
528
  includeGroupName = false
477
529
  ) {
530
+ const prefixes = method[0];
531
+ const operation = method[1];
478
532
  const prefix =
479
533
  includeGroupName && operation.name.indexOf("_") === -1
480
- ? getClassicalLayerPrefix(operation, NameType.Interface)
534
+ ? getClassicalLayerPrefix(prefixes, NameType.Interface)
481
535
  : "";
482
536
  const optionName = `${prefix}${toPascalCase(operation.name)}OptionalParams`;
483
537
  return optionName;
@@ -490,20 +544,22 @@ export function getOperationOptionsName(
490
544
  */
491
545
  function getRequestParameters(
492
546
  dpgContext: SdkContext,
493
- operation: Operation
547
+ operation: ServiceOperation,
548
+ optionalParamName: string = "options"
494
549
  ): string {
495
- if (!operation.parameters) {
550
+ if (!operation.operation.parameters) {
496
551
  return "";
497
552
  }
498
- const operationParameters = operation.parameters.filter(
499
- (p) => p.implementation !== "Client" && !isContentType(p)
553
+ const operationParameters = operation.operation.parameters.filter(
554
+ (p) => (!p.onClient || p.isApiVersionParam) && !isContentType(p)
500
555
  );
501
556
 
502
- const contentTypeParameter = operation.parameters.find(isContentType);
557
+ const contentTypeParameter =
558
+ operation.operation.parameters.find(isContentType);
503
559
 
504
560
  const parametersImplementation: Record<
505
561
  "header" | "query" | "body",
506
- { paramMap: string; param: Parameter }[]
562
+ { paramMap: string; param: SdkServiceParameter }[]
507
563
  > = {
508
564
  header: [],
509
565
  query: [],
@@ -511,13 +567,17 @@ function getRequestParameters(
511
567
  };
512
568
 
513
569
  for (const param of operationParameters) {
514
- if (
515
- param.location === "header" ||
516
- param.location === "query" ||
517
- param.location === "body"
518
- ) {
519
- parametersImplementation[param.location].push({
520
- paramMap: getParameterMap(dpgContext, param),
570
+ if (param.kind === "header" || param.kind === "query") {
571
+ // skip tcgc generated contentType and accept non constant type header parameter
572
+ if (
573
+ param.isGeneratedName &&
574
+ !isConstant(param.type) &&
575
+ (param.name === "contentType" || param.name === "accept")
576
+ ) {
577
+ continue;
578
+ }
579
+ parametersImplementation[param.kind].push({
580
+ paramMap: getParameterMap(dpgContext, param, optionalParamName),
521
581
  param
522
582
  });
523
583
  }
@@ -526,13 +586,20 @@ function getRequestParameters(
526
586
  let paramStr = "";
527
587
 
528
588
  if (contentTypeParameter) {
529
- paramStr = `${getContentTypeValue(contentTypeParameter)},`;
589
+ paramStr = `${getContentTypeValue(contentTypeParameter, optionalParamName)},`;
530
590
  }
531
591
 
532
592
  if (parametersImplementation.header.length) {
533
593
  paramStr = `${paramStr}\nheaders: {${parametersImplementation.header
534
- .map((i) => buildHeaderParameter(dpgContext.program, i.paramMap, i.param))
535
- .join(",\n")}},`;
594
+ .map((i) =>
595
+ buildHeaderParameter(
596
+ dpgContext.program,
597
+ i.paramMap,
598
+ i.param,
599
+ optionalParamName
600
+ )
601
+ )
602
+ .join(",\n")}, ...${optionalParamName}.requestOptions?.headers },`;
536
603
  }
537
604
 
538
605
  if (parametersImplementation.query.length) {
@@ -541,14 +608,14 @@ function getRequestParameters(
541
608
  .join(",\n")}},`;
542
609
  }
543
610
  if (
544
- operation.bodyParameter === undefined &&
611
+ operation.operation.bodyParam === undefined &&
545
612
  parametersImplementation.body.length
546
613
  ) {
547
614
  paramStr = `${paramStr}\nbody: {${parametersImplementation.body
548
615
  .map((i) => i.paramMap)
549
616
  .join(",\n")}}`;
550
- } else if (operation.bodyParameter !== undefined) {
551
- paramStr = `${paramStr}${buildBodyParameter(dpgContext, operation.bodyParameter)}`;
617
+ } else if (operation.operation.bodyParam !== undefined) {
618
+ paramStr = `${paramStr}${buildBodyParameter(dpgContext, operation.operation.bodyParam)}`;
552
619
  }
553
620
  return paramStr;
554
621
  }
@@ -557,8 +624,10 @@ function getRequestParameters(
557
624
  function buildHeaderParameter(
558
625
  program: Program,
559
626
  paramMap: string,
560
- param: Parameter
627
+ param: SdkServiceParameter,
628
+ optionalParamName: string = "options"
561
629
  ): string {
630
+ const paramName = param.name;
562
631
  if (!param.optional && isTypeNullable(param.type) === true) {
563
632
  reportDiagnostic(program, {
564
633
  code: "nullable-required-header",
@@ -568,10 +637,10 @@ function buildHeaderParameter(
568
637
  }
569
638
  const conditions = [];
570
639
  if (param.optional) {
571
- conditions.push(`options?.${param.clientName} !== undefined`);
640
+ conditions.push(`${optionalParamName}?.${paramName} !== undefined`);
572
641
  }
573
642
  if (isTypeNullable(param.type) === true) {
574
- conditions.push(`options?.${param.clientName} !== null`);
643
+ conditions.push(`${optionalParamName}?.${paramName} !== null`);
575
644
  }
576
645
  return conditions.length > 0
577
646
  ? `...(${conditions.join(" && ")} ? {${paramMap}} : {})`
@@ -580,26 +649,30 @@ function buildHeaderParameter(
580
649
 
581
650
  function buildBodyParameter(
582
651
  context: SdkContext,
583
- bodyParameter: BodyParameter | undefined
652
+ bodyParameter: SdkBodyParameter | undefined,
653
+ optionalParamName: string = "options"
584
654
  ) {
585
- if (!bodyParameter || !bodyParameter.type.tcgcType) {
655
+ if (!bodyParameter || !bodyParameter.type) {
586
656
  return "";
587
657
  }
588
658
  const serializerFunctionName = buildModelSerializer(
589
659
  context,
590
- bodyParameter.type.tcgcType!,
660
+ getNullableValidType(bodyParameter.type),
591
661
  false,
592
662
  true
593
663
  );
594
664
 
665
+ const bodyParamName = normalizeName(bodyParameter.name, NameType.Parameter);
595
666
  const bodyNameExpression = bodyParameter.optional
596
- ? `options["${bodyParameter.clientName}"]`
597
- : bodyParameter.clientName;
667
+ ? `${optionalParamName}["${bodyParamName}"]`
668
+ : bodyParamName;
598
669
  const nullOrUndefinedPrefix = getPropertySerializationPrefix(
670
+ context,
599
671
  bodyParameter,
600
- bodyParameter.optional ? "options" : undefined
672
+ bodyParameter.optional ? optionalParamName : undefined
601
673
  );
602
- if (serializerFunctionName) {
674
+ // if a model being used in both spread and non spread operation, we should only leverage the deserializer in non spread operation
675
+ if (serializerFunctionName && !isSpreadBodyParameter(bodyParameter)) {
603
676
  return `\nbody: ${nullOrUndefinedPrefix}${serializerFunctionName}(${bodyNameExpression}),`;
604
677
  } else if (isAzureCoreErrorType(context.program, bodyParameter.type.__raw)) {
605
678
  return `\nbody: ${nullOrUndefinedPrefix}${bodyNameExpression},`;
@@ -609,9 +682,11 @@ function buildBodyParameter(
609
682
  bodyParameter.type,
610
683
  bodyNameExpression,
611
684
  !bodyParameter.optional,
612
- bodyParameter.isBinaryPayload ? "binary" : bodyParameter.format
685
+ isBinaryPayload(context, bodyParameter.__raw!, bodyParameter.contentTypes)
686
+ ? "binary"
687
+ : getEncodeForType(bodyParameter.type)
613
688
  );
614
- return `\nbody: ${serializedBody === bodyNameExpression ? "" : nullOrUndefinedPrefix}${serializedBody},`;
689
+ return `\nbody: ${serializedBody.startsWith(nullOrUndefinedPrefix) ? "" : nullOrUndefinedPrefix}${serializedBody},`;
615
690
  }
616
691
 
617
692
  function getEncodingFormat(type: { format?: string }) {
@@ -629,208 +704,210 @@ function getEncodingFormat(type: { format?: string }) {
629
704
  */
630
705
  export function getParameterMap(
631
706
  context: SdkContext,
632
- param: Parameter | Property
707
+ param: SdkServiceParameter,
708
+ optionalParamName: string = "options"
633
709
  ): string {
634
- if (isConstant(param)) {
635
- return getConstantValue(param);
710
+ if (isConstant(param.type)) {
711
+ return `"${param.name}": ${getConstantValue(param.type)}`;
636
712
  }
637
713
 
638
- if (hasCollectionFormatInfo((param as any).location, (param as any).format)) {
639
- return getCollectionFormat(context, param as Parameter);
714
+ if (hasCollectionFormatInfo(param.kind, (param as any).collectionFormat)) {
715
+ return getCollectionFormat(context, param, optionalParamName);
640
716
  }
641
717
 
642
718
  // if the parameter or property is optional, we don't need to handle the default value
643
719
  if (isOptional(param)) {
644
- return getOptional(context, param);
720
+ return getOptional(context, param, optionalParamName);
645
721
  }
646
722
 
647
723
  if (isRequired(param)) {
648
724
  return getRequired(context, param);
649
725
  }
650
726
 
651
- throw new Error(`Parameter ${param.clientName} is not supported`);
727
+ throw new Error(`Parameter ${param.name} is not supported`);
652
728
  }
653
729
 
654
- function getCollectionFormat(context: SdkContext, param: Parameter) {
655
- const collectionInfo = getCollectionFormatHelper(
656
- param.location,
657
- param.format ?? ""
658
- );
730
+ function getCollectionFormat(
731
+ context: SdkContext,
732
+ param: SdkServiceParameter,
733
+ optionalParamName: string = "options"
734
+ ) {
735
+ const serializedName = getPropertySerializedName(param);
736
+ const format = (param as any).collectionFormat;
737
+ const collectionInfo = getCollectionFormatHelper(param.kind, format ?? "");
659
738
  if (!collectionInfo) {
660
739
  throw "Has collection format info but without helper function detected";
661
740
  }
662
- const isMulti = (param.format ?? "").toLowerCase() === "multi";
663
- const additionalParam = isMulti ? `, "${param.restApiName}"` : "";
741
+ const isMulti = format.toLowerCase() === "multi";
742
+ const additionalParam = isMulti ? `, "${serializedName}"` : "";
664
743
  if (!param.optional) {
665
- return `"${param.restApiName}": ${collectionInfo}(${serializeRequestValue(
744
+ return `"${serializedName}": ${collectionInfo}(${serializeRequestValue(
666
745
  context,
667
746
  param.type,
668
- param.clientName,
747
+ param.name,
669
748
  true,
670
- param.format
749
+ getEncodeForType(param.type)
671
750
  )}${additionalParam})`;
672
751
  }
673
- return `"${param.restApiName}": options?.${
674
- param.clientName
752
+ return `"${serializedName}": ${optionalParamName}?.${
753
+ param.name
675
754
  } !== undefined ? ${collectionInfo}(${serializeRequestValue(
676
755
  context,
677
756
  param.type,
678
- "options?." + param.clientName,
757
+ `${optionalParamName}?.${param.name}`,
679
758
  false,
680
- param.format
759
+ getEncodeForType(param.type)
681
760
  )}${additionalParam}): undefined`;
682
761
  }
683
762
 
684
- function isContentType(param: Parameter): boolean {
763
+ function isContentType(param: SdkServiceParameter): boolean {
685
764
  return (
686
- param.location === "header" &&
687
- param.restApiName.toLowerCase() === "content-type"
765
+ param.kind === "header" &&
766
+ param.serializedName.toLowerCase() === "content-type"
688
767
  );
689
768
  }
690
769
 
691
- function getContentTypeValue(param: Parameter | Property) {
692
- const defaultValue =
693
- param.clientDefaultValue ?? param.type.clientDefaultValue;
694
-
770
+ function getContentTypeValue(
771
+ param: SdkServiceParameter,
772
+ optionalParamName: string = "options"
773
+ ) {
774
+ const defaultValue = param.clientDefaultValue;
775
+ // allow customers to customize the content type if it's guessed by tcgc.
776
+ if (isConstant(param.type)) {
777
+ return `contentType: ${getConstantValue(param.type)}`;
778
+ }
695
779
  if (defaultValue) {
696
- return `contentType: options.${param.clientName} as any ?? "${defaultValue}"`;
780
+ return `contentType: ${optionalParamName}.${param.name} as any ?? "${defaultValue}"`;
697
781
  } else {
698
782
  return `contentType: ${
699
783
  !param.optional
700
784
  ? "contentType"
701
- : "options." + param.clientName + " as any"
785
+ : `${optionalParamName}.` + param.name + " as any"
702
786
  }`;
703
787
  }
704
788
  }
705
789
 
706
- type RequiredType = (Parameter | Property) & {
707
- type: { optional: false | undefined; value: string };
708
- };
709
-
710
- function isRequired(param: Parameter | Property): param is RequiredType {
790
+ function isRequired(param: SdkModelPropertyType) {
711
791
  return !param.optional;
712
792
  }
713
793
 
714
- function getRequired(context: SdkContext, param: RequiredType) {
715
- if (param.type.type === "model") {
794
+ function getRequired(context: SdkContext, param: SdkModelPropertyType) {
795
+ const serializedName = getPropertySerializedName(param);
796
+ const clientValue = `${param.onClient ? "context." : ""}${param.name}`;
797
+ if (param.type.kind === "model") {
716
798
  const { propertiesStr } = getRequestModelMapping(
717
799
  context,
718
- param.type,
719
- param.clientName
800
+ { ...param.type, optional: param.optional },
801
+ clientValue
720
802
  );
721
- return `"${param.restApiName}": { ${propertiesStr.join(",")} }`;
803
+ return `"${serializedName}": { ${propertiesStr.join(",")} }`;
722
804
  }
723
- return `"${param.restApiName}": ${serializeRequestValue(
805
+ return `"${serializedName}": ${serializeRequestValue(
724
806
  context,
725
807
  param.type,
726
- param.clientName,
808
+ clientValue,
727
809
  true,
728
- param.format === undefined &&
729
- (param as Parameter).location === "header" &&
730
- param.type.type === "datetime"
731
- ? "headerDefault"
732
- : param.format
810
+ getEncodeForType(param.type)
733
811
  )}`;
734
812
  }
735
813
 
736
- type ConstantType = (Parameter | Property) & {
737
- type: { type: "constant"; value: string };
738
- };
739
-
740
- function getConstantValue(param: ConstantType) {
741
- const defaultValue =
742
- param.clientDefaultValue ??
743
- param.type.clientDefaultValue ??
744
- param.type.value;
745
-
746
- if (!defaultValue) {
747
- throw new Error(
748
- `Constant ${param.clientName} does not have a default value`
749
- );
814
+ function getConstantValue(param: SdkConstantType) {
815
+ if (typeof param.value === "string") {
816
+ return `"${param.value}"`;
750
817
  }
751
-
752
- return `"${param.restApiName}": ${getType(param.type).name}`;
818
+ return `${param.value}`;
753
819
  }
754
820
 
755
- function isConstant(param: Parameter | Property): param is ConstantType {
756
- return param.type.type === "constant";
821
+ function isConstant(param: SdkType): param is SdkConstantType {
822
+ return param.kind === "constant";
757
823
  }
758
824
 
759
- type OptionalType = (Parameter | Property) & {
760
- type: { optional: true };
761
- };
762
-
763
- function isOptional(param: Parameter | Property): param is OptionalType {
825
+ function isOptional(param: SdkModelPropertyType) {
764
826
  return Boolean(param.optional);
765
827
  }
766
828
 
767
- function getOptional(context: SdkContext, param: OptionalType) {
768
- if (param.type.type === "model") {
829
+ function getOptional(
830
+ context: SdkContext,
831
+ param: SdkHttpParameter,
832
+ optionalParamName: string
833
+ ) {
834
+ const serializedName = getPropertySerializedName(param);
835
+ const paramName = `${param.onClient ? "context." : `${optionalParamName}?.`}${param.name}`;
836
+ if (param.type.kind === "model") {
769
837
  const { propertiesStr, directAssignment } = getRequestModelMapping(
770
838
  context,
771
- param.type,
772
- "options?." + param.clientName + "?."
839
+ { ...param.type, optional: param.optional },
840
+ paramName + "?."
773
841
  );
774
842
  const serializeContent =
775
843
  directAssignment === true
776
844
  ? propertiesStr.join(",")
777
845
  : `{${propertiesStr.join(",")}}`;
778
- return `"${param.restApiName}": ${serializeContent}`;
846
+ return `"${serializedName}": ${serializeContent}`;
779
847
  }
780
- if (
781
- param.restApiName === "api-version" &&
782
- (param as any).location === "query"
783
- ) {
784
- return `"${param.restApiName}": ${
785
- param.clientDefaultValue
786
- ? `options?.${param.clientName} ?? "${param.clientDefaultValue}"`
787
- : `options?.${param.clientName}`
788
- }`;
789
- }
790
- return `"${param.restApiName}": ${serializeRequestValue(
848
+ return `"${serializedName}": ${serializeRequestValue(
791
849
  context,
792
850
  param.type,
793
- `options?.${param.clientName}`,
851
+ paramName,
794
852
  false,
795
- param.format === undefined &&
796
- (param as Parameter).location === "header" &&
797
- param.type.type === "datetime"
798
- ? "headerDefault"
799
- : param.format
853
+ getEncodeForType(param.type)
800
854
  )}`;
801
855
  }
802
856
 
857
+ /**
858
+ * Get the encode for SDK type
859
+ */
860
+ function getEncodeForType(
861
+ type: SdkType | SdkHttpParameter | SdkModelPropertyType
862
+ ) {
863
+ return (type as any).encode;
864
+ }
865
+
866
+ /**
867
+ * Get the optionality for SDK type
868
+ */
869
+ function getOptionalForType(
870
+ type: SdkType | SdkHttpParameter | SdkModelPropertyType
871
+ ) {
872
+ return (type as any).optional;
873
+ }
874
+
803
875
  /**
804
876
  * Builds the assignment for when a property or parameter has a default value
805
877
  */
806
- function getDefaultValue(param: Parameter | Property) {
807
- return param.clientDefaultValue ?? param.type.clientDefaultValue;
878
+ function getDefaultValue(param: SdkServiceParameter) {
879
+ return param.clientDefaultValue;
808
880
  }
809
881
 
810
882
  /**
811
883
  * Extracts the path parameters
812
884
  */
813
- function getPathParameters(dpgContext: SdkContext, operation: Operation) {
814
- if (!operation.parameters) {
885
+ function getPathParameters(
886
+ dpgContext: SdkContext,
887
+ operation: ServiceOperation,
888
+ optionalParamName: string = "options"
889
+ ) {
890
+ if (!operation.operation.parameters) {
815
891
  return "";
816
892
  }
817
893
 
818
894
  let pathParams = "";
819
- for (const param of operation.parameters) {
820
- if (param.location === "path") {
895
+ for (const param of operation.operation.parameters) {
896
+ if (param.kind === "path") {
821
897
  // Path parameters cannot be optional
822
898
  if (param.optional) {
823
899
  reportDiagnostic(dpgContext.program, {
824
900
  code: "optional-path-param",
825
901
  target: NoTarget,
826
902
  format: {
827
- paramName: param.clientName
903
+ paramName: param
828
904
  }
829
905
  });
830
906
  }
831
907
  pathParams += `${pathParams !== "" ? "," : ""} ${getPathParamExpr(
832
908
  param,
833
- getDefaultValue(param)
909
+ getDefaultValue(param) as string,
910
+ optionalParamName
834
911
  )}`;
835
912
  }
836
913
  }
@@ -838,19 +915,32 @@ function getPathParameters(dpgContext: SdkContext, operation: Operation) {
838
915
  return pathParams;
839
916
  }
840
917
 
841
- function getPathParamExpr(param: Parameter, defaultValue?: string) {
918
+ function getPathParamExpr(
919
+ param: SdkServiceParameter,
920
+ defaultValue?: string,
921
+ optionalParamName: string = "options"
922
+ ) {
923
+ if (isConstant(param.type)) {
924
+ return getConstantValue(param.type);
925
+ }
926
+ const paramName = param.onClient
927
+ ? `context.${param.name}`
928
+ : param.optional
929
+ ? `${optionalParamName}["${param.name}"]`
930
+ : param.name;
842
931
  const value = defaultValue
843
932
  ? typeof defaultValue === "string"
844
- ? `options[${param.clientName}] ?? "${defaultValue}"`
845
- : `options[${param.clientName}] ?? ${defaultValue}`
846
- : param.clientName;
847
- if (param.skipUrlEncoding === true) {
933
+ ? `${paramName} ?? "${defaultValue}"`
934
+ : `${paramName} ?? ${defaultValue}`
935
+ : paramName;
936
+ // TODO allowReserved is not supported in Query and Header parameter yet.
937
+ if (param.kind === "path" && param.allowReserved === true) {
848
938
  return `{value: ${value}, allowReserved: true}`;
849
939
  }
850
940
  return value;
851
941
  }
852
942
 
853
- function getNullableCheck(name: string, type: Type) {
943
+ function getNullableCheck(name: string, type: SdkType) {
854
944
  if (!isTypeNullable(type)) {
855
945
  return "";
856
946
  }
@@ -869,42 +959,47 @@ interface RequestModelMappingResult {
869
959
  }
870
960
  export function getRequestModelMapping(
871
961
  context: SdkContext,
872
- modelPropertyType: Type,
962
+ modelPropertyType: SdkModelType & { optional?: boolean },
873
963
  propertyPath: string = "body"
874
964
  ): RequestModelMappingResult {
875
965
  const props: string[] = [];
876
966
  const allParents = getAllAncestors(modelPropertyType);
877
- const properties: Property[] =
967
+ const properties: SdkModelPropertyType[] =
878
968
  getAllProperties(modelPropertyType, allParents) ?? [];
879
969
  if (properties.length <= 0) {
880
970
  return { propertiesStr: [] };
881
971
  }
882
972
  for (const property of properties) {
883
- if (property.readonly) {
973
+ if (property.kind === "property" && isReadOnly(property)) {
884
974
  continue;
885
975
  }
886
976
  const dot = propertyPath.endsWith("?") ? "." : "";
887
-
977
+ const serializedName = getPropertySerializedName(property);
888
978
  const propertyPathWithDot = `${propertyPath ? `${propertyPath}${dot}` : `${dot}`}`;
889
979
  const nullOrUndefinedPrefix = getPropertySerializationPrefix(
980
+ context,
890
981
  property,
891
982
  propertyPath
892
983
  );
893
984
 
894
- const propertyFullName = getPropertyFullName(property, propertyPathWithDot);
985
+ const propertyFullName = getPropertyFullName(
986
+ context,
987
+ property,
988
+ propertyPathWithDot
989
+ );
895
990
  const serializeFunctionName = buildModelSerializer(
896
991
  context,
897
- property.type.tcgcType!,
992
+ getNullableValidType(property.type),
898
993
  false,
899
994
  true
900
995
  );
901
996
  if (serializeFunctionName) {
902
997
  props.push(
903
- `"${property.restApiName}": ${nullOrUndefinedPrefix}${serializeFunctionName}(${propertyFullName})`
998
+ `"${serializedName}": ${nullOrUndefinedPrefix}${serializeFunctionName}(${propertyFullName})`
904
999
  );
905
1000
  } else if (isAzureCoreErrorType(context.program, property.type.__raw)) {
906
1001
  props.push(
907
- `"${property.restApiName}": ${nullOrUndefinedPrefix}${propertyFullName}`
1002
+ `"${serializedName}": ${nullOrUndefinedPrefix}${propertyFullName}`
908
1003
  );
909
1004
  } else {
910
1005
  const serializedValue = serializeRequestValue(
@@ -912,60 +1007,67 @@ export function getRequestModelMapping(
912
1007
  property.type,
913
1008
  propertyFullName,
914
1009
  !property.optional,
915
- property.format
1010
+ getEncodeForType(property.type)
916
1011
  );
917
- props.push(`"${property.restApiName}": ${serializedValue}`);
1012
+ props.push(`"${serializedName}": ${serializedValue}`);
918
1013
  }
919
1014
  }
920
1015
 
921
1016
  return { propertiesStr: props };
922
1017
  }
923
1018
 
1019
+ function getPropertySerializedName(property: SdkModelPropertyType) {
1020
+ return property.kind !== "credential" && property.kind !== "method"
1021
+ ? property.serializedName
1022
+ : property.name;
1023
+ }
1024
+
924
1025
  /**
925
1026
  * This function helps translating an RLC response to an HLC response,
926
1027
  * extracting properties from body and headers and building the HLC response object
927
1028
  */
928
1029
  export function getResponseMapping(
929
1030
  context: SdkContext,
930
- type: Type,
1031
+ type: SdkType,
931
1032
  propertyPath: string = "result.body"
932
1033
  ) {
933
- const allParents = getAllAncestors(type);
934
- const properties = getAllProperties(type, allParents) ?? [];
1034
+ const allParents = type.kind === "model" ? getAllAncestors(type) : [];
1035
+ const properties =
1036
+ type.kind === "model" ? getAllProperties(type, allParents) : [];
935
1037
  const props: string[] = [];
936
1038
  for (const property of properties) {
937
1039
  const dot = propertyPath.endsWith("?") ? "." : "";
938
-
1040
+ const serializedName = getPropertySerializedName(property);
939
1041
  const restValue = `${
940
1042
  propertyPath ? `${propertyPath}${dot}` : `${dot}`
941
- }["${property.restApiName}"]`;
1043
+ }["${serializedName}"]`;
1044
+
942
1045
  const nullOrUndefinedPrefix =
943
1046
  property.optional || isTypeNullable(property.type)
944
1047
  ? `!${restValue}? ${restValue}: `
945
1048
  : "";
946
1049
  const deserializeFunctionName = buildModelDeserializer(
947
1050
  context,
948
- property.type.tcgcType!,
1051
+ getNullableValidType(property.type),
949
1052
  false,
950
1053
  true
951
1054
  );
1055
+ const propertyName = normalizeModelPropertyName(context, property);
952
1056
  if (deserializeFunctionName) {
953
1057
  props.push(
954
- `"${property.clientName}": ${nullOrUndefinedPrefix}${deserializeFunctionName}(${restValue})`
1058
+ `${propertyName}: ${nullOrUndefinedPrefix}${deserializeFunctionName}(${restValue})`
955
1059
  );
956
1060
  } else if (isAzureCoreErrorType(context.program, property.type.__raw)) {
957
- props.push(
958
- `"${property.clientName}": ${nullOrUndefinedPrefix}${restValue}`
959
- );
1061
+ props.push(`${propertyName}: ${nullOrUndefinedPrefix}${restValue}`);
960
1062
  } else {
961
1063
  const deserializeValue = deserializeResponseValue(
962
1064
  context,
963
1065
  property.type,
964
- `${propertyPath}${dot}["${property.restApiName}"]`,
965
- property.format
1066
+ `${propertyPath}${dot}["${serializedName}"]`,
1067
+ getEncodeForType(property.type)
966
1068
  );
967
1069
  props.push(
968
- `"${property.clientName}": ${deserializeValue === `${propertyPath}${dot}["${property.restApiName}"]` ? "" : nullOrUndefinedPrefix}${deserializeValue}`
1070
+ `${propertyName}: ${deserializeValue === `${propertyPath}${dot}["${serializedName}"]` ? "" : nullOrUndefinedPrefix}${deserializeValue}`
969
1071
  );
970
1072
  }
971
1073
  }
@@ -979,7 +1081,7 @@ export function getResponseMapping(
979
1081
  */
980
1082
  export function serializeRequestValue(
981
1083
  context: SdkContext,
982
- type: Type,
1084
+ type: SdkType,
983
1085
  clientValue: string,
984
1086
  required: boolean,
985
1087
  format?: string
@@ -987,50 +1089,48 @@ export function serializeRequestValue(
987
1089
  const getSdkType = useSdkTypes();
988
1090
  const dependencies = useDependencies();
989
1091
  const nullOrUndefinedPrefix =
990
- isTypeNullable(type) || type.optional || !required
1092
+ isTypeNullable(type) || getOptionalForType(type) || !required
991
1093
  ? `!${clientValue}? ${clientValue}: `
992
1094
  : "";
993
- switch (type.type) {
994
- case "datetime":
995
- switch (type.format ?? format) {
1095
+ switch (type.kind) {
1096
+ case "utcDateTime":
1097
+ switch (type.encode ?? format) {
996
1098
  case "rfc7231":
997
- case "headerDefault":
998
1099
  return `${nullOrUndefinedPrefix}${clientValue}.toUTCString()`;
999
1100
  case "unixTimestamp":
1000
1101
  return `${nullOrUndefinedPrefix}((${clientValue}.getTime() / 1000) | 0)`;
1001
1102
  case "rfc3339":
1002
1103
  default:
1003
- return `${getNullableCheck(clientValue, type)} ${clientValue}${
1004
- required ? "" : "?"
1005
- }.toISOString()`;
1104
+ return `${nullOrUndefinedPrefix}${clientValue}.toISOString()`;
1006
1105
  }
1007
- case "list": {
1106
+ case "array": {
1008
1107
  const prefix = nullOrUndefinedPrefix + clientValue;
1009
- if (type.elementType) {
1108
+ if (type.valueType) {
1010
1109
  const elementNullOrUndefinedPrefix =
1011
- isTypeNullable(type.elementType) || type.elementType.optional
1110
+ isTypeNullable(type.valueType) || getOptionalForType(type.valueType)
1012
1111
  ? "!p ? p : "
1013
1112
  : "";
1014
1113
  const serializeFunctionName = buildModelSerializer(
1015
1114
  context,
1016
- type.elementType.tcgcType!,
1115
+ getNullableValidType(type.valueType),
1017
1116
  false,
1018
1117
  true
1019
1118
  );
1020
1119
  if (serializeFunctionName) {
1021
1120
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${serializeFunctionName}(p)})`;
1022
1121
  } else if (
1023
- isAzureCoreErrorType(context.program, type.elementType.__raw)
1122
+ isAzureCoreErrorType(context.program, type.valueType.__raw)
1024
1123
  ) {
1025
1124
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}p})`;
1026
1125
  } else {
1027
- return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${serializeRequestValue(context, type.elementType, "p", true, type.elementType?.format)}})`;
1126
+ return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${serializeRequestValue(context, type.valueType, "p", true, getEncodeForType(type.valueType))}})`;
1028
1127
  }
1029
1128
  }
1030
1129
  return clientValue;
1031
1130
  }
1032
- case "byte-array":
1033
- if (format !== "binary") {
1131
+ case "bytes":
1132
+ // TODO https://github.com/Azure/typespec-azure/issues/1999
1133
+ if (format !== "binary" && format !== "bytes") {
1034
1134
  const uint8ArrayToStringReference = resolveReference(
1035
1135
  dependencies.uint8ArrayToString
1036
1136
  );
@@ -1046,10 +1146,16 @@ export function serializeRequestValue(
1046
1146
  }")`;
1047
1147
  }
1048
1148
  return clientValue;
1049
- case "combined":
1149
+ case "union":
1050
1150
  if (isNormalUnion(type)) {
1051
1151
  return `${clientValue}`;
1052
- } else if (isSpecialHandledUnion(type)) {
1152
+ } else if (
1153
+ isSpecialHandledUnion({
1154
+ ...type,
1155
+ isNonExhaustive:
1156
+ context.rlcOptions?.experimentalExtensibleEnums ?? false
1157
+ })
1158
+ ) {
1053
1159
  const sdkType = getSdkType(type.__raw!);
1054
1160
  const serializerRefkey = refkey(sdkType, "serializer");
1055
1161
  const serializeFunctionName = resolveReference(serializerRefkey);
@@ -1057,6 +1163,16 @@ export function serializeRequestValue(
1057
1163
  } else {
1058
1164
  return `${clientValue} as any`;
1059
1165
  }
1166
+ case "model": // this is to build serialization logic for spread model types
1167
+ return `{${getRequestModelMapping(context, type, "").propertiesStr.join(",")}}`;
1168
+ case "nullable":
1169
+ return serializeRequestValue(
1170
+ context,
1171
+ type.type,
1172
+ clientValue,
1173
+ false,
1174
+ getEncodeForType(type.type)
1175
+ );
1060
1176
  default:
1061
1177
  if (clientValue === "constructorParam") {
1062
1178
  return `${clientValue} as any`;
@@ -1072,7 +1188,7 @@ export function serializeRequestValue(
1072
1188
  */
1073
1189
  export function deserializeResponseValue(
1074
1190
  context: SdkContext,
1075
- type: Type,
1191
+ type: SdkType,
1076
1192
  restValue: string,
1077
1193
  format?: string
1078
1194
  ): string {
@@ -1081,25 +1197,25 @@ export function deserializeResponseValue(
1081
1197
  dependencies.stringToUint8Array
1082
1198
  );
1083
1199
  const nullOrUndefinedPrefix =
1084
- isTypeNullable(type) || type.optional
1200
+ isTypeNullable(type) || getOptionalForType(type)
1085
1201
  ? `!${restValue}? ${restValue}: `
1086
1202
  : "";
1087
- switch (type.type) {
1088
- case "datetime":
1089
- return `${nullOrUndefinedPrefix} new Date(${type.format === "unixTimestamp" ? `${restValue} * 1000` : restValue})`;
1090
- case "list": {
1203
+ switch (type.kind) {
1204
+ case "utcDateTime":
1205
+ return `${nullOrUndefinedPrefix} new Date(${type.encode === "unixTimestamp" ? `${restValue} * 1000` : restValue})`;
1206
+ case "array": {
1091
1207
  const prefix = nullOrUndefinedPrefix + restValue;
1092
1208
  let elementNullOrUndefinedPrefix = "";
1093
1209
  if (
1094
- type.elementType &&
1095
- (isTypeNullable(type.elementType) || type.elementType.optional)
1210
+ type.valueType &&
1211
+ (isTypeNullable(type.valueType) || getOptionalForType(type.valueType))
1096
1212
  ) {
1097
1213
  elementNullOrUndefinedPrefix = "!p ? p :";
1098
1214
  }
1099
- const deserializeFunctionName = type.elementType
1215
+ const deserializeFunctionName = type.valueType
1100
1216
  ? buildModelDeserializer(
1101
1217
  context,
1102
- type.elementType.tcgcType!,
1218
+ getNullableValidType(type.valueType),
1103
1219
  false,
1104
1220
  true
1105
1221
  )
@@ -1107,29 +1223,34 @@ export function deserializeResponseValue(
1107
1223
  if (deserializeFunctionName) {
1108
1224
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${deserializeFunctionName}(p)})`;
1109
1225
  } else if (
1110
- type.elementType &&
1111
- isAzureCoreErrorType(context.program, type.elementType.__raw)
1226
+ type.valueType &&
1227
+ isAzureCoreErrorType(context.program, type.valueType.__raw)
1112
1228
  ) {
1113
1229
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}p})`;
1114
- } else if (type.elementType) {
1115
- return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${deserializeResponseValue(context, type.elementType, "p", type.format)}})`;
1230
+ } else if (type.valueType) {
1231
+ return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${deserializeResponseValue(context, type.valueType, "p", getEncodeForType(type.valueType))}})`;
1116
1232
  } else {
1117
1233
  return restValue;
1118
1234
  }
1119
1235
  }
1120
- case "byte-array":
1121
- if (format !== "binary") {
1236
+ case "bytes":
1237
+ if (format !== "binary" && format !== "bytes") {
1122
1238
  return `typeof ${restValue} === 'string'
1123
1239
  ? ${stringToUint8ArrayReference}(${restValue}, "${format ?? "base64"}")
1124
1240
  : ${restValue}`;
1125
1241
  }
1126
1242
  return restValue;
1127
- case "combined":
1243
+ case "union":
1128
1244
  if (isNormalUnion(type)) {
1129
1245
  return `${restValue}`;
1130
1246
  } else if (isSpecialHandledUnion(type)) {
1131
1247
  const deserializeFunctionName = type
1132
- ? buildModelDeserializer(context, type.tcgcType!, false, true)
1248
+ ? buildModelDeserializer(
1249
+ context,
1250
+ getNullableValidType(type),
1251
+ false,
1252
+ true
1253
+ )
1133
1254
  : undefined;
1134
1255
  if (deserializeFunctionName) {
1135
1256
  return `${deserializeFunctionName}(${restValue})`;
@@ -1139,94 +1260,97 @@ export function deserializeResponseValue(
1139
1260
  } else {
1140
1261
  return `${restValue} as any`;
1141
1262
  }
1263
+ case "model": // generate deserialize logic for spread model types
1264
+ return `{${getResponseMapping(context, type, "").join(",")}}`;
1265
+ case "nullable":
1266
+ return deserializeResponseValue(
1267
+ context,
1268
+ type.type,
1269
+ restValue,
1270
+ getEncodeForType(type.type)
1271
+ );
1142
1272
  default:
1143
1273
  return restValue;
1144
1274
  }
1145
1275
  }
1146
1276
 
1147
- export function isLroAndPagingOperation(op: Operation): boolean {
1148
- return op.discriminator === "lropaging";
1149
- }
1150
-
1151
- export function isLroOnlyOperation(op: Operation): boolean {
1152
- return op.discriminator === "lro";
1277
+ export function isLroAndPagingOperation(
1278
+ op: SdkMethod<SdkHttpOperation>
1279
+ ): op is SdkLroPagingServiceMethod<SdkHttpOperation> {
1280
+ return op.kind === "lropaging";
1153
1281
  }
1154
1282
 
1155
- export function hasPagingOnlyOperation(
1156
- client: Client,
1157
- needRLC?: boolean
1158
- ): boolean;
1159
- export function hasPagingOnlyOperation(
1160
- codeModel: ModularCodeModel,
1161
- needRLC?: boolean
1162
- ): boolean;
1163
- export function hasPagingOnlyOperation(
1164
- clientOrCodeModel: Client | ModularCodeModel,
1165
- needRLC: boolean = false
1166
- ): boolean {
1167
- let clients: Client[] = [];
1168
- if ((clientOrCodeModel as any)?.operationGroups) {
1169
- clients = [clientOrCodeModel as Client];
1170
- } else if ((clientOrCodeModel as any)?.clients) {
1171
- clients = (clientOrCodeModel as ModularCodeModel).clients;
1172
- }
1173
- return clients.some(
1174
- (c) =>
1175
- (needRLC ? c.rlcHelperDetails.hasPaging : false) ||
1176
- (c.operationGroups ?? []).some((og) =>
1177
- (og.operations ?? []).some(isPagingOnlyOperation)
1178
- )
1179
- );
1283
+ export function isLroOnlyOperation(
1284
+ op: SdkMethod<SdkHttpOperation>
1285
+ ): op is SdkLroServiceMethod<SdkHttpOperation> {
1286
+ return op.kind === "lro";
1180
1287
  }
1181
1288
 
1182
- export function isPagingOnlyOperation(op: Operation): boolean {
1183
- return op.discriminator === "paging";
1289
+ export function isPagingOnlyOperation(
1290
+ op: SdkMethod<SdkHttpOperation>
1291
+ ): op is SdkPagingServiceMethod<SdkHttpOperation> {
1292
+ return op.kind === "paging";
1184
1293
  }
1185
1294
 
1186
- export function getAllProperties(type: Type, parents?: Type[]): Property[] {
1187
- const propertiesMap: Map<string, Property> = new Map();
1295
+ export function getAllProperties(
1296
+ type: SdkType,
1297
+ parents?: SdkType[]
1298
+ ): SdkModelPropertyType[] {
1299
+ const propertiesMap: Map<string, SdkModelPropertyType> = new Map();
1188
1300
  if (!type) {
1189
1301
  return [];
1190
1302
  }
1191
1303
  parents?.forEach((p) => {
1192
1304
  getAllProperties(p).forEach((prop) => {
1193
- propertiesMap.set(prop.clientName, prop);
1305
+ propertiesMap.set(prop.name, prop);
1194
1306
  });
1195
1307
  });
1196
- type.properties?.forEach((p) => {
1197
- propertiesMap.set(p.clientName, p);
1198
- });
1308
+ type.kind === "model" &&
1309
+ type.properties
1310
+ ?.filter((p) => {
1311
+ return p.kind === "property";
1312
+ })
1313
+ .forEach((p) => {
1314
+ propertiesMap.set(p.name, p);
1315
+ });
1199
1316
  return [...propertiesMap.values()];
1200
1317
  }
1201
1318
 
1202
- export function getAllAncestors(type: Type): Type[] {
1203
- const ancestors: Type[] = [];
1204
- type?.parents?.forEach((p) => {
1205
- ancestors.push(p);
1206
- ancestors.push(...getAllAncestors(p));
1207
- });
1319
+ export function getAllAncestors(type: SdkType): SdkType[] {
1320
+ const ancestors: SdkType[] = [];
1321
+ if (type.kind === "model" && type.baseModel) {
1322
+ ancestors.push(type.baseModel);
1323
+ ancestors.push(...getAllAncestors(type.baseModel));
1324
+ }
1208
1325
  return ancestors;
1209
1326
  }
1210
1327
 
1211
1328
  export function getPropertySerializationPrefix(
1212
- modularType: Property | Parameter,
1329
+ context: SdkContext,
1330
+ property: SdkServiceParameter | SdkModelPropertyType,
1213
1331
  propertyPath?: string
1214
1332
  ) {
1215
- const propertyFullName = getPropertyFullName(modularType, propertyPath);
1216
- if (modularType.optional || isTypeNullable(modularType.type)) {
1217
- return `!${propertyFullName} ? ${propertyFullName} :`;
1333
+ const propertyFullName = getPropertyFullName(context, property, propertyPath);
1334
+ if (property.optional || isTypeNullable(property.type)) {
1335
+ return `!${propertyFullName}? ${propertyFullName}:`;
1218
1336
  }
1219
1337
 
1220
1338
  return "";
1221
1339
  }
1222
1340
 
1223
1341
  export function getPropertyFullName(
1224
- modularType: Property | Parameter,
1342
+ context: SdkContext,
1343
+ property: SdkServiceParameter | SdkModelPropertyType,
1225
1344
  propertyPath?: string
1226
1345
  ) {
1227
- let fullName = `${modularType.clientName}`;
1228
- if (propertyPath) {
1229
- fullName = `${propertyPath}["${modularType.clientName}"]`;
1346
+ const normalizedPropertyName = normalizeModelPropertyName(context, property)
1347
+ .replace(/^"/g, "")
1348
+ .replace(/"$/g, "");
1349
+ let fullName = normalizedPropertyName;
1350
+ if (propertyPath === "" && property.optional) {
1351
+ fullName = `options?.${normalizedPropertyName}`;
1352
+ } else if (propertyPath) {
1353
+ fullName = `${propertyPath}["${normalizedPropertyName}"]`;
1230
1354
  }
1231
1355
  return fullName;
1232
1356
  }
@@ -1235,14 +1359,12 @@ export function getPropertyFullName(
1235
1359
  * Get an expression representing an array of expected status codes for the operation
1236
1360
  * @param operation The operation
1237
1361
  */
1238
- export function getExpectedStatuses(operation: Operation): string {
1239
- const statusCodes = operation.responses.flatMap((x) =>
1240
- x.statusCodes.filter((s) => s !== "default")
1241
- );
1362
+ export function getExpectedStatuses(operation: ServiceOperation): string {
1363
+ const statusCodes = operation.operation.responses.map((x) => x.statusCodes);
1242
1364
  // LROs may call the same path but with GET to get the operation status.
1243
1365
  if (
1244
1366
  isLroOnlyOperation(operation) &&
1245
- operation.method !== "GET" &&
1367
+ operation.operation.verb !== "get" &&
1246
1368
  !statusCodes.includes(200)
1247
1369
  ) {
1248
1370
  statusCodes.push(200);