@microsoft/m365-spec-parser 0.1.1-alpha.a277dba4e.0 → 0.1.1-alpha.ad8f60cf1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,6 +55,21 @@ var ErrorType;
55
55
  ErrorType["GenerateFailed"] = "generate-failed";
56
56
  ErrorType["ValidateFailed"] = "validate-failed";
57
57
  ErrorType["GetSpecFailed"] = "get-spec-failed";
58
+ ErrorType["AuthTypeIsNotSupported"] = "auth-type-is-not-supported";
59
+ ErrorType["MissingOperationId"] = "missing-operation-id";
60
+ ErrorType["PostBodyContainMultipleMediaTypes"] = "post-body-contain-multiple-media-types";
61
+ ErrorType["ResponseContainMultipleMediaTypes"] = "response-contain-multiple-media-types";
62
+ ErrorType["ResponseJsonIsEmpty"] = "response-json-is-empty";
63
+ ErrorType["PostBodySchemaIsNotJson"] = "post-body-schema-is-not-json";
64
+ ErrorType["PostBodyContainsRequiredUnsupportedSchema"] = "post-body-contains-required-unsupported-schema";
65
+ ErrorType["ParamsContainRequiredUnsupportedSchema"] = "params-contain-required-unsupported-schema";
66
+ ErrorType["ParamsContainsNestedObject"] = "params-contains-nested-object";
67
+ ErrorType["RequestBodyContainsNestedObject"] = "request-body-contains-nested-object";
68
+ ErrorType["ExceededRequiredParamsLimit"] = "exceeded-required-params-limit";
69
+ ErrorType["NoParameter"] = "no-parameter";
70
+ ErrorType["NoAPIInfo"] = "no-api-info";
71
+ ErrorType["MethodNotAllowed"] = "method-not-allowed";
72
+ ErrorType["UrlPathNotExist"] = "url-path-not-exist";
58
73
  ErrorType["Cancelled"] = "cancelled";
59
74
  ErrorType["Unknown"] = "unknown";
60
75
  })(ErrorType || (ErrorType = {}));
@@ -102,7 +117,7 @@ ConstantString.RemoteRefNotSupported = "Remote reference is not supported: %s.";
102
117
  ConstantString.MissingOperationId = "Missing operationIds: %s.";
103
118
  ConstantString.NoSupportedApi = "No supported API is found in the OpenAPI description document: only GET and POST methods are supported, additionally, there can be at most one required parameter, and no auth is allowed.";
104
119
  ConstantString.AdditionalPropertiesNotSupported = "'additionalProperties' is not supported, and will be ignored.";
105
- ConstantString.SchemaNotSupported = "'oneOf', 'anyOf', and 'not' schema are not supported: %s.";
120
+ ConstantString.SchemaNotSupported = "'oneOf', 'allOf', 'anyOf', and 'not' schema are not supported: %s.";
106
121
  ConstantString.UnknownSchema = "Unknown schema: %s.";
107
122
  ConstantString.UrlProtocolNotSupported = "Server url is not correct: protocol %s is not supported, you should use https protocol instead.";
108
123
  ConstantString.RelativeServerUrlNotSupported = "Server url is not correct: relative server url is not supported.";
@@ -122,9 +137,9 @@ ConstantString.AdaptiveCardVersion = "1.5";
122
137
  ConstantString.AdaptiveCardSchema = "http://adaptivecards.io/schemas/adaptive-card.json";
123
138
  ConstantString.AdaptiveCardType = "AdaptiveCard";
124
139
  ConstantString.TextBlockType = "TextBlock";
140
+ ConstantString.ImageType = "Image";
125
141
  ConstantString.ContainerType = "Container";
126
142
  ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
127
- ConstantString.OAuthRegistrationIdPostFix = "OAUTH_REGISTRATION_ID";
128
143
  ConstantString.ResponseCodeFor20X = [
129
144
  "200",
130
145
  "201",
@@ -185,7 +200,8 @@ ConstantString.CommandDescriptionMaxLens = 128;
185
200
  ConstantString.ParameterDescriptionMaxLens = 128;
186
201
  ConstantString.CommandTitleMaxLens = 32;
187
202
  ConstantString.ParameterTitleMaxLens = 32;
188
- ConstantString.SMERequiredParamsMaxNum = 5;
203
+ ConstantString.SMERequiredParamsMaxNum = 5;
204
+ ConstantString.DefaultPluginId = "plugin_1";
189
205
 
190
206
  // Copyright (c) Microsoft Corporation.
191
207
  class Utils {
@@ -200,221 +216,9 @@ class Utils {
200
216
  }
201
217
  return false;
202
218
  }
203
- static checkParameters(paramObject, isCopilot) {
204
- const paramResult = {
205
- requiredNum: 0,
206
- optionalNum: 0,
207
- isValid: true,
208
- };
209
- if (!paramObject) {
210
- return paramResult;
211
- }
212
- for (let i = 0; i < paramObject.length; i++) {
213
- const param = paramObject[i];
214
- const schema = param.schema;
215
- if (isCopilot && this.hasNestedObjectInSchema(schema)) {
216
- paramResult.isValid = false;
217
- continue;
218
- }
219
- const isRequiredWithoutDefault = param.required && schema.default === undefined;
220
- if (isCopilot) {
221
- if (isRequiredWithoutDefault) {
222
- paramResult.requiredNum = paramResult.requiredNum + 1;
223
- }
224
- else {
225
- paramResult.optionalNum = paramResult.optionalNum + 1;
226
- }
227
- continue;
228
- }
229
- if (param.in === "header" || param.in === "cookie") {
230
- if (isRequiredWithoutDefault) {
231
- paramResult.isValid = false;
232
- }
233
- continue;
234
- }
235
- if (schema.type !== "boolean" &&
236
- schema.type !== "string" &&
237
- schema.type !== "number" &&
238
- schema.type !== "integer") {
239
- if (isRequiredWithoutDefault) {
240
- paramResult.isValid = false;
241
- }
242
- continue;
243
- }
244
- if (param.in === "query" || param.in === "path") {
245
- if (isRequiredWithoutDefault) {
246
- paramResult.requiredNum = paramResult.requiredNum + 1;
247
- }
248
- else {
249
- paramResult.optionalNum = paramResult.optionalNum + 1;
250
- }
251
- }
252
- }
253
- return paramResult;
254
- }
255
- static checkPostBody(schema, isRequired = false, isCopilot = false) {
256
- var _a;
257
- const paramResult = {
258
- requiredNum: 0,
259
- optionalNum: 0,
260
- isValid: true,
261
- };
262
- if (Object.keys(schema).length === 0) {
263
- return paramResult;
264
- }
265
- const isRequiredWithoutDefault = isRequired && schema.default === undefined;
266
- if (isCopilot && this.hasNestedObjectInSchema(schema)) {
267
- paramResult.isValid = false;
268
- return paramResult;
269
- }
270
- if (schema.type === "string" ||
271
- schema.type === "integer" ||
272
- schema.type === "boolean" ||
273
- schema.type === "number") {
274
- if (isRequiredWithoutDefault) {
275
- paramResult.requiredNum = paramResult.requiredNum + 1;
276
- }
277
- else {
278
- paramResult.optionalNum = paramResult.optionalNum + 1;
279
- }
280
- }
281
- else if (schema.type === "object") {
282
- const { properties } = schema;
283
- for (const property in properties) {
284
- let isRequired = false;
285
- if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
286
- isRequired = true;
287
- }
288
- const result = Utils.checkPostBody(properties[property], isRequired, isCopilot);
289
- paramResult.requiredNum += result.requiredNum;
290
- paramResult.optionalNum += result.optionalNum;
291
- paramResult.isValid = paramResult.isValid && result.isValid;
292
- }
293
- }
294
- else {
295
- if (isRequiredWithoutDefault && !isCopilot) {
296
- paramResult.isValid = false;
297
- }
298
- }
299
- return paramResult;
300
- }
301
219
  static containMultipleMediaTypes(bodyObject) {
302
220
  return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
303
221
  }
304
- /**
305
- * Checks if the given API is supported.
306
- * @param {string} method - The HTTP method of the API.
307
- * @param {string} path - The path of the API.
308
- * @param {OpenAPIV3.Document} spec - The OpenAPI specification document.
309
- * @returns {boolean} - Returns true if the API is supported, false otherwise.
310
- * @description The following APIs are supported:
311
- * 1. only support Get/Post operation without auth property
312
- * 2. parameter inside query or path only support string, number, boolean and integer
313
- * 3. parameter inside post body only support string, number, boolean, integer and object
314
- * 4. request body + required parameters <= 1
315
- * 5. response body should be “application/json” and not empty, and response code should be 20X
316
- * 6. only support request body with “application/json” content type
317
- */
318
- static isSupportedApi(method, path, spec, options) {
319
- var _a;
320
- const pathObj = spec.paths[path];
321
- method = method.toLocaleLowerCase();
322
- if (pathObj) {
323
- if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && pathObj[method]) {
324
- const securities = pathObj[method].security;
325
- const isTeamsAi = options.projectType === ProjectType.TeamsAi;
326
- const isCopilot = options.projectType === ProjectType.Copilot;
327
- // Teams AI project doesn't care about auth, it will use authProvider for user to implement
328
- if (!isTeamsAi) {
329
- const authArray = Utils.getAuthArray(securities, spec);
330
- if (!Utils.isSupportedAuth(authArray, options)) {
331
- return false;
332
- }
333
- }
334
- const operationObject = pathObj[method];
335
- if (!options.allowMissingId && !operationObject.operationId) {
336
- return false;
337
- }
338
- const paramObject = operationObject.parameters;
339
- const requestBody = operationObject.requestBody;
340
- const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
341
- if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
342
- return false;
343
- }
344
- const responseJson = Utils.getResponseJson(operationObject, isTeamsAi);
345
- if (Object.keys(responseJson).length === 0) {
346
- return false;
347
- }
348
- // Teams AI project doesn't care about request parameters/body
349
- if (isTeamsAi) {
350
- return true;
351
- }
352
- let requestBodyParamResult = {
353
- requiredNum: 0,
354
- optionalNum: 0,
355
- isValid: true,
356
- };
357
- if (requestJsonBody) {
358
- const requestBodySchema = requestJsonBody.schema;
359
- if (isCopilot && requestBodySchema.type !== "object") {
360
- return false;
361
- }
362
- requestBodyParamResult = Utils.checkPostBody(requestBodySchema, requestBody.required, isCopilot);
363
- }
364
- if (!requestBodyParamResult.isValid) {
365
- return false;
366
- }
367
- const paramResult = Utils.checkParameters(paramObject, isCopilot);
368
- if (!paramResult.isValid) {
369
- return false;
370
- }
371
- // Copilot support arbitrary parameters
372
- if (isCopilot) {
373
- return true;
374
- }
375
- if (requestBodyParamResult.requiredNum + paramResult.requiredNum > 1) {
376
- if (options.allowMultipleParameters &&
377
- requestBodyParamResult.requiredNum + paramResult.requiredNum <=
378
- ConstantString.SMERequiredParamsMaxNum) {
379
- return true;
380
- }
381
- return false;
382
- }
383
- else if (requestBodyParamResult.requiredNum +
384
- requestBodyParamResult.optionalNum +
385
- paramResult.requiredNum +
386
- paramResult.optionalNum ===
387
- 0) {
388
- return false;
389
- }
390
- else {
391
- return true;
392
- }
393
- }
394
- }
395
- return false;
396
- }
397
- static isSupportedAuth(authSchemeArray, options) {
398
- if (authSchemeArray.length === 0) {
399
- return true;
400
- }
401
- if (options.allowAPIKeyAuth || options.allowOauth2 || options.allowBearerTokenAuth) {
402
- // Currently we don't support multiple auth in one operation
403
- if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
404
- return false;
405
- }
406
- for (const auths of authSchemeArray) {
407
- if (auths.length === 1) {
408
- if ((options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
409
- (options.allowOauth2 && Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme)) ||
410
- (options.allowBearerTokenAuth && Utils.isBearerTokenAuth(auths[0].authScheme))) {
411
- return true;
412
- }
413
- }
414
- }
415
- }
416
- return false;
417
- }
418
222
  static isBearerTokenAuth(authScheme) {
419
223
  return authScheme.type === "http" && authScheme.scheme === "bearer";
420
224
  }
@@ -422,18 +226,18 @@ class Utils {
422
226
  return authScheme.type === "apiKey";
423
227
  }
424
228
  static isOAuthWithAuthCodeFlow(authScheme) {
425
- if (authScheme.type === "oauth2" && authScheme.flows && authScheme.flows.authorizationCode) {
426
- return true;
427
- }
428
- return false;
229
+ return !!(authScheme.type === "oauth2" &&
230
+ authScheme.flows &&
231
+ authScheme.flows.authorizationCode);
429
232
  }
430
233
  static getAuthArray(securities, spec) {
431
234
  var _a;
432
235
  const result = [];
433
236
  const securitySchemas = (_a = spec.components) === null || _a === void 0 ? void 0 : _a.securitySchemes;
434
- if (securities && securitySchemas) {
435
- for (let i = 0; i < securities.length; i++) {
436
- const security = securities[i];
237
+ const securitiesArr = securities !== null && securities !== void 0 ? securities : spec.security;
238
+ if (securitiesArr && securitySchemas) {
239
+ for (let i = 0; i < securitiesArr.length; i++) {
240
+ const security = securitiesArr[i];
437
241
  const authArray = [];
438
242
  for (const name in security) {
439
243
  const auth = securitySchemas[name];
@@ -450,17 +254,39 @@ class Utils {
450
254
  result.sort((a, b) => a[0].name.localeCompare(b[0].name));
451
255
  return result;
452
256
  }
257
+ static getAuthInfo(spec) {
258
+ let authInfo = undefined;
259
+ for (const url in spec.paths) {
260
+ for (const method in spec.paths[url]) {
261
+ const operation = spec.paths[url][method];
262
+ const authArray = Utils.getAuthArray(operation.security, spec);
263
+ if (authArray && authArray.length > 0) {
264
+ const currentAuth = authArray[0][0];
265
+ if (!authInfo) {
266
+ authInfo = authArray[0][0];
267
+ }
268
+ else if (authInfo.name !== currentAuth.name) {
269
+ throw new SpecParserError(ConstantString.MultipleAuthNotSupported, ErrorType.MultipleAuthNotSupported);
270
+ }
271
+ }
272
+ }
273
+ }
274
+ return authInfo;
275
+ }
453
276
  static updateFirstLetter(str) {
454
277
  return str.charAt(0).toUpperCase() + str.slice(1);
455
278
  }
456
- static getResponseJson(operationObject, isTeamsAiProject = false) {
279
+ static getResponseJson(operationObject) {
457
280
  var _a, _b;
458
281
  let json = {};
282
+ let multipleMediaType = false;
459
283
  for (const code of ConstantString.ResponseCodeFor20X) {
460
284
  const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
461
285
  if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
286
+ multipleMediaType = false;
462
287
  json = responseObject.content["application/json"];
463
- if (!isTeamsAiProject && Utils.containMultipleMediaTypes(responseObject)) {
288
+ if (Utils.containMultipleMediaTypes(responseObject)) {
289
+ multipleMediaType = true;
464
290
  json = {};
465
291
  }
466
292
  else {
@@ -468,7 +294,7 @@ class Utils {
468
294
  }
469
295
  }
470
296
  }
471
- return json;
297
+ return { json, multipleMediaType };
472
298
  }
473
299
  static convertPathToCamelCase(path) {
474
300
  const pathSegments = path.split(/[./{]/);
@@ -488,10 +314,10 @@ class Utils {
488
314
  return undefined;
489
315
  }
490
316
  }
491
- static resolveServerUrl(url) {
317
+ static resolveEnv(str) {
492
318
  const placeHolderReg = /\${{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*}}/g;
493
- let matches = placeHolderReg.exec(url);
494
- let newUrl = url;
319
+ let matches = placeHolderReg.exec(str);
320
+ let newStr = str;
495
321
  while (matches != null) {
496
322
  const envVar = matches[1];
497
323
  const envVal = process.env[envVar];
@@ -499,17 +325,17 @@ class Utils {
499
325
  throw new Error(Utils.format(ConstantString.ResolveServerUrlFailed, envVar));
500
326
  }
501
327
  else {
502
- newUrl = newUrl.replace(matches[0], envVal);
328
+ newStr = newStr.replace(matches[0], envVal);
503
329
  }
504
- matches = placeHolderReg.exec(url);
330
+ matches = placeHolderReg.exec(str);
505
331
  }
506
- return newUrl;
332
+ return newStr;
507
333
  }
508
334
  static checkServerUrl(servers) {
509
335
  const errors = [];
510
336
  let serverUrl;
511
337
  try {
512
- serverUrl = Utils.resolveServerUrl(servers[0].url);
338
+ serverUrl = Utils.resolveEnv(servers[0].url);
513
339
  }
514
340
  catch (err) {
515
341
  errors.push({
@@ -540,6 +366,7 @@ class Utils {
540
366
  return errors;
541
367
  }
542
368
  static validateServer(spec, options) {
369
+ var _a;
543
370
  const errors = [];
544
371
  let hasTopLevelServers = false;
545
372
  let hasPathLevelServers = false;
@@ -560,7 +387,7 @@ class Utils {
560
387
  }
561
388
  for (const method in methods) {
562
389
  const operationObject = methods[method];
563
- if (Utils.isSupportedApi(method, path, spec, options)) {
390
+ if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
564
391
  if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
565
392
  hasOperationLevelServers = true;
566
393
  const serverErrors = Utils.checkServerUrl(operationObject.servers);
@@ -687,13 +514,7 @@ class Utils {
687
514
  }
688
515
  }
689
516
  const operationId = operationItem.operationId;
690
- const parameters = [];
691
- if (requiredParams.length !== 0) {
692
- parameters.push(...requiredParams);
693
- }
694
- else {
695
- parameters.push(optionalParams[0]);
696
- }
517
+ const parameters = [...requiredParams, ...optionalParams];
697
518
  const command = {
698
519
  context: ["compose"],
699
520
  type: "query",
@@ -702,117 +523,534 @@ class Utils {
702
523
  parameters: parameters,
703
524
  description: ((_b = operationItem.description) !== null && _b !== void 0 ? _b : "").slice(0, ConstantString.CommandDescriptionMaxLens),
704
525
  };
705
- let warning = undefined;
706
- if (requiredParams.length === 0 && optionalParams.length > 1) {
707
- warning = {
708
- type: WarningType.OperationOnlyContainsOptionalParam,
709
- content: Utils.format(ConstantString.OperationOnlyContainsOptionalParam, operationId),
710
- data: operationId,
711
- };
526
+ return command;
527
+ }
528
+ static format(str, ...args) {
529
+ let index = 0;
530
+ return str.replace(/%s/g, () => {
531
+ const arg = args[index++];
532
+ return arg !== undefined ? arg : "";
533
+ });
534
+ }
535
+ static getSafeRegistrationIdEnvName(authName) {
536
+ if (!authName) {
537
+ return "";
538
+ }
539
+ let safeRegistrationIdEnvName = authName.toUpperCase().replace(/[^A-Z0-9_]/g, "_");
540
+ if (!safeRegistrationIdEnvName.match(/^[A-Z]/)) {
541
+ safeRegistrationIdEnvName = "PREFIX_" + safeRegistrationIdEnvName;
712
542
  }
713
- return [command, warning];
543
+ return safeRegistrationIdEnvName;
714
544
  }
715
- static listSupportedAPIs(spec, options) {
716
- const paths = spec.paths;
545
+ static getServerObject(spec, method, path) {
546
+ const pathObj = spec.paths[path];
547
+ const operationObject = pathObj[method];
548
+ const rootServer = spec.servers && spec.servers[0];
549
+ const methodServer = spec.paths[path].servers && spec.paths[path].servers[0];
550
+ const operationServer = operationObject.servers && operationObject.servers[0];
551
+ const serverUrl = operationServer || methodServer || rootServer;
552
+ return serverUrl;
553
+ }
554
+ }
555
+
556
+ // Copyright (c) Microsoft Corporation.
557
+ class Validator {
558
+ listAPIs() {
559
+ var _a;
560
+ if (this.apiMap) {
561
+ return this.apiMap;
562
+ }
563
+ const paths = this.spec.paths;
717
564
  const result = {};
718
565
  for (const path in paths) {
719
566
  const methods = paths[path];
720
567
  for (const method in methods) {
721
- if (Utils.isSupportedApi(method, path, spec, options)) {
722
- const operationObject = methods[method];
723
- result[`${method.toUpperCase()} ${path}`] = operationObject;
568
+ const operationObject = methods[method];
569
+ if (((_a = this.options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && operationObject) {
570
+ const validateResult = this.validateAPI(method, path);
571
+ result[`${method.toUpperCase()} ${path}`] = {
572
+ operation: operationObject,
573
+ isValid: validateResult.isValid,
574
+ reason: validateResult.reason,
575
+ };
724
576
  }
725
577
  }
726
578
  }
579
+ this.apiMap = result;
727
580
  return result;
728
581
  }
729
- static validateSpec(spec, parser, isSwaggerFile, options) {
730
- const errors = [];
731
- const warnings = [];
732
- if (isSwaggerFile) {
733
- warnings.push({
734
- type: WarningType.ConvertSwaggerToOpenAPI,
735
- content: ConstantString.ConvertSwaggerToOpenAPI,
582
+ validateSpecVersion() {
583
+ const result = { errors: [], warnings: [] };
584
+ if (this.spec.openapi >= "3.1.0") {
585
+ result.errors.push({
586
+ type: ErrorType.SpecVersionNotSupported,
587
+ content: Utils.format(ConstantString.SpecVersionNotSupported, this.spec.openapi),
588
+ data: this.spec.openapi,
736
589
  });
737
590
  }
738
- // Server validation
739
- const serverErrors = Utils.validateServer(spec, options);
740
- errors.push(...serverErrors);
741
- // Remote reference not supported
742
- const refPaths = parser.$refs.paths();
743
- // refPaths [0] is the current spec file path
744
- if (refPaths.length > 1) {
745
- errors.push({
746
- type: ErrorType.RemoteRefNotSupported,
747
- content: Utils.format(ConstantString.RemoteRefNotSupported, refPaths.join(", ")),
748
- data: refPaths,
749
- });
750
- }
751
- // No supported API
752
- const apiMap = Utils.listSupportedAPIs(spec, options);
753
- if (Object.keys(apiMap).length === 0) {
754
- errors.push({
591
+ return result;
592
+ }
593
+ validateSpecServer() {
594
+ const result = { errors: [], warnings: [] };
595
+ const serverErrors = Utils.validateServer(this.spec, this.options);
596
+ result.errors.push(...serverErrors);
597
+ return result;
598
+ }
599
+ validateSpecNoSupportAPI() {
600
+ const result = { errors: [], warnings: [] };
601
+ const apiMap = this.listAPIs();
602
+ const validAPIs = Object.entries(apiMap).filter(([, value]) => value.isValid);
603
+ if (validAPIs.length === 0) {
604
+ const data = [];
605
+ for (const key in apiMap) {
606
+ const { reason } = apiMap[key];
607
+ const apiInvalidReason = { api: key, reason: reason };
608
+ data.push(apiInvalidReason);
609
+ }
610
+ result.errors.push({
755
611
  type: ErrorType.NoSupportedApi,
756
612
  content: ConstantString.NoSupportedApi,
613
+ data,
757
614
  });
758
615
  }
616
+ return result;
617
+ }
618
+ validateSpecOperationId() {
619
+ const result = { errors: [], warnings: [] };
620
+ const apiMap = this.listAPIs();
759
621
  // OperationId missing
760
622
  const apisMissingOperationId = [];
761
623
  for (const key in apiMap) {
762
- const pathObjectItem = apiMap[key];
763
- if (!pathObjectItem.operationId) {
624
+ const { operation } = apiMap[key];
625
+ if (!operation.operationId) {
764
626
  apisMissingOperationId.push(key);
765
627
  }
766
628
  }
767
629
  if (apisMissingOperationId.length > 0) {
768
- warnings.push({
630
+ result.warnings.push({
769
631
  type: WarningType.OperationIdMissing,
770
632
  content: Utils.format(ConstantString.MissingOperationId, apisMissingOperationId.join(", ")),
771
633
  data: apisMissingOperationId,
772
634
  });
773
635
  }
774
- let status = ValidationStatus.Valid;
775
- if (warnings.length > 0 && errors.length === 0) {
776
- status = ValidationStatus.Warning;
636
+ return result;
637
+ }
638
+ validateMethodAndPath(method, path) {
639
+ const result = { isValid: true, reason: [] };
640
+ if (this.options.allowMethods && !this.options.allowMethods.includes(method)) {
641
+ result.isValid = false;
642
+ result.reason.push(ErrorType.MethodNotAllowed);
643
+ return result;
777
644
  }
778
- else if (errors.length > 0) {
779
- status = ValidationStatus.Error;
645
+ const pathObj = this.spec.paths[path];
646
+ if (!pathObj || !pathObj[method]) {
647
+ result.isValid = false;
648
+ result.reason.push(ErrorType.UrlPathNotExist);
649
+ return result;
780
650
  }
781
- return {
782
- status,
783
- warnings,
784
- errors,
785
- };
651
+ return result;
786
652
  }
787
- static format(str, ...args) {
788
- let index = 0;
789
- return str.replace(/%s/g, () => {
790
- const arg = args[index++];
791
- return arg !== undefined ? arg : "";
792
- });
653
+ validateResponse(method, path) {
654
+ const result = { isValid: true, reason: [] };
655
+ const operationObject = this.spec.paths[path][method];
656
+ const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
657
+ if (this.options.projectType === ProjectType.SME) {
658
+ // only support response body only contains “application/json” content type
659
+ if (multipleMediaType) {
660
+ result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
661
+ }
662
+ else if (Object.keys(json).length === 0) {
663
+ // response body should not be empty
664
+ result.reason.push(ErrorType.ResponseJsonIsEmpty);
665
+ }
666
+ }
667
+ return result;
793
668
  }
794
- static getSafeRegistrationIdEnvName(authName) {
795
- if (!authName) {
796
- return "";
669
+ validateServer(method, path) {
670
+ const result = { isValid: true, reason: [] };
671
+ const serverObj = Utils.getServerObject(this.spec, method, path);
672
+ if (!serverObj) {
673
+ // should contain server URL
674
+ result.reason.push(ErrorType.NoServerInformation);
797
675
  }
798
- let safeRegistrationIdEnvName = authName.toUpperCase().replace(/[^A-Z0-9_]/g, "_");
799
- if (!safeRegistrationIdEnvName.match(/^[A-Z]/)) {
800
- safeRegistrationIdEnvName = "PREFIX_" + safeRegistrationIdEnvName;
676
+ else {
677
+ // server url should be absolute url with https protocol
678
+ const serverValidateResult = Utils.checkServerUrl([serverObj]);
679
+ result.reason.push(...serverValidateResult.map((item) => item.type));
801
680
  }
802
- return safeRegistrationIdEnvName;
681
+ return result;
803
682
  }
804
- static getAllAPICount(spec) {
805
- let count = 0;
806
- const paths = spec.paths;
807
- for (const path in paths) {
808
- const methods = paths[path];
809
- for (const method in methods) {
810
- if (ConstantString.AllOperationMethods.includes(method)) {
811
- count++;
683
+ validateAuth(method, path) {
684
+ const pathObj = this.spec.paths[path];
685
+ const operationObject = pathObj[method];
686
+ const securities = operationObject.security;
687
+ const authSchemeArray = Utils.getAuthArray(securities, this.spec);
688
+ if (authSchemeArray.length === 0) {
689
+ return { isValid: true, reason: [] };
690
+ }
691
+ if (this.options.allowAPIKeyAuth ||
692
+ this.options.allowOauth2 ||
693
+ this.options.allowBearerTokenAuth) {
694
+ // Currently we don't support multiple auth in one operation
695
+ if (authSchemeArray.length > 0 && authSchemeArray.every((auths) => auths.length > 1)) {
696
+ return {
697
+ isValid: false,
698
+ reason: [ErrorType.MultipleAuthNotSupported],
699
+ };
700
+ }
701
+ for (const auths of authSchemeArray) {
702
+ if (auths.length === 1) {
703
+ if ((this.options.allowAPIKeyAuth && Utils.isAPIKeyAuth(auths[0].authScheme)) ||
704
+ (this.options.allowOauth2 && Utils.isOAuthWithAuthCodeFlow(auths[0].authScheme)) ||
705
+ (this.options.allowBearerTokenAuth && Utils.isBearerTokenAuth(auths[0].authScheme))) {
706
+ return { isValid: true, reason: [] };
707
+ }
812
708
  }
813
709
  }
814
710
  }
815
- return count;
711
+ return { isValid: false, reason: [ErrorType.AuthTypeIsNotSupported] };
712
+ }
713
+ checkPostBodySchema(schema, isRequired = false) {
714
+ var _a;
715
+ const paramResult = {
716
+ requiredNum: 0,
717
+ optionalNum: 0,
718
+ isValid: true,
719
+ reason: [],
720
+ };
721
+ if (Object.keys(schema).length === 0) {
722
+ return paramResult;
723
+ }
724
+ const isRequiredWithoutDefault = isRequired && schema.default === undefined;
725
+ const isCopilot = this.projectType === ProjectType.Copilot;
726
+ if (isCopilot && this.hasNestedObjectInSchema(schema)) {
727
+ paramResult.isValid = false;
728
+ paramResult.reason = [ErrorType.RequestBodyContainsNestedObject];
729
+ return paramResult;
730
+ }
731
+ if (schema.type === "string" ||
732
+ schema.type === "integer" ||
733
+ schema.type === "boolean" ||
734
+ schema.type === "number") {
735
+ if (isRequiredWithoutDefault) {
736
+ paramResult.requiredNum = paramResult.requiredNum + 1;
737
+ }
738
+ else {
739
+ paramResult.optionalNum = paramResult.optionalNum + 1;
740
+ }
741
+ }
742
+ else if (schema.type === "object") {
743
+ const { properties } = schema;
744
+ for (const property in properties) {
745
+ let isRequired = false;
746
+ if (schema.required && ((_a = schema.required) === null || _a === void 0 ? void 0 : _a.indexOf(property)) >= 0) {
747
+ isRequired = true;
748
+ }
749
+ const result = this.checkPostBodySchema(properties[property], isRequired);
750
+ paramResult.requiredNum += result.requiredNum;
751
+ paramResult.optionalNum += result.optionalNum;
752
+ paramResult.isValid = paramResult.isValid && result.isValid;
753
+ paramResult.reason.push(...result.reason);
754
+ }
755
+ }
756
+ else {
757
+ if (isRequiredWithoutDefault && !isCopilot) {
758
+ paramResult.isValid = false;
759
+ paramResult.reason.push(ErrorType.PostBodyContainsRequiredUnsupportedSchema);
760
+ }
761
+ }
762
+ return paramResult;
763
+ }
764
+ checkParamSchema(paramObject) {
765
+ const paramResult = {
766
+ requiredNum: 0,
767
+ optionalNum: 0,
768
+ isValid: true,
769
+ reason: [],
770
+ };
771
+ if (!paramObject) {
772
+ return paramResult;
773
+ }
774
+ const isCopilot = this.projectType === ProjectType.Copilot;
775
+ for (let i = 0; i < paramObject.length; i++) {
776
+ const param = paramObject[i];
777
+ const schema = param.schema;
778
+ if (isCopilot && this.hasNestedObjectInSchema(schema)) {
779
+ paramResult.isValid = false;
780
+ paramResult.reason.push(ErrorType.ParamsContainsNestedObject);
781
+ continue;
782
+ }
783
+ const isRequiredWithoutDefault = param.required && schema.default === undefined;
784
+ if (isCopilot) {
785
+ if (isRequiredWithoutDefault) {
786
+ paramResult.requiredNum = paramResult.requiredNum + 1;
787
+ }
788
+ else {
789
+ paramResult.optionalNum = paramResult.optionalNum + 1;
790
+ }
791
+ continue;
792
+ }
793
+ if (param.in === "header" || param.in === "cookie") {
794
+ if (isRequiredWithoutDefault) {
795
+ paramResult.isValid = false;
796
+ paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
797
+ }
798
+ continue;
799
+ }
800
+ if (schema.type !== "boolean" &&
801
+ schema.type !== "string" &&
802
+ schema.type !== "number" &&
803
+ schema.type !== "integer") {
804
+ if (isRequiredWithoutDefault) {
805
+ paramResult.isValid = false;
806
+ paramResult.reason.push(ErrorType.ParamsContainRequiredUnsupportedSchema);
807
+ }
808
+ continue;
809
+ }
810
+ if (param.in === "query" || param.in === "path") {
811
+ if (isRequiredWithoutDefault) {
812
+ paramResult.requiredNum = paramResult.requiredNum + 1;
813
+ }
814
+ else {
815
+ paramResult.optionalNum = paramResult.optionalNum + 1;
816
+ }
817
+ }
818
+ }
819
+ return paramResult;
820
+ }
821
+ hasNestedObjectInSchema(schema) {
822
+ if (schema.type === "object") {
823
+ for (const property in schema.properties) {
824
+ const nestedSchema = schema.properties[property];
825
+ if (nestedSchema.type === "object") {
826
+ return true;
827
+ }
828
+ }
829
+ }
830
+ return false;
831
+ }
832
+ }
833
+
834
+ // Copyright (c) Microsoft Corporation.
835
+ class CopilotValidator extends Validator {
836
+ constructor(spec, options) {
837
+ super();
838
+ this.projectType = ProjectType.Copilot;
839
+ this.options = options;
840
+ this.spec = spec;
841
+ }
842
+ validateSpec() {
843
+ const result = { errors: [], warnings: [] };
844
+ // validate spec version
845
+ let validationResult = this.validateSpecVersion();
846
+ result.errors.push(...validationResult.errors);
847
+ // validate spec server
848
+ validationResult = this.validateSpecServer();
849
+ result.errors.push(...validationResult.errors);
850
+ // validate no supported API
851
+ validationResult = this.validateSpecNoSupportAPI();
852
+ result.errors.push(...validationResult.errors);
853
+ // validate operationId missing
854
+ validationResult = this.validateSpecOperationId();
855
+ result.warnings.push(...validationResult.warnings);
856
+ return result;
857
+ }
858
+ validateAPI(method, path) {
859
+ const result = { isValid: true, reason: [] };
860
+ method = method.toLocaleLowerCase();
861
+ // validate method and path
862
+ const methodAndPathResult = this.validateMethodAndPath(method, path);
863
+ if (!methodAndPathResult.isValid) {
864
+ return methodAndPathResult;
865
+ }
866
+ const operationObject = this.spec.paths[path][method];
867
+ // validate auth
868
+ const authCheckResult = this.validateAuth(method, path);
869
+ result.reason.push(...authCheckResult.reason);
870
+ // validate operationId
871
+ if (!this.options.allowMissingId && !operationObject.operationId) {
872
+ result.reason.push(ErrorType.MissingOperationId);
873
+ }
874
+ // validate server
875
+ const validateServerResult = this.validateServer(method, path);
876
+ result.reason.push(...validateServerResult.reason);
877
+ // validate response
878
+ const validateResponseResult = this.validateResponse(method, path);
879
+ result.reason.push(...validateResponseResult.reason);
880
+ // validate requestBody
881
+ const requestBody = operationObject.requestBody;
882
+ const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
883
+ if (requestJsonBody) {
884
+ const requestBodySchema = requestJsonBody.schema;
885
+ if (requestBodySchema.type !== "object") {
886
+ result.reason.push(ErrorType.PostBodySchemaIsNotJson);
887
+ }
888
+ const requestBodyParamResult = this.checkPostBodySchema(requestBodySchema, requestBody.required);
889
+ result.reason.push(...requestBodyParamResult.reason);
890
+ }
891
+ // validate parameters
892
+ const paramObject = operationObject.parameters;
893
+ const paramResult = this.checkParamSchema(paramObject);
894
+ result.reason.push(...paramResult.reason);
895
+ if (result.reason.length > 0) {
896
+ result.isValid = false;
897
+ }
898
+ return result;
899
+ }
900
+ }
901
+
902
+ // Copyright (c) Microsoft Corporation.
903
+ class SMEValidator extends Validator {
904
+ constructor(spec, options) {
905
+ super();
906
+ this.projectType = ProjectType.SME;
907
+ this.options = options;
908
+ this.spec = spec;
909
+ }
910
+ validateSpec() {
911
+ const result = { errors: [], warnings: [] };
912
+ // validate spec version
913
+ let validationResult = this.validateSpecVersion();
914
+ result.errors.push(...validationResult.errors);
915
+ // validate spec server
916
+ validationResult = this.validateSpecServer();
917
+ result.errors.push(...validationResult.errors);
918
+ // validate no supported API
919
+ validationResult = this.validateSpecNoSupportAPI();
920
+ result.errors.push(...validationResult.errors);
921
+ // validate operationId missing
922
+ if (this.options.allowMissingId) {
923
+ validationResult = this.validateSpecOperationId();
924
+ result.warnings.push(...validationResult.warnings);
925
+ }
926
+ return result;
927
+ }
928
+ validateAPI(method, path) {
929
+ const result = { isValid: true, reason: [] };
930
+ method = method.toLocaleLowerCase();
931
+ // validate method and path
932
+ const methodAndPathResult = this.validateMethodAndPath(method, path);
933
+ if (!methodAndPathResult.isValid) {
934
+ return methodAndPathResult;
935
+ }
936
+ const operationObject = this.spec.paths[path][method];
937
+ // validate auth
938
+ const authCheckResult = this.validateAuth(method, path);
939
+ result.reason.push(...authCheckResult.reason);
940
+ // validate operationId
941
+ if (!this.options.allowMissingId && !operationObject.operationId) {
942
+ result.reason.push(ErrorType.MissingOperationId);
943
+ }
944
+ // validate server
945
+ const validateServerResult = this.validateServer(method, path);
946
+ result.reason.push(...validateServerResult.reason);
947
+ // validate response
948
+ const validateResponseResult = this.validateResponse(method, path);
949
+ result.reason.push(...validateResponseResult.reason);
950
+ let postBodyResult = {
951
+ requiredNum: 0,
952
+ optionalNum: 0,
953
+ isValid: true,
954
+ reason: [],
955
+ };
956
+ // validate requestBody
957
+ const requestBody = operationObject.requestBody;
958
+ const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
959
+ if (Utils.containMultipleMediaTypes(requestBody)) {
960
+ result.reason.push(ErrorType.PostBodyContainMultipleMediaTypes);
961
+ }
962
+ if (requestJsonBody) {
963
+ const requestBodySchema = requestJsonBody.schema;
964
+ postBodyResult = this.checkPostBodySchema(requestBodySchema, requestBody.required);
965
+ result.reason.push(...postBodyResult.reason);
966
+ }
967
+ // validate parameters
968
+ const paramObject = operationObject.parameters;
969
+ const paramResult = this.checkParamSchema(paramObject);
970
+ result.reason.push(...paramResult.reason);
971
+ // validate total parameters count
972
+ if (paramResult.isValid && postBodyResult.isValid) {
973
+ const paramCountResult = this.validateParamCount(postBodyResult, paramResult);
974
+ result.reason.push(...paramCountResult.reason);
975
+ }
976
+ if (result.reason.length > 0) {
977
+ result.isValid = false;
978
+ }
979
+ return result;
980
+ }
981
+ validateParamCount(postBodyResult, paramResult) {
982
+ const result = { isValid: true, reason: [] };
983
+ const totalRequiredParams = postBodyResult.requiredNum + paramResult.requiredNum;
984
+ const totalParams = totalRequiredParams + postBodyResult.optionalNum + paramResult.optionalNum;
985
+ if (totalRequiredParams > 1) {
986
+ if (!this.options.allowMultipleParameters ||
987
+ totalRequiredParams > SMEValidator.SMERequiredParamsMaxNum) {
988
+ result.reason.push(ErrorType.ExceededRequiredParamsLimit);
989
+ }
990
+ }
991
+ else if (totalParams === 0) {
992
+ result.reason.push(ErrorType.NoParameter);
993
+ }
994
+ return result;
995
+ }
996
+ }
997
+ SMEValidator.SMERequiredParamsMaxNum = 5;
998
+
999
+ // Copyright (c) Microsoft Corporation.
1000
+ class TeamsAIValidator extends Validator {
1001
+ constructor(spec, options) {
1002
+ super();
1003
+ this.projectType = ProjectType.TeamsAi;
1004
+ this.options = options;
1005
+ this.spec = spec;
1006
+ }
1007
+ validateSpec() {
1008
+ const result = { errors: [], warnings: [] };
1009
+ // validate spec server
1010
+ let validationResult = this.validateSpecServer();
1011
+ result.errors.push(...validationResult.errors);
1012
+ // validate no supported API
1013
+ validationResult = this.validateSpecNoSupportAPI();
1014
+ result.errors.push(...validationResult.errors);
1015
+ return result;
1016
+ }
1017
+ validateAPI(method, path) {
1018
+ const result = { isValid: true, reason: [] };
1019
+ method = method.toLocaleLowerCase();
1020
+ // validate method and path
1021
+ const methodAndPathResult = this.validateMethodAndPath(method, path);
1022
+ if (!methodAndPathResult.isValid) {
1023
+ return methodAndPathResult;
1024
+ }
1025
+ const operationObject = this.spec.paths[path][method];
1026
+ // validate operationId
1027
+ if (!this.options.allowMissingId && !operationObject.operationId) {
1028
+ result.reason.push(ErrorType.MissingOperationId);
1029
+ }
1030
+ // validate server
1031
+ const validateServerResult = this.validateServer(method, path);
1032
+ result.reason.push(...validateServerResult.reason);
1033
+ if (result.reason.length > 0) {
1034
+ result.isValid = false;
1035
+ }
1036
+ return result;
1037
+ }
1038
+ }
1039
+
1040
+ class ValidatorFactory {
1041
+ static create(spec, options) {
1042
+ var _a;
1043
+ const type = (_a = options.projectType) !== null && _a !== void 0 ? _a : ProjectType.SME;
1044
+ switch (type) {
1045
+ case ProjectType.SME:
1046
+ return new SMEValidator(spec, options);
1047
+ case ProjectType.Copilot:
1048
+ return new CopilotValidator(spec, options);
1049
+ case ProjectType.TeamsAi:
1050
+ return new TeamsAIValidator(spec, options);
1051
+ default:
1052
+ throw new Error(`Invalid project type: ${type}`);
1053
+ }
816
1054
  }
817
1055
  }
818
1056
 
@@ -835,7 +1073,11 @@ class SpecParser {
835
1073
  allowBearerTokenAuth: false,
836
1074
  allowOauth2: false,
837
1075
  allowMethods: ["get", "post"],
1076
+ allowConversationStarters: false,
1077
+ allowResponseSemantics: false,
1078
+ allowConfirmation: false,
838
1079
  projectType: ProjectType.SME,
1080
+ isGptPlugin: false,
839
1081
  };
840
1082
  this.pathOrSpec = pathOrDoc;
841
1083
  this.parser = new SwaggerParser();
@@ -851,11 +1093,7 @@ class SpecParser {
851
1093
  try {
852
1094
  try {
853
1095
  yield this.loadSpec();
854
- yield this.parser.validate(this.spec, {
855
- validate: {
856
- schema: false,
857
- },
858
- });
1096
+ yield this.parser.validate(this.spec);
859
1097
  }
860
1098
  catch (e) {
861
1099
  return {
@@ -864,16 +1102,46 @@ class SpecParser {
864
1102
  errors: [{ type: ErrorType.SpecNotValid, content: e.toString() }],
865
1103
  };
866
1104
  }
1105
+ const errors = [];
1106
+ const warnings = [];
867
1107
  if (!this.options.allowSwagger && this.isSwaggerFile) {
868
1108
  return {
869
1109
  status: ValidationStatus.Error,
870
1110
  warnings: [],
871
1111
  errors: [
872
- { type: ErrorType.SwaggerNotSupported, content: ConstantString.SwaggerNotSupported },
1112
+ {
1113
+ type: ErrorType.SwaggerNotSupported,
1114
+ content: ConstantString.SwaggerNotSupported,
1115
+ },
873
1116
  ],
874
1117
  };
875
1118
  }
876
- return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options);
1119
+ // Remote reference not supported
1120
+ const refPaths = this.parser.$refs.paths();
1121
+ // refPaths [0] is the current spec file path
1122
+ if (refPaths.length > 1) {
1123
+ errors.push({
1124
+ type: ErrorType.RemoteRefNotSupported,
1125
+ content: Utils.format(ConstantString.RemoteRefNotSupported, refPaths.join(", ")),
1126
+ data: refPaths,
1127
+ });
1128
+ }
1129
+ const validator = this.getValidator(this.spec);
1130
+ const validationResult = validator.validateSpec();
1131
+ warnings.push(...validationResult.warnings);
1132
+ errors.push(...validationResult.errors);
1133
+ let status = ValidationStatus.Valid;
1134
+ if (warnings.length > 0 && errors.length === 0) {
1135
+ status = ValidationStatus.Warning;
1136
+ }
1137
+ else if (errors.length > 0) {
1138
+ status = ValidationStatus.Error;
1139
+ }
1140
+ return {
1141
+ status: status,
1142
+ warnings: warnings,
1143
+ errors: errors,
1144
+ };
877
1145
  }
878
1146
  catch (err) {
879
1147
  throw new SpecParserError(err.toString(), ErrorType.ValidateFailed);
@@ -884,17 +1152,20 @@ class SpecParser {
884
1152
  return __awaiter(this, void 0, void 0, function* () {
885
1153
  try {
886
1154
  yield this.loadSpec();
887
- const apiMap = this.getAllSupportedAPIs(this.spec);
1155
+ const apiMap = this.getAPIs(this.spec);
888
1156
  const apiInfos = [];
889
1157
  for (const key in apiMap) {
890
- const pathObjectItem = apiMap[key];
1158
+ const { operation, isValid } = apiMap[key];
1159
+ if (!isValid) {
1160
+ continue;
1161
+ }
891
1162
  const [method, path] = key.split(" ");
892
- const operationId = pathObjectItem.operationId;
1163
+ const operationId = operation.operationId;
893
1164
  // In Browser environment, this api is by default not support api without operationId
894
1165
  if (!operationId) {
895
1166
  continue;
896
1167
  }
897
- const [command, warning] = Utils.parseApiInfo(pathObjectItem, this.options);
1168
+ const command = Utils.parseApiInfo(operation, this.options);
898
1169
  const apiInfo = {
899
1170
  method: method,
900
1171
  path: path,
@@ -903,9 +1174,6 @@ class SpecParser {
903
1174
  parameters: command.parameters,
904
1175
  description: command.description,
905
1176
  };
906
- if (warning) {
907
- apiInfo.warning = warning;
908
- }
909
1177
  apiInfos.push(apiInfo);
910
1178
  }
911
1179
  return apiInfos;
@@ -975,13 +1243,18 @@ class SpecParser {
975
1243
  }
976
1244
  });
977
1245
  }
978
- getAllSupportedAPIs(spec) {
979
- if (this.apiMap !== undefined) {
980
- return this.apiMap;
1246
+ getAPIs(spec) {
1247
+ const validator = this.getValidator(spec);
1248
+ const apiMap = validator.listAPIs();
1249
+ return apiMap;
1250
+ }
1251
+ getValidator(spec) {
1252
+ if (this.validator) {
1253
+ return this.validator;
981
1254
  }
982
- const result = Utils.listSupportedAPIs(spec, this.options);
983
- this.apiMap = result;
984
- return result;
1255
+ const validator = ValidatorFactory.create(spec, this.options);
1256
+ this.validator = validator;
1257
+ return validator;
985
1258
  }
986
1259
  }
987
1260
 
@@ -989,7 +1262,7 @@ class SpecParser {
989
1262
  class AdaptiveCardGenerator {
990
1263
  static generateAdaptiveCard(operationItem) {
991
1264
  try {
992
- const json = Utils.getResponseJson(operationItem);
1265
+ const { json } = Utils.getResponseJson(operationItem);
993
1266
  let cardBody = [];
994
1267
  let schema = json.schema;
995
1268
  let jsonPath = "$";