@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.esm2017.mjs
CHANGED
|
@@ -61,6 +61,8 @@ var WarningType;
|
|
|
61
61
|
WarningType["OperationOnlyContainsOptionalParam"] = "operation-only-contains-optional-param";
|
|
62
62
|
WarningType["ConvertSwaggerToOpenAPI"] = "convert-swagger-to-openapi";
|
|
63
63
|
WarningType["FuncDescriptionTooLong"] = "function-description-too-long";
|
|
64
|
+
WarningType["OperationIdContainsSpecialCharacters"] = "operationid-contains-special-characters";
|
|
65
|
+
WarningType["GenerateJsonDataFailed"] = "generate-json-data-failed";
|
|
64
66
|
WarningType["Unknown"] = "unknown";
|
|
65
67
|
})(WarningType || (WarningType = {}));
|
|
66
68
|
/**
|
|
@@ -98,8 +100,10 @@ ConstantString.ConvertSwaggerToOpenAPI = "The Swagger 2.0 file has been converte
|
|
|
98
100
|
ConstantString.SwaggerNotSupported = "Swagger 2.0 is not supported. Please convert to OpenAPI 3.0 manually before proceeding.";
|
|
99
101
|
ConstantString.SpecVersionNotSupported = "Unsupported OpenAPI version %s. Please use version 3.0.x.";
|
|
100
102
|
ConstantString.MultipleAuthNotSupported = "Multiple authentication methods are unsupported. Ensure all selected APIs use identical authentication.";
|
|
103
|
+
ConstantString.OperationIdContainsSpecialCharacters = "Operation id '%s' in OpenAPI description document contained special characters and was renamed to '%s'.";
|
|
101
104
|
ConstantString.UnsupportedSchema = "Unsupported schema in %s %s: %s";
|
|
102
105
|
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.";
|
|
106
|
+
ConstantString.GenerateJsonDataFailed = "Failed to generate JSON data for api: %s due to %s.";
|
|
103
107
|
ConstantString.WrappedCardVersion = "devPreview";
|
|
104
108
|
ConstantString.WrappedCardSchema = "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.ResponseRenderingTemplate.schema.json";
|
|
105
109
|
ConstantString.WrappedCardResponseLayout = "list";
|
|
@@ -549,29 +553,6 @@ class Utils {
|
|
|
549
553
|
const serverUrl = operationServer || methodServer || rootServer;
|
|
550
554
|
return serverUrl;
|
|
551
555
|
}
|
|
552
|
-
static limitACBodyProperties(body, maxCount) {
|
|
553
|
-
const result = [];
|
|
554
|
-
let currentCount = 0;
|
|
555
|
-
for (const element of body) {
|
|
556
|
-
if (element.type === ConstantString.ContainerType) {
|
|
557
|
-
const items = this.limitACBodyProperties(element.items, maxCount - currentCount);
|
|
558
|
-
result.push({
|
|
559
|
-
type: ConstantString.ContainerType,
|
|
560
|
-
$data: element.$data,
|
|
561
|
-
items: items,
|
|
562
|
-
});
|
|
563
|
-
currentCount += items.length;
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
result.push(element);
|
|
567
|
-
currentCount++;
|
|
568
|
-
}
|
|
569
|
-
if (currentCount >= maxCount) {
|
|
570
|
-
break;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
return result;
|
|
574
|
-
}
|
|
575
556
|
}
|
|
576
557
|
|
|
577
558
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -1306,7 +1287,7 @@ class SpecFilter {
|
|
|
1306
1287
|
|
|
1307
1288
|
// Copyright (c) Microsoft Corporation.
|
|
1308
1289
|
class AdaptiveCardGenerator {
|
|
1309
|
-
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
|
|
1290
|
+
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false, maxElementCount = Number.MAX_SAFE_INTEGER) {
|
|
1310
1291
|
try {
|
|
1311
1292
|
const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
|
|
1312
1293
|
let cardBody = [];
|
|
@@ -1317,7 +1298,7 @@ class AdaptiveCardGenerator {
|
|
|
1317
1298
|
if (jsonPath !== "$") {
|
|
1318
1299
|
schema = schema.properties[jsonPath];
|
|
1319
1300
|
}
|
|
1320
|
-
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "");
|
|
1301
|
+
cardBody = AdaptiveCardGenerator.generateCardFromResponse(schema, "", "", maxElementCount);
|
|
1321
1302
|
}
|
|
1322
1303
|
// if no schema, try to use example value
|
|
1323
1304
|
if (cardBody.length === 0 && (json.examples || json.example)) {
|
|
@@ -1351,10 +1332,14 @@ class AdaptiveCardGenerator {
|
|
|
1351
1332
|
throw new SpecParserError(err.toString(), ErrorType.GenerateAdaptiveCardFailed);
|
|
1352
1333
|
}
|
|
1353
1334
|
}
|
|
1354
|
-
static generateCardFromResponse(schema, name, parentArrayName = "") {
|
|
1335
|
+
static generateCardFromResponse(schema, name, parentArrayName = "", maxElementCount = Number.MAX_SAFE_INTEGER, counter = { count: 0 }) {
|
|
1336
|
+
if (counter.count >= maxElementCount) {
|
|
1337
|
+
return [];
|
|
1338
|
+
}
|
|
1355
1339
|
if (schema.type === "array") {
|
|
1356
1340
|
// schema.items can be arbitrary object: schema { type: array, items: {} }
|
|
1357
1341
|
if (Object.keys(schema.items).length === 0) {
|
|
1342
|
+
counter.count++;
|
|
1358
1343
|
return [
|
|
1359
1344
|
{
|
|
1360
1345
|
type: ConstantString.TextBlockType,
|
|
@@ -1363,7 +1348,7 @@ class AdaptiveCardGenerator {
|
|
|
1363
1348
|
},
|
|
1364
1349
|
];
|
|
1365
1350
|
}
|
|
1366
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name);
|
|
1351
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(schema.items, "", name, maxElementCount, counter);
|
|
1367
1352
|
const template = {
|
|
1368
1353
|
type: ConstantString.ContainerType,
|
|
1369
1354
|
$data: name ? `\${${name}}` : "${$root}",
|
|
@@ -1377,7 +1362,7 @@ class AdaptiveCardGenerator {
|
|
|
1377
1362
|
const { properties } = schema;
|
|
1378
1363
|
const result = [];
|
|
1379
1364
|
for (const property in properties) {
|
|
1380
|
-
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName);
|
|
1365
|
+
const obj = AdaptiveCardGenerator.generateCardFromResponse(properties[property], name ? `${name}.${property}` : property, parentArrayName, maxElementCount, counter);
|
|
1381
1366
|
result.push(...obj);
|
|
1382
1367
|
}
|
|
1383
1368
|
if (schema.additionalProperties) {
|
|
@@ -1390,6 +1375,7 @@ class AdaptiveCardGenerator {
|
|
|
1390
1375
|
schema.type === "integer" ||
|
|
1391
1376
|
schema.type === "boolean" ||
|
|
1392
1377
|
schema.type === "number") {
|
|
1378
|
+
counter.count++;
|
|
1393
1379
|
if (!AdaptiveCardGenerator.isImageUrlProperty(schema, name, parentArrayName)) {
|
|
1394
1380
|
// string in root: "ddd"
|
|
1395
1381
|
let text = "result: ${$root}";
|
|
@@ -1414,24 +1400,17 @@ class AdaptiveCardGenerator {
|
|
|
1414
1400
|
];
|
|
1415
1401
|
}
|
|
1416
1402
|
else {
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
{
|
|
1429
|
-
type: "Image",
|
|
1430
|
-
url: "${$data}",
|
|
1431
|
-
$when: "${$data != null && $data != ''}",
|
|
1432
|
-
},
|
|
1433
|
-
];
|
|
1434
|
-
}
|
|
1403
|
+
const url = name ? `\${${name}}` : "${$data}";
|
|
1404
|
+
const condition = name
|
|
1405
|
+
? `\${${name} != null && ${name} != ''}`
|
|
1406
|
+
: "${$data != null && $data != ''}";
|
|
1407
|
+
return [
|
|
1408
|
+
{
|
|
1409
|
+
type: "Image",
|
|
1410
|
+
url,
|
|
1411
|
+
$when: condition,
|
|
1412
|
+
},
|
|
1413
|
+
];
|
|
1435
1414
|
}
|
|
1436
1415
|
}
|
|
1437
1416
|
if (schema.oneOf || schema.anyOf || schema.not || schema.allOf) {
|
|
@@ -1721,8 +1700,7 @@ class ManifestUpdater {
|
|
|
1721
1700
|
try {
|
|
1722
1701
|
const { json } = Utils.getResponseJson(operationItem);
|
|
1723
1702
|
if (json.schema) {
|
|
1724
|
-
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem);
|
|
1725
|
-
card.body = Utils.limitACBodyProperties(card.body, 5);
|
|
1703
|
+
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem, false, 5);
|
|
1726
1704
|
const responseSemantic = wrapResponseSemantics(card, jsonPath);
|
|
1727
1705
|
funcObj.capabilities = {
|
|
1728
1706
|
response_semantics: responseSemantic,
|
|
@@ -1955,6 +1933,130 @@ class ManifestUpdater {
|
|
|
1955
1933
|
}
|
|
1956
1934
|
}
|
|
1957
1935
|
|
|
1936
|
+
// Copyright (c) Microsoft Corporation.
|
|
1937
|
+
class JsonDataGenerator {
|
|
1938
|
+
static generate(schema) {
|
|
1939
|
+
return this.generateMockData(schema);
|
|
1940
|
+
}
|
|
1941
|
+
static generateMockData(schema) {
|
|
1942
|
+
if (this.visitedSchemas.has(schema)) {
|
|
1943
|
+
return null; // Prevent circular reference
|
|
1944
|
+
}
|
|
1945
|
+
this.visitedSchemas.add(schema);
|
|
1946
|
+
let result;
|
|
1947
|
+
if (schema.anyOf) {
|
|
1948
|
+
// Select the first schema in anyOf
|
|
1949
|
+
const selectedSchema = schema.anyOf[0];
|
|
1950
|
+
result = this.generateMockData(selectedSchema);
|
|
1951
|
+
}
|
|
1952
|
+
else if (schema.oneOf) {
|
|
1953
|
+
// Select the first schema in oneOf
|
|
1954
|
+
const selectedSchema = schema.oneOf[0];
|
|
1955
|
+
result = this.generateMockData(selectedSchema);
|
|
1956
|
+
}
|
|
1957
|
+
else if (schema.allOf) {
|
|
1958
|
+
// merge all schemas in allOf
|
|
1959
|
+
result = {};
|
|
1960
|
+
for (const subschema of schema.allOf) {
|
|
1961
|
+
const data = this.generateMockData(subschema);
|
|
1962
|
+
result = Object.assign(Object.assign({}, result), data);
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
else {
|
|
1966
|
+
switch (schema.type) {
|
|
1967
|
+
case "string":
|
|
1968
|
+
if (schema.example !== undefined) {
|
|
1969
|
+
result = schema.example;
|
|
1970
|
+
}
|
|
1971
|
+
else if (schema.format) {
|
|
1972
|
+
switch (schema.format) {
|
|
1973
|
+
case "date-time":
|
|
1974
|
+
result = "2024-11-01T05:25:43.593Z";
|
|
1975
|
+
break;
|
|
1976
|
+
case "email":
|
|
1977
|
+
result = "example@example.com";
|
|
1978
|
+
break;
|
|
1979
|
+
case "uuid":
|
|
1980
|
+
result = "123e4567-e89b-12d3-a456-426614174000";
|
|
1981
|
+
break;
|
|
1982
|
+
case "ipv4":
|
|
1983
|
+
result = "192.168.0.1";
|
|
1984
|
+
break;
|
|
1985
|
+
case "ipv6":
|
|
1986
|
+
result = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
|
|
1987
|
+
break;
|
|
1988
|
+
default:
|
|
1989
|
+
result = "example string";
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
else {
|
|
1993
|
+
result = "example string";
|
|
1994
|
+
}
|
|
1995
|
+
break;
|
|
1996
|
+
case "number":
|
|
1997
|
+
if (schema.example !== undefined) {
|
|
1998
|
+
result = schema.example;
|
|
1999
|
+
}
|
|
2000
|
+
else if (schema.format) {
|
|
2001
|
+
switch (schema.format) {
|
|
2002
|
+
case "float":
|
|
2003
|
+
result = 3.14;
|
|
2004
|
+
break;
|
|
2005
|
+
case "double":
|
|
2006
|
+
result = 3.14159;
|
|
2007
|
+
break;
|
|
2008
|
+
default:
|
|
2009
|
+
result = 123;
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
else {
|
|
2013
|
+
result = 123;
|
|
2014
|
+
}
|
|
2015
|
+
break;
|
|
2016
|
+
case "integer":
|
|
2017
|
+
if (schema.example !== undefined) {
|
|
2018
|
+
result = schema.example;
|
|
2019
|
+
}
|
|
2020
|
+
else if (schema.format) {
|
|
2021
|
+
switch (schema.format) {
|
|
2022
|
+
case "int32":
|
|
2023
|
+
result = 123456;
|
|
2024
|
+
break;
|
|
2025
|
+
case "int64":
|
|
2026
|
+
result = 123456789;
|
|
2027
|
+
break;
|
|
2028
|
+
default:
|
|
2029
|
+
result = 123;
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
else {
|
|
2033
|
+
result = 123;
|
|
2034
|
+
}
|
|
2035
|
+
break;
|
|
2036
|
+
case "boolean":
|
|
2037
|
+
result = schema.example !== undefined ? schema.example : true;
|
|
2038
|
+
break;
|
|
2039
|
+
case "array":
|
|
2040
|
+
result = [this.generateMockData(schema.items)];
|
|
2041
|
+
break;
|
|
2042
|
+
case "object":
|
|
2043
|
+
result = {};
|
|
2044
|
+
if (schema.properties) {
|
|
2045
|
+
for (const key in schema.properties) {
|
|
2046
|
+
result[key] = this.generateMockData(schema.properties[key]);
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
break;
|
|
2050
|
+
default:
|
|
2051
|
+
result = schema.example || null;
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
this.visitedSchemas.delete(schema);
|
|
2055
|
+
return result;
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
JsonDataGenerator.visitedSchemas = new Set();
|
|
2059
|
+
|
|
1958
2060
|
// Copyright (c) Microsoft Corporation.
|
|
1959
2061
|
/**
|
|
1960
2062
|
* A class that parses an OpenAPI specification file and provides methods to validate, list, and generate artifacts.
|
|
@@ -2183,6 +2285,24 @@ class SpecParser {
|
|
|
2183
2285
|
const newUnResolvedSpec = newSpecs[0];
|
|
2184
2286
|
const newSpec = newSpecs[1];
|
|
2185
2287
|
const authInfo = Utils.getAuthInfo(newSpec);
|
|
2288
|
+
const paths = newUnResolvedSpec.paths;
|
|
2289
|
+
for (const pathUrl in paths) {
|
|
2290
|
+
const operations = paths[pathUrl];
|
|
2291
|
+
for (const method in operations) {
|
|
2292
|
+
const operationItem = operations[method];
|
|
2293
|
+
const operationId = operationItem.operationId;
|
|
2294
|
+
const containsSpecialCharacters = /[^a-zA-Z0-9_]/.test(operationId);
|
|
2295
|
+
if (!containsSpecialCharacters) {
|
|
2296
|
+
continue;
|
|
2297
|
+
}
|
|
2298
|
+
operationItem.operationId = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2299
|
+
result.warnings.push({
|
|
2300
|
+
type: WarningType.OperationIdContainsSpecialCharacters,
|
|
2301
|
+
content: Utils.format(ConstantString.OperationIdContainsSpecialCharacters, operationId, operationItem.operationId),
|
|
2302
|
+
data: operationId,
|
|
2303
|
+
});
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2186
2306
|
await this.saveFilterSpec(outputSpecPath, newUnResolvedSpec);
|
|
2187
2307
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
2188
2308
|
throw new SpecParserError(ConstantString.CancelledMessage, ErrorType.Cancelled);
|
|
@@ -2238,9 +2358,24 @@ class SpecParser {
|
|
|
2238
2358
|
const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2239
2359
|
const fileName = path.join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
|
|
2240
2360
|
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
2361
|
+
const { json } = Utils.getResponseJson(operation, false);
|
|
2362
|
+
const schema = json.schema;
|
|
2363
|
+
let jsonData = {};
|
|
2364
|
+
if (schema && Object.keys(schema).length > 0) {
|
|
2365
|
+
try {
|
|
2366
|
+
jsonData = JsonDataGenerator.generate(schema);
|
|
2367
|
+
}
|
|
2368
|
+
catch (err) {
|
|
2369
|
+
result.warnings.push({
|
|
2370
|
+
type: WarningType.GenerateJsonDataFailed,
|
|
2371
|
+
content: Utils.format(ConstantString.GenerateJsonDataFailed, operation.operationId, err.toString()),
|
|
2372
|
+
data: operation.operationId,
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2241
2376
|
await fs.outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
2242
2377
|
const dataFileName = path.join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
|
|
2243
|
-
await fs.outputJSON(dataFileName,
|
|
2378
|
+
await fs.outputJSON(dataFileName, jsonData, { spaces: 2 });
|
|
2244
2379
|
}
|
|
2245
2380
|
catch (err) {
|
|
2246
2381
|
result.allSuccess = false;
|