@microsoft/m365-spec-parser 0.2.3-alpha.9432e5ed4.0 → 0.2.3-alpha.9aa2f037e.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 +25 -46
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +184 -49
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +25 -46
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +184 -49
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/adaptiveCardGenerator.d.ts +4 -2
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/interfaces.d.ts +2 -0
- package/dist/src/jsonDataGenerator.d.ts +6 -0
- package/dist/src/utils.d.ts +1 -2
- package/package.json +3 -3
package/dist/index.node.cjs.js
CHANGED
|
@@ -103,6 +103,8 @@ 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";
|
|
107
|
+
WarningType["GenerateJsonDataFailed"] = "generate-json-data-failed";
|
|
106
108
|
WarningType["Unknown"] = "unknown";
|
|
107
109
|
})(exports.WarningType || (exports.WarningType = {}));
|
|
108
110
|
/**
|
|
@@ -140,8 +142,10 @@ ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converte
|
|
|
140
142
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
141
143
|
ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
|
|
142
144
|
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
145
|
+
ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
|
|
143
146
|
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
144
147
|
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.";
|
|
148
|
+
ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
|
|
145
149
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
146
150
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
147
151
|
ConstantString.WrappedCardResponseLayout = "list";
|
|
@@ -591,29 +595,6 @@ class Utils {
|
|
|
591
595
|
const serverUrl = operationServer || methodServer || rootServer;
|
|
592
596
|
return serverUrl;
|
|
593
597
|
}
|
|
594
|
-
static limitACBodyProperties(body, maxCount) {
|
|
595
|
-
const result = [];
|
|
596
|
-
let currentCount = 0;
|
|
597
|
-
for (const element of body) {
|
|
598
|
-
if (element.type === ConstantString.ContainerType) {
|
|
599
|
-
const items = this.limitACBodyProperties(element.items, maxCount - currentCount);
|
|
600
|
-
result.push({
|
|
601
|
-
type: ConstantString.ContainerType,
|
|
602
|
-
$data: element.$data,
|
|
603
|
-
items: items,
|
|
604
|
-
});
|
|
605
|
-
currentCount += items.length;
|
|
606
|
-
}
|
|
607
|
-
else {
|
|
608
|
-
result.push(element);
|
|
609
|
-
currentCount++;
|
|
610
|
-
}
|
|
611
|
-
if (currentCount >= maxCount) {
|
|
612
|
-
break;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
return result;
|
|
616
|
-
}
|
|
617
598
|
}
|
|
618
599
|
|
|
619
600
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -1348,7 +1329,7 @@ class SpecFilter {
|
|
|
1348
1329
|
|
|
1349
1330
|
// Copyright (c) Microsoft Corporation.
|
|
1350
1331
|
class AdaptiveCardGenerator {
|
|
1351
|
-
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
|
|
1332
|
+
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
|
|
1352
1333
|
try {
|
|
1353
1334
|
const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
|
|
1354
1335
|
let cardBody = [];
|
|
@@ -1359,7 +1340,7 @@ class AdaptiveCardGenerator {
|
|
|
1359
1340
|
if (jsonPath !== "$") {
|
|
1360
1341
|
schema = schema.properties[jsonPath];
|
|
1361
1342
|
}
|
|
1362
|
-
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "");
|
|
1343
|
+
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "", "", maxElementCount);
|
|
1363
1344
|
}
|
|
1364
1345
|
// if no schema, try to use example value
|
|
1365
1346
|
if (cardBody.length === 0 && (json.examples || json.example)) {
|
|
@@ -1393,10 +1374,14 @@ class AdaptiveCardGenerator {
|
|
|
1393
1374
|
throw new SpecParserError(err.toString(), exports.ErrorType.GenerateAdaptiveCardFailed);
|
|
1394
1375
|
}
|
|
1395
1376
|
}
|
|
1396
|
-
static generateCardFromResponse(schema, name, parentArrayName = "") {
|
|
1377
|
+
static generateCardFromResponse(schema, name, parentArrayName = "", maxElementCount = Number.MAX_SAFE_INTEGER, counter = { count: 0 }) {
|
|
1378
|
+
if (counter.count >= maxElementCount) {
|
|
1379
|
+
return [];
|
|
1380
|
+
}
|
|
1397
1381
|
if (schema.type === "array") {
|
|
1398
1382
|
// schema.items can be arbitrary object: schema { type: array, items: {} }
|
|
1399
1383
|
if (Object.keys(schema.items).length === 0) {
|
|
1384
|
+
counter.count++;
|
|
1400
1385
|
return [
|
|
1401
1386
|
{
|
|
1402
1387
|
type: ConstantString.TextBlockType,
|
|
@@ -1405,7 +1390,7 @@ class AdaptiveCardGenerator {
|
|
|
1405
1390
|
},
|
|
1406
1391
|
];
|
|
1407
1392
|
}
|
|
1408
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name);
|
|
1393
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name, maxElementCount, counter);
|
|
1409
1394
|
const template = {
|
|
1410
1395
|
type: ConstantString.ContainerType,
|
|
1411
1396
|
$data: name ? `\${${name}}` : "${$root}",
|
|
@@ -1419,7 +1404,7 @@ class AdaptiveCardGenerator {
|
|
|
1419
1404
|
const { properties } = schema;
|
|
1420
1405
|
const result = [];
|
|
1421
1406
|
for (const property in properties) {
|
|
1422
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName);
|
|
1407
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName, maxElementCount, counter);
|
|
1423
1408
|
result.push(...obj);
|
|
1424
1409
|
}
|
|
1425
1410
|
if (schema.additionalProperties) {
|
|
@@ -1432,6 +1417,7 @@ class AdaptiveCardGenerator {
|
|
|
1432
1417
|
schema.type === "integer" ||
|
|
1433
1418
|
schema.type === "boolean" ||
|
|
1434
1419
|
schema.type === "number") {
|
|
1420
|
+
counter.count++;
|
|
1435
1421
|
if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) {
|
|
1436
1422
|
// string in root: "ddd"
|
|
1437
1423
|
let text = "result: ${$root}";
|
|
@@ -1456,24 +1442,17 @@ class AdaptiveCardGenerator {
|
|
|
1456
1442
|
];
|
|
1457
1443
|
}
|
|
1458
1444
|
else {
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
{
|
|
1471
|
-
type: "Image",
|
|
1472
|
-
url: "${$data}",
|
|
1473
|
-
$when: "${$data != null && $data != ''}",
|
|
1474
|
-
},
|
|
1475
|
-
];
|
|
1476
|
-
}
|
|
1445
|
+
const url = name ? `\${${name}}` : "${$data}";
|
|
1446
|
+
const condition = name
|
|
1447
|
+
? `\${${name} != null && ${name} != ''}`
|
|
1448
|
+
: "${$data != null && $data != ''}";
|
|
1449
|
+
return [
|
|
1450
|
+
{
|
|
1451
|
+
type: "Image",
|
|
1452
|
+
url,
|
|
1453
|
+
$when: condition,
|
|
1454
|
+
},
|
|
1455
|
+
];
|
|
1477
1456
|
}
|
|
1478
1457
|
}
|
|
1479
1458
|
if (schema.oneOf || schema.anyOf || schema.not || schema.allOf) {
|
|
@@ -1766,8 +1745,7 @@ class ManifestUpdater {
|
|
|
1766
1745
|
try {
|
|
1767
1746
|
const { json } = Utils.getResponseJson(operationItem);
|
|
1768
1747
|
if (json.schema) {
|
|
1769
|
-
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem);
|
|
1770
|
-
card.body = Utils.limitACBodyProperties(card.body, 5);
|
|
1748
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
|
|
1771
1749
|
const responseSemantic = wrapResponseSemantics(card, jsonPath);
|
|
1772
1750
|
funcObj.capabilities = {
|
|
1773
1751
|
response_semantics: responseSemantic,
|
|
@@ -2005,6 +1983,130 @@ class ManifestUpdater {
|
|
|
2005
1983
|
}
|
|
2006
1984
|
}
|
|
2007
1985
|
|
|
1986
|
+
// Copyright (c) Microsoft Corporation.
|
|
1987
|
+
class JsonDataGenerator {
|
|
1988
|
+
static generate(schema) {
|
|
1989
|
+
return this.generateMockData(schema);
|
|
1990
|
+
}
|
|
1991
|
+
static generateMockData(schema) {
|
|
1992
|
+
if (this.visitedSchemas.has(schema)) {
|
|
1993
|
+
return null; // Prevent circular reference
|
|
1994
|
+
}
|
|
1995
|
+
this.visitedSchemas.add(schema);
|
|
1996
|
+
let result;
|
|
1997
|
+
if (schema.anyOf) {
|
|
1998
|
+
// Select the first schema in anyOf
|
|
1999
|
+
const selectedSchema = schema.anyOf[0];
|
|
2000
|
+
result = this.generateMockData(selectedSchema);
|
|
2001
|
+
}
|
|
2002
|
+
else if (schema.oneOf) {
|
|
2003
|
+
// Select the first schema in oneOf
|
|
2004
|
+
const selectedSchema = schema.oneOf[0];
|
|
2005
|
+
result = this.generateMockData(selectedSchema);
|
|
2006
|
+
}
|
|
2007
|
+
else if (schema.allOf) {
|
|
2008
|
+
// merge all schemas in allOf
|
|
2009
|
+
result = {};
|
|
2010
|
+
for (const subschema of schema.allOf) {
|
|
2011
|
+
const data = this.generateMockData(subschema);
|
|
2012
|
+
result = Object.assign(Object.assign({}, result), data);
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
else {
|
|
2016
|
+
switch (schema.type) {
|
|
2017
|
+
case "string":
|
|
2018
|
+
if (schema.example !== undefined) {
|
|
2019
|
+
result = schema.example;
|
|
2020
|
+
}
|
|
2021
|
+
else if (schema.format) {
|
|
2022
|
+
switch (schema.format) {
|
|
2023
|
+
case "date-time":
|
|
2024
|
+
result = "2024-11-01T05:25:43.593Z";
|
|
2025
|
+
break;
|
|
2026
|
+
case "email":
|
|
2027
|
+
result = "example@example.com";
|
|
2028
|
+
break;
|
|
2029
|
+
case "uuid":
|
|
2030
|
+
result = "123e4567-e89b-12d3-a456-426614174000";
|
|
2031
|
+
break;
|
|
2032
|
+
case "ipv4":
|
|
2033
|
+
result = "192.168.0.1";
|
|
2034
|
+
break;
|
|
2035
|
+
case "ipv6":
|
|
2036
|
+
result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
|
|
2037
|
+
break;
|
|
2038
|
+
default:
|
|
2039
|
+
result = "example string";
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
else {
|
|
2043
|
+
result = "example string";
|
|
2044
|
+
}
|
|
2045
|
+
break;
|
|
2046
|
+
case "number":
|
|
2047
|
+
if (schema.example !== undefined) {
|
|
2048
|
+
result = schema.example;
|
|
2049
|
+
}
|
|
2050
|
+
else if (schema.format) {
|
|
2051
|
+
switch (schema.format) {
|
|
2052
|
+
case "float":
|
|
2053
|
+
result = 3.14;
|
|
2054
|
+
break;
|
|
2055
|
+
case "double":
|
|
2056
|
+
result = 3.14159;
|
|
2057
|
+
break;
|
|
2058
|
+
default:
|
|
2059
|
+
result = 123;
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
else {
|
|
2063
|
+
result = 123;
|
|
2064
|
+
}
|
|
2065
|
+
break;
|
|
2066
|
+
case "integer":
|
|
2067
|
+
if (schema.example !== undefined) {
|
|
2068
|
+
result = schema.example;
|
|
2069
|
+
}
|
|
2070
|
+
else if (schema.format) {
|
|
2071
|
+
switch (schema.format) {
|
|
2072
|
+
case "int32":
|
|
2073
|
+
result = 123456;
|
|
2074
|
+
break;
|
|
2075
|
+
case "int64":
|
|
2076
|
+
result = 123456789;
|
|
2077
|
+
break;
|
|
2078
|
+
default:
|
|
2079
|
+
result = 123;
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
else {
|
|
2083
|
+
result = 123;
|
|
2084
|
+
}
|
|
2085
|
+
break;
|
|
2086
|
+
case "boolean":
|
|
2087
|
+
result = schema.example !== undefined ? schema.example : true;
|
|
2088
|
+
break;
|
|
2089
|
+
case "array":
|
|
2090
|
+
result = [this.generateMockData(schema.items)];
|
|
2091
|
+
break;
|
|
2092
|
+
case "object":
|
|
2093
|
+
result = {};
|
|
2094
|
+
if (schema.properties) {
|
|
2095
|
+
for (const key in schema.properties) {
|
|
2096
|
+
result[key] = this.generateMockData(schema.properties[key]);
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
break;
|
|
2100
|
+
default:
|
|
2101
|
+
result = schema.example || null;
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
this.visitedSchemas.delete(schema);
|
|
2105
|
+
return result;
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
JsonDataGenerator.visitedSchemas = new Set();
|
|
2109
|
+
|
|
2008
2110
|
// Copyright (c) Microsoft Corporation.
|
|
2009
2111
|
/**
|
|
2010
2112
|
* A class that parses an OpenAPI specification file and provides methods to validate, list, and generate artifacts.
|
|
@@ -2242,6 +2344,24 @@ class SpecParser {
|
|
|
2242
2344
|
const newUnResolvedSpec = newSpecs[0];
|
|
2243
2345
|
const newSpec = newSpecs[1];
|
|
2244
2346
|
const authInfo = Utils.getAuthInfo(newSpec);
|
|
2347
|
+
const paths = newUnResolvedSpec.paths;
|
|
2348
|
+
for (const pathUrl in paths) {
|
|
2349
|
+
const operations = paths[pathUrl];
|
|
2350
|
+
for (const method in operations) {
|
|
2351
|
+
const operationItem = operations[method];
|
|
2352
|
+
const operationId = operationItem.operationId;
|
|
2353
|
+
const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
|
|
2354
|
+
if (!containsSpecialCharacters) {
|
|
2355
|
+
continue;
|
|
2356
|
+
}
|
|
2357
|
+
operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2358
|
+
result.warnings.push({
|
|
2359
|
+
type: exports.WarningType.OperationIdContainsSpecialCharacters,
|
|
2360
|
+
content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
|
|
2361
|
+
data: operationId,
|
|
2362
|
+
});
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2245
2365
|
yield this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
|
|
2246
2366
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
2247
2367
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
@@ -2299,9 +2419,24 @@ class SpecParser {
|
|
|
2299
2419
|
const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2300
2420
|
const fileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
|
|
2301
2421
|
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
2422
|
+
const { json } = Utils.getResponseJson(operation, false);
|
|
2423
|
+
const schema = json.schema;
|
|
2424
|
+
let jsonData = {};
|
|
2425
|
+
if (schema && Object.keys(schema).length > 0) {
|
|
2426
|
+
try {
|
|
2427
|
+
jsonData = JsonDataGenerator.generate(schema);
|
|
2428
|
+
}
|
|
2429
|
+
catch (err) {
|
|
2430
|
+
result.warnings.push({
|
|
2431
|
+
type: exports.WarningType.GenerateJsonDataFailed,
|
|
2432
|
+
content: Utils.format(ConstantString.GenerateJsonDataFailed, operation.operationId, err.toString()),
|
|
2433
|
+
data: operation.operationId,
|
|
2434
|
+
});
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2302
2437
|
yield fs__default['default'].outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
2303
2438
|
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
|
|
2304
|
-
yield fs__default['default'].outputJSON(dataFileName,
|
|
2439
|
+
yield fs__default['default'].outputJSON(dataFileName, jsonData, { spaces: 2 });
|
|
2305
2440
|
}
|
|
2306
2441
|
catch (err) {
|
|
2307
2442
|
result.allSuccess = false;
|