@azure-tools/typespec-ts 0.36.0 → 0.37.0

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 (143) 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/metaTree.d.ts +0 -5
  13. package/dist/src/metaTree.d.ts.map +1 -1
  14. package/dist/src/modular/buildClassicalClient.d.ts +3 -2
  15. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
  16. package/dist/src/modular/buildClassicalClient.js +64 -62
  17. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  18. package/dist/src/modular/buildClassicalOperationGroups.d.ts +3 -2
  19. package/dist/src/modular/buildClassicalOperationGroups.d.ts.map +1 -1
  20. package/dist/src/modular/buildClassicalOperationGroups.js +35 -27
  21. package/dist/src/modular/buildClassicalOperationGroups.js.map +1 -1
  22. package/dist/src/modular/buildClientContext.d.ts +4 -3
  23. package/dist/src/modular/buildClientContext.d.ts.map +1 -1
  24. package/dist/src/modular/buildClientContext.js +84 -35
  25. package/dist/src/modular/buildClientContext.js.map +1 -1
  26. package/dist/src/modular/buildModularOptions.d.ts +7 -0
  27. package/dist/src/modular/buildModularOptions.d.ts.map +1 -0
  28. package/dist/src/modular/buildModularOptions.js +16 -0
  29. package/dist/src/modular/buildModularOptions.js.map +1 -0
  30. package/dist/src/modular/buildOperations.d.ts +6 -4
  31. package/dist/src/modular/buildOperations.d.ts.map +1 -1
  32. package/dist/src/modular/buildOperations.js +56 -55
  33. package/dist/src/modular/buildOperations.js.map +1 -1
  34. package/dist/src/modular/buildProjectFiles.d.ts +3 -2
  35. package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
  36. package/dist/src/modular/buildProjectFiles.js +18 -16
  37. package/dist/src/modular/buildProjectFiles.js.map +1 -1
  38. package/dist/src/modular/buildRestorePoller.d.ts +4 -2
  39. package/dist/src/modular/buildRestorePoller.d.ts.map +1 -1
  40. package/dist/src/modular/buildRestorePoller.js +22 -18
  41. package/dist/src/modular/buildRestorePoller.js.map +1 -1
  42. package/dist/src/modular/buildRootIndex.d.ts +4 -3
  43. package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
  44. package/dist/src/modular/buildRootIndex.js +40 -31
  45. package/dist/src/modular/buildRootIndex.js.map +1 -1
  46. package/dist/src/modular/buildSubpathIndex.d.ts +4 -2
  47. package/dist/src/modular/buildSubpathIndex.d.ts.map +1 -1
  48. package/dist/src/modular/buildSubpathIndex.js +8 -5
  49. package/dist/src/modular/buildSubpathIndex.js.map +1 -1
  50. package/dist/src/modular/emitLoggerFile.d.ts +2 -3
  51. package/dist/src/modular/emitLoggerFile.d.ts.map +1 -1
  52. package/dist/src/modular/emitLoggerFile.js +4 -4
  53. package/dist/src/modular/emitLoggerFile.js.map +1 -1
  54. package/dist/src/modular/emitModels.d.ts +1 -2
  55. package/dist/src/modular/emitModels.d.ts.map +1 -1
  56. package/dist/src/modular/emitModels.js +10 -3
  57. package/dist/src/modular/emitModels.js.map +1 -1
  58. package/dist/src/modular/emitModelsOptions.d.ts +3 -24
  59. package/dist/src/modular/emitModelsOptions.d.ts.map +1 -1
  60. package/dist/src/modular/emitModelsOptions.js +10 -86
  61. package/dist/src/modular/emitModelsOptions.js.map +1 -1
  62. package/dist/src/modular/emitSamples.js +2 -1
  63. package/dist/src/modular/emitSamples.js.map +1 -1
  64. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts +3 -3
  65. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts.map +1 -1
  66. package/dist/src/modular/helpers/classicalOperationHelpers.js +40 -50
  67. package/dist/src/modular/helpers/classicalOperationHelpers.js.map +1 -1
  68. package/dist/src/modular/helpers/clientHelpers.d.ts +11 -8
  69. package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
  70. package/dist/src/modular/helpers/clientHelpers.js +87 -60
  71. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  72. package/dist/src/modular/helpers/namingHelpers.d.ts +4 -7
  73. package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
  74. package/dist/src/modular/helpers/namingHelpers.js +3 -26
  75. package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
  76. package/dist/src/modular/helpers/operationHelpers.d.ts +21 -20
  77. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  78. package/dist/src/modular/helpers/operationHelpers.js +336 -291
  79. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  80. package/dist/src/modular/helpers/typeHelpers.d.ts +4 -25
  81. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
  82. package/dist/src/modular/helpers/typeHelpers.js +6 -218
  83. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  84. package/dist/src/modular/interfaces.d.ts +15 -8
  85. package/dist/src/modular/interfaces.d.ts.map +1 -1
  86. package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
  87. package/dist/src/modular/serialization/buildDeserializerFunction.js +1 -2
  88. package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
  89. package/dist/src/modular/serialization/buildSerializerFunction.d.ts.map +1 -1
  90. package/dist/src/modular/serialization/buildSerializerFunction.js +1 -2
  91. package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
  92. package/dist/src/modular/serialization/serializeUtils.d.ts +8 -5
  93. package/dist/src/modular/serialization/serializeUtils.d.ts.map +1 -1
  94. package/dist/src/modular/serialization/serializeUtils.js +22 -22
  95. package/dist/src/modular/serialization/serializeUtils.js.map +1 -1
  96. package/dist/src/utils/clientUtils.d.ts +3 -1
  97. package/dist/src/utils/clientUtils.d.ts.map +1 -1
  98. package/dist/src/utils/clientUtils.js +10 -0
  99. package/dist/src/utils/clientUtils.js.map +1 -1
  100. package/dist/src/utils/operationUtil.d.ts +6 -2
  101. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  102. package/dist/src/utils/operationUtil.js +66 -7
  103. package/dist/src/utils/operationUtil.js.map +1 -1
  104. package/dist/tsconfig.tsbuildinfo +1 -1
  105. package/package.json +3 -3
  106. package/src/contextManager.ts +1 -2
  107. package/src/framework/load-static-helpers.ts +24 -1
  108. package/src/index.ts +65 -37
  109. package/src/metaTree.ts +0 -6
  110. package/src/modular/buildClassicalClient.ts +97 -99
  111. package/src/modular/buildClassicalOperationGroups.ts +53 -47
  112. package/src/modular/buildClientContext.ts +101 -44
  113. package/src/modular/buildModularOptions.ts +27 -0
  114. package/src/modular/buildOperations.ts +91 -78
  115. package/src/modular/buildProjectFiles.ts +24 -21
  116. package/src/modular/buildRestorePoller.ts +39 -23
  117. package/src/modular/buildRootIndex.ts +51 -42
  118. package/src/modular/buildSubpathIndex.ts +16 -7
  119. package/src/modular/emitLoggerFile.ts +12 -10
  120. package/src/modular/emitModels.ts +15 -7
  121. package/src/modular/emitModelsOptions.ts +18 -125
  122. package/src/modular/emitSamples.ts +2 -3
  123. package/src/modular/helpers/classicalOperationHelpers.ts +50 -75
  124. package/src/modular/helpers/clientHelpers.ts +107 -73
  125. package/src/modular/helpers/namingHelpers.ts +6 -65
  126. package/src/modular/helpers/operationHelpers.ts +506 -384
  127. package/src/modular/helpers/typeHelpers.ts +11 -267
  128. package/src/modular/interfaces.ts +16 -8
  129. package/src/modular/serialization/buildDeserializerFunction.ts +1 -6
  130. package/src/modular/serialization/buildSerializerFunction.ts +1 -2
  131. package/src/modular/serialization/serializeUtils.ts +31 -30
  132. package/src/utils/clientUtils.ts +23 -1
  133. package/src/utils/operationUtil.ts +106 -14
  134. package/dist/src/modular/buildCodeModel.d.ts +0 -34
  135. package/dist/src/modular/buildCodeModel.d.ts.map +0 -1
  136. package/dist/src/modular/buildCodeModel.js +0 -1489
  137. package/dist/src/modular/buildCodeModel.js.map +0 -1
  138. package/dist/src/modular/modularCodeModel.d.ts +0 -166
  139. package/dist/src/modular/modularCodeModel.d.ts.map +0 -1
  140. package/dist/src/modular/modularCodeModel.js +0 -2
  141. package/dist/src/modular/modularCodeModel.js.map +0 -1
  142. package/src/modular/buildCodeModel.ts +0 -1965
  143. package/src/modular/modularCodeModel.ts +0 -211
@@ -1,13 +1,13 @@
1
1
  import { NoTarget } from "@typespec/compiler";
2
2
  import { PagingHelpers, PollingHelpers } from "../static-helpers-metadata.js";
3
- import { getType, isTypeNullable } from "./typeHelpers.js";
3
+ import { getNullableValidType, isSpreadBodyParameter, isTypeNullable } from "./typeHelpers.js";
4
4
  import { getClassicalLayerPrefix, getOperationName } from "./namingHelpers.js";
5
- import { getCollectionFormatHelper, hasCollectionFormatInfo } from "../../utils/operationUtil.js";
5
+ import { getCollectionFormatHelper, hasCollectionFormatInfo, isBinaryPayload } from "../../utils/operationUtil.js";
6
6
  import { isNormalUnion, isSpecialHandledUnion } from "../serialization/serializeUtils.js";
7
7
  import { getDocsFromDescription, getFixmeForMultilineDocs } from "./docsHelpers.js";
8
8
  import { toPascalCase } from "../../utils/casingUtils.js";
9
9
  import { AzurePollingDependencies } from "../external-dependencies.js";
10
- import { NameType } from "@azure-tools/rlc-common";
10
+ import { NameType, normalizeName } from "@azure-tools/rlc-common";
11
11
  import { buildModelDeserializer } from "../serialization/buildDeserializerFunction.js";
12
12
  import { buildModelSerializer } from "../serialization/buildSerializerFunction.js";
13
13
  import { refkey } from "../../framework/refkey.js";
@@ -16,10 +16,11 @@ import { resolveReference } from "../../framework/reference.js";
16
16
  import { useDependencies } from "../../framework/hooks/useDependencies.js";
17
17
  import { useSdkTypes } from "../../framework/hooks/sdkTypes.js";
18
18
  import { isAzureCoreErrorType } from "../../utils/modelUtils.js";
19
- import { getTypeExpression } from "../type-expressions/get-type-expression.js";
20
- export function getSendPrivateFunction(dpgContext, operation, clientType) {
21
- var _a;
22
- const parameters = getOperationSignatureParameters(dpgContext, operation, clientType);
19
+ import { getTypeExpression, normalizeModelPropertyName } from "../type-expressions/get-type-expression.js";
20
+ import { isReadOnly } from "@azure-tools/typespec-client-generator-core";
21
+ export function getSendPrivateFunction(dpgContext, client, method, clientType) {
22
+ const operation = method[1];
23
+ const parameters = getOperationSignatureParameters(dpgContext, method, clientType);
23
24
  const { name } = getOperationName(operation);
24
25
  const dependencies = useDependencies();
25
26
  const functionStatement = {
@@ -29,18 +30,23 @@ export function getSendPrivateFunction(dpgContext, operation, clientType) {
29
30
  parameters,
30
31
  returnType: resolveReference(dependencies.StreamableMethod)
31
32
  };
32
- const operationPath = operation.url;
33
- const operationMethod = operation.method.toLowerCase();
34
- const optionalParamName = (_a = parameters.filter((p) => { var _a; return (_a = p.type) === null || _a === void 0 ? void 0 : _a.toString().endsWith("OptionalParams"); })[0]) === null || _a === void 0 ? void 0 : _a.name;
33
+ const operationPath = operation.operation.path;
34
+ const operationMethod = operation.operation.verb.toLowerCase();
35
+ const optionalParamName = getOptionalParamsName(parameters);
36
+ const hasQueryApiVersion = operation.operation.parameters.some((p) => p.isApiVersionParam && p.onClient && p.kind === "query");
37
+ const hasClientApiVersion = client.initialization.properties.some((p) => p.isApiVersionParam && p.onClient && p.kind === "method");
35
38
  const statements = [];
36
- statements.push(`return context.path("${operationPath}", ${getPathParameters(dpgContext, operation)}).${operationMethod}({...${resolveReference(dependencies.operationOptionsToRequestParameters)}(${optionalParamName}), ${getRequestParameters(dpgContext, operation)}});`);
39
+ if (hasClientApiVersion && !hasQueryApiVersion) {
40
+ statements.push(`context.pipeline.removePolicy({ name: "ClientApiVersionPolicy"});`);
41
+ }
42
+ statements.push(`return context.path("${operationPath}", ${getPathParameters(dpgContext, operation, optionalParamName)}).${operationMethod}({...${resolveReference(dependencies.operationOptionsToRequestParameters)}(${optionalParamName}), ${getRequestParameters(dpgContext, operation, optionalParamName)}});`);
37
43
  return {
38
44
  ...functionStatement,
39
45
  statements
40
46
  };
41
47
  }
42
48
  export function getDeserializePrivateFunction(context, operation) {
43
- var _a, _b, _c, _d;
49
+ var _a, _b, _c, _d, _e, _f;
44
50
  const { name } = getOperationName(operation);
45
51
  const dependencies = useDependencies();
46
52
  const PathUncheckedResponseReference = resolveReference(dependencies.PathUncheckedResponse);
@@ -55,15 +61,16 @@ export function getDeserializePrivateFunction(context, operation) {
55
61
  const isLroOnly = isLroOnlyOperation(operation);
56
62
  // TODO: Support operation overloads
57
63
  // TODO: Support multiple responses
58
- const response = operation.responses[0];
64
+ const response = operation.response;
65
+ const restResponse = operation.operation.responses[0];
59
66
  let returnType;
60
- if (isLroOnly && operation.method.toLowerCase() !== "patch") {
67
+ if (isLroOnly && operation.operation.verb.toLowerCase() !== "patch") {
61
68
  returnType = buildLroReturnType(context, operation);
62
69
  }
63
- else if ((_a = response === null || response === void 0 ? void 0 : response.type) === null || _a === void 0 ? void 0 : _a.type) {
70
+ else if (response.type && restResponse) {
64
71
  returnType = {
65
- name: response.type.name,
66
- type: getTypeExpression(context, response.type.tcgcType)
72
+ name: (_a = restResponse.name) !== null && _a !== void 0 ? _a : "",
73
+ type: getTypeExpression(context, restResponse.type)
67
74
  };
68
75
  }
69
76
  else {
@@ -81,21 +88,24 @@ export function getDeserializePrivateFunction(context, operation) {
81
88
  statements.push(`const expectedStatuses = ${getExpectedStatuses(operation)};`);
82
89
  statements.push(`if(!expectedStatuses.includes(result.status)){`, `throw ${createRestErrorReference}(result);`, "}");
83
90
  const deserializedType = isLroOnly
84
- ? (_b = operation === null || operation === void 0 ? void 0 : operation.lroMetadata) === null || _b === void 0 ? void 0 : _b.finalResult
85
- : response.type;
86
- const hasLroSubPath = ((_c = operation === null || operation === void 0 ? void 0 : operation.lroMetadata) === null || _c === void 0 ? void 0 : _c.finalResultPath) !== undefined;
91
+ ? (_c = (_b = operation === null || operation === void 0 ? void 0 : operation.lroMetadata) === null || _b === void 0 ? void 0 : _b.finalResponse) === null || _c === void 0 ? void 0 : _c.result
92
+ : restResponse
93
+ ? restResponse.type
94
+ : response.type;
95
+ const lroSubPath = isLroOnly
96
+ ? (_e = (_d = operation === null || operation === void 0 ? void 0 : operation.lroMetadata) === null || _d === void 0 ? void 0 : _d.finalResponse) === null || _e === void 0 ? void 0 : _e.resultPath
97
+ : undefined;
87
98
  const deserializePrefix = "result.body";
88
- const deserializedRoot = hasLroSubPath
89
- ? `${deserializePrefix}.${(_d = operation === null || operation === void 0 ? void 0 : operation.lroMetadata) === null || _d === void 0 ? void 0 : _d.finalResultPath}`
90
- : `${deserializePrefix}`;
91
- if (isLroOnly && hasLroSubPath) {
99
+ const deserializedRoot = `${deserializePrefix}${lroSubPath ? "." + lroSubPath : ""}`;
100
+ if (isLroOnly && lroSubPath) {
92
101
  statements.push(`if(${deserializedRoot.split(".").join("?.")} === undefined) {
93
102
  throw createRestError(\`Expected a result in the response at position "${deserializedRoot}"\`, result);
94
103
  }
95
104
  `);
96
105
  }
97
- if (deserializedType === null || deserializedType === void 0 ? void 0 : deserializedType.tcgcType) {
98
- const deserializeFunctionName = buildModelDeserializer(context, deserializedType.tcgcType, false, true);
106
+ if (deserializedType) {
107
+ const contentTypes = (_f = operation.operation.responses[0]) === null || _f === void 0 ? void 0 : _f.contentTypes;
108
+ const deserializeFunctionName = buildModelDeserializer(context, deserializedType, false, true);
99
109
  if (deserializeFunctionName) {
100
110
  statements.push(`return ${deserializeFunctionName}(${deserializedRoot})`);
101
111
  }
@@ -103,15 +113,14 @@ export function getDeserializePrivateFunction(context, operation) {
103
113
  statements.push(`return ${deserializedRoot}`);
104
114
  }
105
115
  else {
106
- statements.push(`return ${deserializeResponseValue(context, deserializedType, deserializedRoot, response.isBinaryPayload ? "binary" : deserializedType.format)}`);
116
+ statements.push(`return ${deserializeResponseValue(context, deserializedType, deserializedRoot, isBinaryPayload(context, response.type.__raw, contentTypes)
117
+ ? "binary"
118
+ : getEncodeForType(deserializedType))}`);
107
119
  }
108
120
  }
109
121
  else if (returnType.type === "void") {
110
122
  statements.push("return;");
111
123
  }
112
- else if (deserializedType) {
113
- statements.push(`return ${deserializeResponseValue(context, deserializedType, deserializedRoot, response.isBinaryPayload ? "binary" : deserializedType.format)}`);
114
- }
115
124
  else {
116
125
  statements.push("return;");
117
126
  }
@@ -120,34 +129,38 @@ export function getDeserializePrivateFunction(context, operation) {
120
129
  statements
121
130
  };
122
131
  }
123
- function getOperationSignatureParameters(context, operation, clientType) {
124
- var _a;
125
- const optionsType = getOperationOptionsName(operation, true);
132
+ function getOptionalParamsName(parameters) {
133
+ var _a, _b;
134
+ return ((_b = (_a = parameters.filter((p) => { var _a; return (_a = p.type) === null || _a === void 0 ? void 0 : _a.toString().endsWith("OptionalParams"); })[0]) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : "options");
135
+ }
136
+ function getOperationSignatureParameters(context, method, clientType) {
137
+ const operation = method[1];
138
+ const optionsType = getOperationOptionsName(method, true);
126
139
  const parameters = new Map();
127
140
  operation.parameters
128
- .filter((p) => p.implementation === "Method" &&
129
- p.type.type !== "constant" &&
130
- p.clientDefaultValue === undefined &&
131
- !p.optional)
132
- .map((p) => {
141
+ .filter((p) => {
133
142
  var _a;
143
+ return p.onClient === false &&
144
+ p.type.kind !== "constant" &&
145
+ ((_a = operation.operation.parameters.filter((param) => {
146
+ return (param.correspondingMethodParams.length === 1 &&
147
+ param.correspondingMethodParams[0] === p);
148
+ })[0]) === null || _a === void 0 ? void 0 : _a.kind) !== "cookie" &&
149
+ p.clientDefaultValue === undefined &&
150
+ !p.optional &&
151
+ !(p.isGeneratedName &&
152
+ (p.name === "contentType" || p.name === "accept"));
153
+ } // skip tcgc generated contentType and accept header parameter
154
+ )
155
+ .map((p) => {
134
156
  return {
135
- name: p.clientName,
136
- type: getTypeExpression(context, (_a = p.tcgcType) !== null && _a !== void 0 ? _a : p.type.tcgcType)
157
+ name: p.name,
158
+ type: getTypeExpression(context, p.type)
137
159
  };
138
160
  })
139
161
  .forEach((p) => {
140
162
  parameters.set(p.name, p);
141
163
  });
142
- if (operation.bodyParameter && operation.bodyParameter.optional === false) {
143
- parameters.set((_a = operation.bodyParameter) === null || _a === void 0 ? void 0 : _a.clientName, {
144
- hasQuestionToken: operation.bodyParameter.optional,
145
- ...{
146
- name: operation.bodyParameter.clientName,
147
- type: getTypeExpression(context, operation.bodyParameter.type.tcgcType)
148
- }
149
- });
150
- }
151
164
  // Add context as the first parameter
152
165
  const contextParam = { name: "context", type: clientType };
153
166
  // Add the options parameter
@@ -162,45 +175,44 @@ function getOperationSignatureParameters(context, operation, clientType) {
162
175
  /**
163
176
  * This operation builds and returns the function declaration for an operation.
164
177
  */
165
- export function getOperationFunction(context, operation, clientType) {
166
- var _a, _b, _c;
178
+ export function getOperationFunction(context, method, clientType) {
179
+ var _a;
180
+ const operation = method[1];
181
+ // Extract required parameters
182
+ const parameters = getOperationSignatureParameters(context, method, clientType);
183
+ const optionalParamName = getOptionalParamsName(parameters);
167
184
  if (isPagingOnlyOperation(operation)) {
168
185
  // Case 1: paging-only operation
169
- return getPagingOnlyOperationFunction(context, operation, clientType);
186
+ return getPagingOnlyOperationFunction(context, [method[0], operation], clientType);
170
187
  }
171
188
  else if (isLroOnlyOperation(operation)) {
172
189
  // Case 2: lro-only operation
173
- return getLroOnlyOperationFunction(context, operation, clientType);
190
+ return getLroOnlyOperationFunction(context, [method[0], operation], clientType, optionalParamName);
174
191
  }
175
192
  else if (isLroAndPagingOperation(operation)) {
176
193
  // Case 3: both paging + lro operation is not supported yet so handle them as normal operation and customization may be needed
177
194
  // https://github.com/Azure/autorest.typescript/issues/2313
178
195
  }
179
- if (operation.name === "floatSeconds") {
180
- operation;
181
- }
182
- // Extract required parameters
183
- const parameters = getOperationSignatureParameters(context, operation, clientType);
184
196
  // TODO: Support operation overloads
185
- const response = operation.responses[0];
197
+ const response = operation.response;
186
198
  let returnType = { name: "", type: "void" };
187
- if ((_a = response.type) === null || _a === void 0 ? void 0 : _a.type) {
188
- const type = (_b = extractPagingType(response.type, operation.itemName)) !== null && _b !== void 0 ? _b : response.type;
199
+ if (response.type) {
200
+ const type = response.type;
189
201
  returnType = {
190
- name: (_c = type.name) !== null && _c !== void 0 ? _c : "",
191
- type: getTypeExpression(context, type.tcgcType)
202
+ name: (_a = type.name) !== null && _a !== void 0 ? _a : "",
203
+ type: getTypeExpression(context, type)
192
204
  };
193
205
  }
194
206
  const { name, fixme = [] } = getOperationName(operation);
195
207
  const functionStatement = {
196
208
  docs: [
197
- ...getDocsFromDescription(operation.description),
209
+ ...getDocsFromDescription(operation.doc),
198
210
  ...getFixmeForMultilineDocs(fixme)
199
211
  ],
200
212
  isAsync: true,
201
213
  isExported: true,
202
214
  name,
203
- propertyName: operation.name,
215
+ propertyName: normalizeName(operation.name, NameType.Property),
204
216
  parameters,
205
217
  returnType: `Promise<${returnType.type}>`
206
218
  };
@@ -214,36 +226,46 @@ export function getOperationFunction(context, operation, clientType) {
214
226
  statements
215
227
  };
216
228
  }
217
- function getLroOnlyOperationFunction(context, operation, clientType) {
218
- var _a, _b;
229
+ function getLroOnlyOperationFunction(context, method, clientType, optionalParamName = "options") {
230
+ const operation = method[1];
219
231
  // Extract required parameters
220
- const parameters = getOperationSignatureParameters(context, operation, clientType);
232
+ const parameters = getOperationSignatureParameters(context, method, clientType);
221
233
  const returnType = buildLroReturnType(context, operation);
222
234
  const { name, fixme = [] } = getOperationName(operation);
223
235
  const pollerLikeReference = resolveReference(AzurePollingDependencies.PollerLike);
224
236
  const operationStateReference = resolveReference(AzurePollingDependencies.OperationState);
225
237
  const functionStatement = {
226
238
  docs: [
227
- ...getDocsFromDescription(operation.description),
239
+ ...getDocsFromDescription(operation.doc),
228
240
  ...getFixmeForMultilineDocs(fixme)
229
241
  ],
230
242
  isAsync: false,
231
243
  isExported: true,
232
244
  name,
233
- propertyName: operation.name,
245
+ propertyName: normalizeName(operation.name, NameType.Property),
234
246
  parameters,
235
247
  returnType: `${pollerLikeReference}<${operationStateReference}<${returnType.type}>, ${returnType.type}>`
236
248
  };
237
249
  const getLongRunningPollerReference = resolveReference(PollingHelpers.GetLongRunningPoller);
238
- const resourceLocationConfig = ((_a = operation.lroMetadata) === null || _a === void 0 ? void 0 : _a.finalStateVia)
239
- ? `resourceLocationConfig: "${(_b = operation.lroMetadata) === null || _b === void 0 ? void 0 : _b.finalStateVia}"`
250
+ const lroMetadata = operation.kind === "lro" || operation.kind === "lropaging"
251
+ ? operation.lroMetadata
252
+ : undefined;
253
+ const allowedFinalLocation = [
254
+ "azure-async-operation",
255
+ "location",
256
+ "original-uri",
257
+ "operation-location"
258
+ ];
259
+ const resourceLocationConfig = (lroMetadata === null || lroMetadata === void 0 ? void 0 : lroMetadata.finalStateVia) &&
260
+ allowedFinalLocation.includes(lroMetadata === null || lroMetadata === void 0 ? void 0 : lroMetadata.finalStateVia)
261
+ ? `resourceLocationConfig: "${lroMetadata === null || lroMetadata === void 0 ? void 0 : lroMetadata.finalStateVia}"`
240
262
  : "";
241
263
  const statements = [];
242
264
  statements.push(`
243
265
 
244
266
  return ${getLongRunningPollerReference}(context, _${name}Deserialize, ${getExpectedStatuses(operation)}, {
245
- updateIntervalInMs: options?.updateIntervalInMs,
246
- abortSignal: options?.abortSignal,
267
+ updateIntervalInMs: ${optionalParamName}?.updateIntervalInMs,
268
+ abortSignal: ${optionalParamName}?.abortSignal,
247
269
  getInitialResponse: () => _${name}Send(${parameters
248
270
  .map((p) => p.name)
249
271
  .join(", ")}),
@@ -257,27 +279,28 @@ function getLroOnlyOperationFunction(context, operation, clientType) {
257
279
  }
258
280
  function buildLroReturnType(context, operation) {
259
281
  const metadata = operation.lroMetadata;
260
- if (metadata !== undefined && metadata.finalResult !== undefined) {
261
- const type = metadata.finalResult;
282
+ if (metadata !== undefined && metadata.finalResponse !== undefined) {
283
+ const type = metadata.finalResponse.result;
262
284
  return {
263
285
  name: type.name,
264
- type: getTypeExpression(context, type.tcgcType)
286
+ type: getTypeExpression(context, type)
265
287
  };
266
288
  }
267
289
  return { name: "", type: "void" };
268
290
  }
269
- function getPagingOnlyOperationFunction(context, operation, clientType) {
291
+ function getPagingOnlyOperationFunction(context, method, clientType) {
270
292
  var _a, _b, _c;
293
+ const operation = method[1];
271
294
  // Extract required parameters
272
- const parameters = getOperationSignatureParameters(context, operation, clientType);
295
+ const parameters = getOperationSignatureParameters(context, method, clientType);
273
296
  // TODO: Support operation overloads
274
- const response = operation.responses[0];
297
+ const response = operation.response;
275
298
  let returnType = { name: "", type: "void" };
276
- if ((_a = response.type) === null || _a === void 0 ? void 0 : _a.type) {
277
- const type = (_b = extractPagingType(response.type, operation.itemName)) !== null && _b !== void 0 ? _b : response.type;
299
+ if (response.type && response.type.kind === "array") {
300
+ const type = response.type;
278
301
  returnType = {
279
- name: (_c = type.name) !== null && _c !== void 0 ? _c : "",
280
- type: getTypeExpression(context, type.tcgcType)
302
+ name: (_a = type.valueType.name) !== null && _a !== void 0 ? _a : "",
303
+ type: getTypeExpression(context, type.valueType)
281
304
  };
282
305
  }
283
306
  const { name, fixme = [] } = getOperationName(operation);
@@ -285,23 +308,29 @@ function getPagingOnlyOperationFunction(context, operation, clientType) {
285
308
  const buildPagedAsyncIteratorReference = resolveReference(PagingHelpers.BuildPagedAsyncIterator);
286
309
  const functionStatement = {
287
310
  docs: [
288
- ...getDocsFromDescription(operation.description),
311
+ ...getDocsFromDescription(operation.doc),
289
312
  ...getFixmeForMultilineDocs(fixme)
290
313
  ],
291
314
  isAsync: false,
292
315
  isExported: true,
293
316
  name,
294
- propertyName: operation.name,
317
+ propertyName: normalizeName(operation.name, NameType.Property),
295
318
  parameters,
296
319
  returnType: `${pagedAsyncIterableIteratorReference}<${returnType.type}>`
297
320
  };
298
321
  const statements = [];
299
322
  const options = [];
300
- if (operation.itemName) {
301
- options.push(`itemName: "${operation.itemName}"`);
302
- }
303
- if (operation.continuationTokenName) {
304
- options.push(`nextLinkName: "${operation.continuationTokenName}"`);
323
+ // TODO pending tcgc issue to fix https://github.com/Azure/typespec-azure/issues/1985
324
+ const itemName = operation.response.resultPath !== "" && operation.response.resultPath
325
+ ? operation.response.resultPath
326
+ : ((_b = operation.__raw_paged_metadata) === null || _b === void 0 ? void 0 : _b.itemsSegments)
327
+ ? operation.__raw_paged_metadata.itemsSegments[0]
328
+ : undefined;
329
+ if (itemName) {
330
+ options.push(`itemName: "${itemName}"`);
331
+ }
332
+ if ((_c = operation.__raw_paged_metadata) === null || _c === void 0 ? void 0 : _c.nextLinkSegments) {
333
+ options.push(`nextLinkName: "${operation.__raw_paged_metadata.nextLinkSegments[0]}"`);
305
334
  }
306
335
  statements.push(`return ${buildPagedAsyncIteratorReference}(
307
336
  context,
@@ -315,28 +344,11 @@ function getPagingOnlyOperationFunction(context, operation, clientType) {
315
344
  statements
316
345
  };
317
346
  }
318
- function extractPagingType(type, itemName) {
319
- var _a, _b, _c;
320
- if (!itemName) {
321
- return undefined;
322
- }
323
- const allProperties = [
324
- ...((_a = type.properties) !== null && _a !== void 0 ? _a : []),
325
- ...((_b = type.parents) !== null && _b !== void 0 ? _b : []).flatMap((p) => { var _a; return (_a = p.properties) !== null && _a !== void 0 ? _a : []; })
326
- ];
327
- const prop = allProperties
328
- .filter((prop) => prop.restApiName === itemName)
329
- .map((prop) => prop.type);
330
- if (prop.length === 0) {
331
- return undefined;
332
- }
333
- return ((_c = prop[0]) === null || _c === void 0 ? void 0 : _c.type) === "list" && prop[0].elementType
334
- ? prop[0].elementType
335
- : undefined;
336
- }
337
- export function getOperationOptionsName(operation, includeGroupName = false) {
347
+ export function getOperationOptionsName(method, includeGroupName = false) {
348
+ const prefixes = method[0];
349
+ const operation = method[1];
338
350
  const prefix = includeGroupName && operation.name.indexOf("_") === -1
339
- ? getClassicalLayerPrefix(operation, NameType.Interface)
351
+ ? getClassicalLayerPrefix(prefixes, NameType.Interface)
340
352
  : "";
341
353
  const optionName = `${prefix}${toPascalCase(operation.name)}OptionalParams`;
342
354
  return optionName;
@@ -346,54 +358,59 @@ export function getOperationOptionsName(operation, includeGroupName = false) {
346
358
  * RLC internally. This will translate High Level parameters into the RLC ones.
347
359
  * Figuring out what goes in headers, body, path and qsp.
348
360
  */
349
- function getRequestParameters(dpgContext, operation) {
350
- if (!operation.parameters) {
361
+ function getRequestParameters(dpgContext, operation, optionalParamName = "options") {
362
+ if (!operation.operation.parameters) {
351
363
  return "";
352
364
  }
353
- const operationParameters = operation.parameters.filter((p) => p.implementation !== "Client" && !isContentType(p));
354
- const contentTypeParameter = operation.parameters.find(isContentType);
365
+ const operationParameters = operation.operation.parameters.filter((p) => (!p.onClient || p.isApiVersionParam) && !isContentType(p));
366
+ const contentTypeParameter = operation.operation.parameters.find(isContentType);
355
367
  const parametersImplementation = {
356
368
  header: [],
357
369
  query: [],
358
370
  body: []
359
371
  };
360
372
  for (const param of operationParameters) {
361
- if (param.location === "header" ||
362
- param.location === "query" ||
363
- param.location === "body") {
364
- parametersImplementation[param.location].push({
365
- paramMap: getParameterMap(dpgContext, param),
373
+ if (param.kind === "header" || param.kind === "query") {
374
+ // skip tcgc generated contentType and accept non constant type header parameter
375
+ if (param.isGeneratedName &&
376
+ !isConstant(param.type) &&
377
+ (param.name === "contentType" || param.name === "accept")) {
378
+ continue;
379
+ }
380
+ parametersImplementation[param.kind].push({
381
+ paramMap: getParameterMap(dpgContext, param, optionalParamName),
366
382
  param
367
383
  });
368
384
  }
369
385
  }
370
386
  let paramStr = "";
371
387
  if (contentTypeParameter) {
372
- paramStr = `${getContentTypeValue(contentTypeParameter)},`;
388
+ paramStr = `${getContentTypeValue(contentTypeParameter, optionalParamName)},`;
373
389
  }
374
390
  if (parametersImplementation.header.length) {
375
391
  paramStr = `${paramStr}\nheaders: {${parametersImplementation.header
376
- .map((i) => buildHeaderParameter(dpgContext.program, i.paramMap, i.param))
377
- .join(",\n")}},`;
392
+ .map((i) => buildHeaderParameter(dpgContext.program, i.paramMap, i.param, optionalParamName))
393
+ .join(",\n")}, ...${optionalParamName}.requestOptions?.headers },`;
378
394
  }
379
395
  if (parametersImplementation.query.length) {
380
396
  paramStr = `${paramStr}\nqueryParameters: {${parametersImplementation.query
381
397
  .map((i) => i.paramMap)
382
398
  .join(",\n")}},`;
383
399
  }
384
- if (operation.bodyParameter === undefined &&
400
+ if (operation.operation.bodyParam === undefined &&
385
401
  parametersImplementation.body.length) {
386
402
  paramStr = `${paramStr}\nbody: {${parametersImplementation.body
387
403
  .map((i) => i.paramMap)
388
404
  .join(",\n")}}`;
389
405
  }
390
- else if (operation.bodyParameter !== undefined) {
391
- paramStr = `${paramStr}${buildBodyParameter(dpgContext, operation.bodyParameter)}`;
406
+ else if (operation.operation.bodyParam !== undefined) {
407
+ paramStr = `${paramStr}${buildBodyParameter(dpgContext, operation.operation.bodyParam)}`;
392
408
  }
393
409
  return paramStr;
394
410
  }
395
411
  // Specially handle the type for headers because we only allow string/number/boolean values
396
- function buildHeaderParameter(program, paramMap, param) {
412
+ function buildHeaderParameter(program, paramMap, param, optionalParamName = "options") {
413
+ const paramName = param.name;
397
414
  if (!param.optional && isTypeNullable(param.type) === true) {
398
415
  reportDiagnostic(program, {
399
416
  code: "nullable-required-header",
@@ -403,32 +420,36 @@ function buildHeaderParameter(program, paramMap, param) {
403
420
  }
404
421
  const conditions = [];
405
422
  if (param.optional) {
406
- conditions.push(`options?.${param.clientName} !== undefined`);
423
+ conditions.push(`${optionalParamName}?.${paramName} !== undefined`);
407
424
  }
408
425
  if (isTypeNullable(param.type) === true) {
409
- conditions.push(`options?.${param.clientName} !== null`);
426
+ conditions.push(`${optionalParamName}?.${paramName} !== null`);
410
427
  }
411
428
  return conditions.length > 0
412
429
  ? `...(${conditions.join(" && ")} ? {${paramMap}} : {})`
413
430
  : paramMap;
414
431
  }
415
- function buildBodyParameter(context, bodyParameter) {
416
- if (!bodyParameter || !bodyParameter.type.tcgcType) {
432
+ function buildBodyParameter(context, bodyParameter, optionalParamName = "options") {
433
+ if (!bodyParameter || !bodyParameter.type) {
417
434
  return "";
418
435
  }
419
- const serializerFunctionName = buildModelSerializer(context, bodyParameter.type.tcgcType, false, true);
436
+ const serializerFunctionName = buildModelSerializer(context, getNullableValidType(bodyParameter.type), false, true);
437
+ const bodyParamName = normalizeName(bodyParameter.name, NameType.Parameter);
420
438
  const bodyNameExpression = bodyParameter.optional
421
- ? `options["${bodyParameter.clientName}"]`
422
- : bodyParameter.clientName;
423
- const nullOrUndefinedPrefix = getPropertySerializationPrefix(bodyParameter, bodyParameter.optional ? "options" : undefined);
424
- if (serializerFunctionName) {
439
+ ? `${optionalParamName}["${bodyParamName}"]`
440
+ : bodyParamName;
441
+ const nullOrUndefinedPrefix = getPropertySerializationPrefix(context, bodyParameter, bodyParameter.optional ? optionalParamName : undefined);
442
+ // if a model being used in both spread and non spread operation, we should only leverage the deserializer in non spread operation
443
+ if (serializerFunctionName && !isSpreadBodyParameter(bodyParameter)) {
425
444
  return `\nbody: ${nullOrUndefinedPrefix}${serializerFunctionName}(${bodyNameExpression}),`;
426
445
  }
427
446
  else if (isAzureCoreErrorType(context.program, bodyParameter.type.__raw)) {
428
447
  return `\nbody: ${nullOrUndefinedPrefix}${bodyNameExpression},`;
429
448
  }
430
- const serializedBody = serializeRequestValue(context, bodyParameter.type, bodyNameExpression, !bodyParameter.optional, bodyParameter.isBinaryPayload ? "binary" : bodyParameter.format);
431
- return `\nbody: ${serializedBody === bodyNameExpression ? "" : nullOrUndefinedPrefix}${serializedBody},`;
449
+ const serializedBody = serializeRequestValue(context, bodyParameter.type, bodyNameExpression, !bodyParameter.optional, isBinaryPayload(context, bodyParameter.__raw, bodyParameter.contentTypes)
450
+ ? "binary"
451
+ : getEncodeForType(bodyParameter.type));
452
+ return `\nbody: ${serializedBody.startsWith(nullOrUndefinedPrefix) ? "" : nullOrUndefinedPrefix}${serializedBody},`;
432
453
  }
433
454
  function getEncodingFormat(type) {
434
455
  var _a;
@@ -441,138 +462,150 @@ function getEncodingFormat(type) {
441
462
  /**
442
463
  * This function helps with renames, translating client names to rest api names
443
464
  */
444
- export function getParameterMap(context, param) {
445
- if (isConstant(param)) {
446
- return getConstantValue(param);
465
+ export function getParameterMap(context, param, optionalParamName = "options") {
466
+ if (isConstant(param.type)) {
467
+ return `"${param.name}": ${getConstantValue(param.type)}`;
447
468
  }
448
- if (hasCollectionFormatInfo(param.location, param.format)) {
449
- return getCollectionFormat(context, param);
469
+ if (hasCollectionFormatInfo(param.kind, param.collectionFormat)) {
470
+ return getCollectionFormat(context, param, optionalParamName);
450
471
  }
451
472
  // if the parameter or property is optional, we don't need to handle the default value
452
473
  if (isOptional(param)) {
453
- return getOptional(context, param);
474
+ return getOptional(context, param, optionalParamName);
454
475
  }
455
476
  if (isRequired(param)) {
456
477
  return getRequired(context, param);
457
478
  }
458
- throw new Error(`Parameter ${param.clientName} is not supported`);
479
+ throw new Error(`Parameter ${param.name} is not supported`);
459
480
  }
460
- function getCollectionFormat(context, param) {
461
- var _a, _b;
462
- const collectionInfo = getCollectionFormatHelper(param.location, (_a = param.format) !== null && _a !== void 0 ? _a : "");
481
+ function getCollectionFormat(context, param, optionalParamName = "options") {
482
+ const serializedName = getPropertySerializedName(param);
483
+ const format = param.collectionFormat;
484
+ const collectionInfo = getCollectionFormatHelper(param.kind, format !== null && format !== void 0 ? format : "");
463
485
  if (!collectionInfo) {
464
486
  throw "Has collection format info but without helper function detected";
465
487
  }
466
- const isMulti = ((_b = param.format) !== null && _b !== void 0 ? _b : "").toLowerCase() === "multi";
467
- const additionalParam = isMulti ? `, "${param.restApiName}"` : "";
488
+ const isMulti = format.toLowerCase() === "multi";
489
+ const additionalParam = isMulti ? `, "${serializedName}"` : "";
468
490
  if (!param.optional) {
469
- return `"${param.restApiName}": ${collectionInfo}(${serializeRequestValue(context, param.type, param.clientName, true, param.format)}${additionalParam})`;
491
+ return `"${serializedName}": ${collectionInfo}(${serializeRequestValue(context, param.type, param.name, true, getEncodeForType(param.type))}${additionalParam})`;
470
492
  }
471
- return `"${param.restApiName}": options?.${param.clientName} !== undefined ? ${collectionInfo}(${serializeRequestValue(context, param.type, "options?." + param.clientName, false, param.format)}${additionalParam}): undefined`;
493
+ return `"${serializedName}": ${optionalParamName}?.${param.name} !== undefined ? ${collectionInfo}(${serializeRequestValue(context, param.type, `${optionalParamName}?.${param.name}`, false, getEncodeForType(param.type))}${additionalParam}): undefined`;
472
494
  }
473
495
  function isContentType(param) {
474
- return (param.location === "header" &&
475
- param.restApiName.toLowerCase() === "content-type");
496
+ return (param.kind === "header" &&
497
+ param.serializedName.toLowerCase() === "content-type");
476
498
  }
477
- function getContentTypeValue(param) {
478
- var _a;
479
- const defaultValue = (_a = param.clientDefaultValue) !== null && _a !== void 0 ? _a : param.type.clientDefaultValue;
499
+ function getContentTypeValue(param, optionalParamName = "options") {
500
+ const defaultValue = param.clientDefaultValue;
501
+ // allow customers to customize the content type if it's guessed by tcgc.
502
+ if (isConstant(param.type)) {
503
+ return `contentType: ${getConstantValue(param.type)}`;
504
+ }
480
505
  if (defaultValue) {
481
- return `contentType: options.${param.clientName} as any ?? "${defaultValue}"`;
506
+ return `contentType: ${optionalParamName}.${param.name} as any ?? "${defaultValue}"`;
482
507
  }
483
508
  else {
484
509
  return `contentType: ${!param.optional
485
510
  ? "contentType"
486
- : "options." + param.clientName + " as any"}`;
511
+ : `${optionalParamName}.` + param.name + " as any"}`;
487
512
  }
488
513
  }
489
514
  function isRequired(param) {
490
515
  return !param.optional;
491
516
  }
492
517
  function getRequired(context, param) {
493
- if (param.type.type === "model") {
494
- const { propertiesStr } = getRequestModelMapping(context, param.type, param.clientName);
495
- return `"${param.restApiName}": { ${propertiesStr.join(",")} }`;
518
+ const serializedName = getPropertySerializedName(param);
519
+ const clientValue = `${param.onClient ? "context." : ""}${param.name}`;
520
+ if (param.type.kind === "model") {
521
+ const { propertiesStr } = getRequestModelMapping(context, { ...param.type, optional: param.optional }, clientValue);
522
+ return `"${serializedName}": { ${propertiesStr.join(",")} }`;
496
523
  }
497
- return `"${param.restApiName}": ${serializeRequestValue(context, param.type, param.clientName, true, param.format === undefined &&
498
- param.location === "header" &&
499
- param.type.type === "datetime"
500
- ? "headerDefault"
501
- : param.format)}`;
524
+ return `"${serializedName}": ${serializeRequestValue(context, param.type, clientValue, true, getEncodeForType(param.type))}`;
502
525
  }
503
526
  function getConstantValue(param) {
504
- var _a, _b;
505
- const defaultValue = (_b = (_a = param.clientDefaultValue) !== null && _a !== void 0 ? _a : param.type.clientDefaultValue) !== null && _b !== void 0 ? _b : param.type.value;
506
- if (!defaultValue) {
507
- throw new Error(`Constant ${param.clientName} does not have a default value`);
527
+ if (typeof param.value === "string") {
528
+ return `"${param.value}"`;
508
529
  }
509
- return `"${param.restApiName}": ${getType(param.type).name}`;
530
+ return `${param.value}`;
510
531
  }
511
532
  function isConstant(param) {
512
- return param.type.type === "constant";
533
+ return param.kind === "constant";
513
534
  }
514
535
  function isOptional(param) {
515
536
  return Boolean(param.optional);
516
537
  }
517
- function getOptional(context, param) {
518
- if (param.type.type === "model") {
519
- const { propertiesStr, directAssignment } = getRequestModelMapping(context, param.type, "options?." + param.clientName + "?.");
538
+ function getOptional(context, param, optionalParamName) {
539
+ const serializedName = getPropertySerializedName(param);
540
+ const paramName = `${param.onClient ? "context." : `${optionalParamName}?.`}${param.name}`;
541
+ if (param.type.kind === "model") {
542
+ const { propertiesStr, directAssignment } = getRequestModelMapping(context, { ...param.type, optional: param.optional }, paramName + "?.");
520
543
  const serializeContent = directAssignment === true
521
544
  ? propertiesStr.join(",")
522
545
  : `{${propertiesStr.join(",")}}`;
523
- return `"${param.restApiName}": ${serializeContent}`;
524
- }
525
- if (param.restApiName === "api-version" &&
526
- param.location === "query") {
527
- return `"${param.restApiName}": ${param.clientDefaultValue
528
- ? `options?.${param.clientName} ?? "${param.clientDefaultValue}"`
529
- : `options?.${param.clientName}`}`;
546
+ return `"${serializedName}": ${serializeContent}`;
530
547
  }
531
- return `"${param.restApiName}": ${serializeRequestValue(context, param.type, `options?.${param.clientName}`, false, param.format === undefined &&
532
- param.location === "header" &&
533
- param.type.type === "datetime"
534
- ? "headerDefault"
535
- : param.format)}`;
548
+ return `"${serializedName}": ${serializeRequestValue(context, param.type, paramName, false, getEncodeForType(param.type))}`;
549
+ }
550
+ /**
551
+ * Get the encode for SDK type
552
+ */
553
+ function getEncodeForType(type) {
554
+ return type.encode;
555
+ }
556
+ /**
557
+ * Get the optionality for SDK type
558
+ */
559
+ function getOptionalForType(type) {
560
+ return type.optional;
536
561
  }
537
562
  /**
538
563
  * Builds the assignment for when a property or parameter has a default value
539
564
  */
540
565
  function getDefaultValue(param) {
541
- var _a;
542
- return (_a = param.clientDefaultValue) !== null && _a !== void 0 ? _a : param.type.clientDefaultValue;
566
+ return param.clientDefaultValue;
543
567
  }
544
568
  /**
545
569
  * Extracts the path parameters
546
570
  */
547
- function getPathParameters(dpgContext, operation) {
548
- if (!operation.parameters) {
571
+ function getPathParameters(dpgContext, operation, optionalParamName = "options") {
572
+ if (!operation.operation.parameters) {
549
573
  return "";
550
574
  }
551
575
  let pathParams = "";
552
- for (const param of operation.parameters) {
553
- if (param.location === "path") {
576
+ for (const param of operation.operation.parameters) {
577
+ if (param.kind === "path") {
554
578
  // Path parameters cannot be optional
555
579
  if (param.optional) {
556
580
  reportDiagnostic(dpgContext.program, {
557
581
  code: "optional-path-param",
558
582
  target: NoTarget,
559
583
  format: {
560
- paramName: param.clientName
584
+ paramName: param
561
585
  }
562
586
  });
563
587
  }
564
- pathParams += `${pathParams !== "" ? "," : ""} ${getPathParamExpr(param, getDefaultValue(param))}`;
588
+ pathParams += `${pathParams !== "" ? "," : ""} ${getPathParamExpr(param, getDefaultValue(param), optionalParamName)}`;
565
589
  }
566
590
  }
567
591
  return pathParams;
568
592
  }
569
- function getPathParamExpr(param, defaultValue) {
593
+ function getPathParamExpr(param, defaultValue, optionalParamName = "options") {
594
+ if (isConstant(param.type)) {
595
+ return getConstantValue(param.type);
596
+ }
597
+ const paramName = param.onClient
598
+ ? `context.${param.name}`
599
+ : param.optional
600
+ ? `${optionalParamName}["${param.name}"]`
601
+ : param.name;
570
602
  const value = defaultValue
571
603
  ? typeof defaultValue === "string"
572
- ? `options[${param.clientName}] ?? "${defaultValue}"`
573
- : `options[${param.clientName}] ?? ${defaultValue}`
574
- : param.clientName;
575
- if (param.skipUrlEncoding === true) {
604
+ ? `${paramName} ?? "${defaultValue}"`
605
+ : `${paramName} ?? ${defaultValue}`
606
+ : paramName;
607
+ // TODO allowReserved is not supported in Query and Header parameter yet.
608
+ if (param.kind === "path" && param.allowReserved === true) {
576
609
  return `{value: ${value}, allowReserved: true}`;
577
610
  }
578
611
  return value;
@@ -592,52 +625,59 @@ export function getRequestModelMapping(context, modelPropertyType, propertyPath
592
625
  return { propertiesStr: [] };
593
626
  }
594
627
  for (const property of properties) {
595
- if (property.readonly) {
628
+ if (property.kind === "property" && isReadOnly(property)) {
596
629
  continue;
597
630
  }
598
631
  const dot = propertyPath.endsWith("?") ? "." : "";
632
+ const serializedName = getPropertySerializedName(property);
599
633
  const propertyPathWithDot = `${propertyPath ? `${propertyPath}${dot}` : `${dot}`}`;
600
- const nullOrUndefinedPrefix = getPropertySerializationPrefix(property, propertyPath);
601
- const propertyFullName = getPropertyFullName(property, propertyPathWithDot);
602
- const serializeFunctionName = buildModelSerializer(context, property.type.tcgcType, false, true);
634
+ const nullOrUndefinedPrefix = getPropertySerializationPrefix(context, property, propertyPath);
635
+ const propertyFullName = getPropertyFullName(context, property, propertyPathWithDot);
636
+ const serializeFunctionName = buildModelSerializer(context, getNullableValidType(property.type), false, true);
603
637
  if (serializeFunctionName) {
604
- props.push(`"${property.restApiName}": ${nullOrUndefinedPrefix}${serializeFunctionName}(${propertyFullName})`);
638
+ props.push(`"${serializedName}": ${nullOrUndefinedPrefix}${serializeFunctionName}(${propertyFullName})`);
605
639
  }
606
640
  else if (isAzureCoreErrorType(context.program, property.type.__raw)) {
607
- props.push(`"${property.restApiName}": ${nullOrUndefinedPrefix}${propertyFullName}`);
641
+ props.push(`"${serializedName}": ${nullOrUndefinedPrefix}${propertyFullName}`);
608
642
  }
609
643
  else {
610
- const serializedValue = serializeRequestValue(context, property.type, propertyFullName, !property.optional, property.format);
611
- props.push(`"${property.restApiName}": ${serializedValue}`);
644
+ const serializedValue = serializeRequestValue(context, property.type, propertyFullName, !property.optional, getEncodeForType(property.type));
645
+ props.push(`"${serializedName}": ${serializedValue}`);
612
646
  }
613
647
  }
614
648
  return { propertiesStr: props };
615
649
  }
650
+ function getPropertySerializedName(property) {
651
+ return property.kind !== "credential" && property.kind !== "method"
652
+ ? property.serializedName
653
+ : property.name;
654
+ }
616
655
  /**
617
656
  * This function helps translating an RLC response to an HLC response,
618
657
  * extracting properties from body and headers and building the HLC response object
619
658
  */
620
659
  export function getResponseMapping(context, type, propertyPath = "result.body") {
621
- var _a;
622
- const allParents = getAllAncestors(type);
623
- const properties = (_a = getAllProperties(type, allParents)) !== null && _a !== void 0 ? _a : [];
660
+ const allParents = type.kind === "model" ? getAllAncestors(type) : [];
661
+ const properties = type.kind === "model" ? getAllProperties(type, allParents) : [];
624
662
  const props = [];
625
663
  for (const property of properties) {
626
664
  const dot = propertyPath.endsWith("?") ? "." : "";
627
- const restValue = `${propertyPath ? `${propertyPath}${dot}` : `${dot}`}["${property.restApiName}"]`;
665
+ const serializedName = getPropertySerializedName(property);
666
+ const restValue = `${propertyPath ? `${propertyPath}${dot}` : `${dot}`}["${serializedName}"]`;
628
667
  const nullOrUndefinedPrefix = property.optional || isTypeNullable(property.type)
629
668
  ? `!${restValue}? ${restValue}: `
630
669
  : "";
631
- const deserializeFunctionName = buildModelDeserializer(context, property.type.tcgcType, false, true);
670
+ const deserializeFunctionName = buildModelDeserializer(context, getNullableValidType(property.type), false, true);
671
+ const propertyName = normalizeModelPropertyName(context, property);
632
672
  if (deserializeFunctionName) {
633
- props.push(`"${property.clientName}": ${nullOrUndefinedPrefix}${deserializeFunctionName}(${restValue})`);
673
+ props.push(`${propertyName}: ${nullOrUndefinedPrefix}${deserializeFunctionName}(${restValue})`);
634
674
  }
635
675
  else if (isAzureCoreErrorType(context.program, property.type.__raw)) {
636
- props.push(`"${property.clientName}": ${nullOrUndefinedPrefix}${restValue}`);
676
+ props.push(`${propertyName}: ${nullOrUndefinedPrefix}${restValue}`);
637
677
  }
638
678
  else {
639
- const deserializeValue = deserializeResponseValue(context, property.type, `${propertyPath}${dot}["${property.restApiName}"]`, property.format);
640
- props.push(`"${property.clientName}": ${deserializeValue === `${propertyPath}${dot}["${property.restApiName}"]` ? "" : nullOrUndefinedPrefix}${deserializeValue}`);
679
+ const deserializeValue = deserializeResponseValue(context, property.type, `${propertyPath}${dot}["${serializedName}"]`, getEncodeForType(property.type));
680
+ props.push(`${propertyName}: ${deserializeValue === `${propertyPath}${dot}["${serializedName}"]` ? "" : nullOrUndefinedPrefix}${deserializeValue}`);
641
681
  }
642
682
  }
643
683
  return props;
@@ -648,56 +688,59 @@ export function getResponseMapping(context, type, propertyPath = "result.body")
648
688
  * deserialized correctly
649
689
  */
650
690
  export function serializeRequestValue(context, type, clientValue, required, format) {
651
- var _a, _b, _c, _d;
691
+ var _a, _b, _c, _d, _e;
652
692
  const getSdkType = useSdkTypes();
653
693
  const dependencies = useDependencies();
654
- const nullOrUndefinedPrefix = isTypeNullable(type) || type.optional || !required
694
+ const nullOrUndefinedPrefix = isTypeNullable(type) || getOptionalForType(type) || !required
655
695
  ? `!${clientValue}? ${clientValue}: `
656
696
  : "";
657
- switch (type.type) {
658
- case "datetime":
659
- switch ((_a = type.format) !== null && _a !== void 0 ? _a : format) {
697
+ switch (type.kind) {
698
+ case "utcDateTime":
699
+ switch ((_a = type.encode) !== null && _a !== void 0 ? _a : format) {
660
700
  case "rfc7231":
661
- case "headerDefault":
662
701
  return `${nullOrUndefinedPrefix}${clientValue}.toUTCString()`;
663
702
  case "unixTimestamp":
664
703
  return `${nullOrUndefinedPrefix}((${clientValue}.getTime() / 1000) | 0)`;
665
704
  case "rfc3339":
666
705
  default:
667
- return `${getNullableCheck(clientValue, type)} ${clientValue}${required ? "" : "?"}.toISOString()`;
706
+ return `${nullOrUndefinedPrefix}${clientValue}.toISOString()`;
668
707
  }
669
- case "list": {
708
+ case "array": {
670
709
  const prefix = nullOrUndefinedPrefix + clientValue;
671
- if (type.elementType) {
672
- const elementNullOrUndefinedPrefix = isTypeNullable(type.elementType) || type.elementType.optional
710
+ if (type.valueType) {
711
+ const elementNullOrUndefinedPrefix = isTypeNullable(type.valueType) || getOptionalForType(type.valueType)
673
712
  ? "!p ? p : "
674
713
  : "";
675
- const serializeFunctionName = buildModelSerializer(context, type.elementType.tcgcType, false, true);
714
+ const serializeFunctionName = buildModelSerializer(context, getNullableValidType(type.valueType), false, true);
676
715
  if (serializeFunctionName) {
677
716
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${serializeFunctionName}(p)})`;
678
717
  }
679
- else if (isAzureCoreErrorType(context.program, type.elementType.__raw)) {
718
+ else if (isAzureCoreErrorType(context.program, type.valueType.__raw)) {
680
719
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}p})`;
681
720
  }
682
721
  else {
683
- return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${serializeRequestValue(context, type.elementType, "p", true, (_b = type.elementType) === null || _b === void 0 ? void 0 : _b.format)}})`;
722
+ return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${serializeRequestValue(context, type.valueType, "p", true, getEncodeForType(type.valueType))}})`;
684
723
  }
685
724
  }
686
725
  return clientValue;
687
726
  }
688
- case "byte-array":
689
- if (format !== "binary") {
727
+ case "bytes":
728
+ // TODO https://github.com/Azure/typespec-azure/issues/1999
729
+ if (format !== "binary" && format !== "bytes") {
690
730
  const uint8ArrayToStringReference = resolveReference(dependencies.uint8ArrayToString);
691
731
  return required
692
- ? `${getNullableCheck(clientValue, type)} ${uint8ArrayToStringReference}(${clientValue}, "${(_c = getEncodingFormat({ format })) !== null && _c !== void 0 ? _c : "base64"}")`
693
- : `${nullOrUndefinedPrefix} ${uint8ArrayToStringReference}(${clientValue}, "${(_d = getEncodingFormat({ format })) !== null && _d !== void 0 ? _d : "base64"}")`;
732
+ ? `${getNullableCheck(clientValue, type)} ${uint8ArrayToStringReference}(${clientValue}, "${(_b = getEncodingFormat({ format })) !== null && _b !== void 0 ? _b : "base64"}")`
733
+ : `${nullOrUndefinedPrefix} ${uint8ArrayToStringReference}(${clientValue}, "${(_c = getEncodingFormat({ format })) !== null && _c !== void 0 ? _c : "base64"}")`;
694
734
  }
695
735
  return clientValue;
696
- case "combined":
736
+ case "union":
697
737
  if (isNormalUnion(type)) {
698
738
  return `${clientValue}`;
699
739
  }
700
- else if (isSpecialHandledUnion(type)) {
740
+ else if (isSpecialHandledUnion({
741
+ ...type,
742
+ isNonExhaustive: (_e = (_d = context.rlcOptions) === null || _d === void 0 ? void 0 : _d.experimentalExtensibleEnums) !== null && _e !== void 0 ? _e : false
743
+ })) {
701
744
  const sdkType = getSdkType(type.__raw);
702
745
  const serializerRefkey = refkey(sdkType, "serializer");
703
746
  const serializeFunctionName = resolveReference(serializerRefkey);
@@ -706,6 +749,10 @@ export function serializeRequestValue(context, type, clientValue, required, form
706
749
  else {
707
750
  return `${clientValue} as any`;
708
751
  }
752
+ case "model": // this is to build serialization logic for spread model types
753
+ return `{${getRequestModelMapping(context, type, "").propertiesStr.join(",")}}`;
754
+ case "nullable":
755
+ return serializeRequestValue(context, type.type, clientValue, false, getEncodeForType(type.type));
709
756
  default:
710
757
  if (clientValue === "constructorParam") {
711
758
  return `${clientValue} as any`;
@@ -721,50 +768,50 @@ export function serializeRequestValue(context, type, clientValue, required, form
721
768
  export function deserializeResponseValue(context, type, restValue, format) {
722
769
  const dependencies = useDependencies();
723
770
  const stringToUint8ArrayReference = resolveReference(dependencies.stringToUint8Array);
724
- const nullOrUndefinedPrefix = isTypeNullable(type) || type.optional
771
+ const nullOrUndefinedPrefix = isTypeNullable(type) || getOptionalForType(type)
725
772
  ? `!${restValue}? ${restValue}: `
726
773
  : "";
727
- switch (type.type) {
728
- case "datetime":
729
- return `${nullOrUndefinedPrefix} new Date(${type.format === "unixTimestamp" ? `${restValue} * 1000` : restValue})`;
730
- case "list": {
774
+ switch (type.kind) {
775
+ case "utcDateTime":
776
+ return `${nullOrUndefinedPrefix} new Date(${type.encode === "unixTimestamp" ? `${restValue} * 1000` : restValue})`;
777
+ case "array": {
731
778
  const prefix = nullOrUndefinedPrefix + restValue;
732
779
  let elementNullOrUndefinedPrefix = "";
733
- if (type.elementType &&
734
- (isTypeNullable(type.elementType) || type.elementType.optional)) {
780
+ if (type.valueType &&
781
+ (isTypeNullable(type.valueType) || getOptionalForType(type.valueType))) {
735
782
  elementNullOrUndefinedPrefix = "!p ? p :";
736
783
  }
737
- const deserializeFunctionName = type.elementType
738
- ? buildModelDeserializer(context, type.elementType.tcgcType, false, true)
784
+ const deserializeFunctionName = type.valueType
785
+ ? buildModelDeserializer(context, getNullableValidType(type.valueType), false, true)
739
786
  : undefined;
740
787
  if (deserializeFunctionName) {
741
788
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${deserializeFunctionName}(p)})`;
742
789
  }
743
- else if (type.elementType &&
744
- isAzureCoreErrorType(context.program, type.elementType.__raw)) {
790
+ else if (type.valueType &&
791
+ isAzureCoreErrorType(context.program, type.valueType.__raw)) {
745
792
  return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}p})`;
746
793
  }
747
- else if (type.elementType) {
748
- return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${deserializeResponseValue(context, type.elementType, "p", type.format)}})`;
794
+ else if (type.valueType) {
795
+ return `${prefix}.map((p: any) => { return ${elementNullOrUndefinedPrefix}${deserializeResponseValue(context, type.valueType, "p", getEncodeForType(type.valueType))}})`;
749
796
  }
750
797
  else {
751
798
  return restValue;
752
799
  }
753
800
  }
754
- case "byte-array":
755
- if (format !== "binary") {
801
+ case "bytes":
802
+ if (format !== "binary" && format !== "bytes") {
756
803
  return `typeof ${restValue} === 'string'
757
804
  ? ${stringToUint8ArrayReference}(${restValue}, "${format !== null && format !== void 0 ? format : "base64"}")
758
805
  : ${restValue}`;
759
806
  }
760
807
  return restValue;
761
- case "combined":
808
+ case "union":
762
809
  if (isNormalUnion(type)) {
763
810
  return `${restValue}`;
764
811
  }
765
812
  else if (isSpecialHandledUnion(type)) {
766
813
  const deserializeFunctionName = type
767
- ? buildModelDeserializer(context, type.tcgcType, false, true)
814
+ ? buildModelDeserializer(context, getNullableValidType(type), false, true)
768
815
  : undefined;
769
816
  if (deserializeFunctionName) {
770
817
  return `${deserializeFunctionName}(${restValue})`;
@@ -776,32 +823,22 @@ export function deserializeResponseValue(context, type, restValue, format) {
776
823
  else {
777
824
  return `${restValue} as any`;
778
825
  }
826
+ case "model": // generate deserialize logic for spread model types
827
+ return `{${getResponseMapping(context, type, "").join(",")}}`;
828
+ case "nullable":
829
+ return deserializeResponseValue(context, type.type, restValue, getEncodeForType(type.type));
779
830
  default:
780
831
  return restValue;
781
832
  }
782
833
  }
783
834
  export function isLroAndPagingOperation(op) {
784
- return op.discriminator === "lropaging";
835
+ return op.kind === "lropaging";
785
836
  }
786
837
  export function isLroOnlyOperation(op) {
787
- return op.discriminator === "lro";
788
- }
789
- export function hasPagingOnlyOperation(clientOrCodeModel, needRLC = false) {
790
- let clients = [];
791
- if (clientOrCodeModel === null || clientOrCodeModel === void 0 ? void 0 : clientOrCodeModel.operationGroups) {
792
- clients = [clientOrCodeModel];
793
- }
794
- else if (clientOrCodeModel === null || clientOrCodeModel === void 0 ? void 0 : clientOrCodeModel.clients) {
795
- clients = clientOrCodeModel.clients;
796
- }
797
- return clients.some((c) => {
798
- var _a;
799
- return (needRLC ? c.rlcHelperDetails.hasPaging : false) ||
800
- ((_a = c.operationGroups) !== null && _a !== void 0 ? _a : []).some((og) => { var _a; return ((_a = og.operations) !== null && _a !== void 0 ? _a : []).some(isPagingOnlyOperation); });
801
- });
838
+ return op.kind === "lro";
802
839
  }
803
840
  export function isPagingOnlyOperation(op) {
804
- return op.discriminator === "paging";
841
+ return op.kind === "paging";
805
842
  }
806
843
  export function getAllProperties(type, parents) {
807
844
  var _a;
@@ -811,34 +848,42 @@ export function getAllProperties(type, parents) {
811
848
  }
812
849
  parents === null || parents === void 0 ? void 0 : parents.forEach((p) => {
813
850
  getAllProperties(p).forEach((prop) => {
814
- propertiesMap.set(prop.clientName, prop);
851
+ propertiesMap.set(prop.name, prop);
815
852
  });
816
853
  });
817
- (_a = type.properties) === null || _a === void 0 ? void 0 : _a.forEach((p) => {
818
- propertiesMap.set(p.clientName, p);
819
- });
854
+ type.kind === "model" &&
855
+ ((_a = type.properties) === null || _a === void 0 ? void 0 : _a.filter((p) => {
856
+ return p.kind === "property";
857
+ }).forEach((p) => {
858
+ propertiesMap.set(p.name, p);
859
+ }));
820
860
  return [...propertiesMap.values()];
821
861
  }
822
862
  export function getAllAncestors(type) {
823
- var _a;
824
863
  const ancestors = [];
825
- (_a = type === null || type === void 0 ? void 0 : type.parents) === null || _a === void 0 ? void 0 : _a.forEach((p) => {
826
- ancestors.push(p);
827
- ancestors.push(...getAllAncestors(p));
828
- });
864
+ if (type.kind === "model" && type.baseModel) {
865
+ ancestors.push(type.baseModel);
866
+ ancestors.push(...getAllAncestors(type.baseModel));
867
+ }
829
868
  return ancestors;
830
869
  }
831
- export function getPropertySerializationPrefix(modularType, propertyPath) {
832
- const propertyFullName = getPropertyFullName(modularType, propertyPath);
833
- if (modularType.optional || isTypeNullable(modularType.type)) {
834
- return `!${propertyFullName} ? ${propertyFullName} :`;
870
+ export function getPropertySerializationPrefix(context, property, propertyPath) {
871
+ const propertyFullName = getPropertyFullName(context, property, propertyPath);
872
+ if (property.optional || isTypeNullable(property.type)) {
873
+ return `!${propertyFullName}? ${propertyFullName}:`;
835
874
  }
836
875
  return "";
837
876
  }
838
- export function getPropertyFullName(modularType, propertyPath) {
839
- let fullName = `${modularType.clientName}`;
840
- if (propertyPath) {
841
- fullName = `${propertyPath}["${modularType.clientName}"]`;
877
+ export function getPropertyFullName(context, property, propertyPath) {
878
+ const normalizedPropertyName = normalizeModelPropertyName(context, property)
879
+ .replace(/^"/g, "")
880
+ .replace(/"$/g, "");
881
+ let fullName = normalizedPropertyName;
882
+ if (propertyPath === "" && property.optional) {
883
+ fullName = `options?.${normalizedPropertyName}`;
884
+ }
885
+ else if (propertyPath) {
886
+ fullName = `${propertyPath}["${normalizedPropertyName}"]`;
842
887
  }
843
888
  return fullName;
844
889
  }
@@ -847,10 +892,10 @@ export function getPropertyFullName(modularType, propertyPath) {
847
892
  * @param operation The operation
848
893
  */
849
894
  export function getExpectedStatuses(operation) {
850
- const statusCodes = operation.responses.flatMap((x) => x.statusCodes.filter((s) => s !== "default"));
895
+ const statusCodes = operation.operation.responses.map((x) => x.statusCodes);
851
896
  // LROs may call the same path but with GET to get the operation status.
852
897
  if (isLroOnlyOperation(operation) &&
853
- operation.method !== "GET" &&
898
+ operation.operation.verb !== "get" &&
854
899
  !statusCodes.includes(200)) {
855
900
  statusCodes.push(200);
856
901
  }