@microsoft/m365-spec-parser 0.1.1-alpha.8d8f5a0bb.0 → 0.1.1-alpha.a372ccf67.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 +75 -51
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +143 -110
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +75 -51
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +142 -109
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/constants.d.ts +3 -1
- package/dist/src/index.browser.d.ts +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/interfaces.d.ts +31 -3
- package/dist/src/manifestUpdater.d.ts +5 -5
- package/dist/src/specFilter.d.ts +2 -1
- package/dist/src/specParser.browser.d.ts +1 -1
- package/dist/src/specParser.d.ts +1 -2
- package/dist/src/utils.d.ts +11 -10
- package/package.json +3 -3
package/dist/index.esm5.js
CHANGED
|
@@ -45,7 +45,7 @@ var ErrorType;
|
|
|
45
45
|
ErrorType["NoExtraAPICanBeAdded"] = "no-extra-api-can-be-added";
|
|
46
46
|
ErrorType["ResolveServerUrlFailed"] = "resolve-server-url-failed";
|
|
47
47
|
ErrorType["SwaggerNotSupported"] = "swagger-not-supported";
|
|
48
|
-
ErrorType["
|
|
48
|
+
ErrorType["MultipleAuthNotSupported"] = "multiple-auth-not-supported";
|
|
49
49
|
ErrorType["ListFailed"] = "list-failed";
|
|
50
50
|
ErrorType["listSupportedAPIInfoFailed"] = "list-supported-api-info-failed";
|
|
51
51
|
ErrorType["FilterSpecFailed"] = "filter-spec-failed";
|
|
@@ -76,7 +76,13 @@ var ValidationStatus;
|
|
|
76
76
|
ValidationStatus[ValidationStatus["Valid"] = 0] = "Valid";
|
|
77
77
|
ValidationStatus[ValidationStatus["Warning"] = 1] = "Warning";
|
|
78
78
|
ValidationStatus[ValidationStatus["Error"] = 2] = "Error";
|
|
79
|
-
})(ValidationStatus || (ValidationStatus = {}));
|
|
79
|
+
})(ValidationStatus || (ValidationStatus = {}));
|
|
80
|
+
var ProjectType;
|
|
81
|
+
(function (ProjectType) {
|
|
82
|
+
ProjectType[ProjectType["Copilot"] = 0] = "Copilot";
|
|
83
|
+
ProjectType[ProjectType["SME"] = 1] = "SME";
|
|
84
|
+
ProjectType[ProjectType["TeamsAi"] = 2] = "TeamsAi";
|
|
85
|
+
})(ProjectType || (ProjectType = {}));
|
|
80
86
|
|
|
81
87
|
// Copyright (c) Microsoft Corporation.
|
|
82
88
|
class SpecParserError extends Error {
|
|
@@ -103,7 +109,7 @@ ConstantString.ResolveServerUrlFailed = "Unable to resolve the server URL: pleas
|
|
|
103
109
|
ConstantString.OperationOnlyContainsOptionalParam = "Operation %s contains multiple optional parameters. The first optional parameter is used for this command.";
|
|
104
110
|
ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converted to OpenAPI 3.0.";
|
|
105
111
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
106
|
-
ConstantString.
|
|
112
|
+
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
107
113
|
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
108
114
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
109
115
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
@@ -116,6 +122,7 @@ ConstantString.AdaptiveCardType = "AdaptiveCard";
|
|
|
116
122
|
ConstantString.TextBlockType = "TextBlock";
|
|
117
123
|
ConstantString.ContainerType = "Container";
|
|
118
124
|
ConstantString.RegistrationIdPostfix = "REGISTRATION_ID";
|
|
125
|
+
ConstantString.OAuthRegistrationIdPostFix = "OAUTH_REGISTRATION_ID";
|
|
119
126
|
ConstantString.ResponseCodeFor20X = [
|
|
120
127
|
"200",
|
|
121
128
|
"201",
|
|
@@ -175,7 +182,8 @@ ConstantString.FullDescriptionMaxLens = 4000;
|
|
|
175
182
|
ConstantString.CommandDescriptionMaxLens = 128;
|
|
176
183
|
ConstantString.ParameterDescriptionMaxLens = 128;
|
|
177
184
|
ConstantString.CommandTitleMaxLens = 32;
|
|
178
|
-
ConstantString.ParameterTitleMaxLens = 32;
|
|
185
|
+
ConstantString.ParameterTitleMaxLens = 32;
|
|
186
|
+
ConstantString.SMERequiredParamsMaxNum = 5;
|
|
179
187
|
|
|
180
188
|
// Copyright (c) Microsoft Corporation.
|
|
181
189
|
class Utils {
|
|
@@ -288,6 +296,9 @@ class Utils {
|
|
|
288
296
|
}
|
|
289
297
|
return paramResult;
|
|
290
298
|
}
|
|
299
|
+
static containMultipleMediaTypes(bodyObject) {
|
|
300
|
+
return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
|
|
301
|
+
}
|
|
291
302
|
/**
|
|
292
303
|
* Checks if the given API is supported.
|
|
293
304
|
* @param {string} method - The HTTP method of the API.
|
|
@@ -302,32 +313,40 @@ class Utils {
|
|
|
302
313
|
* 5. response body should be “application/json” and not empty, and response code should be 20X
|
|
303
314
|
* 6. only support request body with “application/json” content type
|
|
304
315
|
*/
|
|
305
|
-
static isSupportedApi(method, path, spec,
|
|
316
|
+
static isSupportedApi(method, path, spec, options) {
|
|
317
|
+
var _a;
|
|
306
318
|
const pathObj = spec.paths[path];
|
|
307
319
|
method = method.toLocaleLowerCase();
|
|
308
320
|
if (pathObj) {
|
|
309
|
-
if ((
|
|
310
|
-
pathObj[method]) {
|
|
321
|
+
if (((_a = options.allowMethods) === null || _a === void 0 ? void 0 : _a.includes(method)) && pathObj[method]) {
|
|
311
322
|
const securities = pathObj[method].security;
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
323
|
+
const isTeamsAi = options.projectType === ProjectType.TeamsAi;
|
|
324
|
+
const isCopilot = options.projectType === ProjectType.Copilot;
|
|
325
|
+
// Teams AI project doesn't care about auth, it will use authProvider for user to implement
|
|
326
|
+
if (!isTeamsAi) {
|
|
327
|
+
const authArray = Utils.getAuthArray(securities, spec);
|
|
328
|
+
if (!Utils.isSupportedAuth(authArray, options)) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
315
331
|
}
|
|
316
332
|
const operationObject = pathObj[method];
|
|
317
|
-
if (!allowMissingId && !operationObject.operationId) {
|
|
333
|
+
if (!options.allowMissingId && !operationObject.operationId) {
|
|
318
334
|
return false;
|
|
319
335
|
}
|
|
320
336
|
const paramObject = operationObject.parameters;
|
|
321
337
|
const requestBody = operationObject.requestBody;
|
|
322
338
|
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
323
|
-
|
|
324
|
-
if (mediaTypesCount > 1) {
|
|
339
|
+
if (!isTeamsAi && Utils.containMultipleMediaTypes(requestBody)) {
|
|
325
340
|
return false;
|
|
326
341
|
}
|
|
327
|
-
const responseJson = Utils.getResponseJson(operationObject);
|
|
342
|
+
const responseJson = Utils.getResponseJson(operationObject, isTeamsAi);
|
|
328
343
|
if (Object.keys(responseJson).length === 0) {
|
|
329
344
|
return false;
|
|
330
345
|
}
|
|
346
|
+
// Teams AI project doesn't care about request parameters/body
|
|
347
|
+
if (isTeamsAi) {
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
331
350
|
let requestBodyParamResult = {
|
|
332
351
|
requiredNum: 0,
|
|
333
352
|
optionalNum: 0,
|
|
@@ -352,8 +371,9 @@ class Utils {
|
|
|
352
371
|
return true;
|
|
353
372
|
}
|
|
354
373
|
if (requestBodyParamResult.requiredNum + paramResult.requiredNum > 1) {
|
|
355
|
-
if (allowMultipleParameters &&
|
|
356
|
-
requestBodyParamResult.requiredNum + paramResult.requiredNum <=
|
|
374
|
+
if (options.allowMultipleParameters &&
|
|
375
|
+
requestBodyParamResult.requiredNum + paramResult.requiredNum <=
|
|
376
|
+
ConstantString.SMERequiredParamsMaxNum) {
|
|
357
377
|
return true;
|
|
358
378
|
}
|
|
359
379
|
return false;
|
|
@@ -372,29 +392,31 @@ class Utils {
|
|
|
372
392
|
}
|
|
373
393
|
return false;
|
|
374
394
|
}
|
|
375
|
-
static isSupportedAuth(authSchemaArray,
|
|
395
|
+
static isSupportedAuth(authSchemaArray, options) {
|
|
376
396
|
if (authSchemaArray.length === 0) {
|
|
377
397
|
return true;
|
|
378
398
|
}
|
|
379
|
-
if (allowAPIKeyAuth || allowOauth2) {
|
|
399
|
+
if (options.allowAPIKeyAuth || options.allowOauth2) {
|
|
380
400
|
// Currently we don't support multiple auth in one operation
|
|
381
401
|
if (authSchemaArray.length > 0 && authSchemaArray.every((auths) => auths.length > 1)) {
|
|
382
402
|
return false;
|
|
383
403
|
}
|
|
384
404
|
for (const auths of authSchemaArray) {
|
|
385
405
|
if (auths.length === 1) {
|
|
386
|
-
if (!allowOauth2 &&
|
|
406
|
+
if (!options.allowOauth2 &&
|
|
407
|
+
options.allowAPIKeyAuth &&
|
|
408
|
+
Utils.isAPIKeyAuth(auths[0].authSchema)) {
|
|
387
409
|
return true;
|
|
388
410
|
}
|
|
389
|
-
else if (!allowAPIKeyAuth &&
|
|
390
|
-
allowOauth2 &&
|
|
391
|
-
Utils.
|
|
411
|
+
else if (!options.allowAPIKeyAuth &&
|
|
412
|
+
options.allowOauth2 &&
|
|
413
|
+
Utils.isOAuthWithAuthCodeFlow(auths[0].authSchema)) {
|
|
392
414
|
return true;
|
|
393
415
|
}
|
|
394
|
-
else if (allowAPIKeyAuth &&
|
|
395
|
-
allowOauth2 &&
|
|
416
|
+
else if (options.allowAPIKeyAuth &&
|
|
417
|
+
options.allowOauth2 &&
|
|
396
418
|
(Utils.isAPIKeyAuth(auths[0].authSchema) ||
|
|
397
|
-
Utils.
|
|
419
|
+
Utils.isOAuthWithAuthCodeFlow(auths[0].authSchema))) {
|
|
398
420
|
return true;
|
|
399
421
|
}
|
|
400
422
|
}
|
|
@@ -405,10 +427,11 @@ class Utils {
|
|
|
405
427
|
static isAPIKeyAuth(authSchema) {
|
|
406
428
|
return authSchema.type === "apiKey";
|
|
407
429
|
}
|
|
408
|
-
static
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
430
|
+
static isOAuthWithAuthCodeFlow(authSchema) {
|
|
431
|
+
if (authSchema.type === "oauth2" && authSchema.flows && authSchema.flows.authorizationCode) {
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
return false;
|
|
412
435
|
}
|
|
413
436
|
static getAuthArray(securities, spec) {
|
|
414
437
|
var _a;
|
|
@@ -436,18 +459,19 @@ class Utils {
|
|
|
436
459
|
static updateFirstLetter(str) {
|
|
437
460
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
438
461
|
}
|
|
439
|
-
static getResponseJson(operationObject) {
|
|
462
|
+
static getResponseJson(operationObject, isTeamsAiProject = false) {
|
|
440
463
|
var _a, _b;
|
|
441
464
|
let json = {};
|
|
442
465
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
443
466
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
444
|
-
const mediaTypesCount = Object.keys((responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) || {}).length;
|
|
445
|
-
if (mediaTypesCount > 1) {
|
|
446
|
-
return {};
|
|
447
|
-
}
|
|
448
467
|
if ((_b = responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) === null || _b === void 0 ? void 0 : _b["application/json"]) {
|
|
449
468
|
json = responseObject.content["application/json"];
|
|
450
|
-
|
|
469
|
+
if (!isTeamsAiProject && Utils.containMultipleMediaTypes(responseObject)) {
|
|
470
|
+
json = {};
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
451
475
|
}
|
|
452
476
|
}
|
|
453
477
|
return json;
|
|
@@ -521,7 +545,7 @@ class Utils {
|
|
|
521
545
|
}
|
|
522
546
|
return errors;
|
|
523
547
|
}
|
|
524
|
-
static validateServer(spec,
|
|
548
|
+
static validateServer(spec, options) {
|
|
525
549
|
const errors = [];
|
|
526
550
|
let hasTopLevelServers = false;
|
|
527
551
|
let hasPathLevelServers = false;
|
|
@@ -542,7 +566,7 @@ class Utils {
|
|
|
542
566
|
}
|
|
543
567
|
for (const method in methods) {
|
|
544
568
|
const operationObject = methods[method];
|
|
545
|
-
if (Utils.isSupportedApi(method, path, spec,
|
|
569
|
+
if (Utils.isSupportedApi(method, path, spec, options)) {
|
|
546
570
|
if ((operationObject === null || operationObject === void 0 ? void 0 : operationObject.servers) && operationObject.servers.length >= 1) {
|
|
547
571
|
hasOperationLevelServers = true;
|
|
548
572
|
const serverErrors = Utils.checkServerUrl(operationObject.servers);
|
|
@@ -629,7 +653,7 @@ class Utils {
|
|
|
629
653
|
param.value = schema.default;
|
|
630
654
|
}
|
|
631
655
|
}
|
|
632
|
-
static parseApiInfo(operationItem,
|
|
656
|
+
static parseApiInfo(operationItem, options) {
|
|
633
657
|
var _a, _b;
|
|
634
658
|
const requiredParams = [];
|
|
635
659
|
const optionalParams = [];
|
|
@@ -643,7 +667,7 @@ class Utils {
|
|
|
643
667
|
description: ((_a = param.description) !== null && _a !== void 0 ? _a : "").slice(0, ConstantString.ParameterDescriptionMaxLens),
|
|
644
668
|
};
|
|
645
669
|
const schema = param.schema;
|
|
646
|
-
if (allowMultipleParameters && schema) {
|
|
670
|
+
if (options.allowMultipleParameters && schema) {
|
|
647
671
|
Utils.updateParameterWithInputType(schema, parameter);
|
|
648
672
|
}
|
|
649
673
|
if (param.in !== "header" && param.in !== "cookie") {
|
|
@@ -661,7 +685,7 @@ class Utils {
|
|
|
661
685
|
const requestJson = requestBody.content["application/json"];
|
|
662
686
|
if (Object.keys(requestJson).length !== 0) {
|
|
663
687
|
const schema = requestJson.schema;
|
|
664
|
-
const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", allowMultipleParameters, requestBody.required);
|
|
688
|
+
const [requiredP, optionalP] = Utils.generateParametersFromSchema(schema, "requestBody", !!options.allowMultipleParameters, requestBody.required);
|
|
665
689
|
requiredParams.push(...requiredP);
|
|
666
690
|
optionalParams.push(...optionalP);
|
|
667
691
|
}
|
|
@@ -692,14 +716,13 @@ class Utils {
|
|
|
692
716
|
}
|
|
693
717
|
return [command, warning];
|
|
694
718
|
}
|
|
695
|
-
static listSupportedAPIs(spec,
|
|
719
|
+
static listSupportedAPIs(spec, options) {
|
|
696
720
|
const paths = spec.paths;
|
|
697
721
|
const result = {};
|
|
698
722
|
for (const path in paths) {
|
|
699
723
|
const methods = paths[path];
|
|
700
724
|
for (const method in methods) {
|
|
701
|
-
|
|
702
|
-
if (Utils.isSupportedApi(method, path, spec, allowMissingId, allowAPIKeyAuth, allowMultipleParameters, allowOauth2, isCopilot)) {
|
|
725
|
+
if (Utils.isSupportedApi(method, path, spec, options)) {
|
|
703
726
|
const operationObject = methods[method];
|
|
704
727
|
result[`${method.toUpperCase()} ${path}`] = operationObject;
|
|
705
728
|
}
|
|
@@ -707,7 +730,7 @@ class Utils {
|
|
|
707
730
|
}
|
|
708
731
|
return result;
|
|
709
732
|
}
|
|
710
|
-
static validateSpec(spec, parser, isSwaggerFile,
|
|
733
|
+
static validateSpec(spec, parser, isSwaggerFile, options) {
|
|
711
734
|
const errors = [];
|
|
712
735
|
const warnings = [];
|
|
713
736
|
if (isSwaggerFile) {
|
|
@@ -717,7 +740,7 @@ class Utils {
|
|
|
717
740
|
});
|
|
718
741
|
}
|
|
719
742
|
// Server validation
|
|
720
|
-
const serverErrors = Utils.validateServer(spec,
|
|
743
|
+
const serverErrors = Utils.validateServer(spec, options);
|
|
721
744
|
errors.push(...serverErrors);
|
|
722
745
|
// Remote reference not supported
|
|
723
746
|
const refPaths = parser.$refs.paths();
|
|
@@ -730,7 +753,7 @@ class Utils {
|
|
|
730
753
|
});
|
|
731
754
|
}
|
|
732
755
|
// No supported API
|
|
733
|
-
const apiMap = Utils.listSupportedAPIs(spec,
|
|
756
|
+
const apiMap = Utils.listSupportedAPIs(spec, options);
|
|
734
757
|
if (Object.keys(apiMap).length === 0) {
|
|
735
758
|
errors.push({
|
|
736
759
|
type: ErrorType.NoSupportedApi,
|
|
@@ -801,7 +824,8 @@ class SpecParser {
|
|
|
801
824
|
allowAPIKeyAuth: false,
|
|
802
825
|
allowMultipleParameters: false,
|
|
803
826
|
allowOauth2: false,
|
|
804
|
-
|
|
827
|
+
allowMethods: ["get", "post"],
|
|
828
|
+
projectType: ProjectType.SME,
|
|
805
829
|
};
|
|
806
830
|
this.pathOrSpec = pathOrDoc;
|
|
807
831
|
this.parser = new SwaggerParser();
|
|
@@ -839,7 +863,7 @@ class SpecParser {
|
|
|
839
863
|
],
|
|
840
864
|
};
|
|
841
865
|
}
|
|
842
|
-
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options
|
|
866
|
+
return Utils.validateSpec(this.spec, this.parser, !!this.isSwaggerFile, this.options);
|
|
843
867
|
}
|
|
844
868
|
catch (err) {
|
|
845
869
|
throw new SpecParserError(err.toString(), ErrorType.ValidateFailed);
|
|
@@ -860,7 +884,7 @@ class SpecParser {
|
|
|
860
884
|
if (!operationId) {
|
|
861
885
|
continue;
|
|
862
886
|
}
|
|
863
|
-
const [command, warning] = Utils.parseApiInfo(pathObjectItem, this.options
|
|
887
|
+
const [command, warning] = Utils.parseApiInfo(pathObjectItem, this.options);
|
|
864
888
|
const apiInfo = {
|
|
865
889
|
method: method,
|
|
866
890
|
path: path,
|
|
@@ -924,7 +948,7 @@ class SpecParser {
|
|
|
924
948
|
* @param isMe Boolean that indicates whether the project is an Messaging Extension. For Messaging Extension, composeExtensions will be added in Teams app manifest.
|
|
925
949
|
*/
|
|
926
950
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
927
|
-
generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal
|
|
951
|
+
generate(manifestPath, filter, outputSpecPath, adaptiveCardFolder, signal) {
|
|
928
952
|
return __awaiter(this, void 0, void 0, function* () {
|
|
929
953
|
throw new Error("Method not implemented.");
|
|
930
954
|
});
|
|
@@ -945,7 +969,7 @@ class SpecParser {
|
|
|
945
969
|
if (this.apiMap !== undefined) {
|
|
946
970
|
return this.apiMap;
|
|
947
971
|
}
|
|
948
|
-
const result = Utils.listSupportedAPIs(spec, this.options
|
|
972
|
+
const result = Utils.listSupportedAPIs(spec, this.options);
|
|
949
973
|
this.apiMap = result;
|
|
950
974
|
return result;
|
|
951
975
|
}
|