@microsoft/m365-spec-parser 0.2.2 → 0.2.3-alpha.2269ef021.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 +35 -66
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +55 -69
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +35 -66
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +55 -69
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/adaptiveCardGenerator.d.ts +4 -2
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/interfaces.d.ts +1 -0
- package/dist/src/utils.d.ts +2 -2
- package/package.json +3 -3
package/dist/index.node.cjs.js
CHANGED
|
@@ -103,6 +103,7 @@ exports.WarningType = void 0;
|
|
|
103
103
|
WarningType["OperationOnlyContainsOptionalParam"] = "operation-only-contains-optional-param";
|
|
104
104
|
WarningType["ConvertSwaggerToOpenAPI"] = "convert-swagger-to-openapi";
|
|
105
105
|
WarningType["FuncDescriptionTooLong"] = "function-description-too-long";
|
|
106
|
+
WarningType["OperationIdContainsSpecialCharacters"] = "operationid-contains-special-characters";
|
|
106
107
|
WarningType["Unknown"] = "unknown";
|
|
107
108
|
})(exports.WarningType || (exports.WarningType = {}));
|
|
108
109
|
/**
|
|
@@ -140,6 +141,7 @@ ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converte
|
|
|
140
141
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
141
142
|
ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
|
|
142
143
|
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
144
|
+
ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
|
|
143
145
|
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
144
146
|
ConstantString.FuncDescriptionTooLong = "The description of the function '%s' is too long. The current length is %s characters, while the maximum allowed length is %s characters.";
|
|
145
147
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
@@ -236,16 +238,19 @@ class SpecParserError extends Error {
|
|
|
236
238
|
// Copyright (c) Microsoft Corporation.
|
|
237
239
|
class Utils {
|
|
238
240
|
static hasNestedObjectInSchema(schema) {
|
|
239
|
-
if (schema
|
|
241
|
+
if (this.isObjectSchema(schema)) {
|
|
240
242
|
for (const property in schema.properties) {
|
|
241
243
|
const nestedSchema = schema.properties[property];
|
|
242
|
-
if (nestedSchema
|
|
244
|
+
if (this.isObjectSchema(nestedSchema)) {
|
|
243
245
|
return true;
|
|
244
246
|
}
|
|
245
247
|
}
|
|
246
248
|
}
|
|
247
249
|
return false;
|
|
248
250
|
}
|
|
251
|
+
static isObjectSchema(schema) {
|
|
252
|
+
return schema.type === "object" || (!schema.type && !!schema.properties);
|
|
253
|
+
}
|
|
249
254
|
static containMultipleMediaTypes(bodyObject) {
|
|
250
255
|
return Object.keys((bodyObject === null || bodyObject === void 0 ? void 0 : bodyObject.content) || {}).length > 1;
|
|
251
256
|
}
|
|
@@ -474,7 +479,7 @@ class Utils {
|
|
|
474
479
|
optionalParams.push(parameter);
|
|
475
480
|
}
|
|
476
481
|
}
|
|
477
|
-
else if (schema
|
|
482
|
+
else if (Utils.isObjectSchema(schema)) {
|
|
478
483
|
const { properties } = schema;
|
|
479
484
|
for (const property in properties) {
|
|
480
485
|
let isRequired = false;
|
|
@@ -588,29 +593,6 @@ class Utils {
|
|
|
588
593
|
const serverUrl = operationServer || methodServer || rootServer;
|
|
589
594
|
return serverUrl;
|
|
590
595
|
}
|
|
591
|
-
static limitACBodyProperties(body, maxCount) {
|
|
592
|
-
const result = [];
|
|
593
|
-
let currentCount = 0;
|
|
594
|
-
for (const element of body) {
|
|
595
|
-
if (element.type === ConstantString.ContainerType) {
|
|
596
|
-
const items = this.limitACBodyProperties(element.items, maxCount - currentCount);
|
|
597
|
-
result.push({
|
|
598
|
-
type: ConstantString.ContainerType,
|
|
599
|
-
$data: element.$data,
|
|
600
|
-
items: items,
|
|
601
|
-
});
|
|
602
|
-
currentCount += items.length;
|
|
603
|
-
}
|
|
604
|
-
else {
|
|
605
|
-
result.push(element);
|
|
606
|
-
currentCount++;
|
|
607
|
-
}
|
|
608
|
-
if (currentCount >= maxCount) {
|
|
609
|
-
break;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
return result;
|
|
613
|
-
}
|
|
614
596
|
}
|
|
615
597
|
|
|
616
598
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -812,7 +794,7 @@ class Validator {
|
|
|
812
794
|
}
|
|
813
795
|
const isRequiredWithoutDefault = isRequired && schema.default === undefined;
|
|
814
796
|
const isCopilot = this.projectType === exports.ProjectType.Copilot;
|
|
815
|
-
if (isCopilot &&
|
|
797
|
+
if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
|
|
816
798
|
paramResult.isValid = false;
|
|
817
799
|
paramResult.reason = [exports.ErrorType.RequestBodyContainsNestedObject];
|
|
818
800
|
return paramResult;
|
|
@@ -828,7 +810,7 @@ class Validator {
|
|
|
828
810
|
paramResult.optionalNum = paramResult.optionalNum + 1;
|
|
829
811
|
}
|
|
830
812
|
}
|
|
831
|
-
else if (schema
|
|
813
|
+
else if (Utils.isObjectSchema(schema)) {
|
|
832
814
|
const { properties } = schema;
|
|
833
815
|
for (const property in properties) {
|
|
834
816
|
let isRequired = false;
|
|
@@ -864,7 +846,7 @@ class Validator {
|
|
|
864
846
|
for (let i = 0; i < paramObject.length; i++) {
|
|
865
847
|
const param = paramObject[i];
|
|
866
848
|
const schema = param.schema;
|
|
867
|
-
if (isCopilot &&
|
|
849
|
+
if (isCopilot && Utils.hasNestedObjectInSchema(schema)) {
|
|
868
850
|
paramResult.isValid = false;
|
|
869
851
|
paramResult.reason.push(exports.ErrorType.ParamsContainsNestedObject);
|
|
870
852
|
continue;
|
|
@@ -907,17 +889,6 @@ class Validator {
|
|
|
907
889
|
}
|
|
908
890
|
return paramResult;
|
|
909
891
|
}
|
|
910
|
-
hasNestedObjectInSchema(schema) {
|
|
911
|
-
if (schema.type === "object") {
|
|
912
|
-
for (const property in schema.properties) {
|
|
913
|
-
const nestedSchema = schema.properties[property];
|
|
914
|
-
if (nestedSchema.type === "object") {
|
|
915
|
-
return true;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
|
-
return false;
|
|
920
|
-
}
|
|
921
892
|
}
|
|
922
893
|
|
|
923
894
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -976,7 +947,7 @@ class CopilotValidator extends Validator {
|
|
|
976
947
|
const requestJsonBody = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content["application/json"];
|
|
977
948
|
if (requestJsonBody) {
|
|
978
949
|
const requestBodySchema = requestJsonBody.schema;
|
|
979
|
-
if (requestBodySchema
|
|
950
|
+
if (!Utils.isObjectSchema(requestBodySchema)) {
|
|
980
951
|
result.reason.push(exports.ErrorType.PostBodySchemaIsNotJson);
|
|
981
952
|
}
|
|
982
953
|
const requestBodyParamResult = this.checkPostBodySchema(requestBodySchema, requestBody.required);
|
|
@@ -1356,7 +1327,7 @@ class SpecFilter {
|
|
|
1356
1327
|
|
|
1357
1328
|
// Copyright (c) Microsoft Corporation.
|
|
1358
1329
|
class AdaptiveCardGenerator {
|
|
1359
|
-
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
|
|
1330
|
+
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
|
|
1360
1331
|
try {
|
|
1361
1332
|
const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
|
|
1362
1333
|
let cardBody = [];
|
|
@@ -1367,7 +1338,7 @@ class AdaptiveCardGenerator {
|
|
|
1367
1338
|
if (jsonPath !== "$") {
|
|
1368
1339
|
schema = schema.properties[jsonPath];
|
|
1369
1340
|
}
|
|
1370
|
-
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "");
|
|
1341
|
+
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "", "", maxElementCount);
|
|
1371
1342
|
}
|
|
1372
1343
|
// if no schema, try to use example value
|
|
1373
1344
|
if (cardBody.length === 0 && (json.examples || json.example)) {
|
|
@@ -1401,10 +1372,14 @@ class AdaptiveCardGenerator {
|
|
|
1401
1372
|
throw new SpecParserError(err.toString(), exports.ErrorType.GenerateAdaptiveCardFailed);
|
|
1402
1373
|
}
|
|
1403
1374
|
}
|
|
1404
|
-
static generateCardFromResponse(schema, name, parentArrayName = "") {
|
|
1375
|
+
static generateCardFromResponse(schema, name, parentArrayName = "", maxElementCount = Number.MAX_SAFE_INTEGER, counter = { count: 0 }) {
|
|
1376
|
+
if (counter.count >= maxElementCount) {
|
|
1377
|
+
return [];
|
|
1378
|
+
}
|
|
1405
1379
|
if (schema.type === "array") {
|
|
1406
1380
|
// schema.items can be arbitrary object: schema { type: array, items: {} }
|
|
1407
1381
|
if (Object.keys(schema.items).length === 0) {
|
|
1382
|
+
counter.count++;
|
|
1408
1383
|
return [
|
|
1409
1384
|
{
|
|
1410
1385
|
type: ConstantString.TextBlockType,
|
|
@@ -1413,7 +1388,7 @@ class AdaptiveCardGenerator {
|
|
|
1413
1388
|
},
|
|
1414
1389
|
];
|
|
1415
1390
|
}
|
|
1416
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name);
|
|
1391
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name, maxElementCount, counter);
|
|
1417
1392
|
const template = {
|
|
1418
1393
|
type: ConstantString.ContainerType,
|
|
1419
1394
|
$data: name ? `\${${name}}` : "${$root}",
|
|
@@ -1423,11 +1398,11 @@ class AdaptiveCardGenerator {
|
|
|
1423
1398
|
return [template];
|
|
1424
1399
|
}
|
|
1425
1400
|
// some schema may not contain type but contain properties
|
|
1426
|
-
if (
|
|
1401
|
+
if (Utils.isObjectSchema(schema)) {
|
|
1427
1402
|
const { properties } = schema;
|
|
1428
1403
|
const result = [];
|
|
1429
1404
|
for (const property in properties) {
|
|
1430
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName);
|
|
1405
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName, maxElementCount, counter);
|
|
1431
1406
|
result.push(...obj);
|
|
1432
1407
|
}
|
|
1433
1408
|
if (schema.additionalProperties) {
|
|
@@ -1440,6 +1415,7 @@ class AdaptiveCardGenerator {
|
|
|
1440
1415
|
schema.type === "integer" ||
|
|
1441
1416
|
schema.type === "boolean" ||
|
|
1442
1417
|
schema.type === "number") {
|
|
1418
|
+
counter.count++;
|
|
1443
1419
|
if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) {
|
|
1444
1420
|
// string in root: "ddd"
|
|
1445
1421
|
let text = "result: ${$root}";
|
|
@@ -1464,24 +1440,17 @@ class AdaptiveCardGenerator {
|
|
|
1464
1440
|
];
|
|
1465
1441
|
}
|
|
1466
1442
|
else {
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
{
|
|
1479
|
-
type: "Image",
|
|
1480
|
-
url: "${$data}",
|
|
1481
|
-
$when: "${$data != null && $data != ''}",
|
|
1482
|
-
},
|
|
1483
|
-
];
|
|
1484
|
-
}
|
|
1443
|
+
const url = name ? `\${${name}}` : "${$data}";
|
|
1444
|
+
const condition = name
|
|
1445
|
+
? `\${${name} != null && ${name} != ''}`
|
|
1446
|
+
: "${$data != null && $data != ''}";
|
|
1447
|
+
return [
|
|
1448
|
+
{
|
|
1449
|
+
type: "Image",
|
|
1450
|
+
url,
|
|
1451
|
+
$when: condition,
|
|
1452
|
+
},
|
|
1453
|
+
];
|
|
1485
1454
|
}
|
|
1486
1455
|
}
|
|
1487
1456
|
if (schema.oneOf || schema.anyOf || schema.not || schema.allOf) {
|
|
@@ -1491,7 +1460,7 @@ class AdaptiveCardGenerator {
|
|
|
1491
1460
|
}
|
|
1492
1461
|
// Find the first array property in the response schema object with the well-known name
|
|
1493
1462
|
static getResponseJsonPathFromSchema(schema) {
|
|
1494
|
-
if (
|
|
1463
|
+
if (Utils.isObjectSchema(schema)) {
|
|
1495
1464
|
const { properties } = schema;
|
|
1496
1465
|
for (const property in properties) {
|
|
1497
1466
|
const schema = properties[property];
|
|
@@ -1746,7 +1715,7 @@ class ManifestUpdater {
|
|
|
1746
1715
|
if (requestBody) {
|
|
1747
1716
|
const requestJsonBody = requestBody.content["application/json"];
|
|
1748
1717
|
const requestBodySchema = requestJsonBody.schema;
|
|
1749
|
-
if (requestBodySchema
|
|
1718
|
+
if (Utils.isObjectSchema(requestBodySchema)) {
|
|
1750
1719
|
for (const property in requestBodySchema.properties) {
|
|
1751
1720
|
const schema = requestBodySchema.properties[property];
|
|
1752
1721
|
ManifestUpdater.checkSchema(schema, method, pathUrl);
|
|
@@ -1774,8 +1743,7 @@ class ManifestUpdater {
|
|
|
1774
1743
|
try {
|
|
1775
1744
|
const { json } = Utils.getResponseJson(operationItem);
|
|
1776
1745
|
if (json.schema) {
|
|
1777
|
-
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem);
|
|
1778
|
-
card.body = Utils.limitACBodyProperties(card.body, 5);
|
|
1746
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
|
|
1779
1747
|
const responseSemantic = wrapResponseSemantics(card, jsonPath);
|
|
1780
1748
|
funcObj.capabilities = {
|
|
1781
1749
|
response_semantics: responseSemantic,
|
|
@@ -2250,6 +2218,24 @@ class SpecParser {
|
|
|
2250
2218
|
const newUnResolvedSpec = newSpecs[0];
|
|
2251
2219
|
const newSpec = newSpecs[1];
|
|
2252
2220
|
const authInfo = Utils.getAuthInfo(newSpec);
|
|
2221
|
+
const paths = newUnResolvedSpec.paths;
|
|
2222
|
+
for (const pathUrl in paths) {
|
|
2223
|
+
const operations = paths[pathUrl];
|
|
2224
|
+
for (const method in operations) {
|
|
2225
|
+
const operationItem = operations[method];
|
|
2226
|
+
const operationId = operationItem.operationId;
|
|
2227
|
+
const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
|
|
2228
|
+
if (!containsSpecialCharacters) {
|
|
2229
|
+
continue;
|
|
2230
|
+
}
|
|
2231
|
+
operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2232
|
+
result.warnings.push({
|
|
2233
|
+
type: exports.WarningType.OperationIdContainsSpecialCharacters,
|
|
2234
|
+
content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
|
|
2235
|
+
data: operationId,
|
|
2236
|
+
});
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2253
2239
|
yield this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
|
|
2254
2240
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
2255
2241
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|