@autorest/typescript 6.0.0-beta.15 → 6.0.0-beta.18

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 (245) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +37 -3
  3. package/dist/src/autorestSession.d.ts +12 -4
  4. package/dist/src/autorestSession.d.ts.map +1 -1
  5. package/dist/src/autorestSession.js +3 -9
  6. package/dist/src/autorestSession.js.map +1 -1
  7. package/dist/src/conflictResolver.d.ts.map +1 -1
  8. package/dist/src/conflictResolver.js.map +1 -1
  9. package/dist/src/generators/clientFileGenerator.d.ts.map +1 -1
  10. package/dist/src/generators/clientFileGenerator.js +181 -31
  11. package/dist/src/generators/clientFileGenerator.js.map +1 -1
  12. package/dist/src/generators/indexGenerator.d.ts.map +1 -1
  13. package/dist/src/generators/indexGenerator.js +70 -9
  14. package/dist/src/generators/indexGenerator.js.map +1 -1
  15. package/dist/src/generators/modelsGenerator.d.ts.map +1 -1
  16. package/dist/src/generators/modelsGenerator.js +21 -3
  17. package/dist/src/generators/modelsGenerator.js.map +1 -1
  18. package/dist/src/generators/operationGenerator.d.ts.map +1 -1
  19. package/dist/src/generators/operationGenerator.js +10 -8
  20. package/dist/src/generators/operationGenerator.js.map +1 -1
  21. package/dist/src/generators/samples/sampleEnv.hbs +4 -0
  22. package/dist/src/generators/samples/sampleEnvGenerator.d.ts +3 -0
  23. package/dist/src/generators/samples/sampleEnvGenerator.d.ts.map +1 -0
  24. package/dist/src/generators/samples/sampleEnvGenerator.js +17 -0
  25. package/dist/src/generators/samples/sampleEnvGenerator.js.map +1 -0
  26. package/dist/src/generators/samples/sampleGenerator.d.ts +13 -0
  27. package/dist/src/generators/samples/sampleGenerator.d.ts.map +1 -0
  28. package/dist/src/generators/samples/sampleGenerator.js +43 -0
  29. package/dist/src/generators/samples/sampleGenerator.js.map +1 -0
  30. package/dist/src/generators/static/apiExtractorConfig.js +2 -2
  31. package/dist/src/generators/static/apiExtractorConfig.js.map +1 -1
  32. package/dist/src/generators/static/esLintConfigGenerator.d.ts +3 -0
  33. package/dist/src/generators/static/esLintConfigGenerator.d.ts.map +1 -0
  34. package/dist/src/generators/static/esLintConfigGenerator.js +26 -0
  35. package/dist/src/generators/static/esLintConfigGenerator.js.map +1 -0
  36. package/dist/src/generators/static/{README.md.hbs → hlcREADME.md.hbs} +19 -0
  37. package/dist/src/generators/static/karma.conf.js.hbs +141 -0
  38. package/dist/src/generators/static/karmaConfigFileGenerator.d.ts +3 -0
  39. package/dist/src/generators/static/karmaConfigFileGenerator.d.ts.map +1 -0
  40. package/dist/src/generators/static/karmaConfigFileGenerator.js +23 -0
  41. package/dist/src/generators/static/karmaConfigFileGenerator.js.map +1 -0
  42. package/dist/src/generators/static/packageFileGenerator.d.ts.map +1 -1
  43. package/dist/src/generators/static/packageFileGenerator.js +171 -46
  44. package/dist/src/generators/static/packageFileGenerator.js.map +1 -1
  45. package/dist/src/generators/static/readmeFileGenerator.d.ts +2 -2
  46. package/dist/src/generators/static/readmeFileGenerator.d.ts.map +1 -1
  47. package/dist/src/generators/static/readmeFileGenerator.js +31 -17
  48. package/dist/src/generators/static/readmeFileGenerator.js.map +1 -1
  49. package/dist/src/generators/static/rlcREADME.md.hbs +71 -0
  50. package/dist/src/generators/static/rollupConfigFileGenerator.d.ts.map +1 -1
  51. package/dist/src/generators/static/rollupConfigFileGenerator.js +12 -71
  52. package/dist/src/generators/static/rollupConfigFileGenerator.js.map +1 -1
  53. package/dist/src/generators/static/samples.ts.hbs +49 -0
  54. package/dist/src/generators/static/tsConfigFileGenerator.d.ts.map +1 -1
  55. package/dist/src/generators/static/tsConfigFileGenerator.js +40 -18
  56. package/dist/src/generators/static/tsConfigFileGenerator.js.map +1 -1
  57. package/dist/src/generators/test/envBrowserFileGenerator.d.ts +3 -0
  58. package/dist/src/generators/test/envBrowserFileGenerator.d.ts.map +1 -0
  59. package/dist/src/generators/test/envBrowserFileGenerator.js +15 -0
  60. package/dist/src/generators/test/envBrowserFileGenerator.js.map +1 -0
  61. package/dist/src/generators/test/envFileGenerator.d.ts +3 -0
  62. package/dist/src/generators/test/envFileGenerator.d.ts.map +1 -0
  63. package/dist/src/generators/test/envFileGenerator.js +23 -0
  64. package/dist/src/generators/test/envFileGenerator.js.map +1 -0
  65. package/dist/src/generators/test/recordedClientFileGenerator.d.ts +3 -0
  66. package/dist/src/generators/test/recordedClientFileGenerator.d.ts.map +1 -0
  67. package/dist/src/generators/test/recordedClientFileGenerator.js +23 -0
  68. package/dist/src/generators/test/recordedClientFileGenerator.js.map +1 -0
  69. package/dist/src/generators/test/rlcEnv.ts.hbs +3 -0
  70. package/dist/src/generators/test/rlcRecordedClient.ts.hbs +35 -0
  71. package/dist/src/generators/test/rlcSampleTest.spec.ts.hbs +19 -0
  72. package/dist/src/generators/{static → test}/sampleTest.ts.hbs +0 -0
  73. package/dist/src/generators/test/sampleTestGenerator.d.ts.map +1 -1
  74. package/dist/src/generators/test/sampleTestGenerator.js +23 -7
  75. package/dist/src/generators/test/sampleTestGenerator.js.map +1 -1
  76. package/dist/src/generators/utils/pagingOperations.d.ts +5 -0
  77. package/dist/src/generators/utils/pagingOperations.d.ts.map +1 -1
  78. package/dist/src/generators/utils/pagingOperations.js +2 -1
  79. package/dist/src/generators/utils/pagingOperations.js.map +1 -1
  80. package/dist/src/main.d.ts +2 -2
  81. package/dist/src/main.d.ts.map +1 -1
  82. package/dist/src/main.js +3 -3
  83. package/dist/src/main.js.map +1 -1
  84. package/dist/src/models/clientDetails.d.ts +7 -0
  85. package/dist/src/models/clientDetails.d.ts.map +1 -1
  86. package/dist/src/models/modelDetails.d.ts +2 -2
  87. package/dist/src/models/modelDetails.d.ts.map +1 -1
  88. package/dist/src/models/operationDetails.d.ts +1 -0
  89. package/dist/src/models/operationDetails.d.ts.map +1 -1
  90. package/dist/src/models/sampleDetails.d.ts +22 -0
  91. package/dist/src/models/sampleDetails.d.ts.map +1 -0
  92. package/dist/src/models/sampleDetails.js +3 -0
  93. package/dist/src/models/sampleDetails.js.map +1 -0
  94. package/dist/src/restLevelClient/generateClient.d.ts +1 -1
  95. package/dist/src/restLevelClient/generateClient.d.ts.map +1 -1
  96. package/dist/src/restLevelClient/generateClient.js +81 -168
  97. package/dist/src/restLevelClient/generateClient.js.map +1 -1
  98. package/dist/src/restLevelClient/generateClientDefinition.d.ts +6 -0
  99. package/dist/src/restLevelClient/generateClientDefinition.d.ts.map +1 -0
  100. package/dist/src/restLevelClient/generateClientDefinition.js +231 -0
  101. package/dist/src/restLevelClient/generateClientDefinition.js.map +1 -0
  102. package/dist/src/restLevelClient/generateMethodShortcuts.d.ts +8 -0
  103. package/dist/src/restLevelClient/generateMethodShortcuts.d.ts.map +1 -0
  104. package/dist/src/restLevelClient/generateMethodShortcuts.js +70 -0
  105. package/dist/src/restLevelClient/generateMethodShortcuts.js.map +1 -0
  106. package/dist/src/restLevelClient/generateObjectTypes.d.ts.map +1 -1
  107. package/dist/src/restLevelClient/generateObjectTypes.js.map +1 -1
  108. package/dist/src/restLevelClient/generatePagingHelper.d.ts.map +1 -1
  109. package/dist/src/restLevelClient/generatePagingHelper.js +2 -1
  110. package/dist/src/restLevelClient/generatePagingHelper.js.map +1 -1
  111. package/dist/src/restLevelClient/generateParameterTypes.d.ts.map +1 -1
  112. package/dist/src/restLevelClient/generateParameterTypes.js +104 -18
  113. package/dist/src/restLevelClient/generateParameterTypes.js.map +1 -1
  114. package/dist/src/restLevelClient/generatePollingHelper.d.ts.map +1 -1
  115. package/dist/src/restLevelClient/generatePollingHelper.js +3 -1
  116. package/dist/src/restLevelClient/generatePollingHelper.js.map +1 -1
  117. package/dist/src/restLevelClient/generateResponseTypes.d.ts.map +1 -1
  118. package/dist/src/restLevelClient/generateResponseTypes.js +4 -1
  119. package/dist/src/restLevelClient/generateResponseTypes.js.map +1 -1
  120. package/dist/src/restLevelClient/generateRestLevel.d.ts.map +1 -1
  121. package/dist/src/restLevelClient/generateRestLevel.js +31 -4
  122. package/dist/src/restLevelClient/generateRestLevel.js.map +1 -1
  123. package/dist/src/restLevelClient/generateSchemaTypes.d.ts.map +1 -1
  124. package/dist/src/restLevelClient/generateSchemaTypes.js +5 -2
  125. package/dist/src/restLevelClient/generateSchemaTypes.js.map +1 -1
  126. package/dist/src/restLevelClient/generateTopLevelIndexFile.d.ts +4 -0
  127. package/dist/src/restLevelClient/generateTopLevelIndexFile.d.ts.map +1 -0
  128. package/dist/src/restLevelClient/generateTopLevelIndexFile.js +37 -0
  129. package/dist/src/restLevelClient/generateTopLevelIndexFile.js.map +1 -0
  130. package/dist/src/restLevelClient/helpers/operationHelpers.d.ts +10 -0
  131. package/dist/src/restLevelClient/helpers/operationHelpers.d.ts.map +1 -0
  132. package/dist/src/restLevelClient/helpers/operationHelpers.js +64 -0
  133. package/dist/src/restLevelClient/helpers/operationHelpers.js.map +1 -0
  134. package/dist/src/restLevelClient/interfaces.d.ts +24 -0
  135. package/dist/src/restLevelClient/interfaces.d.ts.map +1 -0
  136. package/dist/src/restLevelClient/interfaces.js +3 -0
  137. package/dist/src/restLevelClient/interfaces.js.map +1 -0
  138. package/dist/src/restLevelClient/operationHelpers.d.ts.map +1 -1
  139. package/dist/src/restLevelClient/operationHelpers.js +4 -1
  140. package/dist/src/restLevelClient/operationHelpers.js.map +1 -1
  141. package/dist/src/restLevelClient/schemaHelpers.d.ts.map +1 -1
  142. package/dist/src/restLevelClient/schemaHelpers.js +10 -2
  143. package/dist/src/restLevelClient/schemaHelpers.js.map +1 -1
  144. package/dist/src/transforms/mapperTransforms.js +1 -1
  145. package/dist/src/transforms/mapperTransforms.js.map +1 -1
  146. package/dist/src/transforms/objectTransforms.js +1 -1
  147. package/dist/src/transforms/objectTransforms.js.map +1 -1
  148. package/dist/src/transforms/operationTransforms.d.ts.map +1 -1
  149. package/dist/src/transforms/operationTransforms.js +1 -0
  150. package/dist/src/transforms/operationTransforms.js.map +1 -1
  151. package/dist/src/transforms/parameterTransforms.d.ts.map +1 -1
  152. package/dist/src/transforms/parameterTransforms.js +20 -4
  153. package/dist/src/transforms/parameterTransforms.js.map +1 -1
  154. package/dist/src/transforms/samplesTransforms.d.ts +7 -0
  155. package/dist/src/transforms/samplesTransforms.d.ts.map +1 -0
  156. package/dist/src/transforms/samplesTransforms.js +283 -0
  157. package/dist/src/transforms/samplesTransforms.js.map +1 -0
  158. package/dist/src/transforms/transforms.d.ts +1 -2
  159. package/dist/src/transforms/transforms.d.ts.map +1 -1
  160. package/dist/src/transforms/transforms.js +5 -4
  161. package/dist/src/transforms/transforms.js.map +1 -1
  162. package/dist/src/typescriptGenerator.d.ts +2 -2
  163. package/dist/src/typescriptGenerator.d.ts.map +1 -1
  164. package/dist/src/typescriptGenerator.js +19 -8
  165. package/dist/src/typescriptGenerator.js.map +1 -1
  166. package/dist/src/utils/autorestOptions.d.ts +2 -2
  167. package/dist/src/utils/autorestOptions.d.ts.map +1 -1
  168. package/dist/src/utils/autorestOptions.js +107 -30
  169. package/dist/src/utils/autorestOptions.js.map +1 -1
  170. package/dist/src/utils/nameUtils.d.ts +6 -2
  171. package/dist/src/utils/nameUtils.d.ts.map +1 -1
  172. package/dist/src/utils/nameUtils.js +9 -5
  173. package/dist/src/utils/nameUtils.js.map +1 -1
  174. package/dist/src/utils/schemaHelpers.js +8 -3
  175. package/dist/src/utils/schemaHelpers.js.map +1 -1
  176. package/package.json +26 -10
  177. package/src/autorestSession.ts +20 -16
  178. package/src/conflictResolver.ts +0 -1
  179. package/src/generators/clientFileGenerator.ts +264 -33
  180. package/src/generators/indexGenerator.ts +78 -9
  181. package/src/generators/modelsGenerator.ts +22 -2
  182. package/src/generators/operationGenerator.ts +11 -9
  183. package/src/generators/samples/sampleEnv.hbs +4 -0
  184. package/src/generators/samples/sampleEnvGenerator.ts +14 -0
  185. package/src/generators/samples/sampleGenerator.ts +50 -0
  186. package/src/generators/static/apiExtractorConfig.ts +2 -2
  187. package/src/generators/static/esLintConfigGenerator.ts +24 -0
  188. package/src/generators/static/{README.md.hbs → hlcREADME.md.hbs} +19 -0
  189. package/src/generators/static/karma.conf.js.hbs +141 -0
  190. package/src/generators/static/karmaConfigFileGenerator.ts +20 -0
  191. package/src/generators/static/packageFileGenerator.ts +183 -46
  192. package/src/generators/static/readmeFileGenerator.ts +57 -34
  193. package/src/generators/static/rlcREADME.md.hbs +71 -0
  194. package/src/generators/static/rollupConfigFileGenerator.ts +13 -71
  195. package/src/generators/static/samples.ts.hbs +49 -0
  196. package/src/generators/static/tsConfigFileGenerator.ts +47 -20
  197. package/src/generators/test/envBrowserFileGenerator.ts +14 -0
  198. package/src/generators/test/envFileGenerator.ts +22 -0
  199. package/src/generators/test/recordedClientFileGenerator.ts +22 -0
  200. package/src/generators/test/rlcEnv.ts.hbs +3 -0
  201. package/src/generators/test/rlcRecordedClient.ts.hbs +35 -0
  202. package/src/generators/test/rlcSampleTest.spec.ts.hbs +19 -0
  203. package/src/generators/{static → test}/sampleTest.ts.hbs +0 -0
  204. package/src/generators/test/sampleTestGenerator.ts +23 -8
  205. package/src/generators/utils/pagingOperations.ts +1 -1
  206. package/src/main.ts +8 -5
  207. package/src/models/clientDetails.ts +8 -0
  208. package/src/models/modelDetails.ts +2 -2
  209. package/src/models/operationDetails.ts +1 -0
  210. package/src/models/sampleDetails.ts +22 -0
  211. package/src/restLevelClient/generateClient.ts +101 -260
  212. package/src/restLevelClient/generateClientDefinition.ts +343 -0
  213. package/src/restLevelClient/generateMethodShortcuts.ts +121 -0
  214. package/src/restLevelClient/generateObjectTypes.ts +1 -3
  215. package/src/restLevelClient/generatePagingHelper.ts +3 -2
  216. package/src/restLevelClient/generateParameterTypes.ts +155 -25
  217. package/src/restLevelClient/generatePollingHelper.ts +3 -3
  218. package/src/restLevelClient/generateResponseTypes.ts +4 -1
  219. package/src/restLevelClient/generateRestLevel.ts +36 -8
  220. package/src/restLevelClient/generateSchemaTypes.ts +5 -3
  221. package/src/restLevelClient/generateTopLevelIndexFile.ts +37 -0
  222. package/src/restLevelClient/helpers/operationHelpers.ts +93 -0
  223. package/src/restLevelClient/interfaces.ts +26 -0
  224. package/src/restLevelClient/operationHelpers.ts +8 -2
  225. package/src/restLevelClient/schemaHelpers.ts +10 -3
  226. package/src/transforms/mapperTransforms.ts +1 -1
  227. package/src/transforms/objectTransforms.ts +1 -1
  228. package/src/transforms/operationTransforms.ts +1 -0
  229. package/src/transforms/parameterTransforms.ts +20 -4
  230. package/src/transforms/samplesTransforms.ts +300 -0
  231. package/src/transforms/transforms.ts +6 -6
  232. package/src/typescriptGenerator.ts +20 -11
  233. package/src/utils/autorestOptions.ts +170 -59
  234. package/src/utils/nameUtils.ts +16 -8
  235. package/src/utils/schemaHelpers.ts +2 -2
  236. package/dist/src/generators/clientContextFileGenerator.d.ts +0 -5
  237. package/dist/src/generators/clientContextFileGenerator.d.ts.map +0 -1
  238. package/dist/src/generators/clientContextFileGenerator.js +0 -263
  239. package/dist/src/generators/clientContextFileGenerator.js.map +0 -1
  240. package/dist/src/restLevelClient/helpers/getOperationParameters.d.ts +0 -6
  241. package/dist/src/restLevelClient/helpers/getOperationParameters.d.ts.map +0 -1
  242. package/dist/src/restLevelClient/helpers/getOperationParameters.js +0 -29
  243. package/dist/src/restLevelClient/helpers/getOperationParameters.js.map +0 -1
  244. package/src/generators/clientContextFileGenerator.ts +0 -405
  245. package/src/restLevelClient/helpers/getOperationParameters.ts +0 -37
@@ -3,20 +3,24 @@ import {
3
3
  Operation,
4
4
  Parameter,
5
5
  SchemaContext,
6
- Request as OperationRequest
6
+ Request as OperationRequest,
7
+ ParameterLocation
7
8
  } from "@autorest/codemodel";
8
9
  import {
9
10
  InterfaceDeclarationStructure,
10
11
  Project,
12
+ PropertySignatureStructure,
11
13
  SourceFile,
12
14
  StructureKind
13
15
  } from "ts-morph";
16
+ import * as path from 'path';
14
17
  import { getLanguageMetadata } from "../utils/languageHelpers";
15
18
  import { NameType, normalizeName } from "../utils/nameUtils";
16
- import { getDocs, getPropertySignature } from "./getPropertySignature";
19
+ import { getPropertySignature } from "./getPropertySignature";
17
20
  import { primitiveSchemaToType } from "./schemaHelpers";
18
- import { getOperationParameters } from "./helpers/getOperationParameters";
21
+ import { getOperationParameters } from "./helpers/operationHelpers";
19
22
  import { hasInputModels } from "./helpers/modelHelpers";
23
+ import { getAutorestOptions } from "../autorestSession";
20
24
 
21
25
  /**
22
26
  * Generates the interfaces describing each operation parameters
@@ -25,8 +29,9 @@ export function generateParameterInterfaces(
25
29
  model: CodeModel,
26
30
  project: Project
27
31
  ) {
32
+ const { srcPath } = getAutorestOptions();
28
33
  const parametersFile = project.createSourceFile(
29
- `src/parameters.ts`,
34
+ path.join(srcPath, `parameters.ts`),
30
35
  undefined,
31
36
  {
32
37
  overwrite: true
@@ -73,6 +78,15 @@ export function generateParameterInterfaces(
73
78
 
74
79
  const request = operation.requests ? operation.requests[i] : undefined;
75
80
 
81
+ const pathParameterDefinitions = buildPathParameterDefinitions(
82
+ operationName,
83
+ parameters,
84
+ model,
85
+ parametersFile,
86
+ internalReferences,
87
+ i
88
+ )
89
+
76
90
  const headerParameterDefinitions = buildHeaderParameterDefinitions(
77
91
  operationName,
78
92
  parameters,
@@ -99,8 +113,9 @@ export function generateParameterInterfaces(
99
113
 
100
114
  // Add interfaces for body and query parameters
101
115
  parametersFile.addInterfaces([
102
- ...(bodyParameterDefinition ? [bodyParameterDefinition] : []),
116
+ ...(bodyParameterDefinition ?? []),
103
117
  ...(queryParameterDefinitions ?? []),
118
+ ...(pathParameterDefinitions ? [pathParameterDefinitions]: []),
104
119
  ...(headerParameterDefinitions ? [headerParameterDefinitions] : []),
105
120
  ...(contentTypeParameterDefinition
106
121
  ? [contentTypeParameterDefinition]
@@ -232,6 +247,81 @@ function buildHeaderParameterDefinitions(
232
247
  };
233
248
  }
234
249
 
250
+ function getPathInterfaceDefinition(
251
+ parameters: Parameter[],
252
+ baseName: string,
253
+ model: CodeModel
254
+ ): undefined | InterfaceDeclarationStructure {
255
+ // Check if there are any path parameters
256
+ const pathParameters = parameters.filter(
257
+ p => p.protocol.http?.in === ParameterLocation.Uri && model.globalParameters?.indexOf(p) === -1
258
+ );
259
+ if (!pathParameters.length) {
260
+ return undefined;
261
+ }
262
+ const pathInterfaceName = `${baseName}PathParameters`;
263
+ return {
264
+ kind: StructureKind.Interface,
265
+ isExported: true,
266
+ name: pathInterfaceName,
267
+ properties: pathParameters.map((h: Parameter) => {
268
+ const description = getLanguageMetadata(h.language).description;
269
+ return {
270
+ name: `"${getLanguageMetadata(h.language).serializedName}"`,
271
+ ...(description && { docs: [{ description }] }),
272
+ type: primitiveSchemaToType(h.schema, [
273
+ SchemaContext.Input,
274
+ SchemaContext.Exception
275
+ ]),
276
+ hasQuestionToken: !h.required
277
+ };
278
+ })
279
+ };
280
+ }
281
+
282
+ function buildPathParameterDefinitions(
283
+ operationName: string,
284
+ parameters: Parameter[],
285
+ model: CodeModel,
286
+ parametersFile: SourceFile,
287
+ internalReferences: Set<string>,
288
+ requestIndex: number
289
+ ): InterfaceDeclarationStructure | undefined {
290
+ const pathParameters = parameters.filter(
291
+ p => p.protocol.http?.in === ParameterLocation.Uri && model.globalParameters?.indexOf(p) === -1
292
+ );
293
+ if (!pathParameters.length) {
294
+ return undefined;
295
+ }
296
+
297
+ const nameSuffix = requestIndex > 0 ? `${requestIndex}` : "";
298
+ const pathParameterInterfaceName = `${operationName}PathParam${nameSuffix}`;
299
+
300
+ const pathInterface = getPathInterfaceDefinition(
301
+ pathParameters,
302
+ operationName,
303
+ model
304
+ );
305
+
306
+ if (pathInterface) {
307
+ parametersFile.addInterface(pathInterface);
308
+ }
309
+
310
+ internalReferences.add(pathParameterInterfaceName);
311
+
312
+ return {
313
+ isExported: true,
314
+ kind: StructureKind.Interface,
315
+ name: pathParameterInterfaceName,
316
+ properties: [
317
+ {
318
+ name: "pathParameters",
319
+ type: `${operationName}PathParameters`,
320
+ kind: StructureKind.PropertySignature
321
+ }
322
+ ]
323
+ };
324
+ }
235
325
  /**
236
326
  * Gets the interface definition for an operation bodyParameters
237
327
  */
@@ -242,36 +332,76 @@ function buildBodyParametersDefinition(
242
332
  importedModels: Set<string>,
243
333
  internalReferences: Set<string>,
244
334
  requestIndex: number
245
- ): InterfaceDeclarationStructure | undefined {
335
+ ): InterfaceDeclarationStructure[] {
246
336
  const bodyParameters = parameters.filter(p => p.protocol.http?.in === "body");
247
337
  if (!bodyParameters.length) {
248
- return undefined;
338
+ return [];
249
339
  }
250
340
 
251
341
  const nameSuffix = requestIndex > 0 ? `${requestIndex}` : "";
252
342
  const bodyParameterInterfaceName = `${operationName}BodyParam${nameSuffix}`;
253
- // There is only one body parameter can't be more than one so we can safely take the first
254
- const bodySignature = getPropertySignature(
255
- bodyParameters[0],
256
- schemaUsage,
257
- importedModels
258
- );
259
-
260
343
  internalReferences.add(bodyParameterInterfaceName);
261
344
 
262
- return {
263
- isExported: true,
264
- kind: StructureKind.Interface,
265
- name: bodyParameterInterfaceName,
266
- properties: [
345
+ // In case of formData we'd get multiple properties in body marked as partialBody
346
+ if (bodyParameters.some(p => p.isPartialBody)) {
347
+ let allOptionalParts = true;
348
+ const propertiesDefinitions: PropertySignatureStructure[] = [];
349
+ for (const param of bodyParameters) {
350
+ if (param.required) {
351
+ allOptionalParts = false;
352
+ }
353
+
354
+ propertiesDefinitions.push(
355
+ getPropertySignature(param, schemaUsage, importedModels)
356
+ );
357
+ }
358
+
359
+ const formBodyName = `${operationName}FormBody`;
360
+ const formBodyInterface: InterfaceDeclarationStructure = {
361
+ isExported: true,
362
+ kind: StructureKind.Interface,
363
+ name: formBodyName,
364
+ properties: propertiesDefinitions
365
+ };
366
+
367
+ return [
368
+ {
369
+ isExported: true,
370
+ kind: StructureKind.Interface,
371
+ name: bodyParameterInterfaceName,
372
+ properties: [
373
+ {
374
+ name: "body",
375
+ type: formBodyName,
376
+ hasQuestionToken: allOptionalParts
377
+ }
378
+ ]
379
+ },
380
+ formBodyInterface
381
+ ];
382
+ } else {
383
+ const bodySignature = getPropertySignature(
384
+ bodyParameters[0],
385
+ schemaUsage,
386
+ importedModels
387
+ );
388
+
389
+ return [
267
390
  {
268
- docs: bodySignature.docs,
269
- name: "body",
270
- type: bodySignature.type,
271
- hasQuestionToken: bodySignature.hasQuestionToken
391
+ isExported: true,
392
+ kind: StructureKind.Interface,
393
+ name: bodyParameterInterfaceName,
394
+ properties: [
395
+ {
396
+ docs: bodySignature.docs,
397
+ name: "body",
398
+ type: bodySignature.type,
399
+ hasQuestionToken: bodySignature.hasQuestionToken
400
+ }
401
+ ]
272
402
  }
273
- ]
274
- };
403
+ ];
404
+ }
275
405
  }
276
406
 
277
407
  /**
@@ -1,9 +1,8 @@
1
1
  import { readFileSync } from "fs";
2
- import { getSession } from "../autorestSession";
3
- import { extractPaginationDetails } from "../utils/extractPaginationDetails";
4
2
  import * as path from "path";
5
3
  import * as hbs from "handlebars";
6
4
  import { Project } from "ts-morph";
5
+ import { getAutorestOptions } from "../autorestSession";
7
6
 
8
7
  export function generatePollingHelper(project: Project) {
9
8
  let file: string = "";
@@ -13,7 +12,8 @@ export function generatePollingHelper(project: Project) {
13
12
  });
14
13
 
15
14
  const readmeFileContents = hbs.compile(file, { noEscape: true });
16
- project.createSourceFile("src/pollingHelper.ts", readmeFileContents({}), {
15
+ const { srcPath } = getAutorestOptions();
16
+ project.createSourceFile(path.join(srcPath, "pollingHelper.ts"), readmeFileContents({}), {
17
17
  overwrite: true
18
18
  });
19
19
  }
@@ -22,10 +22,13 @@ import { NameType, normalizeName } from "../utils/nameUtils";
22
22
  import { getElementType, getFormatDocs, primitiveSchemaToType } from "./schemaHelpers";
23
23
  import { getLanguageMetadata } from "../utils/languageHelpers";
24
24
  import { hasOutputModels } from "./helpers/modelHelpers";
25
+ import { getAutorestOptions } from "../autorestSession";
26
+ import * as path from 'path';
25
27
 
26
28
  export function generateResponseInterfaces(model: CodeModel, project: Project) {
29
+ const { srcPath } = getAutorestOptions();
27
30
  const responsesFile = project.createSourceFile(
28
- `src/responses.ts`,
31
+ path.join(srcPath, `responses.ts`),
29
32
  undefined,
30
33
  {
31
34
  overwrite: true
@@ -1,4 +1,4 @@
1
- import { getHost, getSession } from "../autorestSession";
1
+ import { getAutorestOptions, getHost, getSession } from "../autorestSession";
2
2
  import { Project, IndentationText } from "ts-morph";
3
3
  import { generatePackageJson } from "../generators/static/packageFileGenerator";
4
4
  import { generateLicenseFile } from "../generators/static/licenseFileGenerator";
@@ -10,18 +10,32 @@ import { generateSchemaTypes } from "./generateSchemaTypes";
10
10
  import { format } from "prettier";
11
11
  import { prettierJSONOptions, prettierTypeScriptOptions } from "./config";
12
12
  import { generateParameterInterfaces } from "./generateParameterTypes";
13
- import { generatePathFirstClient } from "./generateClient";
13
+ import { generatePathFirstClient } from "./generateClientDefinition";
14
+ import { generateClient } from "./generateClient";
14
15
  import { generateIndexFile } from "../generators/indexGenerator";
15
16
  import { generatePagingHelper } from "./generatePagingHelper";
16
17
  import { generatePollingHelper } from "./generatePollingHelper";
18
+ import { generateTopLevelIndexFile } from "./generateTopLevelIndexFile";
17
19
  import { hasPagingOperations } from "../utils/extractPaginationDetails";
18
20
  import { hasPollingOperations } from "./helpers/hasPollingOperations";
21
+ import { generateKarmaConfigFile } from "../generators/static/karmaConfigFileGenerator";
22
+ import { generateEnvFile } from "../generators/test/envFileGenerator";
23
+ import { generateEnvBrowserFile } from "../generators/test/envBrowserFileGenerator";
24
+ import { generateRecordedClientFile } from "../generators/test/recordedClientFileGenerator";
25
+ import { generateSampleTestFile } from "../generators/test/sampleTestGenerator";
26
+ import { generateEsLintConfig } from "../generators/static/esLintConfigGenerator";
27
+ import { generateRollupConfig } from "../generators/static/rollupConfigFileGenerator";
28
+ import { generateReadmeFile } from "../generators/static/readmeFileGenerator";
29
+ import * as path from "path";
30
+ import * as fsextra from "fs-extra";
31
+
19
32
  /**
20
33
  * Generates a Rest Level Client library
21
34
  */
22
35
  export async function generateRestLevelClient() {
23
36
  const host = getHost();
24
37
  const { model } = getSession();
38
+ const { outputPath, srcPath } = getAutorestOptions();
25
39
 
26
40
  const project = new Project({
27
41
  useInMemoryFileSystem: true,
@@ -39,19 +53,34 @@ export async function generateRestLevelClient() {
39
53
  }
40
54
 
41
55
  performCodeModelMutations(model);
56
+ generateReadmeFile(model.language, model.info, project);
42
57
  generatePackageJson(project);
43
58
  generateLicenseFile(project);
44
59
  generateTsConfig(project);
45
60
  generateApiExtractorConfig(project);
61
+ generateRollupConfig(project);
62
+ generateEsLintConfig(project);
63
+
64
+ generateKarmaConfigFile(project);
65
+ generateEnvFile(project);
66
+ generateEnvBrowserFile(project);
67
+ generateRecordedClientFile(project);
68
+ generateSampleTestFile(project);
69
+
46
70
  generateResponseInterfaces(model, project);
47
71
  generateSchemaTypes(model, project);
48
72
  generateParameterInterfaces(model, project);
49
73
  generatePathFirstClient(model, project);
74
+ generateClient(model, project);
50
75
  generateIndexFile(project);
51
76
 
77
+ generateTopLevelIndexFile(model, project);
78
+
52
79
  // Save the source files to the virtual filesystem
53
80
  project.saveSync();
54
81
  const fs = project.getFileSystem();
82
+ const pathToClear = outputPath ? path.join(outputPath, srcPath) : srcPath;
83
+ fsextra.emptyDirSync(`${pathToClear}`);
55
84
 
56
85
  // Loop over the files
57
86
  for (const file of project.getSourceFiles()) {
@@ -61,7 +90,7 @@ export async function generateRestLevelClient() {
61
90
  let fileContents = fs.readFileSync(filePath);
62
91
  const licenseHeader = `// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n`;
63
92
 
64
- if (!isJson) {
93
+ if (isSourceCode) {
65
94
  fileContents = `${licenseHeader.trimLeft()}\n${fileContents}`;
66
95
  }
67
96
 
@@ -72,11 +101,10 @@ export async function generateRestLevelClient() {
72
101
  isJson ? prettierJSONOptions : prettierTypeScriptOptions
73
102
  );
74
103
  }
75
-
76
104
  // Write the file to the AutoRest host
77
- host.WriteFile(
78
- filePath.substr(1), // Get rid of the leading slash '/'
79
- fileContents
80
- );
105
+ host.writeFile({
106
+ filename: filePath.substr(1), // Get rid of the leading slash '/'
107
+ content: fileContents
108
+ });
81
109
  }
82
110
  }
@@ -1,9 +1,11 @@
1
1
  import { CodeModel, SchemaContext } from "@autorest/codemodel";
2
2
  import { Project } from "ts-morph";
3
+ import * as path from 'path';
3
4
  import {
4
5
  buildObjectInterfaces,
5
6
  buildPolymorphicAliases
6
7
  } from "./generateObjectTypes";
8
+ import { getAutorestOptions } from "../autorestSession";
7
9
 
8
10
  /**
9
11
  * Generates types to represent schema definitions in the swagger
@@ -18,10 +20,10 @@ export function generateSchemaTypes(model: CodeModel, project: Project) {
18
20
  const objectTypeAliases = buildPolymorphicAliases(model, [
19
21
  SchemaContext.Input
20
22
  ]);
21
-
23
+ const { srcPath } = getAutorestOptions();
22
24
  if (objectTypeAliases.length || objectsDefinitions.length) {
23
25
  const inputModelsFile = project.createSourceFile(
24
- `src/models.ts`,
26
+ path.join(srcPath, `models.ts`),
25
27
  undefined,
26
28
  {
27
29
  overwrite: true
@@ -42,7 +44,7 @@ export function generateSchemaTypes(model: CodeModel, project: Project) {
42
44
 
43
45
  if (outputObjectTypeAliases.length || outputObjectsDefinitions.length) {
44
46
  const outputModelsFile = project.createSourceFile(
45
- `src/outputModels.ts`,
47
+ path.join(srcPath, `outputModels.ts`),
46
48
  undefined,
47
49
  {
48
50
  overwrite: true
@@ -0,0 +1,37 @@
1
+ import { Project } from 'ts-morph';
2
+ import * as path from 'path';
3
+ import { getAutorestOptions } from '../autorestSession';
4
+ import { CodeModel } from '@autorest/codemodel';
5
+ import { NameType, normalizeName } from '../utils/nameUtils';
6
+
7
+ const batchOutputFolder: [string, string, string][] = [];
8
+
9
+ export function generateTopLevelIndexFile(model: CodeModel, project: Project) {
10
+ const { multiClient, batch, srcPath } = getAutorestOptions();
11
+ if (srcPath) {
12
+ const clientName = model.language.default.name;
13
+ const moduleName = normalizeName(clientName, NameType.File);
14
+ const relativePath = srcPath.replace('/src', '');
15
+ batchOutputFolder.push([relativePath, clientName, moduleName]);
16
+ }
17
+
18
+ if (multiClient && batch && batch.length > 1 && batchOutputFolder.length === batch.length) {
19
+ const { srcPath } = getAutorestOptions();
20
+ const fileDirectory= path.join(srcPath as string, '../../');
21
+ const file = project.createSourceFile('/src/index.ts', undefined, {
22
+ overwrite: true
23
+ });
24
+ file.moveToDirectory(fileDirectory);
25
+ const allModules: string[] = [];
26
+ batchOutputFolder.forEach(item => {
27
+ file.addImportDeclaration({
28
+ namespaceImport: item[1],
29
+ moduleSpecifier: `${item[0]}`
30
+ });
31
+ allModules.push(item[1]);
32
+ });
33
+ file.addExportDeclaration({
34
+ namedExports: [...allModules]
35
+ });
36
+ }
37
+ }
@@ -0,0 +1,93 @@
1
+ import {
2
+ ImplementationLocation,
3
+ Operation,
4
+ Parameter,
5
+ SchemaContext
6
+ } from "@autorest/codemodel";
7
+ import {
8
+ OptionalKind,
9
+ MethodSignatureStructure,
10
+ ParameterDeclarationStructure
11
+ } from "ts-morph";
12
+ import { Methods, PathParameter } from "../interfaces";
13
+ import { getElementType } from "../schemaHelpers";
14
+
15
+ /**
16
+ * Given an operation, extract all its parameters
17
+ */
18
+ export function getOperationParameters(
19
+ operation: Operation,
20
+ requestIndex = 0
21
+ ): Parameter[] {
22
+ const operationParams = [
23
+ ...(operation.parameters ?? []),
24
+ ...(operation.signatureParameters ?? [])
25
+ ];
26
+
27
+ const distinctParams = new Set(operationParams);
28
+
29
+ if (operation.requests) {
30
+ [
31
+ ...(operation.requests[requestIndex].parameters ?? []),
32
+ ...(operation.requests[requestIndex].signatureParameters ?? [])
33
+ ].forEach(p => distinctParams.add(p));
34
+ }
35
+
36
+ return [...distinctParams].filter(filterMethodNotSynthetic);
37
+ }
38
+
39
+ function filterMethodNotSynthetic(parameter: Parameter) {
40
+ const isApiVersion =
41
+ parameter.origin &&
42
+ parameter.language.default.serializedName === "api-version" &&
43
+ parameter.implementation === ImplementationLocation.Method;
44
+ // Origin is added by M4 on synthetic parameters
45
+ return (
46
+ (!parameter.origin || isApiVersion) &&
47
+ parameter.implementation === ImplementationLocation.Method
48
+ );
49
+ }
50
+
51
+ export function buildMethodDefinitions(
52
+ methods: Methods,
53
+ pathParams: PathParameter[] = []
54
+ ): OptionalKind<MethodSignatureStructure>[] {
55
+ const methodDefinitions: OptionalKind<MethodSignatureStructure>[] = [];
56
+ for (const key of Object.keys(methods)) {
57
+ const method = methods[key];
58
+ const description = methods[key][0].description;
59
+
60
+ let areAllOptional = methods[key][0].hasOptionalOptions;
61
+
62
+ methodDefinitions.push({
63
+ name: key,
64
+ ...(description && { docs: [{ description }] }),
65
+ parameters: [
66
+ ...getPathParamDefinitions(pathParams),
67
+ {
68
+ name: "options",
69
+ hasQuestionToken: areAllOptional,
70
+ type: method.map(m => m.optionsName).join(" | ")
71
+ }
72
+ ],
73
+ returnType: method.map(m => m.returnType).join(" | ")
74
+ });
75
+ }
76
+
77
+ return methodDefinitions;
78
+ }
79
+
80
+ export function getPathParamDefinitions(
81
+ pathParams: PathParameter[]
82
+ ): OptionalKind<ParameterDeclarationStructure>[] {
83
+ return pathParams.map(p => {
84
+ return {
85
+ name: p.name,
86
+ type: getElementType(p.schema, [
87
+ SchemaContext.Input,
88
+ SchemaContext.Exception
89
+ ]),
90
+ description: p.description
91
+ };
92
+ });
93
+ }
@@ -0,0 +1,26 @@
1
+ import { Schema } from "@autorest/codemodel";
2
+
3
+ export type PathParameter = {
4
+ name: string;
5
+ schema: Schema;
6
+ description?: string;
7
+ };
8
+
9
+ export type Methods = {
10
+ [key: string]: [
11
+ {
12
+ optionsName: string;
13
+ description: string;
14
+ hasOptionalOptions: boolean;
15
+ returnType: string;
16
+ }
17
+ ];
18
+ };
19
+
20
+ export type Paths = {
21
+ [key: string]: {
22
+ name: string;
23
+ pathParameters: PathParameter[];
24
+ methods: Methods;
25
+ };
26
+ };
@@ -2,7 +2,9 @@ import {
2
2
  AnyObjectSchema,
3
3
  Operation,
4
4
  SchemaResponse,
5
- Response
5
+ Response,
6
+ Schema,
7
+ BinarySchema
6
8
  } from "@autorest/codemodel";
7
9
  import { getLanguageMetadata } from "../utils/languageHelpers";
8
10
  import { NameType, normalizeName } from "../utils/nameUtils";
@@ -22,7 +24,11 @@ export function getResponseTypeName(
22
24
 
23
25
  export function responseToSchemaResponse(response: Response | SchemaResponse) {
24
26
  if (!isSchemaResponse(response)) {
25
- return new SchemaResponse(new AnyObjectSchema("AnyObject schema"), {
27
+ let schema: Schema = (response as any).binary
28
+ ? new BinarySchema("Binary schema")
29
+ : new AnyObjectSchema("AnyObject schema");
30
+
31
+ return new SchemaResponse(schema, {
26
32
  ...response
27
33
  });
28
34
  } else {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  AnyObjectSchema,
3
3
  ArraySchema,
4
- ByteArraySchema,
5
4
  ChoiceSchema,
6
5
  ConstantSchema,
6
+ DateTimeSchema,
7
7
  DictionarySchema,
8
8
  isObjectSchema,
9
9
  ObjectSchema,
@@ -115,7 +115,6 @@ export function primitiveSchemaToType(
115
115
  case SchemaType.Char:
116
116
  return "string";
117
117
  case SchemaType.ByteArray:
118
- case SchemaType.Binary:
119
118
  case SchemaType.Duration:
120
119
  case SchemaType.Credential:
121
120
  case SchemaType.UnixTime:
@@ -123,6 +122,10 @@ export function primitiveSchemaToType(
123
122
  case SchemaType.Uuid:
124
123
  case SchemaType.String:
125
124
  return "string";
125
+ case SchemaType.Binary:
126
+ return schemaUse.includes(SchemaContext.Output)
127
+ ? "Uint8Array"
128
+ : "string | Uint8Array";
126
129
  case SchemaType.Boolean:
127
130
  return "boolean";
128
131
  case SchemaType.Choice:
@@ -132,7 +135,11 @@ export function primitiveSchemaToType(
132
135
  .join(" | ");
133
136
  case SchemaType.Constant:
134
137
  const value = (schema as ConstantSchema).value.value;
135
- return typeof value === "string" ? `"${value}"` : value;
138
+ return typeof value === "string"
139
+ ? (schema as ConstantSchema)?.valueType?.type === SchemaType.DateTime
140
+ ? `"${(new Date(`${value}`)).toISOString()}"`
141
+ : `"${value}"`
142
+ : value;
136
143
  }
137
144
 
138
145
  throw new Error(`Unknown primitive schema ${schema.type}`);
@@ -693,7 +693,7 @@ function processProperties(
693
693
  const propName = getLanguageMetadata(prop.language).name;
694
694
  const name = normalizeName(
695
695
  propName,
696
- NameType.Property,
696
+ prop.language.default.isTopLevelParameter? NameType.Parameter: NameType.Property,
697
697
  true /** shouldGuard */
698
698
  );
699
699
  modelProperties[name] = getMapperOrRef(prop.schema, serializedName, {
@@ -92,7 +92,7 @@ export function transformProperty({
92
92
  return {
93
93
  name: normalizeName(
94
94
  metadata.name,
95
- NameType.Property,
95
+ metadata.isTopLevelParameter? NameType.Parameter: NameType.Property,
96
96
  true /** shouldGuard */
97
97
  ),
98
98
  description,
@@ -491,6 +491,7 @@ export async function transformOperationGroup(
491
491
  return {
492
492
  name: operationGroupClassName,
493
493
  key: operationGroup.$key,
494
+ originalKey: operationGroup.$key,
494
495
  operations,
495
496
  isTopLevel,
496
497
  mediaTypes