@azure-tools/rlc-common 1.0.0-beta.1 → 1.0.0-beta.4

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 (88) hide show
  1. package/.eslintrc.json +23 -0
  2. package/.prettierignore +1 -0
  3. package/.prettierrc +7 -0
  4. package/.rush/temp/package-deps_build.json +25 -20
  5. package/.rush/temp/shrinkwrap-deps.json +81 -6
  6. package/CHANGELOG.md +15 -1
  7. package/CONTRIBUTING.md +29 -0
  8. package/README.md +3 -0
  9. package/dist/buildClient.js +44 -6
  10. package/dist/buildClient.js.map +1 -1
  11. package/dist/buildClientDefinitions.js.map +1 -1
  12. package/dist/buildIsUnexpectedHelper.js +52 -51
  13. package/dist/buildIsUnexpectedHelper.js.map +1 -1
  14. package/dist/buildMethodShortcuts.js +1 -1
  15. package/dist/buildMethodShortcuts.js.map +1 -1
  16. package/dist/buildObjectTypes.js +16 -9
  17. package/dist/buildObjectTypes.js.map +1 -1
  18. package/dist/buildParameterTypes.js +45 -3
  19. package/dist/buildParameterTypes.js.map +1 -1
  20. package/dist/buildResponseTypes.js +1 -1
  21. package/dist/buildResponseTypes.js.map +1 -1
  22. package/dist/helpers/nameConstructors.js +2 -2
  23. package/dist/helpers/nameConstructors.js.map +1 -1
  24. package/dist/helpers/nameUtils.js +1 -1
  25. package/dist/helpers/nameUtils.js.map +1 -1
  26. package/dist/helpers/operationHelpers.js +1 -1
  27. package/dist/helpers/operationHelpers.js.map +1 -1
  28. package/dist/helpers/shortcutMethods.js +1 -1
  29. package/dist/helpers/shortcutMethods.js.map +1 -1
  30. package/dist/interfaces.js.map +1 -1
  31. package/dist/metadata/buildPackageFile.js +2 -2
  32. package/dist/metadata/buildPackageFile.js.map +1 -1
  33. package/dist/metadata/buildReadmeFile.js +3 -3
  34. package/dist/package.json +1 -1
  35. package/dist/static/paginateContent.js +1 -1
  36. package/dist/test/template.js +1 -0
  37. package/dist/test/template.js.map +1 -1
  38. package/dist-esm/buildClient.js +43 -5
  39. package/dist-esm/buildClient.js.map +1 -1
  40. package/dist-esm/buildClientDefinitions.js +1 -1
  41. package/dist-esm/buildClientDefinitions.js.map +1 -1
  42. package/dist-esm/buildIsUnexpectedHelper.js +52 -51
  43. package/dist-esm/buildIsUnexpectedHelper.js.map +1 -1
  44. package/dist-esm/buildMethodShortcuts.js +1 -1
  45. package/dist-esm/buildMethodShortcuts.js.map +1 -1
  46. package/dist-esm/buildObjectTypes.js +16 -7
  47. package/dist-esm/buildObjectTypes.js.map +1 -1
  48. package/dist-esm/buildParameterTypes.js +49 -2
  49. package/dist-esm/buildParameterTypes.js.map +1 -1
  50. package/dist-esm/buildResponseTypes.js +1 -1
  51. package/dist-esm/buildResponseTypes.js.map +1 -1
  52. package/dist-esm/helpers/nameConstructors.js +2 -2
  53. package/dist-esm/helpers/nameConstructors.js.map +1 -1
  54. package/dist-esm/helpers/nameUtils.js +1 -1
  55. package/dist-esm/helpers/nameUtils.js.map +1 -1
  56. package/dist-esm/helpers/operationHelpers.js +1 -1
  57. package/dist-esm/helpers/operationHelpers.js.map +1 -1
  58. package/dist-esm/helpers/shortcutMethods.js +1 -1
  59. package/dist-esm/helpers/shortcutMethods.js.map +1 -1
  60. package/dist-esm/interfaces.js.map +1 -1
  61. package/dist-esm/metadata/buildPackageFile.js +2 -2
  62. package/dist-esm/metadata/buildPackageFile.js.map +1 -1
  63. package/dist-esm/metadata/buildReadmeFile.js +3 -3
  64. package/dist-esm/package.json +1 -1
  65. package/dist-esm/static/paginateContent.js +1 -1
  66. package/dist-esm/test/template.js +1 -0
  67. package/dist-esm/test/template.js.map +1 -1
  68. package/package.json +10 -4
  69. package/src/buildClient.ts +70 -7
  70. package/src/buildClientDefinitions.ts +6 -2
  71. package/src/buildIsUnexpectedHelper.ts +52 -52
  72. package/src/buildMethodShortcuts.ts +1 -1
  73. package/src/buildObjectTypes.ts +24 -8
  74. package/src/buildParameterTypes.ts +59 -3
  75. package/src/buildResponseTypes.ts +1 -1
  76. package/src/helpers/nameConstructors.ts +2 -2
  77. package/src/helpers/nameUtils.ts +1 -1
  78. package/src/helpers/operationHelpers.ts +1 -1
  79. package/src/helpers/schemaHelpers.ts +1 -1
  80. package/src/helpers/shortcutMethods.ts +1 -1
  81. package/src/interfaces.ts +8 -0
  82. package/src/metadata/buildPackageFile.ts +2 -2
  83. package/src/metadata/buildReadmeFile.ts +3 -3
  84. package/src/static/paginateContent.ts +1 -1
  85. package/src/test/template.ts +1 -0
  86. package/types/buildParameterTypes.d.ts +9 -1
  87. package/types/interfaces.d.ts +7 -0
  88. package/types/test/template.d.ts +1 -1
@@ -22,9 +22,9 @@ export function buildIsUnexpectedHelper(model: RLCModel) {
22
22
  });
23
23
 
24
24
  let map: Record<string, string[]> = {};
25
- let allResponseTypes: Set<string> = new Set();
26
- let allErrorTypes: Set<string> = new Set();
27
- let overloads: OptionalKind<FunctionDeclarationOverloadStructure>[] = [];
25
+ const allResponseTypes: Set<string> = new Set();
26
+ const allErrorTypes: Set<string> = new Set();
27
+ const overloads: OptionalKind<FunctionDeclarationOverloadStructure>[] = [];
28
28
  const pathDictionary = model.paths;
29
29
 
30
30
  for (const [path, details] of Object.entries(pathDictionary)) {
@@ -112,7 +112,7 @@ export function buildIsUnexpectedHelper(model: RLCModel) {
112
112
  } pathDetails = responseMap[\`\${method} \${url.pathname}\`];
113
113
  if (!pathDetails) {`,
114
114
  hasTemplate
115
- ? "pathDetails = geParametrizedPathSuccess(method, url.pathname);"
115
+ ? "pathDetails = getParametrizedPathSuccess(method, url.pathname);"
116
116
  : `return true;`,
117
117
  ` }
118
118
  return !pathDetails.includes(response.status);
@@ -122,7 +122,7 @@ export function buildIsUnexpectedHelper(model: RLCModel) {
122
122
  if (hasTemplate) {
123
123
  isErrorHelper.addFunction({
124
124
  isExported: false,
125
- name: "geParametrizedPathSuccess",
125
+ name: "getParametrizedPathSuccess",
126
126
  parameters: [
127
127
  {
128
128
  name: "method",
@@ -136,75 +136,75 @@ export function buildIsUnexpectedHelper(model: RLCModel) {
136
136
  returnType: `string[]`,
137
137
  statements: [
138
138
  `
139
- const pathParts = path.split("/");
140
-
141
- // Iterate the responseMap to find a match
142
- for (const [key, value] of Object.entries(responseMap)) {
143
- // Extracting the path from the map key which is in format
144
- // GET /path/foo
145
- if (!key.startsWith(method)) {
146
- continue;
147
- }
148
- const candidatePath = getPathFromMapKey(key);
149
- // Get each part of the url path
150
- const candidateParts = candidatePath.split("/");
151
-
152
- // If the candidate and actual paths don't match in size
153
- // we move on to the next candidate path
154
- if (
155
- candidateParts.length === pathParts.length &&
156
- hasParametrizedPath(key)
157
- ) {
139
+ const pathParts = path.split("/");
140
+
141
+ // Traverse list to match the longest candidate
142
+ // matchedLen: the length of candidate path
143
+ // matchedValue: the matched status code array
144
+ let matchedLen = -1,
145
+ matchedValue: string[] = [];
146
+
147
+ // Iterate the responseMap to find a match
148
+ for (const [key, value] of Object.entries(responseMap)) {
149
+ // Extracting the path from the map key which is in format
150
+ // GET /path/foo
151
+ if (!key.startsWith(method)) {
152
+ continue;
153
+ }
154
+ const candidatePath = getPathFromMapKey(key);
155
+ // Get each part of the url path
156
+ const candidateParts = candidatePath.split("/");
157
+
158
158
  // track if we have found a match to return the values found.
159
159
  let found = true;
160
- for (let i = 0; i < candidateParts.length; i++) {
160
+ for (
161
+ let i = candidateParts.length - 1, j = pathParts.length - 1;
162
+ i >= 1 && j >= 1;
163
+ i--, j--
164
+ ) {
161
165
  if (
162
166
  candidateParts[i]?.startsWith("{") &&
163
- candidateParts[i]?.endsWith("}")
167
+ candidateParts[i]?.indexOf("}") !== -1
164
168
  ) {
169
+ const start = candidateParts[i]!.indexOf("}") + 1,
170
+ end = candidateParts[i]?.length;
165
171
  // If the current part of the candidate is a "template" part
166
- // it is a match with the actual path part on hand
167
- // skip as the parameterized part can match anything
172
+ // Try to use the suffix of pattern to match the path
173
+ // {guid} ==> $
174
+ // {guid}:export ==> :export$
175
+ const isMatched = new RegExp(
176
+ \`\${candidateParts[i]?.slice(start, end)}\`
177
+ ).test(pathParts[j] || '');
178
+
179
+ if (!isMatched) {
180
+ found = false;
181
+ break;
182
+ }
168
183
  continue;
169
184
  }
170
-
185
+
171
186
  // If the candidate part is not a template and
172
187
  // the parts don't match mark the candidate as not found
173
188
  // to move on with the next candidate path.
174
- if (candidateParts[i] !== pathParts[i]) {
189
+ if (candidateParts[i] !== pathParts[j]) {
175
190
  found = false;
176
191
  break;
177
192
  }
178
193
  }
179
-
194
+
180
195
  // We finished evaluating the current candidate parts
181
- // if all parts matched we return the success values form
182
- // the path mapping.
183
- if (found) {
184
- return value;
196
+ // Update the matched value if and only if we found the longer pattern
197
+ if (found && candidatePath.length > matchedLen) {
198
+ matchedLen = candidatePath.length;
199
+ matchedValue = value;
185
200
  }
186
201
  }
187
- }
188
-
189
- // No match was found, return an empty array.
190
- return [];
202
+
203
+ return matchedValue;
191
204
  `
192
205
  ]
193
206
  });
194
207
 
195
- isErrorHelper.addFunction({
196
- isExported: false,
197
- name: "hasParametrizedPath",
198
- parameters: [
199
- {
200
- name: "path",
201
- type: "string"
202
- }
203
- ],
204
- returnType: `boolean`,
205
- statements: [`return path.includes("/{");`]
206
- });
207
-
208
208
  isErrorHelper.addFunction({
209
209
  isExported: false,
210
210
  name: "getPathFromMapKey",
@@ -22,7 +22,7 @@ export const REST_CLIENT_RESERVED: ReservedName[] = [
22
22
  ];
23
23
 
24
24
  export function buildMethodShortcutImplementation(paths: Paths) {
25
- let keys: Record<string, string[]> = {};
25
+ const keys: Record<string, string[]> = {};
26
26
  for (const path of Object.keys(paths)) {
27
27
  const groupName = normalizeName(
28
28
  paths[path].operationGroupName,
@@ -123,7 +123,7 @@ function getPolymorphicTypeAlias(
123
123
  }
124
124
 
125
125
  const description = objectSchema.description;
126
-
126
+
127
127
  return {
128
128
  kind: StructureKind.TypeAlias,
129
129
  ...(description && { docs: [{ description }] }),
@@ -316,7 +316,7 @@ function getImmediateParentsNames(
316
316
  return [];
317
317
  }
318
318
 
319
- let extendFrom: string[] = [];
319
+ const extendFrom: string[] = [];
320
320
 
321
321
  // If an immediate parent is a DictionarySchema, that means that the object has been marked
322
322
  // with additional properties. We need to add Record<string, unknown> to the extend list and
@@ -350,7 +350,13 @@ function getPropertySignatures(
350
350
  schemaUsage: SchemaContext[],
351
351
  importedModels: Set<string>
352
352
  ) {
353
- return Object.keys(properties).map((p) =>
353
+ let validProperties = Object.keys(properties);
354
+ if (schemaUsage.includes(SchemaContext.Input)) {
355
+ validProperties = validProperties.filter((p) => {
356
+ return !properties[p].readOnly;
357
+ });
358
+ }
359
+ return validProperties.map((p) =>
354
360
  getPropertySignature(
355
361
  { ...properties[p], name: p },
356
362
  schemaUsage,
@@ -374,11 +380,7 @@ export function getPropertySignature(
374
380
 
375
381
  const description = property.description;
376
382
  const type =
377
- ((schemaUsage.includes(SchemaContext.Output) &&
378
- property.usage?.includes(SchemaContext.Output)) ||
379
- (schemaUsage.includes(SchemaContext.Exception) &&
380
- property.usage?.includes(SchemaContext.Exception))) &&
381
- property.outputTypeName
383
+ generateForOutput(schemaUsage, property.usage) && property.outputTypeName
382
384
  ? property.outputTypeName
383
385
  : property.typeName
384
386
  ? property.typeName
@@ -387,7 +389,21 @@ export function getPropertySignature(
387
389
  name: propertyName,
388
390
  ...(description && { docs: [{ description }] }),
389
391
  hasQuestionToken: !property.required,
392
+ isReadonly:
393
+ generateForOutput(schemaUsage, property.usage) && property.readOnly,
390
394
  type,
391
395
  kind: StructureKind.PropertySignature
392
396
  };
393
397
  }
398
+
399
+ function generateForOutput(
400
+ schemaUsage: SchemaContext[],
401
+ propertyUsage?: SchemaContext[]
402
+ ) {
403
+ return (
404
+ (schemaUsage.includes(SchemaContext.Output) &&
405
+ propertyUsage?.includes(SchemaContext.Output)) ||
406
+ (schemaUsage.includes(SchemaContext.Exception) &&
407
+ propertyUsage?.includes(SchemaContext.Exception))
408
+ );
409
+ }
@@ -11,12 +11,12 @@ import {
11
11
  import * as path from "path";
12
12
  import {
13
13
  ImportKind,
14
+ ObjectSchema,
14
15
  ParameterMetadata,
15
16
  ParameterMetadatas,
16
17
  RLCModel,
17
18
  Schema
18
19
  } from "./interfaces.js";
19
- import { NameType, normalizeName } from "./helpers/nameUtils.js";
20
20
  import {
21
21
  getParameterBaseName,
22
22
  getParameterTypeName
@@ -92,6 +92,11 @@ export function buildParameterTypes(model: RLCModel) {
92
92
  i
93
93
  );
94
94
 
95
+ const bodyTypeAlias = buildBodyTypeAlias(parameter);
96
+ if (bodyTypeAlias) {
97
+ parametersFile.addTypeAlias(bodyTypeAlias);
98
+ }
99
+
95
100
  // Add interfaces for body and query parameters
96
101
  parametersFile.addInterfaces([
97
102
  ...(bodyParameterDefinition ?? []),
@@ -215,7 +220,7 @@ function getPropertyFromSchema(schema: Schema): PropertySignatureStructure {
215
220
  name: schema.name,
216
221
  ...(description && { docs: [{ description }] }),
217
222
  type: schema.type,
218
- hasQuestionToken: !Boolean(schema.required),
223
+ hasQuestionToken: !schema.required,
219
224
  kind: StructureKind.PropertySignature
220
225
  };
221
226
  }
@@ -296,8 +301,12 @@ function buildHeaderParameterDefinitions(
296
301
  baseName
297
302
  );
298
303
 
304
+ let isOptional = true;
299
305
  if (headersInterface) {
300
306
  parametersFile.addInterface(headersInterface);
307
+ isOptional = !(headersInterface.properties || []).some(
308
+ (prop) => prop.hasQuestionToken === false
309
+ );
301
310
  }
302
311
 
303
312
  internalReferences.add(headerParameterInterfaceName);
@@ -310,7 +319,8 @@ function buildHeaderParameterDefinitions(
310
319
  {
311
320
  name: "headers",
312
321
  type: `RawHttpHeadersInput & ${baseName}Headers`,
313
- kind: StructureKind.PropertySignature
322
+ kind: StructureKind.PropertySignature,
323
+ hasQuestionToken: isOptional
314
324
  }
315
325
  ]
316
326
  };
@@ -433,3 +443,49 @@ function buildBodyParametersDefinition(
433
443
  ];
434
444
  }
435
445
  }
446
+
447
+ export function buildBodyTypeAlias(parameters: ParameterMetadatas) {
448
+ const bodyParameters = parameters.body;
449
+ if (
450
+ !bodyParameters ||
451
+ !bodyParameters?.body ||
452
+ !bodyParameters?.body.length
453
+ ) {
454
+ return undefined;
455
+ }
456
+ const schema = bodyParameters.body[0] as ObjectSchema;
457
+ const headerParameters = (parameters.parameters || []).filter(
458
+ (p) => p.type === "header" && p.name === "contentType"
459
+ );
460
+ if (!headerParameters.length || headerParameters.length > 1) {
461
+ return undefined;
462
+ }
463
+
464
+ const contentType = headerParameters[0].param.type;
465
+ const readOnlyProperties = [];
466
+ if (schema.properties) {
467
+ for (const propertyName of Object.keys(schema.properties)) {
468
+ const prop = schema.properties[propertyName];
469
+ if (prop?.readOnly) {
470
+ if (propertyName.startsWith('"') && propertyName.endsWith('"')) {
471
+ readOnlyProperties.push(`${propertyName}`);
472
+ } else {
473
+ readOnlyProperties.push(`"${propertyName}"`);
474
+ }
475
+ }
476
+ }
477
+ }
478
+
479
+ const description = `${schema.description}`;
480
+ const typeName = `${schema.typeName}ResourceMergeAndPatch`;
481
+ if (contentType.includes("application/merge-patch+json")) {
482
+ const type = `Partial<${schema.typeName}>`;
483
+ return {
484
+ // kind: StructureKind.TypeAlias,
485
+ ...(description && { docs: [{ description }] }),
486
+ name: `${typeName}`,
487
+ type,
488
+ isExported: true
489
+ };
490
+ }
491
+ }
@@ -125,7 +125,7 @@ function getResponseHeaderInterfaceDefinition(
125
125
  name: h.name,
126
126
  ...(description && { docs: [{ description }] }),
127
127
  type: h.type,
128
- hasQuestionToken: !Boolean(h.required)
128
+ hasQuestionToken: !h.required
129
129
  };
130
130
  })
131
131
  };
@@ -18,7 +18,7 @@ export function getResponseTypeName(
18
18
  operationName?: string,
19
19
  statusCode?: string
20
20
  ): string {
21
- if (Boolean(operationName)) {
21
+ if (operationName) {
22
22
  baseNameOrOperationGroup = getResponseBaseName(
23
23
  baseNameOrOperationGroup,
24
24
  operationName!,
@@ -79,7 +79,7 @@ export function getParameterTypeName(
79
79
  baseNameOrOperationGroup: string,
80
80
  operationName?: string
81
81
  ) {
82
- if (Boolean(operationName)) {
82
+ if (operationName) {
83
83
  baseNameOrOperationGroup = getParameterBaseName(
84
84
  baseNameOrOperationGroup,
85
85
  operationName!
@@ -202,7 +202,7 @@ function toCasing(str: string, casing: CasingConvention): string {
202
202
  }
203
203
 
204
204
  function getNameParts(name: string) {
205
- let parts = name.split(/[-._ ]+/);
205
+ const parts = name.split(/[-._ ]+/);
206
206
 
207
207
  return parts.length > 0 ? parts : [name];
208
208
  }
@@ -26,7 +26,7 @@ export function buildMethodDefinitions(
26
26
 
27
27
  for (const method of verbMethods) {
28
28
  const description = method.description;
29
- let areAllOptional = method.hasOptionalOptions;
29
+ const areAllOptional = method.hasOptionalOptions;
30
30
 
31
31
  methodDefinitions.push({
32
32
  name: key,
@@ -22,4 +22,4 @@ export function isConstantSchema(schema: Schema) {
22
22
  return true;
23
23
  }
24
24
  return false;
25
- }
25
+ }
@@ -13,7 +13,7 @@ import { NameType, normalizeName } from "./nameUtils.js";
13
13
  export function generateMethodShortcuts(
14
14
  paths: Paths
15
15
  ): OptionalKind<InterfaceDeclarationStructure>[] {
16
- let keys: Record<string, OptionalKind<MethodSignatureStructure>[]> = {};
16
+ const keys: Record<string, OptionalKind<MethodSignatureStructure>[]> = {};
17
17
  for (const path in paths) {
18
18
  const groupName = paths[path].operationGroupName;
19
19
  const definitions = buildOperationDefinitions(paths[path]);
package/src/interfaces.ts CHANGED
@@ -14,9 +14,15 @@ export interface RLCModel {
14
14
  urlInfo?: UrlInfo;
15
15
  }
16
16
 
17
+ export interface PathTemplateApiVersion {
18
+ value: string;
19
+ templateName: string;
20
+ }
21
+
17
22
  export interface UrlInfo {
18
23
  endpoint?: string;
19
24
  urlParameters?: PathParameter[];
25
+ pathTemplateApiVersion?: PathTemplateApiVersion;
20
26
  }
21
27
  export interface AnnotationDetails {
22
28
  hasPaging?: boolean;
@@ -63,6 +69,7 @@ export type PathParameter = {
63
69
  name: string;
64
70
  type: string;
65
71
  description?: string;
72
+ value?: string | number | boolean;
66
73
  };
67
74
 
68
75
  export interface OperationAnnotations {
@@ -89,6 +96,7 @@ export interface RLCOptions {
89
96
  productDocLink?: string;
90
97
  serviceInfo?: ServiceInfo;
91
98
  azureArm?: boolean;
99
+ "sdk-folder"?: string;
92
100
  }
93
101
 
94
102
  export interface ServiceInfo {
@@ -57,7 +57,6 @@ function restLevelPackage(model: RLCModel, hasSamplesGenerated: boolean) {
57
57
  if (packageDetails.version.includes("beta")) {
58
58
  apiRefUrlQueryParameter = "?view=azure-node-preview";
59
59
  }
60
- const description = packageDetails.description;
61
60
  const hasPaging = hasPagingOperations(model);
62
61
  const hasLRO = hasPollingOperations(model);
63
62
  const packageInfo: Record<string, any> = {
@@ -146,7 +145,7 @@ function restLevelPackage(model: RLCModel, hasSamplesGenerated: boolean) {
146
145
  prettier: "2.2.1",
147
146
  rimraf: "^3.0.0",
148
147
  "source-map-support": "^0.5.9",
149
- typescript: "~4.6.0"
148
+ typescript: "~4.8.0"
150
149
  }
151
150
  };
152
151
 
@@ -196,6 +195,7 @@ function restLevelPackage(model: RLCModel, hasSamplesGenerated: boolean) {
196
195
  packageInfo.devDependencies["@azure/identity"] = "^2.0.1";
197
196
  packageInfo.devDependencies["@azure-tools/test-recorder"] = "^2.0.0";
198
197
  packageInfo.devDependencies["mocha"] = "^7.1.1";
198
+ packageInfo.devDependencies["@types/mocha"] = "^7.0.2";
199
199
  packageInfo.devDependencies["mocha-junit-reporter"] = "^1.18.0";
200
200
  packageInfo.devDependencies["cross-env"] = "^7.0.2";
201
201
  packageInfo.devDependencies["@types/chai"] = "^4.2.8";
@@ -35,7 +35,7 @@ Key links:
35
35
 
36
36
  ### Currently supported environments
37
37
 
38
- - Node.js version 14.x.x or higher
38
+ - LTS versions of Node.js
39
39
 
40
40
  ### Prerequisites
41
41
 
@@ -72,7 +72,7 @@ AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET
72
72
  Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the \`AZURE_LOG_LEVEL\` environment variable to \`info\`. Alternatively, logging can be enabled at runtime by calling \`setLogLevel\` in the \`@azure/logger\`:
73
73
 
74
74
  \`\`\`javascript
75
- import { setLogLevel } from "@azure/logger";
75
+ const { setLogLevel } = require("@azure/logger");
76
76
 
77
77
  setLogLevel("info");
78
78
  \`\`\`
@@ -168,7 +168,7 @@ function createMetadata(model: RLCModel): Metadata | undefined {
168
168
  const clientPackageName = packageDetails?.name;
169
169
  const clientClassName = getClientName(model);
170
170
  const serviceName = getServiceName(model);
171
- var apiRefUrlQueryParameter: string = "";
171
+ let apiRefUrlQueryParameter: string = "";
172
172
  if (packageDetails?.version.includes("beta")) {
173
173
  apiRefUrlQueryParameter = "?view=azure-node-preview";
174
174
  }
@@ -156,7 +156,7 @@ function checkPagingRequest(response: PathUncheckedResponse): void {
156
156
  ];
157
157
  if (!Http2xxStatusCodes.includes(response.status)) {
158
158
  throw createRestError(
159
- \`Pagination failed with unexpected statusCode \${response.status\}\`,
159
+ \`Pagination failed with unexpected statusCode \${response.status}\`,
160
160
  response
161
161
  );
162
162
  }
@@ -65,6 +65,7 @@ module.exports = function (config) {
65
65
  "AZURE_CLIENT_ID",
66
66
  "AZURE_TENANT_ID",
67
67
  "SUBSCRIPTION_ID",
68
+ "RECORDINGS_RELATIVE_PATH",
68
69
  ],
69
70
 
70
71
  // test results reporter to use
@@ -1,5 +1,13 @@
1
- import { RLCModel } from "./interfaces.js";
1
+ import { ParameterMetadatas, RLCModel } from "./interfaces.js";
2
2
  export declare function buildParameterTypes(model: RLCModel): {
3
3
  path: string;
4
4
  content: string;
5
5
  } | undefined;
6
+ export declare function buildBodyTypeAlias(parameters: ParameterMetadatas): {
7
+ name: string;
8
+ type: string;
9
+ isExported: boolean;
10
+ docs?: {
11
+ description: string;
12
+ }[] | undefined;
13
+ } | undefined;
@@ -11,9 +11,14 @@ export interface RLCModel {
11
11
  annotations?: AnnotationDetails;
12
12
  urlInfo?: UrlInfo;
13
13
  }
14
+ export interface PathTemplateApiVersion {
15
+ value: string;
16
+ templateName: string;
17
+ }
14
18
  export interface UrlInfo {
15
19
  endpoint?: string;
16
20
  urlParameters?: PathParameter[];
21
+ pathTemplateApiVersion?: PathTemplateApiVersion;
17
22
  }
18
23
  export interface AnnotationDetails {
19
24
  hasPaging?: boolean;
@@ -54,6 +59,7 @@ export declare type PathParameter = {
54
59
  name: string;
55
60
  type: string;
56
61
  description?: string;
62
+ value?: string | number | boolean;
57
63
  };
58
64
  export interface OperationAnnotations {
59
65
  isLongRunning?: boolean;
@@ -78,6 +84,7 @@ export interface RLCOptions {
78
84
  productDocLink?: string;
79
85
  serviceInfo?: ServiceInfo;
80
86
  azureArm?: boolean;
87
+ "sdk-folder"?: string;
81
88
  }
82
89
  export interface ServiceInfo {
83
90
  title?: string;
@@ -1,5 +1,5 @@
1
1
  export declare const envContent = "\nimport * as dotenv from \"dotenv\";\n\ndotenv.config();\n";
2
2
  export declare const envBrowserContent = "\nimport * as dotenv from \"dotenv\";\n\ndotenv.config();\n";
3
- export declare const karmaConfig = "\n// https://github.com/karma-runner/karma-chrome-launcher\nprocess.env.CHROME_BIN = require(\"puppeteer\").executablePath();\nrequire(\"dotenv\").config();\nconst { relativeRecordingsPath } = require(\"@azure-tools/test-recorder\");\nprocess.env.RECORDINGS_RELATIVE_PATH = relativeRecordingsPath();\n\nmodule.exports = function (config) {\n config.set({\n // base path that will be used to resolve all patterns (eg. files, exclude)\n basePath: \"./\",\n\n // frameworks to use\n // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n frameworks: [\"source-map-support\", \"mocha\"],\n\n plugins: [\n \"karma-mocha\",\n \"karma-mocha-reporter\",\n \"karma-chrome-launcher\",\n \"karma-edge-launcher\",\n \"karma-firefox-launcher\",\n \"karma-ie-launcher\",\n \"karma-env-preprocessor\",\n \"karma-coverage\",\n \"karma-sourcemap-loader\",\n \"karma-junit-reporter\",\n \"karma-source-map-support\",\n ],\n\n // list of files / patterns to load in the browser\n files: [\n \"dist-test/index.browser.js\",\n { pattern: \"dist-test/index.browser.js.map\", type: \"html\", included: false, served: true },\n ],\n\n // list of files / patterns to exclude\n exclude: [],\n\n // preprocess matching files before serving them to the browser\n // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n preprocessors: {\n \"**/*.js\": [\"sourcemap\", \"env\"],\n // IMPORTANT: COMMENT following line if you want to debug in your browsers!!\n // Preprocess source file to calculate code coverage, however this will make source file unreadable\n // \"dist-test/index.js\": [\"coverage\"]\n },\n\n envPreprocessor: [\n \"TEST_MODE\",\n \"ENDPOINT\",\n \"AZURE_CLIENT_SECRET\",\n \"AZURE_CLIENT_ID\",\n \"AZURE_TENANT_ID\",\n \"SUBSCRIPTION_ID\",\n ],\n\n // test results reporter to use\n // possible values: 'dots', 'progress'\n // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n reporters: [\"mocha\", \"coverage\", \"junit\"],\n\n coverageReporter: {\n // specify a common output directory\n dir: \"coverage-browser/\",\n reporters: [\n { type: \"json\", subdir: \".\", file: \"coverage.json\" },\n { type: \"lcovonly\", subdir: \".\", file: \"lcov.info\" },\n { type: \"html\", subdir: \"html\" },\n { type: \"cobertura\", subdir: \".\", file: \"cobertura-coverage.xml\" },\n ],\n },\n\n junitReporter: {\n outputDir: \"\", // results will be saved as $outputDir/$browserName.xml\n outputFile: \"test-results.browser.xml\", // if included, results will be saved as $outputDir/$browserName/$outputFile\n suite: \"\", // suite will become the package name attribute in xml testsuite element\n useBrowserName: false, // add browser name to report and classes names\n nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element\n classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element\n properties: {}, // key value pair of properties to add to the <properties> section of the report\n },\n\n // web server port\n port: 9876,\n\n // enable / disable colors in the output (reporters and logs)\n colors: true,\n\n // level of logging\n // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n logLevel: config.LOG_INFO,\n\n // enable / disable watching file and executing tests whenever any file changes\n autoWatch: false,\n\n // --no-sandbox allows our tests to run in Linux without having to change the system.\n // --disable-web-security allows us to authenticate from the browser without having to write tests using interactive auth, which would be far more complex.\n browsers: [\"ChromeHeadlessNoSandbox\"],\n customLaunchers: {\n ChromeHeadlessNoSandbox: {\n base: \"ChromeHeadless\",\n flags: [\"--no-sandbox\", \"--disable-web-security\"],\n },\n },\n\n // Continuous Integration mode\n // if true, Karma captures browsers, runs the tests and exits\n singleRun: false,\n\n // Concurrency level\n // how many browser should be started simultaneous\n concurrency: 1,\n\n browserNoActivityTimeout: 60000000,\n browserDisconnectTimeout: 10000,\n browserDisconnectTolerance: 3,\n\n client: {\n mocha: {\n // change Karma's debug.html to the mocha web reporter\n reporter: \"html\",\n timeout: \"600000\",\n },\n },\n });\n};\n";
3
+ export declare const karmaConfig = "\n// https://github.com/karma-runner/karma-chrome-launcher\nprocess.env.CHROME_BIN = require(\"puppeteer\").executablePath();\nrequire(\"dotenv\").config();\nconst { relativeRecordingsPath } = require(\"@azure-tools/test-recorder\");\nprocess.env.RECORDINGS_RELATIVE_PATH = relativeRecordingsPath();\n\nmodule.exports = function (config) {\n config.set({\n // base path that will be used to resolve all patterns (eg. files, exclude)\n basePath: \"./\",\n\n // frameworks to use\n // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n frameworks: [\"source-map-support\", \"mocha\"],\n\n plugins: [\n \"karma-mocha\",\n \"karma-mocha-reporter\",\n \"karma-chrome-launcher\",\n \"karma-edge-launcher\",\n \"karma-firefox-launcher\",\n \"karma-ie-launcher\",\n \"karma-env-preprocessor\",\n \"karma-coverage\",\n \"karma-sourcemap-loader\",\n \"karma-junit-reporter\",\n \"karma-source-map-support\",\n ],\n\n // list of files / patterns to load in the browser\n files: [\n \"dist-test/index.browser.js\",\n { pattern: \"dist-test/index.browser.js.map\", type: \"html\", included: false, served: true },\n ],\n\n // list of files / patterns to exclude\n exclude: [],\n\n // preprocess matching files before serving them to the browser\n // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n preprocessors: {\n \"**/*.js\": [\"sourcemap\", \"env\"],\n // IMPORTANT: COMMENT following line if you want to debug in your browsers!!\n // Preprocess source file to calculate code coverage, however this will make source file unreadable\n // \"dist-test/index.js\": [\"coverage\"]\n },\n\n envPreprocessor: [\n \"TEST_MODE\",\n \"ENDPOINT\",\n \"AZURE_CLIENT_SECRET\",\n \"AZURE_CLIENT_ID\",\n \"AZURE_TENANT_ID\",\n \"SUBSCRIPTION_ID\",\n \"RECORDINGS_RELATIVE_PATH\",\n ],\n\n // test results reporter to use\n // possible values: 'dots', 'progress'\n // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n reporters: [\"mocha\", \"coverage\", \"junit\"],\n\n coverageReporter: {\n // specify a common output directory\n dir: \"coverage-browser/\",\n reporters: [\n { type: \"json\", subdir: \".\", file: \"coverage.json\" },\n { type: \"lcovonly\", subdir: \".\", file: \"lcov.info\" },\n { type: \"html\", subdir: \"html\" },\n { type: \"cobertura\", subdir: \".\", file: \"cobertura-coverage.xml\" },\n ],\n },\n\n junitReporter: {\n outputDir: \"\", // results will be saved as $outputDir/$browserName.xml\n outputFile: \"test-results.browser.xml\", // if included, results will be saved as $outputDir/$browserName/$outputFile\n suite: \"\", // suite will become the package name attribute in xml testsuite element\n useBrowserName: false, // add browser name to report and classes names\n nameFormatter: undefined, // function (browser, result) to customize the name attribute in xml testcase element\n classNameFormatter: undefined, // function (browser, result) to customize the classname attribute in xml testcase element\n properties: {}, // key value pair of properties to add to the <properties> section of the report\n },\n\n // web server port\n port: 9876,\n\n // enable / disable colors in the output (reporters and logs)\n colors: true,\n\n // level of logging\n // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n logLevel: config.LOG_INFO,\n\n // enable / disable watching file and executing tests whenever any file changes\n autoWatch: false,\n\n // --no-sandbox allows our tests to run in Linux without having to change the system.\n // --disable-web-security allows us to authenticate from the browser without having to write tests using interactive auth, which would be far more complex.\n browsers: [\"ChromeHeadlessNoSandbox\"],\n customLaunchers: {\n ChromeHeadlessNoSandbox: {\n base: \"ChromeHeadless\",\n flags: [\"--no-sandbox\", \"--disable-web-security\"],\n },\n },\n\n // Continuous Integration mode\n // if true, Karma captures browsers, runs the tests and exits\n singleRun: false,\n\n // Concurrency level\n // how many browser should be started simultaneous\n concurrency: 1,\n\n browserNoActivityTimeout: 60000000,\n browserDisconnectTimeout: 10000,\n browserDisconnectTolerance: 3,\n\n client: {\n mocha: {\n // change Karma's debug.html to the mocha web reporter\n reporter: \"html\",\n timeout: \"600000\",\n },\n },\n });\n};\n";
4
4
  export declare const recordedClientContent = "\nimport { Context } from \"mocha\";\nimport { Recorder, RecorderStartOptions } from \"@azure-tools/test-recorder\";\nimport \"./env\";\n\nconst envSetupForPlayback: Record<string, string> = {\n ENDPOINT: \"https://endpoint\",\n AZURE_CLIENT_ID: \"azure_client_id\",\n AZURE_CLIENT_SECRET: \"azure_client_secret\",\n AZURE_TENANT_ID: \"88888888-8888-8888-8888-888888888888\",\n SUBSCRIPTION_ID: \"azure_subscription_id\"\n};\n\nconst recorderEnvSetup: RecorderStartOptions = {\n envSetupForPlayback\n};\n\n/**\n* creates the recorder and reads the environment variables from the `.env` file.\n* Should be called first in the test suite to make sure environment variables are\n* read before they are being used.\n*/\nexport async function createRecorder(context: Context): Promise<Recorder> {\n const recorder = new Recorder(context.currentTest);\n await recorder.start(recorderEnvSetup);\n return recorder;\n}\n";
5
5
  export declare const sampleTestContent = "\nimport { Recorder } from \"@azure-tools/test-recorder\";\nimport { assert } from \"chai\";\nimport { createRecorder } from \"./utils/recordedClient\";\nimport { Context } from \"mocha\";\n\ndescribe(\"My test\", () => {\n let recorder: Recorder;\n\n beforeEach(async function(this: Context) {\n recorder = await createRecorder(this);\n });\n\n afterEach(async function() {\n await recorder.stop();\n });\n\n it(\"sample test\", async function() {\n assert.equal(1, 1);\n });\n});\n";