@autorest/typescript 6.0.0-alpha.16.20220105.1 → 6.0.0-alpha.16.20220119.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 (55) hide show
  1. package/dist/src/autorestSession.d.ts +1 -0
  2. package/dist/src/autorestSession.d.ts.map +1 -1
  3. package/dist/src/autorestSession.js.map +1 -1
  4. package/dist/src/generators/indexGenerator.d.ts.map +1 -1
  5. package/dist/src/generators/indexGenerator.js +66 -3
  6. package/dist/src/generators/indexGenerator.js.map +1 -1
  7. package/dist/src/generators/static/packageFileGenerator.js +6 -0
  8. package/dist/src/generators/static/packageFileGenerator.js.map +1 -1
  9. package/dist/src/restLevelClient/generateClient.d.ts +1 -1
  10. package/dist/src/restLevelClient/generateClient.d.ts.map +1 -1
  11. package/dist/src/restLevelClient/generateClient.js +23 -193
  12. package/dist/src/restLevelClient/generateClient.js.map +1 -1
  13. package/dist/src/restLevelClient/generateClientDefinition.d.ts +6 -0
  14. package/dist/src/restLevelClient/generateClientDefinition.d.ts.map +1 -0
  15. package/dist/src/restLevelClient/generateClientDefinition.js +228 -0
  16. package/dist/src/restLevelClient/generateClientDefinition.js.map +1 -0
  17. package/dist/src/restLevelClient/generatePagingHelper.d.ts.map +1 -1
  18. package/dist/src/restLevelClient/generatePagingHelper.js +2 -1
  19. package/dist/src/restLevelClient/generatePagingHelper.js.map +1 -1
  20. package/dist/src/restLevelClient/generateParameterTypes.d.ts.map +1 -1
  21. package/dist/src/restLevelClient/generateParameterTypes.js +51 -1
  22. package/dist/src/restLevelClient/generateParameterTypes.js.map +1 -1
  23. package/dist/src/restLevelClient/generatePollingHelper.d.ts.map +1 -1
  24. package/dist/src/restLevelClient/generatePollingHelper.js +3 -1
  25. package/dist/src/restLevelClient/generatePollingHelper.js.map +1 -1
  26. package/dist/src/restLevelClient/generateResponseTypes.d.ts.map +1 -1
  27. package/dist/src/restLevelClient/generateResponseTypes.js +4 -1
  28. package/dist/src/restLevelClient/generateResponseTypes.js.map +1 -1
  29. package/dist/src/restLevelClient/generateRestLevel.d.ts.map +1 -1
  30. package/dist/src/restLevelClient/generateRestLevel.js +5 -1
  31. package/dist/src/restLevelClient/generateRestLevel.js.map +1 -1
  32. package/dist/src/restLevelClient/generateSchemaTypes.d.ts.map +1 -1
  33. package/dist/src/restLevelClient/generateSchemaTypes.js +5 -2
  34. package/dist/src/restLevelClient/generateSchemaTypes.js.map +1 -1
  35. package/dist/src/restLevelClient/generateTopLevelIndexFile.d.ts +4 -0
  36. package/dist/src/restLevelClient/generateTopLevelIndexFile.d.ts.map +1 -0
  37. package/dist/src/restLevelClient/generateTopLevelIndexFile.js +41 -0
  38. package/dist/src/restLevelClient/generateTopLevelIndexFile.js.map +1 -0
  39. package/dist/src/utils/autorestOptions.d.ts.map +1 -1
  40. package/dist/src/utils/autorestOptions.js +8 -0
  41. package/dist/src/utils/autorestOptions.js.map +1 -1
  42. package/package.json +2 -2
  43. package/src/autorestSession.ts +1 -0
  44. package/src/generators/indexGenerator.ts +75 -4
  45. package/src/generators/static/packageFileGenerator.ts +6 -0
  46. package/src/restLevelClient/generateClient.ts +25 -276
  47. package/src/restLevelClient/generateClientDefinition.ts +325 -0
  48. package/src/restLevelClient/generatePagingHelper.ts +3 -2
  49. package/src/restLevelClient/generateParameterTypes.ts +91 -2
  50. package/src/restLevelClient/generatePollingHelper.ts +3 -1
  51. package/src/restLevelClient/generateResponseTypes.ts +4 -1
  52. package/src/restLevelClient/generateRestLevel.ts +8 -2
  53. package/src/restLevelClient/generateSchemaTypes.ts +5 -3
  54. package/src/restLevelClient/generateTopLevelIndexFile.ts +41 -0
  55. package/src/utils/autorestOptions.ts +9 -0
@@ -0,0 +1,325 @@
1
+ import {
2
+ CodeModel,
3
+ Operation,
4
+ ParameterLocation,
5
+ ImplementationLocation
6
+ } from "@autorest/codemodel";
7
+
8
+ import { getResponseTypeName } from "./operationHelpers";
9
+
10
+ import {
11
+ CallSignatureDeclarationStructure,
12
+ Project,
13
+ SourceFile,
14
+ StructureKind,
15
+ Writers
16
+ } from "ts-morph";
17
+ import * as path from 'path';
18
+
19
+ import { getAutorestOptions, getSession } from "../autorestSession";
20
+ import { transformBaseUrl } from "../transforms/urlTransforms";
21
+ import { NameType, normalizeName } from "../utils/nameUtils";
22
+ import { getLanguageMetadata } from "../utils/languageHelpers";
23
+ import {
24
+ buildMethodDefinitions,
25
+ getOperationParameters,
26
+ getPathParamDefinitions
27
+ } from "./helpers/operationHelpers";
28
+ import { generateMethodShortcuts } from "./generateMethodShortcuts";
29
+ import { Methods, PathParameter, Paths } from "./interfaces";
30
+ export let pathDictionary: Paths = {};
31
+
32
+ export function generatePathFirstClient(model: CodeModel, project: Project) {
33
+ const name = normalizeName(
34
+ getLanguageMetadata(model.language).name,
35
+ NameType.File
36
+ );
37
+ const { srcPath } = getAutorestOptions();
38
+ const clientFile = project.createSourceFile(path.join(srcPath, `clientDefinitions.ts`), undefined, {
39
+ overwrite: true
40
+ });
41
+
42
+ // Get all paths
43
+ const importedParameters = new Set<string>();
44
+ const importedResponses = new Set<string>();
45
+ pathDictionary = {};
46
+ for (const operationGroup of model.operationGroups) {
47
+ for (const operation of operationGroup.operations) {
48
+ const operationName = getLanguageMetadata(operation.language).name;
49
+ const operationDescription = getLanguageMetadata(operation.language)
50
+ .description;
51
+ const pathParameters: PathParameter[] =
52
+ operation.parameters
53
+ ?.filter(p => p.protocol.http?.in === ParameterLocation.Path)
54
+ .map(p => {
55
+ const languageMetadata = getLanguageMetadata(p.language);
56
+ return {
57
+ name: languageMetadata.serializedName || languageMetadata.name,
58
+ schema: p.schema,
59
+ description: languageMetadata.description
60
+ };
61
+ }) || [];
62
+ const path: string = operation.requests?.[0].protocol.http?.path;
63
+ pathParameters.sort(function compare(a: PathParameter, b: PathParameter) {
64
+ return path.indexOf(a.name) - path.indexOf(b.name);
65
+ });
66
+
67
+ for (const request of operation.requests || []) {
68
+ const path: string = (request.protocol.http?.path as string) || "";
69
+ const method = request.protocol.http?.method;
70
+
71
+ if (path && method) {
72
+ if (!pathDictionary[path]) {
73
+ pathDictionary[path] = {
74
+ pathParameters,
75
+ methods: {},
76
+ name: operationName
77
+ };
78
+ }
79
+ const hasOptionalOptions = !hasRequiredOptions(operation);
80
+
81
+ const newMethod = {
82
+ description: operationDescription,
83
+ optionsName: getOperationOptionsType(operation, importedParameters),
84
+ hasOptionalOptions,
85
+ returnType: `Promise<${getOperationReturnType(
86
+ operation,
87
+ importedResponses
88
+ )}>`
89
+ };
90
+
91
+ if (pathDictionary[path].methods[`${method}`]) {
92
+ pathDictionary[path].methods[`${method}`].push(newMethod);
93
+ } else {
94
+ pathDictionary[path].methods[`${method}`] = [newMethod];
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ writeShortcutInterface(model, pathDictionary, clientFile);
102
+ clientFile.addInterface({
103
+ name: "Routes",
104
+ isExported: true,
105
+ callSignatures: getPathFirstRoutesInterfaceDefinition(
106
+ pathDictionary,
107
+ clientFile
108
+ )
109
+ });
110
+
111
+ const clientName = getLanguageMetadata(model.language).name;
112
+ const uriParameter = getClientUriParameter();
113
+
114
+ const { addCredentials, credentialKeyHeaderName } = getAutorestOptions();
115
+ const credentialTypes = addCredentials ? ["TokenCredential"] : [];
116
+
117
+ if (credentialKeyHeaderName) {
118
+ credentialTypes.push("KeyCredential");
119
+ }
120
+
121
+ const clientIterfaceName = `${clientName}RestClient`;
122
+
123
+ const { rlcShortcut } = getAutorestOptions();
124
+
125
+ let shortcutElements = !rlcShortcut
126
+ ? []
127
+ : model.operationGroups.map(og => {
128
+ const groupName = og.language.default.name;
129
+ const name = normalizeName(groupName, NameType.Property);
130
+ const interfaceName = normalizeName(
131
+ `${name}Operations`,
132
+ NameType.Interface
133
+ );
134
+ return { name, type: interfaceName };
135
+ });
136
+
137
+ // There may be operations without an operation group, those shortcut
138
+ // methods need to be handled differently.
139
+ const shortcutsInOperationGroup = shortcutElements.filter(s => s.name);
140
+
141
+ clientFile.addTypeAlias({
142
+ isExported: true,
143
+ name: clientIterfaceName,
144
+ type: Writers.intersectionType(
145
+ "Client",
146
+ Writers.objectType({
147
+ properties: [
148
+ { name: "path", type: "Routes" },
149
+ ...shortcutsInOperationGroup
150
+ ]
151
+ }),
152
+ // If the length of shortcutMethods in operation group and all shortcutMethods
153
+ // is the same, then we don't have any operations at the client level
154
+ // Otherwise we need to make the client interface name an union with the
155
+ // definition of all client level shortcut methods
156
+ ...(shortcutsInOperationGroup.length !== shortcutElements.length
157
+ ? [`ClientOperations`]
158
+ : [])
159
+ )
160
+ });
161
+
162
+ if (importedParameters.size) {
163
+ clientFile.addImportDeclaration({
164
+ namedImports: [...importedParameters],
165
+ moduleSpecifier: "./parameters"
166
+ });
167
+ }
168
+
169
+ if (importedResponses.size) {
170
+ clientFile.addImportDeclaration({
171
+ namedImports: [...importedResponses],
172
+ moduleSpecifier: "./responses"
173
+ });
174
+ }
175
+
176
+ clientFile.addImportDeclarations([
177
+ {
178
+ namedImports: ["Client"],
179
+ moduleSpecifier: "@azure-rest/core-client"
180
+ }
181
+ ]);
182
+
183
+ clientFile.addImportDeclarations([
184
+ {
185
+ namedImports: credentialTypes,
186
+ moduleSpecifier: "@azure/core-auth"
187
+ }
188
+ ]);
189
+ }
190
+
191
+ function writeShortcutInterface(
192
+ model: CodeModel,
193
+ pathDictionary: Paths,
194
+ clientFile: SourceFile
195
+ ) {
196
+ const { rlcShortcut } = getAutorestOptions();
197
+ if (!rlcShortcut) {
198
+ return;
199
+ }
200
+
201
+ // Create a map of Operation group descriptions
202
+ const descriptions = model.operationGroups.reduce((map, current) => {
203
+ const { name, description } = current.language.default;
204
+ map.set(name, description);
205
+
206
+ return map;
207
+ }, new Map<string, string>());
208
+
209
+ const shortcuts = generateMethodShortcuts(model, pathDictionary);
210
+
211
+ for (const group of Object.keys(shortcuts)) {
212
+ const groupName = normalizeName(group, NameType.Interface) || "Client";
213
+ const groupOperations = shortcuts[group];
214
+
215
+ clientFile.addInterface({
216
+ docs: [
217
+ descriptions.get(group) ||
218
+ `Contains operations for ${groupName} operations`
219
+ ],
220
+ name: `${groupName}Operations`,
221
+ isExported: true,
222
+ methods: groupOperations
223
+ });
224
+ }
225
+ }
226
+
227
+ function hasRequiredOptions(operation: Operation) {
228
+ return getOperationParameters(operation)
229
+ .filter(p => p.implementation === ImplementationLocation.Method)
230
+ .filter(p => ["query", "body", "headers"].includes(p.protocol.http?.in))
231
+ .some(p => p.required);
232
+ }
233
+
234
+ function getOperationOptionsType(
235
+ operation: Operation,
236
+ importedParameters = new Set<string>()
237
+ ) {
238
+ const paramsName = `${
239
+ getLanguageMetadata(operation.language).name
240
+ }Parameters`;
241
+ importedParameters.add(paramsName);
242
+
243
+ return paramsName;
244
+ }
245
+
246
+ function getOperationReturnType(
247
+ operation: Operation,
248
+ importedResponses = new Set<string>()
249
+ ) {
250
+ let returnType: string = "HttpResponse";
251
+ if (operation.responses && operation.responses.length) {
252
+ const responses = [...operation.responses, ...(operation.exceptions || [])];
253
+
254
+ const responseTypes = responses
255
+ .filter(
256
+ r => r.protocol.http?.statusCodes && r.protocol.http?.statusCodes.length
257
+ )
258
+ .map(r => {
259
+ const responseName = getResponseTypeName(operation, r);
260
+ importedResponses.add(responseName);
261
+ return responseName;
262
+ });
263
+
264
+ if (responseTypes.length) {
265
+ returnType = responseTypes.join(" | ");
266
+ }
267
+ }
268
+
269
+ return returnType;
270
+ }
271
+
272
+ function getPathFirstRoutesInterfaceDefinition(
273
+ paths: Paths,
274
+ sourcefile: SourceFile
275
+ ): CallSignatureDeclarationStructure[] {
276
+ const signatures: CallSignatureDeclarationStructure[] = [];
277
+ for (const key of Object.keys(paths)) {
278
+ generatePathFirstRouteMethodsDefinition(
279
+ paths[key].name,
280
+ paths[key].methods,
281
+ sourcefile
282
+ );
283
+ const pathParams = paths[key].pathParameters;
284
+ signatures.push({
285
+ docs: [
286
+ `Resource for '${key
287
+ .replace(/}/g, "\\}")
288
+ .replace(
289
+ /{/g,
290
+ "\\{"
291
+ )}' has methods for the following verbs: ${Object.keys(
292
+ paths[key].methods
293
+ ).join(", ")}`
294
+ ],
295
+ parameters: [
296
+ { name: "path", type: `"${key}"` },
297
+ ...getPathParamDefinitions(pathParams)
298
+ ],
299
+ returnType: paths[key].name,
300
+ kind: StructureKind.CallSignature
301
+ });
302
+ }
303
+ return signatures;
304
+ }
305
+
306
+ function getClientUriParameter() {
307
+ const { model } = getSession();
308
+ const { parameterName } = transformBaseUrl(model);
309
+ return parameterName;
310
+ }
311
+
312
+ function generatePathFirstRouteMethodsDefinition(
313
+ operationName: string,
314
+ methods: Methods,
315
+ file: SourceFile
316
+ ): void {
317
+ const methodDefinitions = buildMethodDefinitions(methods);
318
+
319
+ file.addInterface({
320
+ methods: methodDefinitions,
321
+ name: operationName,
322
+ isExported: true
323
+ });
324
+ }
325
+
@@ -1,5 +1,5 @@
1
1
  import { readFileSync } from "fs";
2
- import { getSession } from "../autorestSession";
2
+ import { getAutorestOptions, getSession } from "../autorestSession";
3
3
  import { extractPaginationDetails } from "../utils/extractPaginationDetails";
4
4
  import * as path from "path";
5
5
  import * as hbs from "handlebars";
@@ -29,9 +29,10 @@ export function generatePagingHelper(project: Project) {
29
29
  return `"${value}"`;
30
30
  });
31
31
 
32
+ const { srcPath } = getAutorestOptions();
32
33
  const readmeFileContents = hbs.compile(file, { noEscape: true });
33
34
  project.createSourceFile(
34
- "src/paginateHelper.ts",
35
+ path.join(srcPath, "paginateHelper.ts"),
35
36
  readmeFileContents(pagingInfo),
36
37
  {
37
38
  overwrite: true
@@ -3,7 +3,8 @@ 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,
@@ -12,12 +13,14 @@ import {
12
13
  SourceFile,
13
14
  StructureKind
14
15
  } from "ts-morph";
16
+ import * as path from 'path';
15
17
  import { getLanguageMetadata } from "../utils/languageHelpers";
16
18
  import { NameType, normalizeName } from "../utils/nameUtils";
17
19
  import { getPropertySignature } from "./getPropertySignature";
18
20
  import { primitiveSchemaToType } from "./schemaHelpers";
19
21
  import { getOperationParameters } from "./helpers/operationHelpers";
20
22
  import { hasInputModels } from "./helpers/modelHelpers";
23
+ import { getAutorestOptions } from "../autorestSession";
21
24
 
22
25
  /**
23
26
  * Generates the interfaces describing each operation parameters
@@ -26,8 +29,9 @@ export function generateParameterInterfaces(
26
29
  model: CodeModel,
27
30
  project: Project
28
31
  ) {
32
+ const { srcPath } = getAutorestOptions();
29
33
  const parametersFile = project.createSourceFile(
30
- `src/parameters.ts`,
34
+ path.join(srcPath, `parameters.ts`),
31
35
  undefined,
32
36
  {
33
37
  overwrite: true
@@ -74,6 +78,15 @@ export function generateParameterInterfaces(
74
78
 
75
79
  const request = operation.requests ? operation.requests[i] : undefined;
76
80
 
81
+ const pathParameterDefinitions = buildPathParameterDefinitions(
82
+ operationName,
83
+ parameters,
84
+ model,
85
+ parametersFile,
86
+ internalReferences,
87
+ i
88
+ )
89
+
77
90
  const headerParameterDefinitions = buildHeaderParameterDefinitions(
78
91
  operationName,
79
92
  parameters,
@@ -102,6 +115,7 @@ export function generateParameterInterfaces(
102
115
  parametersFile.addInterfaces([
103
116
  ...(bodyParameterDefinition ?? []),
104
117
  ...(queryParameterDefinitions ?? []),
118
+ ...(pathParameterDefinitions ? [pathParameterDefinitions]: []),
105
119
  ...(headerParameterDefinitions ? [headerParameterDefinitions] : []),
106
120
  ...(contentTypeParameterDefinition
107
121
  ? [contentTypeParameterDefinition]
@@ -233,6 +247,81 @@ function buildHeaderParameterDefinitions(
233
247
  };
234
248
  }
235
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
+ }
236
325
  /**
237
326
  * Gets the interface definition for an operation bodyParameters
238
327
  */
@@ -2,6 +2,7 @@ import { readFileSync } from "fs";
2
2
  import * as path from "path";
3
3
  import * as hbs from "handlebars";
4
4
  import { Project } from "ts-morph";
5
+ import { getAutorestOptions } from "../autorestSession";
5
6
 
6
7
  export function generatePollingHelper(project: Project) {
7
8
  let file: string = "";
@@ -11,7 +12,8 @@ export function generatePollingHelper(project: Project) {
11
12
  });
12
13
 
13
14
  const readmeFileContents = hbs.compile(file, { noEscape: true });
14
- project.createSourceFile("src/pollingHelper.ts", readmeFileContents({}), {
15
+ const { srcPath } = getAutorestOptions();
16
+ project.createSourceFile(path.join(srcPath, "pollingHelper.ts"), readmeFileContents({}), {
15
17
  overwrite: true
16
18
  });
17
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,10 +10,12 @@ 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";
19
21
  import { generateKarmaConfigFile } from "../generators/static/karmaConfigFileGenerator";
@@ -21,6 +23,7 @@ import { generateEnvFile } from "../generators/test/envFileGenerator";
21
23
  import { generateEnvBrowserFile } from "../generators/test/envBrowserFileGenerator";
22
24
  import { generateRecordedClientFile } from "../generators/test/recordedClientFileGenerator";
23
25
  import { generateSampleTestFile } from "../generators/test/sampleTestGenerator";
26
+
24
27
  /**
25
28
  * Generates a Rest Level Client library
26
29
  */
@@ -59,7 +62,10 @@ export async function generateRestLevelClient() {
59
62
  generateSchemaTypes(model, project);
60
63
  generateParameterInterfaces(model, project);
61
64
  generatePathFirstClient(model, project);
65
+ generateClient(model, project);
62
66
  generateIndexFile(project);
67
+
68
+ generateTopLevelIndexFile(model, project);
63
69
 
64
70
  // Save the source files to the virtual filesystem
65
71
  project.saveSync();
@@ -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,41 @@
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 { 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 (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
+ file.addExportDeclaration({
32
+ moduleSpecifier: `${item[0]}/${item[2]}`,
33
+ namedExports: [`${item[1]} as ${item[1]}Client`]
34
+ })
35
+ allModules.push(item[1]);
36
+ });
37
+ file.addExportDeclaration({
38
+ namedExports: [...allModules]
39
+ });
40
+ }
41
+ }
@@ -33,6 +33,7 @@ export async function extractAutorestOptions(): Promise<AutorestOptions> {
33
33
  const headAsBoolean = await getHeadAsBoolean(host);
34
34
  const isTestPackage = await getIsTestPackage(host);
35
35
  const generateTest = await getGenerateTest(host);
36
+ const batch = await getBatch(host);
36
37
  const generateSample = await getGenerateSample(host);
37
38
 
38
39
  return {
@@ -59,6 +60,7 @@ export async function extractAutorestOptions(): Promise<AutorestOptions> {
59
60
  headAsBoolean,
60
61
  isTestPackage,
61
62
  generateTest,
63
+ batch,
62
64
  generateSample
63
65
  };
64
66
  }
@@ -284,3 +286,10 @@ async function getAzureOutputDirectoryPath(
284
286
  ? outputDirectoryRelativePath
285
287
  : undefined;
286
288
  }
289
+
290
+
291
+ async function getBatch(host: AutorestExtensionHost): Promise<[string, any][] | undefined> {
292
+ const batch = await host.getValue<[string, any][]>('batch');
293
+ return batch;
294
+
295
+ }