@azure-tools/typespec-ts 0.30.1 → 0.31.0-alpha.20240723.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 (184) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/src/contextManager.d.ts +4 -0
  3. package/dist/src/contextManager.d.ts.map +1 -1
  4. package/dist/src/contextManager.js.map +1 -1
  5. package/dist/src/framework/declaration.d.ts +9 -0
  6. package/dist/src/framework/declaration.d.ts.map +1 -0
  7. package/dist/src/framework/declaration.js +28 -0
  8. package/dist/src/framework/declaration.js.map +1 -0
  9. package/dist/src/framework/hooks/binder.d.ts +25 -0
  10. package/dist/src/framework/hooks/binder.d.ts.map +1 -0
  11. package/dist/src/framework/hooks/binder.js +168 -0
  12. package/dist/src/framework/hooks/binder.js.map +1 -0
  13. package/dist/src/framework/hooks/sdkTypes.d.ts +12 -0
  14. package/dist/src/framework/hooks/sdkTypes.d.ts.map +1 -0
  15. package/dist/src/framework/hooks/sdkTypes.js +67 -0
  16. package/dist/src/framework/hooks/sdkTypes.js.map +1 -0
  17. package/dist/src/framework/reference.d.ts +2 -0
  18. package/dist/src/framework/reference.d.ts.map +1 -0
  19. package/dist/src/framework/reference.js +8 -0
  20. package/dist/src/framework/reference.js.map +1 -0
  21. package/dist/src/framework/refkey.d.ts +7 -0
  22. package/dist/src/framework/refkey.d.ts.map +1 -0
  23. package/dist/src/framework/refkey.js +22 -0
  24. package/dist/src/framework/refkey.js.map +1 -0
  25. package/dist/src/framework/sample.d.ts +2 -0
  26. package/dist/src/framework/sample.d.ts.map +1 -0
  27. package/dist/src/framework/sample.js +71 -0
  28. package/dist/src/framework/sample.js.map +1 -0
  29. package/dist/src/framework/utils/tsmorph-helpers.d.ts +2 -0
  30. package/dist/src/framework/utils/tsmorph-helpers.d.ts.map +1 -0
  31. package/dist/src/framework/utils/tsmorph-helpers.js +2 -0
  32. package/dist/src/framework/utils/tsmorph-helpers.js.map +1 -0
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +7 -8
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/lib.d.ts +10 -1
  37. package/dist/src/lib.d.ts.map +1 -1
  38. package/dist/src/lib.js +6 -0
  39. package/dist/src/lib.js.map +1 -1
  40. package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
  41. package/dist/src/modular/buildClassicalClient.js +6 -5
  42. package/dist/src/modular/buildClassicalClient.js.map +1 -1
  43. package/dist/src/modular/buildClientContext.d.ts.map +1 -1
  44. package/dist/src/modular/buildClientContext.js +8 -4
  45. package/dist/src/modular/buildClientContext.js.map +1 -1
  46. package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
  47. package/dist/src/modular/buildCodeModel.js +22 -11
  48. package/dist/src/modular/buildCodeModel.js.map +1 -1
  49. package/dist/src/modular/buildOperations.d.ts +1 -2
  50. package/dist/src/modular/buildOperations.d.ts.map +1 -1
  51. package/dist/src/modular/buildOperations.js +3 -9
  52. package/dist/src/modular/buildOperations.js.map +1 -1
  53. package/dist/src/modular/buildRootIndex.js +1 -1
  54. package/dist/src/modular/buildRootIndex.js.map +1 -1
  55. package/dist/src/modular/buildSerializeUtils.d.ts.map +1 -1
  56. package/dist/src/modular/buildSerializeUtils.js +2 -1
  57. package/dist/src/modular/buildSerializeUtils.js.map +1 -1
  58. package/dist/src/modular/helpers/clientHelpers.d.ts +4 -0
  59. package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
  60. package/dist/src/modular/helpers/clientHelpers.js +15 -1
  61. package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
  62. package/dist/src/modular/helpers/namingHelpers.d.ts +1 -0
  63. package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
  64. package/dist/src/modular/helpers/namingHelpers.js +3 -1
  65. package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
  66. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  67. package/dist/src/modular/helpers/operationHelpers.js +60 -40
  68. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  69. package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
  70. package/dist/src/modular/helpers/typeHelpers.js +6 -1
  71. package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
  72. package/dist/src/modular/modularCodeModel.d.ts +2 -0
  73. package/dist/src/modular/modularCodeModel.d.ts.map +1 -1
  74. package/dist/src/transform/transformApiVersionInfo.d.ts.map +1 -1
  75. package/dist/src/transform/transformApiVersionInfo.js +3 -5
  76. package/dist/src/transform/transformApiVersionInfo.js.map +1 -1
  77. package/dist/src/transform/transformHelperFunctionDetails.d.ts.map +1 -1
  78. package/dist/src/transform/transformHelperFunctionDetails.js +7 -10
  79. package/dist/src/transform/transformHelperFunctionDetails.js.map +1 -1
  80. package/dist/src/transform/transformParameters.d.ts.map +1 -1
  81. package/dist/src/transform/transformParameters.js +5 -7
  82. package/dist/src/transform/transformParameters.js.map +1 -1
  83. package/dist/src/transform/transformPaths.d.ts.map +1 -1
  84. package/dist/src/transform/transformPaths.js +4 -6
  85. package/dist/src/transform/transformPaths.js.map +1 -1
  86. package/dist/src/transform/transformResponses.d.ts.map +1 -1
  87. package/dist/src/transform/transformResponses.js +70 -16
  88. package/dist/src/transform/transformResponses.js.map +1 -1
  89. package/dist/src/transform/transformSchemas.d.ts.map +1 -1
  90. package/dist/src/transform/transformSchemas.js +5 -6
  91. package/dist/src/transform/transformSchemas.js.map +1 -1
  92. package/dist/src/transform/transformTelemetryInfo.d.ts.map +1 -1
  93. package/dist/src/transform/transformTelemetryInfo.js +3 -6
  94. package/dist/src/transform/transformTelemetryInfo.js.map +1 -1
  95. package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
  96. package/dist/src/transform/transfromRLCOptions.js +5 -6
  97. package/dist/src/transform/transfromRLCOptions.js.map +1 -1
  98. package/dist/src/utils/modelUtils.d.ts +3 -3
  99. package/dist/src/utils/modelUtils.d.ts.map +1 -1
  100. package/dist/src/utils/modelUtils.js +42 -24
  101. package/dist/src/utils/modelUtils.js.map +1 -1
  102. package/dist/src/utils/operationUtil.d.ts +2 -2
  103. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  104. package/dist/src/utils/operationUtil.js +5 -7
  105. package/dist/src/utils/operationUtil.js.map +1 -1
  106. package/dist/tsconfig.tsbuildinfo +1 -1
  107. package/package.json +23 -23
  108. package/src/contextManager.ts +4 -0
  109. package/src/framework/declaration.ts +100 -0
  110. package/src/framework/hooks/binder.ts +259 -0
  111. package/src/framework/hooks/sdkTypes.ts +101 -0
  112. package/src/framework/reference.ts +9 -0
  113. package/src/framework/refkey.ts +28 -0
  114. package/src/framework/sample.ts +92 -0
  115. package/src/framework/utils/tsmorph-helpers.ts +0 -0
  116. package/src/index.ts +8 -10
  117. package/src/lib.ts +6 -0
  118. package/src/modular/buildClassicalClient.ts +11 -4
  119. package/src/modular/buildClientContext.ts +11 -5
  120. package/src/modular/buildCodeModel.ts +25 -21
  121. package/src/modular/buildOperations.ts +13 -41
  122. package/src/modular/buildRootIndex.ts +1 -1
  123. package/src/modular/buildSerializeUtils.ts +2 -1
  124. package/src/modular/helpers/clientHelpers.ts +25 -1
  125. package/src/modular/helpers/namingHelpers.ts +4 -1
  126. package/src/modular/helpers/operationHelpers.ts +86 -45
  127. package/src/modular/helpers/typeHelpers.ts +6 -1
  128. package/src/modular/modularCodeModel.ts +2 -0
  129. package/src/transform/transformApiVersionInfo.ts +3 -6
  130. package/src/transform/transformHelperFunctionDetails.ts +9 -9
  131. package/src/transform/transformParameters.ts +5 -6
  132. package/src/transform/transformPaths.ts +5 -9
  133. package/src/transform/transformResponses.ts +92 -19
  134. package/src/transform/transformSchemas.ts +6 -5
  135. package/src/transform/transformTelemetryInfo.ts +3 -5
  136. package/src/transform/transfromRLCOptions.ts +5 -10
  137. package/src/utils/modelUtils.ts +49 -39
  138. package/src/utils/operationUtil.ts +6 -12
  139. package/dist/src/modular/serialization/collectionUtils.d.ts +0 -3
  140. package/dist/src/modular/serialization/collectionUtils.d.ts.map +0 -1
  141. package/dist/src/modular/serialization/collectionUtils.js +0 -17
  142. package/dist/src/modular/serialization/collectionUtils.js.map +0 -1
  143. package/dist/src/modular/serialization/index.d.ts +0 -5
  144. package/dist/src/modular/serialization/index.d.ts.map +0 -1
  145. package/dist/src/modular/serialization/index.js +0 -155
  146. package/dist/src/modular/serialization/index.js.map +0 -1
  147. package/dist/src/modular/serialization/operationHelpers.d.ts +0 -37
  148. package/dist/src/modular/serialization/operationHelpers.d.ts.map +0 -1
  149. package/dist/src/modular/serialization/operationHelpers.js +0 -457
  150. package/dist/src/modular/serialization/operationHelpers.js.map +0 -1
  151. package/dist/src/modular/serialization/serializeArray.d.ts +0 -5
  152. package/dist/src/modular/serialization/serializeArray.d.ts.map +0 -1
  153. package/dist/src/modular/serialization/serializeArray.js +0 -33
  154. package/dist/src/modular/serialization/serializeArray.js.map +0 -1
  155. package/dist/src/modular/serialization/serializeDateTime.d.ts +0 -4
  156. package/dist/src/modular/serialization/serializeDateTime.d.ts.map +0 -1
  157. package/dist/src/modular/serialization/serializeDateTime.js +0 -19
  158. package/dist/src/modular/serialization/serializeDateTime.js.map +0 -1
  159. package/dist/src/modular/serialization/serializeHeaders.d.ts +0 -7
  160. package/dist/src/modular/serialization/serializeHeaders.d.ts.map +0 -1
  161. package/dist/src/modular/serialization/serializeHeaders.js +0 -44
  162. package/dist/src/modular/serialization/serializeHeaders.js.map +0 -1
  163. package/dist/src/modular/serialization/serializers.d.ts +0 -17
  164. package/dist/src/modular/serialization/serializers.d.ts.map +0 -1
  165. package/dist/src/modular/serialization/serializers.js +0 -175
  166. package/dist/src/modular/serialization/serializers.js.map +0 -1
  167. package/dist/src/modular/serialization/util.d.ts +0 -27
  168. package/dist/src/modular/serialization/util.d.ts.map +0 -1
  169. package/dist/src/modular/serialization/util.js +0 -115
  170. package/dist/src/modular/serialization/util.js.map +0 -1
  171. package/dist/src/reify/index.d.ts +0 -12
  172. package/dist/src/reify/index.d.ts.map +0 -1
  173. package/dist/src/reify/index.js +0 -22
  174. package/dist/src/reify/index.js.map +0 -1
  175. package/src/modular/serialization/collectionUtils.ts +0 -20
  176. package/src/modular/serialization/index.ts +0 -267
  177. package/src/modular/serialization/operationHelpers.ts +0 -659
  178. package/src/modular/serialization/serializeArray.ts +0 -51
  179. package/src/modular/serialization/serializeDateTime.ts +0 -22
  180. package/src/modular/serialization/serializeHeaders.ts +0 -64
  181. package/src/modular/serialization/serializers.ts +0 -304
  182. package/src/modular/serialization/util.ts +0 -171
  183. package/src/modular/static/karma.conf.cjs +0 -120
  184. package/src/reify/index.ts +0 -41
@@ -1,659 +0,0 @@
1
- import {
2
- addImportToSpecifier,
3
- getResponseBaseName,
4
- getResponseTypeName,
5
- Imports as RuntimeImports,
6
- NameType,
7
- OperationResponse
8
- } from "@azure-tools/rlc-common";
9
- import { SdkContext } from "@azure-tools/typespec-client-generator-core";
10
- import {
11
- FunctionDeclarationStructure,
12
- OptionalKind,
13
- ParameterDeclarationStructure
14
- } from "ts-morph";
15
-
16
- import { toPascalCase } from "../../utils/casingUtils.js";
17
- import {
18
- getDocsFromDescription,
19
- getFixmeForMultilineDocs
20
- } from "../helpers/docsHelpers.js";
21
- import {
22
- getClassicalLayerPrefix,
23
- getOperationName
24
- } from "../helpers/namingHelpers.js";
25
- import { buildType } from "../helpers/typeHelpers.js";
26
- import {
27
- BodyParameter,
28
- Client,
29
- ModularCodeModel,
30
- Operation,
31
- ParameterLocation,
32
- Property,
33
- Type
34
- } from "../modularCodeModel.js";
35
-
36
- import { UsageFlags } from "@typespec/compiler";
37
- import _ from "lodash";
38
- import { Parameter } from "../modularCodeModel.js";
39
- import { serializeType } from "../serialization/serializers.js";
40
- import { SerializerMap, isDefined } from "../serialization/util.js";
41
-
42
- export function getRLCResponseType(rlcResponse?: OperationResponse) {
43
- if (!rlcResponse?.responses) {
44
- return;
45
- }
46
- return rlcResponse?.responses
47
- .map((resp) => {
48
- const baseResponseName = getResponseBaseName(
49
- rlcResponse.operationGroup,
50
- rlcResponse.operationName,
51
- resp.statusCode
52
- );
53
- // Get the information to build the Response Interface
54
- return resp.predefinedName ?? getResponseTypeName(baseResponseName);
55
- })
56
- .join(" | ");
57
- }
58
-
59
- export function getRLCLroLogicalResponse(rlcResponse?: OperationResponse) {
60
- const logicalResponse = (rlcResponse?.responses ?? []).filter(
61
- (r) => r.predefinedName && r.predefinedName.endsWith(`LogicalResponse`)
62
- );
63
- return logicalResponse.length > 0
64
- ? logicalResponse[0]!.predefinedName!
65
- : "any";
66
- }
67
-
68
- export function getSendPrivateFunction(
69
- dpgContext: SdkContext,
70
- operation: Operation,
71
- clientType: string,
72
- serializerMap: SerializerMap | undefined,
73
- runtimeImports: RuntimeImports
74
- ): OptionalKind<FunctionDeclarationStructure> {
75
- const parameters = getOperationSignatureParameters(operation, clientType);
76
- const { name } = getOperationName(operation);
77
- const returnType = `StreamableMethod<${getRLCResponseType(
78
- operation.rlcResponse
79
- )}>`;
80
-
81
- const functionStatement: OptionalKind<FunctionDeclarationStructure> = {
82
- isAsync: false,
83
- isExported: true,
84
- name: `_${name}Send`,
85
- parameters,
86
- returnType
87
- };
88
-
89
- const operationPath = operation.url;
90
- const operationMethod = operation.method.toLowerCase();
91
- const optionalParamName = parameters.filter(
92
- (p) => p.type?.toString().endsWith("OptionalParams")
93
- )[0]?.name;
94
-
95
- const statements: string[] = [];
96
- statements.push(
97
- `return context.path("${operationPath}", ${getPathParameters(
98
- operation
99
- )}).${operationMethod}({...operationOptionsToRequestParameters(${optionalParamName}), ${getRequestParameters(
100
- dpgContext,
101
- operation,
102
- serializerMap!,
103
- runtimeImports
104
- )}}) ${operation.isOverload ? `as ${returnType}` : ``} ;`
105
- );
106
-
107
- return {
108
- ...functionStatement,
109
- statements
110
- };
111
- }
112
-
113
- export function getDeserializePrivateFunction(
114
- dpgContext: SdkContext,
115
- operation: Operation,
116
- needSubClient: boolean,
117
- needUnexpectedHelper: boolean,
118
- runtimeImports: RuntimeImports,
119
- serializerMap: SerializerMap | undefined
120
- ): OptionalKind<FunctionDeclarationStructure> {
121
- const { name } = getOperationName(operation);
122
- const parameters: OptionalKind<ParameterDeclarationStructure>[] = [
123
- {
124
- name: "result",
125
- type: getRLCResponseType(operation.rlcResponse)
126
- }
127
- ];
128
- // TODO: Support LRO + paging operation
129
- // https://github.com/Azure/autorest.typescript/issues/2313
130
- const isLroOnly = isLroOnlyOperation(operation);
131
-
132
- // TODO: Support operation overloads
133
- const response = operation.responses[0]!;
134
- let returnType;
135
- if (isLroOnly && operation.method.toLowerCase() !== "patch") {
136
- returnType = buildLroReturnType(operation);
137
- } else if (response?.type?.type) {
138
- returnType = buildType(
139
- response.type.name,
140
- response.type,
141
- response.type.format
142
- );
143
- } else {
144
- returnType = { name: "", type: "void" };
145
- }
146
-
147
- const functionStatement: OptionalKind<FunctionDeclarationStructure> = {
148
- isAsync: true,
149
- isExported: true,
150
- name: `_${name}Deserialize`,
151
- parameters,
152
- returnType: `Promise<${returnType.type}>`
153
- };
154
- const statements: string[] = [];
155
- if (needUnexpectedHelper) {
156
- statements.push(
157
- `if(${needSubClient ? "UnexpectedHelper." : ""}isUnexpected(result)){`,
158
- `throw createRestError(result);`,
159
- "}"
160
- );
161
- addImportToSpecifier("restClient", runtimeImports, "createRestError");
162
- } else {
163
- const validStatus = [
164
- ...new Set(
165
- operation.responses
166
- .flatMap((r) => r.statusCodes)
167
- .filter((s) => s !== "default")
168
- )
169
- ];
170
-
171
- if (validStatus.length > 0) {
172
- statements.push(
173
- `if(${validStatus
174
- .map((s) => `result.status !== "${s}"`)
175
- .join(" || ")}){`,
176
- `throw createRestError(result);`,
177
- "}"
178
- );
179
- addImportToSpecifier("restClient", runtimeImports, "createRestError");
180
- }
181
- }
182
-
183
- let deserializedType = isLroOnly
184
- ? operation?.lroMetadata?.finalResult
185
- : response?.type ?? "void"; // Is setting void here correct? We are handling the case where no response above but here we are
186
- let hasLroSubPath = operation?.lroMetadata?.finalResultPath !== undefined;
187
- let deserializedRoot = hasLroSubPath
188
- ? `result.body.${operation?.lroMetadata?.finalResultPath}`
189
- : "result.body";
190
- // TODO: Hard-coded for LRO PATCH case for now
191
- // https://github.com/Azure/autorest.typescript/issues/2314
192
- if (isLroOnly && operation.method.toLowerCase() === "patch") {
193
- deserializedType = response.type;
194
- hasLroSubPath = false;
195
- deserializedRoot = "result.body";
196
- }
197
- if (isLroOnly) {
198
- const lroLogicalResponse = getRLCLroLogicalResponse(operation.rlcResponse);
199
- statements.push(`result = result as ${lroLogicalResponse};`);
200
- if (hasLroSubPath) {
201
- statements.push(
202
- `if(${deserializedRoot.split(".").join("?.")} === undefined) {
203
- throw createRestError(\`Expected a result in the response at position "${deserializedRoot}"\`, result);
204
- }
205
- `
206
- );
207
- }
208
- }
209
-
210
- if (isDefined(deserializedType?.tcgcType)) {
211
- statements.push(
212
- `return ${deserializeResponseValue(
213
- dpgContext,
214
- serializerMap!,
215
- deserializedType,
216
- deserializedRoot,
217
- runtimeImports
218
- )}`
219
- );
220
- } else if (returnType.type === "void") {
221
- statements.push("return");
222
- } else {
223
- statements.push(`return result.body`);
224
- }
225
- return {
226
- ...functionStatement,
227
- statements
228
- };
229
- }
230
-
231
- export function getOperationSignatureParameters(
232
- operation: Operation,
233
- clientType: string
234
- ): OptionalKind<ParameterDeclarationStructure>[] {
235
- const optionsType = getOperationOptionsName(operation, true);
236
- const parameters: Map<
237
- string,
238
- OptionalKind<ParameterDeclarationStructure>
239
- > = new Map();
240
-
241
- operation.parameters
242
- .filter(
243
- (p) =>
244
- p.implementation === "Method" &&
245
- p.type.type !== "constant" &&
246
- p.clientDefaultValue === undefined &&
247
- !p.optional
248
- )
249
- .map((p) => buildType(p.clientName, p.type, p.format))
250
- .forEach((p) => {
251
- parameters.set(p.name, p);
252
- });
253
-
254
- if (operation.bodyParameter) {
255
- parameters.set(operation.bodyParameter?.clientName, {
256
- hasQuestionToken: operation.bodyParameter.optional,
257
- ...buildType(
258
- operation.bodyParameter.clientName,
259
- operation.bodyParameter.type,
260
- operation.bodyParameter.type.format
261
- )
262
- });
263
- }
264
- // Add context as the first parameter
265
- const contextParam = { name: "context", type: clientType };
266
-
267
- // Add the options parameter
268
- const optionsParam = {
269
- name: parameters.has("options") ? "optionalParams" : "options",
270
- type: optionsType,
271
- initializer: "{ requestOptions: {} }"
272
- };
273
-
274
- const finalParameters = [contextParam, ...parameters.values(), optionsParam];
275
-
276
- return finalParameters;
277
- }
278
-
279
- /**
280
- * This operation builds and returns the function declaration for an operation.
281
- */
282
- export function getOperationFunction(
283
- operation: Operation,
284
- clientType: string
285
- ): OptionalKind<FunctionDeclarationStructure> & { propertyName?: string } {
286
- if (isPagingOnlyOperation(operation)) {
287
- // Case 1: paging-only operation
288
- return getPagingOnlyOperationFunction(operation, clientType);
289
- } else if (isLroOnlyOperation(operation)) {
290
- // Case 2: lro-only operation
291
- return getLroOnlyOperationFunction(operation, clientType);
292
- } else if (isLroAndPagingOperation(operation)) {
293
- // Case 3: both paging + lro operation is not supported yet so handle them as normal operation and customization may be needed
294
- // https://github.com/Azure/autorest.typescript/issues/2313
295
- }
296
-
297
- // Extract required parameters
298
- const parameters: OptionalKind<ParameterDeclarationStructure>[] =
299
- getOperationSignatureParameters(operation, clientType);
300
- // TODO: Support operation overloads
301
- const response = operation.responses[0]!;
302
- let returnType = { name: "", type: "void" };
303
- if (response.type?.type) {
304
- const type =
305
- extractPagingType(response.type, operation.itemName) ?? response.type;
306
- returnType = buildType(type.name, type, type.format);
307
- }
308
- const { name, fixme = [] } = getOperationName(operation);
309
- const functionStatement = {
310
- docs: [
311
- ...getDocsFromDescription(operation.description),
312
- ...getFixmeForMultilineDocs(fixme)
313
- ],
314
- isAsync: true,
315
- isExported: true,
316
- name,
317
- propertyName: operation.name,
318
- parameters,
319
- returnType: `Promise<${returnType.type}>`
320
- };
321
-
322
- const statements: string[] = [];
323
- statements.push(
324
- `const result = await _${name}Send(${parameters
325
- .map((p) => p.name)
326
- .join(", ")});`
327
- );
328
- statements.push(`return _${name}Deserialize(result);`);
329
-
330
- return {
331
- ...functionStatement,
332
- statements
333
- };
334
- }
335
-
336
- function getLroOnlyOperationFunction(operation: Operation, clientType: string) {
337
- // Extract required parameters
338
- const parameters: OptionalKind<ParameterDeclarationStructure>[] =
339
- getOperationSignatureParameters(operation, clientType);
340
- const returnType = buildLroReturnType(operation);
341
- const { name, fixme = [] } = getOperationName(operation);
342
- const functionStatement = {
343
- docs: [
344
- ...getDocsFromDescription(operation.description),
345
- ...getFixmeForMultilineDocs(fixme)
346
- ],
347
- isAsync: false,
348
- isExported: true,
349
- name,
350
- propertyName: operation.name,
351
- parameters,
352
- returnType: `PollerLike<OperationState<${returnType.type}>, ${returnType.type}>`
353
- };
354
-
355
- const statements: string[] = [];
356
- statements.push(`
357
- return getLongRunningPoller(context, _${name}Deserialize, {
358
- updateIntervalInMs: options?.updateIntervalInMs,
359
- abortSignal: options?.abortSignal,
360
- getInitialResponse: () => _${name}Send(${parameters
361
- .map((p) => p.name)
362
- .join(", ")})
363
- }) as PollerLike<OperationState<${returnType.type}>, ${returnType.type}>;
364
- `);
365
-
366
- return {
367
- ...functionStatement,
368
- statements
369
- };
370
- }
371
-
372
- export function buildLroReturnType(operation: Operation) {
373
- const metadata = operation.lroMetadata;
374
- if (metadata !== undefined && metadata.finalResult !== undefined) {
375
- const type = metadata.finalResult;
376
- return buildType(type.name, type, type.format);
377
- }
378
- return { name: "", type: "void" };
379
- }
380
-
381
- export function getPagingOnlyOperationFunction(
382
- operation: Operation,
383
- clientType: string
384
- ) {
385
- // Extract required parameters
386
- const parameters: OptionalKind<ParameterDeclarationStructure>[] =
387
- getOperationSignatureParameters(operation, clientType);
388
-
389
- // TODO: Support operation overloads
390
- const response = operation.responses[0];
391
- let returnType = { name: "", type: "void" };
392
- if (response?.type?.type) {
393
- const type =
394
- extractPagingType(response.type, operation.itemName) ?? response.type;
395
- returnType = buildType(type.name, type, type.format);
396
- }
397
- const { name, fixme = [] } = getOperationName(operation);
398
- const functionStatement = {
399
- docs: [
400
- ...getDocsFromDescription(operation.description),
401
- ...getFixmeForMultilineDocs(fixme)
402
- ],
403
- isAsync: false,
404
- isExported: true,
405
- name,
406
- propertyName: operation.name,
407
- parameters,
408
- returnType: `PagedAsyncIterableIterator<${returnType.type}>`
409
- };
410
-
411
- const statements: string[] = [];
412
- const options = [];
413
- if (operation.itemName) {
414
- options.push(`itemName: "${operation.itemName}"`);
415
- }
416
- if (operation.continuationTokenName) {
417
- options.push(`nextLinkName: "${operation.continuationTokenName}"`);
418
- }
419
- statements.push(
420
- `return buildPagedAsyncIterator(
421
- context,
422
- () => _${name}Send(${parameters.map((p) => p.name).join(", ")}),
423
- _${name}Deserialize,
424
- ${options.length > 0 ? `{${options.join(", ")}}` : ``}
425
- );`
426
- );
427
-
428
- return {
429
- ...functionStatement,
430
- statements
431
- };
432
- }
433
-
434
- function extractPagingType(type: Type, itemName?: string): Type | undefined {
435
- if (!itemName) {
436
- return undefined;
437
- }
438
- const prop = (type.properties ?? [])
439
- ?.filter((prop) => prop.restApiName === itemName)
440
- .map((prop) => prop.type);
441
- if (prop.length === 0) {
442
- return undefined;
443
- }
444
- return prop[0]?.type === "list" && prop[0].elementType
445
- ? prop[0].elementType
446
- : undefined;
447
- }
448
- export function getOperationOptionsName(
449
- operation: Operation,
450
- includeGroupName = false
451
- ) {
452
- const prefix =
453
- includeGroupName && operation.name.indexOf("_") === -1
454
- ? getClassicalLayerPrefix(operation, NameType.Interface)
455
- : "";
456
- const optionName = `${prefix}${toPascalCase(operation.name)}OptionalParams`;
457
- return optionName;
458
- }
459
-
460
- /**
461
- * This function build the request parameters that we will provide to the
462
- * RLC internally. This will translate High Level parameters into the RLC ones.
463
- * Figuring out what goes in headers, body, path and qsp.
464
- */
465
- function getRequestParameters(
466
- dpgContext: SdkContext,
467
- operation: Operation,
468
- serializerMap: SerializerMap,
469
- runtimeImports: RuntimeImports
470
- ): string {
471
- if (!operation.parameters) {
472
- return "";
473
- }
474
- const operationParameters = operation.parameters.filter(
475
- (p) => p.implementation !== "Client" && !isContentType(p)
476
- );
477
-
478
- const contentTypeParameter = operation.parameters.find(isContentType);
479
-
480
- const parametersImplementation: Partial<
481
- Record<ParameterLocation, Parameter[] | BodyParameter[]>
482
- > = _.groupBy(operationParameters, (p) => p.location);
483
-
484
- parametersImplementation["body"] = isDefined(operation.bodyParameter)
485
- ? [operation.bodyParameter]
486
- : parametersImplementation["body"];
487
-
488
- const params = [
489
- ...(contentTypeParameter
490
- ? [getContentTypeValue(contentTypeParameter)]
491
- : []),
492
- ...[
493
- (
494
- [
495
- ["headers", "header"],
496
- ["queryParameters", "query"],
497
- ["body", "body"]
498
- ] as const
499
- )
500
- .map(
501
- ([id, location]) => [id, parametersImplementation[location]] as const
502
- )
503
- .filter(([_, paramList]) => paramList?.length)
504
- .flatMap(([id, paramList]) =>
505
- paramList!.map((i) => {
506
- const initializer = serializeType({
507
- dpgContext,
508
- functionType: UsageFlags.Input,
509
- serializerMap,
510
- type: i.tcgcType!,
511
- valueExpr:
512
- id === "body" ? i.clientName : `options?.${i.clientName}`,
513
- importCallback: (importType, importedName) =>
514
- addImportToSpecifier(importType, runtimeImports, importedName)
515
- });
516
- return `${id}: ${initializer}`;
517
- })
518
- )
519
- ]
520
- ];
521
-
522
- return params.join(",\n");
523
- }
524
-
525
- function isContentType(param: Parameter): boolean {
526
- return (
527
- param.location === "header" &&
528
- param.restApiName.toLowerCase() === "content-type"
529
- );
530
- }
531
-
532
- function getContentTypeValue(param: Parameter | Property) {
533
- const defaultValue =
534
- param.clientDefaultValue ?? param.type.clientDefaultValue;
535
-
536
- if (defaultValue) {
537
- return `contentType: options.${param.clientName} as any ?? "${defaultValue}"`;
538
- } else {
539
- return `contentType: ${
540
- !param.optional
541
- ? "contentType"
542
- : "options." + param.clientName + " as any"
543
- }`;
544
- }
545
- }
546
-
547
- /**
548
- * Builds the assignment for when a property or parameter has a default value
549
- */
550
- function getDefaultValue(param: Parameter | Property) {
551
- return (param.clientDefaultValue ?? param.type.clientDefaultValue) !==
552
- undefined
553
- ? `${param.optional ? "??" : ""} "${
554
- param.clientDefaultValue ?? param.type.clientDefaultValue
555
- }"`
556
- : "";
557
- }
558
-
559
- /**
560
- * Extracts the path parameters
561
- */
562
- function getPathParameters(operation: Operation) {
563
- if (!operation.parameters) {
564
- return "";
565
- }
566
-
567
- let pathParams = "";
568
- for (const param of operation.parameters) {
569
- if (param.location === "path") {
570
- if (!param.optional) {
571
- pathParams += `${pathParams !== "" ? "," : ""} ${param.clientName}`;
572
- continue;
573
- }
574
-
575
- const defaultValue = getDefaultValue(param);
576
-
577
- pathParams += `${pathParams !== "" ? "," : ""} options.${
578
- param.clientName
579
- }`;
580
-
581
- if (defaultValue) {
582
- pathParams += ` ?? "${defaultValue}"`;
583
- }
584
- }
585
- }
586
-
587
- return pathParams;
588
- }
589
-
590
- /**
591
- * This function helps converting strings into JS complex types recursively.
592
- * We need to drill down into Array elements to make sure that the element type is
593
- * deserialized correctly
594
- */
595
- function deserializeResponseValue(
596
- dpgContext: SdkContext,
597
- serializerMap: SerializerMap,
598
- type: Type,
599
- restValue: string,
600
- runtimeImports: RuntimeImports
601
- ): string {
602
- return serializeType({
603
- dpgContext,
604
- functionType: UsageFlags.Output,
605
- serializerMap,
606
- type: type.tcgcType!,
607
- valueExpr: restValue,
608
- importCallback: (importType, importedName) =>
609
- addImportToSpecifier(importType, runtimeImports, importedName)
610
- });
611
- }
612
-
613
- function isLroAndPagingOperation(op: Operation): boolean {
614
- return op.discriminator === "lropaging";
615
- }
616
-
617
- export function isLroOnlyOperation(op: Operation): boolean {
618
- return op.discriminator === "lro";
619
- }
620
-
621
- export function hasPagingOnlyOperation(
622
- client: Client,
623
- needRLC?: boolean
624
- ): boolean;
625
- export function hasPagingOnlyOperation(
626
- codeModel: ModularCodeModel,
627
- needRLC?: boolean
628
- ): boolean;
629
- export function hasPagingOnlyOperation(
630
- clientOrCodeModel: Client | ModularCodeModel,
631
- needRLC: boolean = false
632
- ): boolean {
633
- let clients: Client[] = [];
634
- if ((clientOrCodeModel as any)?.operationGroups) {
635
- clients = [clientOrCodeModel as Client];
636
- } else if ((clientOrCodeModel as any)?.clients) {
637
- clients = (clientOrCodeModel as ModularCodeModel).clients;
638
- }
639
- return clients.some(
640
- (c) =>
641
- (needRLC ? c.rlcHelperDetails.hasPaging : false) ||
642
- (c.operationGroups ?? []).some((og) =>
643
- (og.operations ?? []).some(isPagingOnlyOperation)
644
- )
645
- );
646
- }
647
-
648
- export function isPagingOnlyOperation(op: Operation): boolean {
649
- return op.discriminator === "paging";
650
- }
651
-
652
- export function getAllAncestors(type: Type): Type[] {
653
- const ancestors: Type[] = [];
654
- type?.parents?.forEach((p) => {
655
- ancestors.push(p);
656
- ancestors.push(...getAllAncestors(p));
657
- });
658
- return ancestors;
659
- }
@@ -1,51 +0,0 @@
1
- import {
2
- SdkArrayType,
3
- SdkType
4
- } from "@azure-tools/typespec-client-generator-core";
5
- import { UsageFlags } from "@typespec/compiler";
6
- import { SerializeTypeOptions, serializeType } from "./serializers.js";
7
- import { SerializerOutput, getModularTypeId, getRLCTypeId } from "./util.js";
8
-
9
- export function serializeArray(
10
- options: SerializeTypeOptions<SdkArrayType>
11
- ): SerializerOutput {
12
- const { dpgContext, functionType, serializerMap, type, valueExpr } = options;
13
- const valueType = type.valueType as SdkType & { name?: string };
14
- const mapParameterId = "e";
15
-
16
- const elementTypeName =
17
- functionType === UsageFlags.Input
18
- ? getModularTypeId(valueType)
19
- : getRLCTypeId(dpgContext, valueType);
20
-
21
- const serializedChildExpr = serializeType({
22
- ...options,
23
- type: valueType,
24
- valueExpr: mapParameterId
25
- });
26
-
27
- if (serializedChildExpr === mapParameterId) {
28
- // mapping over identity function, so map is unnecessary
29
- // arr.map((e) => e) -> arr
30
- return valueExpr;
31
- }
32
-
33
- // arr.map((e) => f(e)) -> arr.map(f)
34
- const unaryFunctionInvocation =
35
- /(?<functionName>\w+)\((?<childArgExpr>\w+)\)/;
36
-
37
- const { functionName, childArgExpr } =
38
- serializedChildExpr.match(unaryFunctionInvocation)?.groups ?? {};
39
-
40
- const mapArg =
41
- elementTypeName && serializerMap?.[elementTypeName]
42
- ? mapParameterId
43
- : `${mapParameterId}: ${elementTypeName}`;
44
-
45
- const mapFunction =
46
- childArgExpr === mapParameterId
47
- ? functionName
48
- : `(${mapArg})=>(${serializedChildExpr})`;
49
-
50
- return `${valueExpr}.map(${mapFunction})`;
51
- }