@azure-tools/typespec-ts 0.55.0-dev.8 → 0.55.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 (192) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +1 -77
  3. package/dist/src/framework/hooks/sdk-types.d.ts +3 -2
  4. package/dist/src/framework/hooks/sdk-types.d.ts.map +1 -1
  5. package/dist/src/framework/hooks/sdk-types.js +3 -2
  6. package/dist/src/framework/hooks/sdk-types.js.map +1 -1
  7. package/dist/src/index.d.ts.map +1 -1
  8. package/dist/src/index.js +24 -80
  9. package/dist/src/index.js.map +1 -1
  10. package/dist/src/lib.d.ts +2 -12
  11. package/dist/src/lib.d.ts.map +1 -1
  12. package/dist/src/lib.js +0 -65
  13. package/dist/src/lib.js.map +1 -1
  14. package/dist/src/modular/build-classical-client.js +2 -2
  15. package/dist/src/modular/build-classical-client.js.map +1 -1
  16. package/dist/src/modular/emit-models.d.ts.map +1 -1
  17. package/dist/src/modular/emit-models.js +19 -5
  18. package/dist/src/modular/emit-models.js.map +1 -1
  19. package/dist/src/modular/emit-samples.js +92 -19
  20. package/dist/src/modular/emit-samples.js.map +1 -1
  21. package/dist/src/modular/serialization/serialize-utils.js +2 -2
  22. package/dist/src/modular/serialization/serialize-utils.js.map +1 -1
  23. package/dist/src/rlc-common/helpers/name-constructors.d.ts.map +1 -1
  24. package/dist/src/rlc-common/helpers/name-constructors.js +1 -7
  25. package/dist/src/rlc-common/helpers/name-constructors.js.map +1 -1
  26. package/dist/src/rlc-common/index.d.ts +0 -16
  27. package/dist/src/rlc-common/index.d.ts.map +1 -1
  28. package/dist/src/rlc-common/index.js +0 -16
  29. package/dist/src/rlc-common/index.js.map +1 -1
  30. package/dist/src/rlc-common/interfaces.d.ts +0 -10
  31. package/dist/src/rlc-common/interfaces.d.ts.map +1 -1
  32. package/dist/src/rlc-common/interfaces.js.map +1 -1
  33. package/dist/src/rlc-common/metadata/build-package-file.d.ts.map +1 -1
  34. package/dist/src/rlc-common/metadata/build-package-file.js +0 -12
  35. package/dist/src/rlc-common/metadata/build-package-file.js.map +1 -1
  36. package/dist/src/rlc-common/metadata/build-readme-file.d.ts.map +1 -1
  37. package/dist/src/rlc-common/metadata/build-readme-file.js +4 -89
  38. package/dist/src/rlc-common/metadata/build-readme-file.js.map +1 -1
  39. package/dist/src/rlc-common/metadata/package-json/build-azure-monorepo-package.d.ts +0 -1
  40. package/dist/src/rlc-common/metadata/package-json/build-azure-monorepo-package.d.ts.map +1 -1
  41. package/dist/src/rlc-common/metadata/package-json/build-azure-monorepo-package.js +2 -2
  42. package/dist/src/rlc-common/metadata/package-json/build-azure-monorepo-package.js.map +1 -1
  43. package/dist/src/rlc-common/metadata/package-json/package-common.d.ts +0 -1
  44. package/dist/src/rlc-common/metadata/package-json/package-common.d.ts.map +1 -1
  45. package/dist/src/rlc-common/metadata/package-json/package-common.js.map +1 -1
  46. package/dist/src/rlc-common/test/build-snippets.d.ts.map +1 -1
  47. package/dist/src/rlc-common/test/build-snippets.js +0 -1
  48. package/dist/src/rlc-common/test/build-snippets.js.map +1 -1
  49. package/dist/src/rlc-common/test/template.d.ts +1 -1
  50. package/dist/src/rlc-common/test/template.d.ts.map +1 -1
  51. package/dist/src/rlc-common/test/template.js +0 -4
  52. package/dist/src/rlc-common/test/template.js.map +1 -1
  53. package/dist/src/transform/transform-schemas.js +1 -1
  54. package/dist/src/transform/transform-schemas.js.map +1 -1
  55. package/dist/src/transform/transform.d.ts.map +1 -1
  56. package/dist/src/transform/transform.js +5 -11
  57. package/dist/src/transform/transform.js.map +1 -1
  58. package/dist/src/transform/transfrom-rlc-options.d.ts +2 -2
  59. package/dist/src/transform/transfrom-rlc-options.d.ts.map +1 -1
  60. package/dist/src/transform/transfrom-rlc-options.js +19 -39
  61. package/dist/src/transform/transfrom-rlc-options.js.map +1 -1
  62. package/dist/src/utils/client-utils.d.ts +1 -1
  63. package/dist/src/utils/client-utils.d.ts.map +1 -1
  64. package/dist/src/utils/client-utils.js +4 -5
  65. package/dist/src/utils/client-utils.js.map +1 -1
  66. package/dist/src/utils/emit-util.d.ts +0 -1
  67. package/dist/src/utils/emit-util.d.ts.map +1 -1
  68. package/dist/src/utils/emit-util.js +0 -13
  69. package/dist/src/utils/emit-util.js.map +1 -1
  70. package/dist/src/utils/model-utils.d.ts +1 -1
  71. package/dist/src/utils/model-utils.d.ts.map +1 -1
  72. package/dist/src/utils/model-utils.js +4 -11
  73. package/dist/src/utils/model-utils.js.map +1 -1
  74. package/dist/tsconfig.tsbuildinfo +1 -1
  75. package/package.json +40 -44
  76. package/src/framework/hooks/sdk-types.ts +3 -2
  77. package/src/index.ts +27 -105
  78. package/src/lib.ts +1 -77
  79. package/src/modular/build-classical-client.ts +2 -2
  80. package/src/modular/emit-models.ts +20 -5
  81. package/src/modular/emit-samples.ts +119 -38
  82. package/src/modular/serialization/serialize-utils.ts +2 -2
  83. package/src/rlc-common/helpers/name-constructors.ts +1 -8
  84. package/src/rlc-common/index.ts +0 -16
  85. package/src/rlc-common/interfaces.ts +0 -11
  86. package/src/rlc-common/metadata/build-package-file.ts +0 -13
  87. package/src/rlc-common/metadata/build-readme-file.ts +4 -99
  88. package/src/rlc-common/metadata/package-json/build-azure-monorepo-package.ts +2 -3
  89. package/src/rlc-common/metadata/package-json/package-common.ts +0 -1
  90. package/src/rlc-common/test/build-snippets.ts +0 -1
  91. package/src/rlc-common/test/template.ts +0 -4
  92. package/src/transform/transform-schemas.ts +1 -1
  93. package/src/transform/transform.ts +4 -14
  94. package/src/transform/transfrom-rlc-options.ts +19 -63
  95. package/src/utils/client-utils.ts +4 -5
  96. package/src/utils/emit-util.ts +1 -14
  97. package/src/utils/model-utils.ts +4 -17
  98. package/dist/src/rlc-common/build-client-definitions.d.ts +0 -6
  99. package/dist/src/rlc-common/build-client-definitions.d.ts.map +0 -1
  100. package/dist/src/rlc-common/build-client-definitions.js +0 -157
  101. package/dist/src/rlc-common/build-client-definitions.js.map +0 -1
  102. package/dist/src/rlc-common/build-client.d.ts +0 -9
  103. package/dist/src/rlc-common/build-client.d.ts.map +0 -1
  104. package/dist/src/rlc-common/build-client.js +0 -375
  105. package/dist/src/rlc-common/build-client.js.map +0 -1
  106. package/dist/src/rlc-common/build-index-file.d.ts +0 -6
  107. package/dist/src/rlc-common/build-index-file.d.ts.map +0 -1
  108. package/dist/src/rlc-common/build-index-file.js +0 -180
  109. package/dist/src/rlc-common/build-index-file.js.map +0 -1
  110. package/dist/src/rlc-common/build-is-unexpected-helper.d.ts +0 -6
  111. package/dist/src/rlc-common/build-is-unexpected-helper.d.ts.map +0 -1
  112. package/dist/src/rlc-common/build-is-unexpected-helper.js +0 -219
  113. package/dist/src/rlc-common/build-is-unexpected-helper.js.map +0 -1
  114. package/dist/src/rlc-common/build-logger.d.ts +0 -6
  115. package/dist/src/rlc-common/build-logger.d.ts.map +0 -1
  116. package/dist/src/rlc-common/build-logger.js +0 -23
  117. package/dist/src/rlc-common/build-logger.js.map +0 -1
  118. package/dist/src/rlc-common/build-method-shortcuts.d.ts +0 -5
  119. package/dist/src/rlc-common/build-method-shortcuts.d.ts.map +0 -1
  120. package/dist/src/rlc-common/build-method-shortcuts.js +0 -54
  121. package/dist/src/rlc-common/build-method-shortcuts.js.map +0 -1
  122. package/dist/src/rlc-common/build-object-types.d.ts +0 -29
  123. package/dist/src/rlc-common/build-object-types.d.ts.map +0 -1
  124. package/dist/src/rlc-common/build-object-types.js +0 -410
  125. package/dist/src/rlc-common/build-object-types.js.map +0 -1
  126. package/dist/src/rlc-common/build-paginate-helper.d.ts +0 -6
  127. package/dist/src/rlc-common/build-paginate-helper.d.ts.map +0 -1
  128. package/dist/src/rlc-common/build-paginate-helper.js +0 -27
  129. package/dist/src/rlc-common/build-paginate-helper.js.map +0 -1
  130. package/dist/src/rlc-common/build-parameter-types.d.ts +0 -14
  131. package/dist/src/rlc-common/build-parameter-types.d.ts.map +0 -1
  132. package/dist/src/rlc-common/build-parameter-types.js +0 -338
  133. package/dist/src/rlc-common/build-parameter-types.js.map +0 -1
  134. package/dist/src/rlc-common/build-polling-helper.d.ts +0 -6
  135. package/dist/src/rlc-common/build-polling-helper.d.ts.map +0 -1
  136. package/dist/src/rlc-common/build-polling-helper.js +0 -59
  137. package/dist/src/rlc-common/build-polling-helper.js.map +0 -1
  138. package/dist/src/rlc-common/build-response-types.d.ts +0 -6
  139. package/dist/src/rlc-common/build-response-types.d.ts.map +0 -1
  140. package/dist/src/rlc-common/build-response-types.js +0 -140
  141. package/dist/src/rlc-common/build-response-types.js.map +0 -1
  142. package/dist/src/rlc-common/build-samples.d.ts +0 -3
  143. package/dist/src/rlc-common/build-samples.d.ts.map +0 -1
  144. package/dist/src/rlc-common/build-samples.js +0 -30
  145. package/dist/src/rlc-common/build-samples.js.map +0 -1
  146. package/dist/src/rlc-common/build-schema-type.d.ts +0 -20
  147. package/dist/src/rlc-common/build-schema-type.d.ts.map +0 -1
  148. package/dist/src/rlc-common/build-schema-type.js +0 -64
  149. package/dist/src/rlc-common/build-schema-type.js.map +0 -1
  150. package/dist/src/rlc-common/build-serialize-helper.d.ts +0 -6
  151. package/dist/src/rlc-common/build-serialize-helper.d.ts.map +0 -1
  152. package/dist/src/rlc-common/build-serialize-helper.js +0 -36
  153. package/dist/src/rlc-common/build-serialize-helper.js.map +0 -1
  154. package/dist/src/rlc-common/build-top-level-index-file.d.ts +0 -6
  155. package/dist/src/rlc-common/build-top-level-index-file.d.ts.map +0 -1
  156. package/dist/src/rlc-common/build-top-level-index-file.js +0 -44
  157. package/dist/src/rlc-common/build-top-level-index-file.js.map +0 -1
  158. package/dist/src/rlc-common/helpers/path-utils.d.ts +0 -2
  159. package/dist/src/rlc-common/helpers/path-utils.d.ts.map +0 -1
  160. package/dist/src/rlc-common/helpers/path-utils.js +0 -9
  161. package/dist/src/rlc-common/helpers/path-utils.js.map +0 -1
  162. package/dist/src/rlc-common/helpers/shortcut-methods.d.ts +0 -4
  163. package/dist/src/rlc-common/helpers/shortcut-methods.d.ts.map +0 -1
  164. package/dist/src/rlc-common/helpers/shortcut-methods.js +0 -49
  165. package/dist/src/rlc-common/helpers/shortcut-methods.js.map +0 -1
  166. package/dist/src/rlc-common/helpers/value-generation-util.d.ts +0 -12
  167. package/dist/src/rlc-common/helpers/value-generation-util.d.ts.map +0 -1
  168. package/dist/src/rlc-common/helpers/value-generation-util.js +0 -161
  169. package/dist/src/rlc-common/helpers/value-generation-util.js.map +0 -1
  170. package/dist/src/rlc-common/transform-sample-groups.d.ts +0 -9
  171. package/dist/src/rlc-common/transform-sample-groups.d.ts.map +0 -1
  172. package/dist/src/rlc-common/transform-sample-groups.js +0 -298
  173. package/dist/src/rlc-common/transform-sample-groups.js.map +0 -1
  174. package/src/rlc-common/build-client-definitions.ts +0 -226
  175. package/src/rlc-common/build-client.ts +0 -463
  176. package/src/rlc-common/build-index-file.ts +0 -220
  177. package/src/rlc-common/build-is-unexpected-helper.ts +0 -241
  178. package/src/rlc-common/build-logger.ts +0 -29
  179. package/src/rlc-common/build-method-shortcuts.ts +0 -71
  180. package/src/rlc-common/build-object-types.ts +0 -591
  181. package/src/rlc-common/build-paginate-helper.ts +0 -31
  182. package/src/rlc-common/build-parameter-types.ts +0 -460
  183. package/src/rlc-common/build-polling-helper.ts +0 -80
  184. package/src/rlc-common/build-response-types.ts +0 -170
  185. package/src/rlc-common/build-samples.ts +0 -32
  186. package/src/rlc-common/build-schema-type.ts +0 -79
  187. package/src/rlc-common/build-serialize-helper.ts +0 -49
  188. package/src/rlc-common/build-top-level-index-file.ts +0 -51
  189. package/src/rlc-common/helpers/path-utils.ts +0 -8
  190. package/src/rlc-common/helpers/shortcut-methods.ts +0 -58
  191. package/src/rlc-common/helpers/value-generation-util.ts +0 -234
  192. package/src/rlc-common/transform-sample-groups.ts +0 -383
@@ -1,460 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
-
4
- import { joinPaths } from "@typespec/compiler";
5
- import {
6
- InterfaceDeclarationStructure,
7
- Project,
8
- PropertySignatureStructure,
9
- SourceFile,
10
- StructureKind,
11
- } from "ts-morph";
12
- import { getObjectInterfaceDeclaration } from "./build-object-types.js";
13
- import { getImportSpecifier } from "./helpers/imports-util.js";
14
- import { getParameterBaseName, getParameterTypeName } from "./helpers/name-constructors.js";
15
- import { getGeneratedWrapperTypes } from "./helpers/operation-helpers.js";
16
- import {
17
- ObjectSchema,
18
- ParameterMetadata,
19
- ParameterMetadatas,
20
- RLCModel,
21
- Schema,
22
- SchemaContext,
23
- } from "./interfaces.js";
24
-
25
- export function buildParameterTypes(model: RLCModel) {
26
- const project = new Project({ useInMemoryFileSystem: true });
27
- const srcPath = model.srcPath;
28
- const filePath = joinPaths(srcPath, `parameters.ts`);
29
- const partialBodyTypeNames = new Set<string>();
30
- const parametersFile = project.createSourceFile(filePath, undefined, {
31
- overwrite: true,
32
- });
33
- let hasHeaders = false;
34
-
35
- if (!model.parameters) {
36
- return;
37
- }
38
- for (const requestParameter of model.parameters) {
39
- const baseParameterName = getParameterBaseName(
40
- requestParameter.operationGroup,
41
- requestParameter.operationName,
42
- );
43
- const requestCount = requestParameter?.parameters?.length ?? 0;
44
- const topParamName = getParameterTypeName(baseParameterName);
45
- const subParamNames: string[] = [];
46
-
47
- // We need to loop the requests. An operation with multiple requests means that
48
- // the operation can get different values for content-type and each value may
49
- // have a different type associated to it.
50
- for (let i = 0; i < requestCount; i++) {
51
- const parameter = requestParameter.parameters[i];
52
- if (!parameter) {
53
- continue;
54
- }
55
- const internalReferences = new Set<string>();
56
- // In case we have more than one request to model we need to add a suffix to differentiate
57
- const nameSuffix = i > 0 ? `${i}` : "";
58
- const parameterInterfaceName =
59
- requestCount > 1 ? `${baseParameterName}RequestParameters${nameSuffix}` : topParamName;
60
- const queryParameterDefinitions = buildQueryParameterDefinition(
61
- parameter,
62
- baseParameterName,
63
- internalReferences,
64
- i,
65
- );
66
- const pathParameterDefinitions = buildPathParameterDefinitions(parameter);
67
-
68
- const headerParameterDefinitions = buildHeaderParameterDefinitions(
69
- parameter,
70
- baseParameterName,
71
- parametersFile,
72
- internalReferences,
73
- i,
74
- );
75
-
76
- const contentTypeParameterDefinition = buildContentTypeParametersDefinition(
77
- parameter,
78
- baseParameterName,
79
- internalReferences,
80
- i,
81
- );
82
-
83
- const bodyParameterDefinition = buildBodyParametersDefinition(
84
- parameter,
85
- baseParameterName,
86
- internalReferences,
87
- i,
88
- );
89
-
90
- const bodyTypeAlias = buildBodyTypeAlias(parameter, partialBodyTypeNames);
91
- if (bodyTypeAlias) {
92
- parametersFile.addTypeAlias(bodyTypeAlias);
93
- }
94
-
95
- // Add interfaces for body and query parameters
96
- parametersFile.addInterfaces([
97
- ...(bodyParameterDefinition ?? []),
98
- ...(queryParameterDefinitions ?? []),
99
- ...(pathParameterDefinitions ?? []),
100
- ...(headerParameterDefinitions ? [headerParameterDefinitions] : []),
101
- ...(contentTypeParameterDefinition ? [contentTypeParameterDefinition] : []),
102
- ]);
103
-
104
- // Add Operation parameters type alias which is composed of the types we generated above
105
- // plus the common type RequestParameters
106
- parametersFile.addTypeAlias({
107
- name: parameterInterfaceName,
108
- isExported: true,
109
- type: [...internalReferences, "RequestParameters"].join(" & "),
110
- });
111
-
112
- subParamNames.push(parameterInterfaceName);
113
-
114
- if (headerParameterDefinitions !== undefined) {
115
- hasHeaders = true;
116
- }
117
- }
118
- // Add Operation parameters type alias which is composed of the types we generated above
119
- // plus the common type RequestParameters
120
- if (requestCount > 1) {
121
- parametersFile.addTypeAlias({
122
- name: topParamName,
123
- isExported: true,
124
- type: [...subParamNames].join(" | "),
125
- });
126
- }
127
- }
128
-
129
- if (hasHeaders) {
130
- parametersFile.addImportDeclarations([
131
- {
132
- isTypeOnly: true,
133
- namedImports: ["RawHttpHeadersInput"],
134
- moduleSpecifier: getImportSpecifier("restPipeline", model.importInfo.runtimeImports),
135
- },
136
- ]);
137
- }
138
- parametersFile.addImportDeclarations([
139
- {
140
- isTypeOnly: true,
141
- namedImports: ["RequestParameters"],
142
- moduleSpecifier: getImportSpecifier("restClient", model.importInfo.runtimeImports),
143
- },
144
- ]);
145
- if ((model.importInfo.internalImports?.parameter?.importsSet?.size ?? 0) > 0) {
146
- parametersFile.addImportDeclarations([
147
- {
148
- isTypeOnly: true,
149
- namedImports: Array.from(model.importInfo.internalImports.parameter.importsSet!),
150
- moduleSpecifier: `./models.js`,
151
- },
152
- ]);
153
- }
154
- // Add NodeReadableStream import if binary types are used in parameters.
155
- // platform-types.ts is generated directly under src/ (no static-helpers/
156
- // subdirectory) to match the RLC design where all output lives in src/.
157
- // The platform-types static helper resolves NodeReadableStream to
158
- // NodeJS.ReadableStream on Node and `never` on browser/react-native, so the
159
- // union arm drops out naturally in non-Node builds.
160
- if (parametersFile.getFullText().includes("NodeReadableStream")) {
161
- parametersFile.addImportDeclarations([
162
- {
163
- isTypeOnly: true,
164
- namedImports: ["NodeReadableStream"],
165
- moduleSpecifier: "#platform/platform-types",
166
- },
167
- ]);
168
- }
169
- return { path: filePath, content: parametersFile.getFullText() };
170
- }
171
-
172
- function buildQueryParameterDefinition(
173
- parameters: ParameterMetadatas,
174
- baseName: string,
175
- internalReferences: Set<string>,
176
- requestIndex: number,
177
- ): InterfaceDeclarationStructure[] | undefined {
178
- const queryParameters = (parameters?.parameters || []).filter((p) => p.type === "query");
179
-
180
- if (!queryParameters.length) {
181
- return undefined;
182
- }
183
-
184
- const nameSuffix = requestIndex > 0 ? `${requestIndex}` : "";
185
- const queryParameterInterfaceName = `${baseName}QueryParam${nameSuffix}`;
186
- const queryParameterPropertiesName = `${baseName}QueryParamProperties`;
187
-
188
- // Get the property signature for each query parameter
189
- const propertiesDefinition = queryParameters.map((qp) => getPropertyFromSchema(qp.param));
190
- // Get wrapper types for query parameters
191
- const wrapperTypesDefinition = getGeneratedWrapperTypes(queryParameters).map((wrapObj) => {
192
- return getObjectInterfaceDeclaration(
193
- wrapObj.name,
194
- wrapObj,
195
- [SchemaContext.Input],
196
- new Set<string>(),
197
- );
198
- });
199
-
200
- const hasRequiredParameters = propertiesDefinition.some((p) => !p.hasQuestionToken);
201
-
202
- const propertiesInterface: InterfaceDeclarationStructure = {
203
- kind: StructureKind.Interface,
204
- isExported: true,
205
- name: queryParameterPropertiesName,
206
- properties: propertiesDefinition,
207
- };
208
-
209
- const parameterInterface: InterfaceDeclarationStructure = {
210
- kind: StructureKind.Interface,
211
- isExported: true,
212
- name: queryParameterInterfaceName,
213
- properties: [
214
- {
215
- name: "queryParameters",
216
- type: queryParameterPropertiesName,
217
- // Mark as optional if there are no required parameters
218
- hasQuestionToken: !hasRequiredParameters,
219
- },
220
- ],
221
- };
222
-
223
- // Mark the queryParameter interface for importing
224
- internalReferences.add(queryParameterInterfaceName);
225
-
226
- return [...wrapperTypesDefinition, propertiesInterface, parameterInterface];
227
- }
228
-
229
- function getPropertyFromSchema(schema: Schema): PropertySignatureStructure {
230
- const description = schema.description;
231
- return {
232
- name: schema.name,
233
- ...(description && { docs: [{ description }] }),
234
- type: schema.type,
235
- hasQuestionToken: !schema.required,
236
- kind: StructureKind.PropertySignature,
237
- };
238
- }
239
-
240
- function buildPathParameterDefinitions(
241
- parameters: ParameterMetadatas,
242
- ): InterfaceDeclarationStructure[] | undefined {
243
- const pathParameters = (parameters.parameters || []).filter((p) => p.type === "path");
244
- if (!pathParameters.length) {
245
- return undefined;
246
- }
247
- const allDefinitions: InterfaceDeclarationStructure[] = [];
248
-
249
- // we only need to build the wrapper types if the path parameters are objects
250
- const wrapperTypesDefinition = getGeneratedWrapperTypes(pathParameters).map((wrap) => {
251
- return getObjectInterfaceDeclaration(wrap.name, wrap, [SchemaContext.Input], new Set<string>());
252
- });
253
- allDefinitions.push(...wrapperTypesDefinition);
254
- return allDefinitions;
255
- }
256
-
257
- function buildHeaderParameterDefinitions(
258
- parameters: ParameterMetadatas,
259
- baseName: string,
260
- parametersFile: SourceFile,
261
- internalReferences: Set<string>,
262
- requestIndex: number,
263
- ): InterfaceDeclarationStructure | undefined {
264
- const headerParameters = (parameters.parameters || []).filter(
265
- (p) => p.type === "header" && p.name !== "contentType",
266
- );
267
- if (!headerParameters.length) {
268
- return undefined;
269
- }
270
-
271
- const nameSuffix = requestIndex > 0 ? `${requestIndex}` : "";
272
- const headerParameterInterfaceName = `${baseName}HeaderParam${nameSuffix}`;
273
-
274
- const headersInterface = getRequestHeaderInterfaceDefinition(headerParameters, baseName);
275
-
276
- let isOptional = true;
277
- if (headersInterface) {
278
- parametersFile.addInterface(headersInterface);
279
- isOptional = !(headersInterface.properties || []).some(
280
- (prop) => prop.hasQuestionToken === false,
281
- );
282
- }
283
-
284
- internalReferences.add(headerParameterInterfaceName);
285
-
286
- return {
287
- isExported: true,
288
- kind: StructureKind.Interface,
289
- name: headerParameterInterfaceName,
290
- properties: [
291
- {
292
- name: "headers",
293
- type: `RawHttpHeadersInput & ${baseName}Headers`,
294
- kind: StructureKind.PropertySignature,
295
- hasQuestionToken: isOptional,
296
- },
297
- ],
298
- };
299
- }
300
-
301
- function getRequestHeaderInterfaceDefinition(
302
- headerParameters: ParameterMetadata[],
303
- baseName: string,
304
- ): undefined | InterfaceDeclarationStructure {
305
- const headersInterfaceName = `${baseName}Headers`;
306
- return {
307
- kind: StructureKind.Interface,
308
- isExported: true,
309
- name: headersInterfaceName,
310
- properties: headerParameters.map((h: ParameterMetadata) => getPropertyFromSchema(h.param)),
311
- };
312
- }
313
-
314
- function buildContentTypeParametersDefinition(
315
- parameters: ParameterMetadatas,
316
- baseName: string,
317
- internalReferences: Set<string>,
318
- requestIndex: number,
319
- ): InterfaceDeclarationStructure | undefined {
320
- const mediaTypeParameters = (parameters.parameters || []).filter(
321
- (p) => p.type === "header" && p.name === "contentType",
322
- );
323
- if (!mediaTypeParameters.length) {
324
- return undefined;
325
- }
326
-
327
- const nameSuffix = requestIndex > 0 ? `${requestIndex}` : "";
328
- const mediaTypesParameterInterfaceName = `${baseName}MediaTypesParam${nameSuffix}`;
329
-
330
- // Mark the queryParameter interface for importing
331
- internalReferences.add(mediaTypesParameterInterfaceName);
332
- const firstMediaType = mediaTypeParameters[0];
333
- if (!firstMediaType) {
334
- return undefined;
335
- }
336
- const mediaParam = firstMediaType.param;
337
-
338
- return {
339
- isExported: true,
340
- kind: StructureKind.Interface,
341
- name: mediaTypesParameterInterfaceName,
342
- properties: [getPropertyFromSchema(mediaParam)],
343
- };
344
- }
345
-
346
- function buildBodyParametersDefinition(
347
- parameters: ParameterMetadatas,
348
- baseName: string,
349
- internalReferences: Set<string>,
350
- requestIndex: number,
351
- ): InterfaceDeclarationStructure[] {
352
- const bodyParameters = parameters.body;
353
- if (!bodyParameters || !bodyParameters?.body || !bodyParameters?.body.length) {
354
- return [];
355
- }
356
-
357
- const nameSuffix = requestIndex > 0 ? `${requestIndex}` : "";
358
- const bodyParameterInterfaceName = `${baseName}BodyParam${nameSuffix}`;
359
- internalReferences.add(bodyParameterInterfaceName);
360
-
361
- // In case of formData we'd get multiple properties in body marked as partialBody
362
- if (bodyParameters.isPartialBody) {
363
- let allOptionalParts = true;
364
- const propertiesDefinitions: PropertySignatureStructure[] = [];
365
- for (const param of bodyParameters.body) {
366
- if (param.required) {
367
- allOptionalParts = false;
368
- }
369
-
370
- propertiesDefinitions.push(getPropertyFromSchema(param));
371
- }
372
-
373
- const formBodyName = `${baseName}FormBody`;
374
- const formBodyInterface: InterfaceDeclarationStructure = {
375
- isExported: true,
376
- kind: StructureKind.Interface,
377
- name: formBodyName,
378
- properties: propertiesDefinitions,
379
- };
380
-
381
- return [
382
- {
383
- isExported: true,
384
- kind: StructureKind.Interface,
385
- name: bodyParameterInterfaceName,
386
- properties: [
387
- {
388
- name: "body",
389
- type: formBodyName,
390
- hasQuestionToken: allOptionalParts,
391
- },
392
- ],
393
- },
394
- formBodyInterface,
395
- ];
396
- } else {
397
- const firstBody = bodyParameters.body[0];
398
- if (!firstBody) {
399
- return [];
400
- }
401
- const bodySignature = getPropertyFromSchema(firstBody);
402
-
403
- return [
404
- {
405
- isExported: true,
406
- kind: StructureKind.Interface,
407
- name: bodyParameterInterfaceName,
408
- properties: [
409
- {
410
- docs: bodySignature.docs,
411
- name: "body",
412
- type: bodySignature.type,
413
- hasQuestionToken: bodySignature.hasQuestionToken,
414
- },
415
- ],
416
- },
417
- ];
418
- }
419
- }
420
-
421
- export function buildBodyTypeAlias(
422
- parameters: ParameterMetadatas,
423
- partialBodyTypeNames: Set<string>,
424
- ) {
425
- const bodyParameters = parameters.body;
426
- if (!bodyParameters || !bodyParameters?.body || !bodyParameters?.body.length) {
427
- return undefined;
428
- }
429
- const schema = bodyParameters.body[0] as ObjectSchema;
430
- const headerParameters = (parameters.parameters || []).filter(
431
- (p) => p.type === "header" && p.name === "contentType",
432
- );
433
- if (!headerParameters.length || headerParameters.length > 1) {
434
- return undefined;
435
- }
436
-
437
- const firstHeader = headerParameters[0];
438
- if (!firstHeader) {
439
- return undefined;
440
- }
441
- const contentType = firstHeader.param.type;
442
- const description = `${schema.description}`;
443
- const typeName = `${schema.typeName}ResourceMergeAndPatch`;
444
- if (partialBodyTypeNames.has(typeName)) {
445
- return null;
446
- } else {
447
- partialBodyTypeNames.add(typeName);
448
- }
449
- if (contentType.includes("application/merge-patch+json")) {
450
- const type = `Partial<${schema.typeName}>`;
451
- return {
452
- // kind: StructureKind.TypeAlias,
453
- ...(description && { docs: [{ description }] }),
454
- name: `${typeName}`,
455
- type,
456
- isExported: true,
457
- };
458
- }
459
- return undefined;
460
- }
@@ -1,80 +0,0 @@
1
- import { joinPaths } from "@typespec/compiler";
2
- import { OPERATION_LRO_HIGH_PRIORITY, RLCModel } from "./interfaces.js";
3
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
- // @ts-ignore: to fix the handlebars issue
5
- import hbs from "handlebars";
6
- import { hasPollingOperations } from "./helpers/operation-helpers.js";
7
- import { pollingContent } from "./static/polling-content.js";
8
-
9
- interface LroDetail {
10
- clientOverload?: boolean;
11
- overloadMap?: ResponseMap[];
12
- importedResponses?: string[];
13
- }
14
-
15
- interface ResponseMap {
16
- initialResponses: string;
17
- finalResponses: string;
18
- precedence?: number;
19
- }
20
-
21
- export function buildPollingHelper(model: RLCModel) {
22
- if (!hasPollingOperations(model)) {
23
- return;
24
- }
25
-
26
- const lroDetail: LroDetail = buildLroHelperDetail(model);
27
- const readmeFileContents = hbs.compile(pollingContent, { noEscape: true });
28
- const { srcPath } = model;
29
- return {
30
- path: joinPaths(srcPath, "pollingHelper.ts"),
31
- content: readmeFileContents(lroDetail),
32
- };
33
- }
34
-
35
- function buildLroHelperDetail(model: RLCModel): LroDetail {
36
- if (!model.helperDetails?.clientLroOverload) {
37
- return {
38
- clientOverload: false,
39
- };
40
- }
41
- const mapDetail = [];
42
- const pathDictionary = model.paths;
43
- const responses = new Set<string>();
44
- for (const details of Object.values(pathDictionary)) {
45
- for (const methodDetails of Object.values(details.methods)) {
46
- const firstMethod = methodDetails[0];
47
- if (!firstMethod) {
48
- continue;
49
- }
50
- const lroDetail = firstMethod.operationHelperDetail?.lroDetails;
51
- if (lroDetail?.isLongRunning) {
52
- const initialResponses = firstMethod.responseTypes.success.concat(
53
- firstMethod.responseTypes.error,
54
- );
55
-
56
- const finalResponse = lroDetail.logicalResponseTypes?.success.concat(
57
- firstMethod.responseTypes.error,
58
- );
59
-
60
- if (initialResponses && finalResponse) {
61
- initialResponses.forEach((n) => responses.add(n));
62
- finalResponse.forEach((n) => responses.add(n));
63
- mapDetail!.push({
64
- initialResponses: initialResponses.join("|"),
65
- finalResponses: finalResponse.join("|"),
66
- precedence: lroDetail.precedence ?? OPERATION_LRO_HIGH_PRIORITY,
67
- });
68
- }
69
- }
70
- }
71
- }
72
-
73
- // Sorted by the precedence
74
- mapDetail.sort((d1, d2) => d1.precedence - d2.precedence);
75
- return {
76
- clientOverload: responses.size > 0 && mapDetail.length > 0,
77
- importedResponses: Array.from(responses),
78
- overloadMap: mapDetail,
79
- };
80
- }
@@ -1,170 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
-
4
- import { joinPaths } from "@typespec/compiler";
5
- import {
6
- InterfaceDeclarationStructure,
7
- OptionalKind,
8
- Project,
9
- PropertySignatureStructure,
10
- StructureKind,
11
- } from "ts-morph";
12
- import { getImportSpecifier } from "./helpers/imports-util.js";
13
- import { getResponseBaseName, getResponseTypeName } from "./helpers/name-constructors.js";
14
- import { ResponseHeaderSchema, ResponseMetadata, RLCModel } from "./interfaces.js";
15
-
16
- let hasErrorResponse = false;
17
- export function buildResponseTypes(model: RLCModel) {
18
- const project = new Project({ useInMemoryFileSystem: true });
19
- const srcPath = model.srcPath;
20
- const filePath = joinPaths(srcPath, `responses.ts`);
21
- hasErrorResponse = false;
22
- const responsesFile = project.createSourceFile(filePath, undefined, {
23
- overwrite: true,
24
- });
25
- // Set used to track down which models need to be imported
26
- // Track if we need to import RawHttpHeaders
27
- let hasHeaders = false;
28
- if (!model.responses) {
29
- return;
30
- }
31
- for (const operationResponse of model.responses) {
32
- for (const response of operationResponse.responses) {
33
- // Building the response type base name
34
- const baseResponseName = getResponseBaseName(
35
- operationResponse.operationGroup,
36
- operationResponse.operationName,
37
- response.statusCode,
38
- );
39
-
40
- // Build the response header
41
- const headersInterface: InterfaceDeclarationStructure | undefined =
42
- getResponseHeaderInterfaceDefinition(response, baseResponseName);
43
- if (headersInterface) {
44
- hasHeaders = true;
45
- responsesFile.addInterface(headersInterface);
46
- }
47
-
48
- // Get the information to build the Response Interface
49
- const responseTypeName = response.predefinedName ?? getResponseTypeName(baseResponseName);
50
- const responseProperties = getResponseInterfaceProperties(response, headersInterface?.name);
51
-
52
- const responseInterfaceDefinition: OptionalKind<InterfaceDeclarationStructure> = {
53
- name: responseTypeName,
54
- properties: responseProperties,
55
- isExported: true,
56
- extends: ["HttpResponse"],
57
- };
58
-
59
- // Only add a description if one was provided in the Swagger
60
- // otherwise skip to avoid having empty TSDoc lines
61
- if (response.description) {
62
- responseInterfaceDefinition.docs = [{ description: response.description }];
63
- }
64
-
65
- // Add the response interface to the responses file
66
- responsesFile.addInterface(responseInterfaceDefinition);
67
- }
68
- }
69
-
70
- if (hasHeaders) {
71
- responsesFile.addImportDeclarations([
72
- {
73
- isTypeOnly: true,
74
- namedImports: ["RawHttpHeaders"],
75
- moduleSpecifier: getImportSpecifier("restPipeline", model.importInfo.runtimeImports),
76
- },
77
- ]);
78
- }
79
- const namedImports = ["HttpResponse"];
80
- if (hasErrorResponse) {
81
- namedImports.push("ErrorResponse");
82
- }
83
- responsesFile.addImportDeclarations([
84
- {
85
- isTypeOnly: true,
86
- namedImports,
87
- moduleSpecifier: getImportSpecifier("restClient", model.importInfo.runtimeImports),
88
- },
89
- ]);
90
-
91
- if ((model.importInfo.internalImports.response?.importsSet?.size ?? 0) > 0) {
92
- const modelNamedImports = Array.from(
93
- model.importInfo.internalImports.response!.importsSet!,
94
- ).filter((modelName) => {
95
- return !(modelName === "ErrorResponseOutput" && hasErrorResponse);
96
- });
97
- responsesFile.addImportDeclarations([
98
- {
99
- isTypeOnly: true,
100
- namedImports: modelNamedImports,
101
- moduleSpecifier: `./outputModels.js`,
102
- },
103
- ]);
104
- }
105
- return { path: filePath, content: responsesFile.getFullText() };
106
- }
107
-
108
- function getResponseHeaderInterfaceDefinition(
109
- response: ResponseMetadata,
110
- baseName: string,
111
- ): undefined | InterfaceDeclarationStructure {
112
- // Check if there are any required headers
113
- if (!response.headers) {
114
- return;
115
- }
116
- const headersInterfaceName = `${baseName}Headers`;
117
- return {
118
- kind: StructureKind.Interface,
119
- isExported: true,
120
- name: headersInterfaceName,
121
- properties: response?.headers.map((h: ResponseHeaderSchema) => {
122
- const description = h.description;
123
- return {
124
- name: h.name,
125
- ...(description && { docs: [{ description }] }),
126
- type: h.type,
127
- hasQuestionToken: !h.required,
128
- };
129
- }),
130
- };
131
- }
132
-
133
- /**
134
- * Gets the properties that need to be part of the response interface
135
- */
136
- function getResponseInterfaceProperties(response: ResponseMetadata, headersInterfaceName?: string) {
137
- const statusCode = response.statusCode;
138
- const responseProperties: PropertySignatureStructure[] = [
139
- {
140
- name: "status",
141
- type: statusCode === "default" ? `string` : `"${statusCode}"`,
142
- kind: StructureKind.PropertySignature,
143
- },
144
- ];
145
-
146
- if (response.body) {
147
- const description = response.body.description;
148
- let type = response.body.type;
149
- if (response.body.type === "ErrorResponseOutput" && response.body.fromCore) {
150
- type = "ErrorResponse";
151
- hasErrorResponse = true;
152
- }
153
- responseProperties.push({
154
- name: "body",
155
- type,
156
- kind: StructureKind.PropertySignature,
157
- ...(description && { docs: [{ description }] }),
158
- });
159
- }
160
-
161
- if (headersInterfaceName) {
162
- responseProperties.push({
163
- name: "headers",
164
- type: `RawHttpHeaders & ${headersInterfaceName}`,
165
- kind: StructureKind.PropertySignature,
166
- });
167
- }
168
-
169
- return responseProperties;
170
- }