@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.
- package/dist/index.esm2017.js +108 -24
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +516 -321
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +108 -24
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +526 -327
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/adaptiveCardWrapper.d.ts +2 -0
- package/dist/src/constants.d.ts +7 -3
- package/dist/src/index.d.ts +1 -1
- package/dist/src/interfaces.d.ts +26 -0
- package/dist/src/manifestUpdater.d.ts +6 -4
- package/dist/src/specParser.browser.d.ts +0 -1
- package/dist/src/specParser.d.ts +1 -1
- package/dist/src/utils.d.ts +1 -0
- package/package.json +3 -4
package/dist/index.esm2017.js
CHANGED
|
@@ -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 =
|
|
112
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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
|
-
|
|
866
|
-
|
|
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) {
|