@microsoft/m365-spec-parser 0.1.1-alpha.18377bc6e.0 → 0.1.1-alpha.194555abc.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.
@@ -17,6 +17,7 @@ var ErrorType;
17
17
  ErrorType["SwaggerNotSupported"] = "swagger-not-supported";
18
18
  ErrorType["MultipleAuthNotSupported"] = "multiple-auth-not-supported";
19
19
  ErrorType["SpecVersionNotSupported"] = "spec-version-not-supported";
20
+ ErrorType["CircularReferenceNotSupported"] = "circular-reference-not-supported";
20
21
  ErrorType["ListFailed"] = "list-failed";
21
22
  ErrorType["listSupportedAPIInfoFailed"] = "list-supported-api-info-failed";
22
23
  ErrorType["FilterSpecFailed"] = "filter-spec-failed";
@@ -87,7 +88,7 @@ ConstantString.RemoteRefNotSupported = "Remote reference is not supported: %s.";
87
88
  ConstantString.MissingOperationId = "Missing operationIds: %s.";
88
89
  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.";
89
90
  ConstantString.AdditionalPropertiesNotSupported = "'additionalProperties' is not supported, and will be ignored.";
90
- ConstantString.SchemaNotSupported = "'oneOf', 'anyOf', and 'not' schema are not supported: %s.";
91
+ ConstantString.SchemaNotSupported = "'oneOf', 'allOf', 'anyOf', and 'not' schema are not supported: %s.";
91
92
  ConstantString.UnknownSchema = "Unknown schema: %s.";
92
93
  ConstantString.UrlProtocolNotSupported = "Server url is not correct: protocol %s is not supported, you should use https protocol instead.";
93
94
  ConstantString.RelativeServerUrlNotSupported = "Server url is not correct: relative server url is not supported.";
@@ -107,9 +108,14 @@ ConstantString.AdaptiveCardVersion = "1.5";
107
108
  ConstantString.AdaptiveCardSchema = "http://adaptivecards.io/schemas/adaptive-card.json";
108
109
  ConstantString.AdaptiveCardType = "AdaptiveCard";
109
110
  ConstantString.TextBlockType = "TextBlock";
111
+ ConstantString.ImageType = "Image";
110
112
  ConstantString.ContainerType = "Container";
111
- ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
112
- ConstantString.OAuthRegistrationIdPostFix = "OAUTH_REGISTRATION_ID";
113
+ ConstantString.RegistrationIdPostfix = {
114
+ apiKey: "REGISTRATION_ID",
115
+ oauth2: "CONFIGURATION_ID",
116
+ http: "REGISTRATION_ID",
117
+ openIdConnect: "REGISTRATION_ID",
118
+ };
113
119
  ConstantString.ResponseCodeFor20X = [
114
120
  "200",
115
121
  "201",
@@ -168,9 +174,11 @@ ConstantString.ShortDescriptionMaxLens = 80;
168
174
  ConstantString.FullDescriptionMaxLens = 4000;
169
175
  ConstantString.CommandDescriptionMaxLens = 128;
170
176
  ConstantString.ParameterDescriptionMaxLens = 128;
177
+ ConstantString.ConversationStarterMaxLens = 50;
171
178
  ConstantString.CommandTitleMaxLens = 32;
172
179
  ConstantString.ParameterTitleMaxLens = 32;
173
- ConstantString.SMERequiredParamsMaxNum = 5;
180
+ ConstantString.SMERequiredParamsMaxNum = 5;
181
+ ConstantString.DefaultPluginId = "plugin_1";
174
182
 
175
183
  // Copyright (c) Microsoft Corporation.
176
184
  class Utils {
@@ -203,9 +211,10 @@ class Utils {
203
211
  var _a;
204
212
  const result = [];
205
213
  const securitySchemas = (_a = spec.components) === null || _a === void 0 ? void 0 : _a.securitySchemes;
206
- if (securities && securitySchemas) {
207
- for (let i = 0; i < securities.length; i++) {
208
- const security = securities[i];
214
+ const securitiesArr = securities !== null && securities !== void 0 ? securities : spec.security;
215
+ if (securitiesArr && securitySchemas) {
216
+ for (let i = 0; i < securitiesArr.length; i++) {
217
+ const security = securitiesArr[i];
209
218
  const authArray = [];
210
219
  for (const name in security) {
211
220
  const auth = securitySchemas[name];
@@ -222,6 +231,25 @@ class Utils {
222
231
  result.sort((a, b) => a[0].name.localeCompare(b[0].name));
223
232
  return result;
224
233
  }
234
+ static getAuthInfo(spec) {
235
+ let authInfo = undefined;
236
+ for (const url in spec.paths) {
237
+ for (const method in spec.paths[url]) {
238
+ const operation = spec.paths[url][method];
239
+ const authArray = Utils.getAuthArray(operation.security, spec);
240
+ if (authArray && authArray.length > 0) {
241
+ const currentAuth = authArray[0][0];
242
+ if (!authInfo) {
243
+ authInfo = authArray[0][0];
244
+ }
245
+ else if (authInfo.name !== currentAuth.name) {
246
+ throw new SpecParserError(ConstantString.MultipleAuthNotSupported, ErrorType.MultipleAuthNotSupported);
247
+ }
248
+ }
249
+ }
250
+ }
251
+ return authInfo;
252
+ }
225
253
  static updateFirstLetter(str) {
226
254
  return str.charAt(0).toUpperCase() + str.slice(1);
227
255
  }
@@ -504,6 +532,19 @@ class Utils {
504
532
 
505
533
  // Copyright (c) Microsoft Corporation.
506
534
  class Validator {
535
+ constructor() {
536
+ this.hasCircularReference = false;
537
+ }
538
+ checkCircularReference() {
539
+ try {
540
+ JSON.stringify(this.spec);
541
+ }
542
+ catch (e) {
543
+ if (e.message.includes("Converting circular structure to JSON")) {
544
+ this.hasCircularReference = true;
545
+ }
546
+ }
547
+ }
507
548
  listAPIs() {
508
549
  var _a;
509
550
  if (this.apiMap) {
@@ -550,9 +591,16 @@ class Validator {
550
591
  const apiMap = this.listAPIs();
551
592
  const validAPIs = Object.entries(apiMap).filter(([, value]) => value.isValid);
552
593
  if (validAPIs.length === 0) {
594
+ const data = [];
595
+ for (const key in apiMap) {
596
+ const { reason } = apiMap[key];
597
+ const apiInvalidReason = { api: key, reason: reason };
598
+ data.push(apiInvalidReason);
599
+ }
553
600
  result.errors.push({
554
601
  type: ErrorType.NoSupportedApi,
555
602
  content: ConstantString.NoSupportedApi,
603
+ data,
556
604
  });
557
605
  }
558
606
  return result;
@@ -592,17 +640,35 @@ class Validator {
592
640
  }
593
641
  return result;
594
642
  }
643
+ validateCircularReference(method, path) {
644
+ const result = { isValid: true, reason: [] };
645
+ if (this.hasCircularReference) {
646
+ const operationObject = this.spec.paths[path][method];
647
+ try {
648
+ JSON.stringify(operationObject);
649
+ }
650
+ catch (e) {
651
+ if (e.message.includes("Converting circular structure to JSON")) {
652
+ result.isValid = false;
653
+ result.reason.push(ErrorType.CircularReferenceNotSupported);
654
+ }
655
+ }
656
+ }
657
+ return result;
658
+ }
595
659
  validateResponse(method, path) {
596
660
  const result = { isValid: true, reason: [] };
597
661
  const operationObject = this.spec.paths[path][method];
598
662
  const { json, multipleMediaType } = Utils.getResponseJson(operationObject);
599
- // only support response body only contains “application/json” content type
600
- if (multipleMediaType) {
601
- result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
602
- }
603
- else if (Object.keys(json).length === 0) {
604
- // response body should not be empty
605
- result.reason.push(ErrorType.ResponseJsonIsEmpty);
663
+ if (this.options.projectType === ProjectType.SME) {
664
+ // only support response body only contains “application/json” content type
665
+ if (multipleMediaType) {
666
+ result.reason.push(ErrorType.ResponseContainMultipleMediaTypes);
667
+ }
668
+ else if (Object.keys(json).length === 0) {
669
+ // response body should not be empty
670
+ result.reason.push(ErrorType.ResponseJsonIsEmpty);
671
+ }
606
672
  }
607
673
  return result;
608
674
  }
@@ -778,6 +844,7 @@ class CopilotValidator extends Validator {
778
844
  this.projectType = ProjectType.Copilot;
779
845
  this.options = options;
780
846
  this.spec = spec;
847
+ this.checkCircularReference();
781
848
  }
782
849
  validateSpec() {
783
850
  const result = { errors: [], warnings: [] };
@@ -803,6 +870,10 @@ class CopilotValidator extends Validator {
803
870
  if (!methodAndPathResult.isValid) {
804
871
  return methodAndPathResult;
805
872
  }
873
+ const circularReferenceResult = this.validateCircularReference(method, path);
874
+ if (!circularReferenceResult.isValid) {
875
+ return circularReferenceResult;
876
+ }
806
877
  const operationObject = this.spec.paths[path][method];
807
878
  // validate auth
808
879
  const authCheckResult = this.validateAuth(method, path);
@@ -820,9 +891,6 @@ class CopilotValidator extends Validator {
820
891
  // validate requestBody
821
892
  const requestBody = operationObject.requestBody;
822
893
  const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
823
- if (Utils.containMultipleMediaTypes(requestBody)) {
824
- result.reason.push(ErrorType.PostBodyContainMultipleMediaTypes);
825
- }
826
894
  if (requestJsonBody) {
827
895
  const requestBodySchema = requestJsonBody.schema;
828
896
  if (requestBodySchema.type !== "object") {
@@ -849,6 +917,7 @@ class SMEValidator extends Validator {
849
917
  this.projectType = ProjectType.SME;
850
918
  this.options = options;
851
919
  this.spec = spec;
920
+ this.checkCircularReference();
852
921
  }
853
922
  validateSpec() {
854
923
  const result = { errors: [], warnings: [] };
@@ -862,8 +931,10 @@ class SMEValidator extends Validator {
862
931
  validationResult = this.validateSpecNoSupportAPI();
863
932
  result.errors.push(...validationResult.errors);
864
933
  // validate operationId missing
865
- validationResult = this.validateSpecOperationId();
866
- result.warnings.push(...validationResult.warnings);
934
+ if (this.options.allowMissingId) {
935
+ validationResult = this.validateSpecOperationId();
936
+ result.warnings.push(...validationResult.warnings);
937
+ }
867
938
  return result;
868
939
  }
869
940
  validateAPI(method, path) {
@@ -874,6 +945,10 @@ class SMEValidator extends Validator {
874
945
  if (!methodAndPathResult.isValid) {
875
946
  return methodAndPathResult;
876
947
  }
948
+ const circularReferenceResult = this.validateCircularReference(method, path);
949
+ if (!circularReferenceResult.isValid) {
950
+ return circularReferenceResult;
951
+ }
877
952
  const operationObject = this.spec.paths[path][method];
878
953
  // validate auth
879
954
  const authCheckResult = this.validateAuth(method, path);
@@ -944,6 +1019,7 @@ class TeamsAIValidator extends Validator {
944
1019
  this.projectType = ProjectType.TeamsAi;
945
1020
  this.options = options;
946
1021
  this.spec = spec;
1022
+ this.checkCircularReference();
947
1023
  }
948
1024
  validateSpec() {
949
1025
  const result = { errors: [], warnings: [] };
@@ -963,6 +1039,10 @@ class TeamsAIValidator extends Validator {
963
1039
  if (!methodAndPathResult.isValid) {
964
1040
  return methodAndPathResult;
965
1041
  }
1042
+ const circularReferenceResult = this.validateCircularReference(method, path);
1043
+ if (!circularReferenceResult.isValid) {
1044
+ return circularReferenceResult;
1045
+ }
966
1046
  const operationObject = this.spec.paths[path][method];
967
1047
  // validate operationId
968
1048
  if (!this.options.allowMissingId && !operationObject.operationId) {
@@ -1014,7 +1094,11 @@ class SpecParser {
1014
1094
  allowBearerTokenAuth: false,
1015
1095
  allowOauth2: false,
1016
1096
  allowMethods: ["get", "post"],
1097
+ allowConversationStarters: false,
1098
+ allowResponseSemantics: false,
1099
+ allowConfirmation: false,
1017
1100
  projectType: ProjectType.SME,
1101
+ isGptPlugin: false,
1018
1102
  };
1019
1103
  this.pathOrSpec = pathOrDoc;
1020
1104
  this.parser = new SwaggerParser();
@@ -1029,7 +1113,11 @@ class SpecParser {
1029
1113
  try {
1030
1114
  try {
1031
1115
  await this.loadSpec();
1032
- await this.parser.validate(this.spec);
1116
+ await this.parser.validate(this.spec, {
1117
+ validate: {
1118
+ schema: false,
1119
+ },
1120
+ });
1033
1121
  }
1034
1122
  catch (e) {
1035
1123
  return {
@@ -1167,12 +1255,8 @@ class SpecParser {
1167
1255
  }
1168
1256
  }
1169
1257
  getAPIs(spec) {
1170
- if (this.apiMap !== undefined) {
1171
- return this.apiMap;
1172
- }
1173
1258
  const validator = this.getValidator(spec);
1174
1259
  const apiMap = validator.listAPIs();
1175
- this.apiMap = apiMap;
1176
1260
  return apiMap;
1177
1261
  }
1178
1262
  getValidator(spec) {