@microsoft/m365-spec-parser 0.2.1 → 0.2.2-alpha.070ff93c3.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 +91 -15
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +306 -42
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +91 -15
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +306 -42
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/adaptiveCardGenerator.d.ts +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/interfaces.d.ts +9 -3
- package/dist/src/specOptimizer.d.ts +18 -0
- package/dist/src/specParser.d.ts +1 -0
- package/dist/src/utils.d.ts +6 -5
- package/package.json +3 -3
package/dist/index.node.cjs.js
CHANGED
|
@@ -59,10 +59,12 @@ exports.ErrorType = void 0;
|
|
|
59
59
|
ErrorType["RelativeServerUrlNotSupported"] = "relative-server-url-not-supported";
|
|
60
60
|
ErrorType["NoSupportedApi"] = "no-supported-api";
|
|
61
61
|
ErrorType["NoExtraAPICanBeAdded"] = "no-extra-api-can-be-added";
|
|
62
|
+
ErrorType["AddedAPINotInOriginalSpec"] = "added-api-not-in-original-spec";
|
|
62
63
|
ErrorType["ResolveServerUrlFailed"] = "resolve-server-url-failed";
|
|
63
64
|
ErrorType["SwaggerNotSupported"] = "swagger-not-supported";
|
|
64
65
|
ErrorType["MultipleAuthNotSupported"] = "multiple-auth-not-supported";
|
|
65
66
|
ErrorType["SpecVersionNotSupported"] = "spec-version-not-supported";
|
|
67
|
+
ErrorType["CircularReferenceNotSupported"] = "circular-reference-not-supported";
|
|
66
68
|
ErrorType["ListFailed"] = "list-failed";
|
|
67
69
|
ErrorType["listSupportedAPIInfoFailed"] = "list-supported-api-info-failed";
|
|
68
70
|
ErrorType["FilterSpecFailed"] = "filter-spec-failed";
|
|
@@ -299,21 +301,28 @@ class Utils {
|
|
|
299
301
|
static updateFirstLetter(str) {
|
|
300
302
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
301
303
|
}
|
|
302
|
-
static getResponseJson(operationObject) {
|
|
303
|
-
var _a
|
|
304
|
+
static getResponseJson(operationObject, allowMultipleMediaType = false) {
|
|
305
|
+
var _a;
|
|
304
306
|
let json = {};
|
|
305
307
|
let multipleMediaType = false;
|
|
306
308
|
for (const code of ConstantString.ResponseCodeFor20X) {
|
|
307
309
|
const responseObject = (_a = operationObject === null || operationObject === void 0 ? void 0 : operationObject.responses) === null || _a === void 0 ? void 0 : _a[code];
|
|
308
|
-
if (
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
310
|
+
if (responseObject === null || responseObject === void 0 ? void 0 : responseObject.content) {
|
|
311
|
+
for (const contentType of Object.keys(responseObject.content)) {
|
|
312
|
+
// json media type can also be "application/json; charset=utf-8"
|
|
313
|
+
if (contentType.indexOf("application/json") >= 0) {
|
|
314
|
+
multipleMediaType = false;
|
|
315
|
+
json = responseObject.content[contentType];
|
|
316
|
+
if (Utils.containMultipleMediaTypes(responseObject)) {
|
|
317
|
+
multipleMediaType = true;
|
|
318
|
+
if (!allowMultipleMediaType) {
|
|
319
|
+
json = {};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
return { json, multipleMediaType };
|
|
324
|
+
}
|
|
325
|
+
}
|
|
317
326
|
}
|
|
318
327
|
}
|
|
319
328
|
}
|
|
@@ -574,10 +583,46 @@ class Utils {
|
|
|
574
583
|
const serverUrl = operationServer || methodServer || rootServer;
|
|
575
584
|
return serverUrl;
|
|
576
585
|
}
|
|
586
|
+
static limitACBodyProperties(body, maxCount) {
|
|
587
|
+
const result = [];
|
|
588
|
+
let currentCount = 0;
|
|
589
|
+
for (const element of body) {
|
|
590
|
+
if (element.type === ConstantString.ContainerType) {
|
|
591
|
+
const items = this.limitACBodyProperties(element.items, maxCount - currentCount);
|
|
592
|
+
result.push({
|
|
593
|
+
type: ConstantString.ContainerType,
|
|
594
|
+
$data: element.$data,
|
|
595
|
+
items: items,
|
|
596
|
+
});
|
|
597
|
+
currentCount += items.length;
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
result.push(element);
|
|
601
|
+
currentCount++;
|
|
602
|
+
}
|
|
603
|
+
if (currentCount >= maxCount) {
|
|
604
|
+
break;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return result;
|
|
608
|
+
}
|
|
577
609
|
}
|
|
578
610
|
|
|
579
611
|
// Copyright (c) Microsoft Corporation.
|
|
580
612
|
class Validator {
|
|
613
|
+
constructor() {
|
|
614
|
+
this.hasCircularReference = false;
|
|
615
|
+
}
|
|
616
|
+
checkCircularReference() {
|
|
617
|
+
try {
|
|
618
|
+
JSON.stringify(this.spec);
|
|
619
|
+
}
|
|
620
|
+
catch (e) {
|
|
621
|
+
if (e.message.includes("Converting circular structure to JSON")) {
|
|
622
|
+
this.hasCircularReference = true;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
581
626
|
listAPIs() {
|
|
582
627
|
var _a;
|
|
583
628
|
if (this.apiMap) {
|
|
@@ -673,6 +718,22 @@ class Validator {
|
|
|
673
718
|
}
|
|
674
719
|
return result;
|
|
675
720
|
}
|
|
721
|
+
validateCircularReference(method, path) {
|
|
722
|
+
const result = { isValid: true, reason: [] };
|
|
723
|
+
if (this.hasCircularReference) {
|
|
724
|
+
const operationObject = this.spec.paths[path][method];
|
|
725
|
+
try {
|
|
726
|
+
JSON.stringify(operationObject);
|
|
727
|
+
}
|
|
728
|
+
catch (e) {
|
|
729
|
+
if (e.message.includes("Converting circular structure to JSON")) {
|
|
730
|
+
result.isValid = false;
|
|
731
|
+
result.reason.push(exports.ErrorType.CircularReferenceNotSupported);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
return result;
|
|
736
|
+
}
|
|
676
737
|
validateResponse(method, path) {
|
|
677
738
|
const result = { isValid: true, reason: [] };
|
|
678
739
|
const operationObject = this.spec.paths[path][method];
|
|
@@ -861,6 +922,7 @@ class CopilotValidator extends Validator {
|
|
|
861
922
|
this.projectType = exports.ProjectType.Copilot;
|
|
862
923
|
this.options = options;
|
|
863
924
|
this.spec = spec;
|
|
925
|
+
this.checkCircularReference();
|
|
864
926
|
}
|
|
865
927
|
validateSpec() {
|
|
866
928
|
const result = { errors: [], warnings: [] };
|
|
@@ -886,6 +948,10 @@ class CopilotValidator extends Validator {
|
|
|
886
948
|
if (!methodAndPathResult.isValid) {
|
|
887
949
|
return methodAndPathResult;
|
|
888
950
|
}
|
|
951
|
+
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
952
|
+
if (!circularReferenceResult.isValid) {
|
|
953
|
+
return circularReferenceResult;
|
|
954
|
+
}
|
|
889
955
|
const operationObject = this.spec.paths[path][method];
|
|
890
956
|
// validate auth
|
|
891
957
|
const authCheckResult = this.validateAuth(method, path);
|
|
@@ -929,6 +995,7 @@ class SMEValidator extends Validator {
|
|
|
929
995
|
this.projectType = exports.ProjectType.SME;
|
|
930
996
|
this.options = options;
|
|
931
997
|
this.spec = spec;
|
|
998
|
+
this.checkCircularReference();
|
|
932
999
|
}
|
|
933
1000
|
validateSpec() {
|
|
934
1001
|
const result = { errors: [], warnings: [] };
|
|
@@ -956,6 +1023,10 @@ class SMEValidator extends Validator {
|
|
|
956
1023
|
if (!methodAndPathResult.isValid) {
|
|
957
1024
|
return methodAndPathResult;
|
|
958
1025
|
}
|
|
1026
|
+
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
1027
|
+
if (!circularReferenceResult.isValid) {
|
|
1028
|
+
return circularReferenceResult;
|
|
1029
|
+
}
|
|
959
1030
|
const operationObject = this.spec.paths[path][method];
|
|
960
1031
|
// validate auth
|
|
961
1032
|
const authCheckResult = this.validateAuth(method, path);
|
|
@@ -1026,6 +1097,7 @@ class TeamsAIValidator extends Validator {
|
|
|
1026
1097
|
this.projectType = exports.ProjectType.TeamsAi;
|
|
1027
1098
|
this.options = options;
|
|
1028
1099
|
this.spec = spec;
|
|
1100
|
+
this.checkCircularReference();
|
|
1029
1101
|
}
|
|
1030
1102
|
validateSpec() {
|
|
1031
1103
|
const result = { errors: [], warnings: [] };
|
|
@@ -1045,6 +1117,10 @@ class TeamsAIValidator extends Validator {
|
|
|
1045
1117
|
if (!methodAndPathResult.isValid) {
|
|
1046
1118
|
return methodAndPathResult;
|
|
1047
1119
|
}
|
|
1120
|
+
const circularReferenceResult = this.validateCircularReference(method, path);
|
|
1121
|
+
if (!circularReferenceResult.isValid) {
|
|
1122
|
+
return circularReferenceResult;
|
|
1123
|
+
}
|
|
1048
1124
|
const operationObject = this.spec.paths[path][method];
|
|
1049
1125
|
// validate operationId
|
|
1050
1126
|
if (!this.options.allowMissingId && !operationObject.operationId) {
|
|
@@ -1077,6 +1153,161 @@ class ValidatorFactory {
|
|
|
1077
1153
|
}
|
|
1078
1154
|
}
|
|
1079
1155
|
|
|
1156
|
+
// Copyright (c) Microsoft Corporation.
|
|
1157
|
+
class SpecOptimizer {
|
|
1158
|
+
static optimize(spec, options) {
|
|
1159
|
+
const mergedOptions = Object.assign(Object.assign({}, SpecOptimizer.defaultOptions), (options !== null && options !== void 0 ? options : {}));
|
|
1160
|
+
const newSpec = JSON.parse(JSON.stringify(spec));
|
|
1161
|
+
if (mergedOptions.removeUserDefinedRootProperty) {
|
|
1162
|
+
SpecOptimizer.removeUserDefinedRootProperty(newSpec);
|
|
1163
|
+
}
|
|
1164
|
+
if (mergedOptions.removeUnusedComponents) {
|
|
1165
|
+
SpecOptimizer.removeUnusedComponents(newSpec);
|
|
1166
|
+
}
|
|
1167
|
+
if (mergedOptions.removeUnusedTags) {
|
|
1168
|
+
SpecOptimizer.removeUnusedTags(newSpec);
|
|
1169
|
+
}
|
|
1170
|
+
if (mergedOptions.removeUnusedSecuritySchemas) {
|
|
1171
|
+
SpecOptimizer.removeUnusedSecuritySchemas(newSpec);
|
|
1172
|
+
}
|
|
1173
|
+
return newSpec;
|
|
1174
|
+
}
|
|
1175
|
+
static removeUnusedSecuritySchemas(spec) {
|
|
1176
|
+
if (!spec.components || !spec.components.securitySchemes) {
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1179
|
+
const usedSecuritySchemas = new Set();
|
|
1180
|
+
for (const pathKey in spec.paths) {
|
|
1181
|
+
for (const methodKey in spec.paths[pathKey]) {
|
|
1182
|
+
const operation = spec.paths[pathKey][methodKey];
|
|
1183
|
+
if (operation.security) {
|
|
1184
|
+
operation.security.forEach((securityReq) => {
|
|
1185
|
+
for (const schemaKey in securityReq) {
|
|
1186
|
+
usedSecuritySchemas.add(schemaKey);
|
|
1187
|
+
}
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
if (spec.security) {
|
|
1193
|
+
spec.security.forEach((securityReq) => {
|
|
1194
|
+
for (const schemaKey in securityReq) {
|
|
1195
|
+
usedSecuritySchemas.add(schemaKey);
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
for (const schemaKey in spec.components.securitySchemes) {
|
|
1200
|
+
if (!usedSecuritySchemas.has(schemaKey)) {
|
|
1201
|
+
delete spec.components.securitySchemes[schemaKey];
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
if (Object.keys(spec.components.securitySchemes).length === 0) {
|
|
1205
|
+
delete spec.components.securitySchemes;
|
|
1206
|
+
}
|
|
1207
|
+
if (Object.keys(spec.components).length === 0) {
|
|
1208
|
+
delete spec.components;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
static removeUnusedTags(spec) {
|
|
1212
|
+
if (!spec.tags) {
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
const usedTags = new Set();
|
|
1216
|
+
for (const pathKey in spec.paths) {
|
|
1217
|
+
for (const methodKey in spec.paths[pathKey]) {
|
|
1218
|
+
const operation = spec.paths[pathKey][methodKey];
|
|
1219
|
+
if (operation.tags) {
|
|
1220
|
+
operation.tags.forEach((tag) => usedTags.add(tag));
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
spec.tags = spec.tags.filter((tagObj) => usedTags.has(tagObj.name));
|
|
1225
|
+
}
|
|
1226
|
+
static removeUserDefinedRootProperty(spec) {
|
|
1227
|
+
for (const key in spec) {
|
|
1228
|
+
if (key.startsWith("x-")) {
|
|
1229
|
+
delete spec[key];
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
static removeUnusedComponents(spec) {
|
|
1234
|
+
const components = spec.components;
|
|
1235
|
+
if (!components) {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
delete spec.components;
|
|
1239
|
+
const usedComponentsSet = new Set();
|
|
1240
|
+
const specString = JSON.stringify(spec);
|
|
1241
|
+
const componentReferences = SpecOptimizer.getComponentReferences(specString);
|
|
1242
|
+
for (const reference of componentReferences) {
|
|
1243
|
+
this.addComponent(reference, usedComponentsSet, components);
|
|
1244
|
+
}
|
|
1245
|
+
const newComponents = {};
|
|
1246
|
+
for (const componentName of usedComponentsSet) {
|
|
1247
|
+
const parts = componentName.split("/");
|
|
1248
|
+
const component = this.getComponent(componentName, components);
|
|
1249
|
+
if (component) {
|
|
1250
|
+
let current = newComponents;
|
|
1251
|
+
for (let i = 2; i < parts.length; i++) {
|
|
1252
|
+
if (i === parts.length - 1) {
|
|
1253
|
+
current[parts[i]] = component;
|
|
1254
|
+
}
|
|
1255
|
+
else if (!current[parts[i]]) {
|
|
1256
|
+
current[parts[i]] = {};
|
|
1257
|
+
}
|
|
1258
|
+
current = current[parts[i]];
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
// securitySchemes are referenced directly by name, to void issue, just keep them all and use removeUnusedSecuritySchemas to remove unused ones
|
|
1263
|
+
if (components.securitySchemes) {
|
|
1264
|
+
newComponents.securitySchemes = components.securitySchemes;
|
|
1265
|
+
}
|
|
1266
|
+
if (Object.keys(newComponents).length !== 0) {
|
|
1267
|
+
spec.components = newComponents;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
static getComponentReferences(specString) {
|
|
1271
|
+
const matches = Array.from(specString.matchAll(/['"](#\/components\/.+?)['"]/g));
|
|
1272
|
+
const matchResult = matches.map((match) => match[1]);
|
|
1273
|
+
return matchResult;
|
|
1274
|
+
}
|
|
1275
|
+
static getComponent(componentPath, components) {
|
|
1276
|
+
const parts = componentPath.split("/");
|
|
1277
|
+
let current = components;
|
|
1278
|
+
for (const part of parts) {
|
|
1279
|
+
if (part === "#" || part === "components") {
|
|
1280
|
+
continue;
|
|
1281
|
+
}
|
|
1282
|
+
current = current[part];
|
|
1283
|
+
if (!current) {
|
|
1284
|
+
return null;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
return current;
|
|
1288
|
+
}
|
|
1289
|
+
static addComponent(componentName, usedComponentsSet, components) {
|
|
1290
|
+
if (usedComponentsSet.has(componentName)) {
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1293
|
+
usedComponentsSet.add(componentName);
|
|
1294
|
+
const component = this.getComponent(componentName, components);
|
|
1295
|
+
if (component) {
|
|
1296
|
+
const componentString = JSON.stringify(component);
|
|
1297
|
+
const componentReferences = SpecOptimizer.getComponentReferences(componentString);
|
|
1298
|
+
for (const reference of componentReferences) {
|
|
1299
|
+
this.addComponent(reference, usedComponentsSet, components);
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
SpecOptimizer.defaultOptions = {
|
|
1305
|
+
removeUnusedComponents: true,
|
|
1306
|
+
removeUnusedTags: true,
|
|
1307
|
+
removeUserDefinedRootProperty: true,
|
|
1308
|
+
removeUnusedSecuritySchemas: true,
|
|
1309
|
+
};
|
|
1310
|
+
|
|
1080
1311
|
// Copyright (c) Microsoft Corporation.
|
|
1081
1312
|
class SpecFilter {
|
|
1082
1313
|
static specFilter(filter, unResolveSpec, resolvedSpec, options) {
|
|
@@ -1110,7 +1341,7 @@ class SpecFilter {
|
|
|
1110
1341
|
}
|
|
1111
1342
|
}
|
|
1112
1343
|
newSpec.paths = newPaths;
|
|
1113
|
-
return newSpec;
|
|
1344
|
+
return SpecOptimizer.optimize(newSpec);
|
|
1114
1345
|
}
|
|
1115
1346
|
catch (err) {
|
|
1116
1347
|
throw new SpecParserError(err.toString(), exports.ErrorType.FilterSpecFailed);
|
|
@@ -1120,9 +1351,9 @@ class SpecFilter {
|
|
|
1120
1351
|
|
|
1121
1352
|
// Copyright (c) Microsoft Corporation.
|
|
1122
1353
|
class AdaptiveCardGenerator {
|
|
1123
|
-
static generateAdaptiveCard(operationItem) {
|
|
1354
|
+
static generateAdaptiveCard(operationItem, allowMultipleMediaType = false) {
|
|
1124
1355
|
try {
|
|
1125
|
-
const { json } = Utils.getResponseJson(operationItem);
|
|
1356
|
+
const { json } = Utils.getResponseJson(operationItem, allowMultipleMediaType);
|
|
1126
1357
|
let cardBody = [];
|
|
1127
1358
|
let schema = json.schema;
|
|
1128
1359
|
let jsonPath = "$";
|
|
@@ -1233,7 +1464,7 @@ class AdaptiveCardGenerator {
|
|
|
1233
1464
|
{
|
|
1234
1465
|
type: "Image",
|
|
1235
1466
|
url: `\${${name}}`,
|
|
1236
|
-
$when: `\${${name} != null}`,
|
|
1467
|
+
$when: `\${${name} != null && ${name} != ''}`,
|
|
1237
1468
|
},
|
|
1238
1469
|
];
|
|
1239
1470
|
}
|
|
@@ -1242,7 +1473,7 @@ class AdaptiveCardGenerator {
|
|
|
1242
1473
|
{
|
|
1243
1474
|
type: "Image",
|
|
1244
1475
|
url: "${$data}",
|
|
1245
|
-
$when: "${$data != null}",
|
|
1476
|
+
$when: "${$data != null && $data != ''}",
|
|
1246
1477
|
},
|
|
1247
1478
|
];
|
|
1248
1479
|
}
|
|
@@ -1335,7 +1566,7 @@ function inferPreviewCardTemplate(card) {
|
|
|
1335
1566
|
result.image = {
|
|
1336
1567
|
url: `\${${inferredProperties.imageUrl}}`,
|
|
1337
1568
|
alt: `\${if(${inferredProperties.imageUrl}, ${inferredProperties.imageUrl}, 'N/A')}`,
|
|
1338
|
-
$when: `\${${inferredProperties.imageUrl} != null}`,
|
|
1569
|
+
$when: `\${${inferredProperties.imageUrl} != null && ${inferredProperties.imageUrl} != ''}`,
|
|
1339
1570
|
};
|
|
1340
1571
|
}
|
|
1341
1572
|
return result;
|
|
@@ -1480,6 +1711,7 @@ class ManifestUpdater {
|
|
|
1480
1711
|
const confirmationBodies = [];
|
|
1481
1712
|
if (operationItem) {
|
|
1482
1713
|
const operationId = operationItem.operationId;
|
|
1714
|
+
const safeFunctionName = operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
1483
1715
|
const description = (_a = operationItem.description) !== null && _a !== void 0 ? _a : "";
|
|
1484
1716
|
const summary = operationItem.summary;
|
|
1485
1717
|
const paramObject = operationItem.parameters;
|
|
@@ -1507,7 +1739,7 @@ class ManifestUpdater {
|
|
|
1507
1739
|
}
|
|
1508
1740
|
}
|
|
1509
1741
|
const funcObj = {
|
|
1510
|
-
name:
|
|
1742
|
+
name: safeFunctionName,
|
|
1511
1743
|
description: description,
|
|
1512
1744
|
};
|
|
1513
1745
|
if (options.allowResponseSemantics) {
|
|
@@ -1515,7 +1747,7 @@ class ManifestUpdater {
|
|
|
1515
1747
|
const { json } = Utils.getResponseJson(operationItem);
|
|
1516
1748
|
if (json.schema) {
|
|
1517
1749
|
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operationItem);
|
|
1518
|
-
card.body = card.body
|
|
1750
|
+
card.body = Utils.limitACBodyProperties(card.body, 5);
|
|
1519
1751
|
const responseSemantic = wrapResponseSemantics(card, jsonPath);
|
|
1520
1752
|
funcObj.capabilities = {
|
|
1521
1753
|
response_semantics: responseSemantic,
|
|
@@ -1543,7 +1775,7 @@ class ManifestUpdater {
|
|
|
1543
1775
|
}
|
|
1544
1776
|
}
|
|
1545
1777
|
functions.push(funcObj);
|
|
1546
|
-
functionNames.push(
|
|
1778
|
+
functionNames.push(safeFunctionName);
|
|
1547
1779
|
const conversationStarterStr = (summary !== null && summary !== void 0 ? summary : description).slice(0, ConstantString.ConversationStarterMaxLens);
|
|
1548
1780
|
if (conversationStarterStr) {
|
|
1549
1781
|
conversationStarters.push(conversationStarterStr);
|
|
@@ -1643,7 +1875,6 @@ class ManifestUpdater {
|
|
|
1643
1875
|
const auth = authInfo.authScheme;
|
|
1644
1876
|
const safeRegistrationIdName = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
|
|
1645
1877
|
if (Utils.isAPIKeyAuth(auth) || Utils.isBearerTokenAuth(auth)) {
|
|
1646
|
-
const safeApiSecretRegistrationId = Utils.getSafeRegistrationIdEnvName(`${authInfo.name}_${ConstantString.RegistrationIdPostfix[authInfo.authScheme.type]}`);
|
|
1647
1878
|
composeExtension.authorization = {
|
|
1648
1879
|
authType: "apiSecretServiceAuth",
|
|
1649
1880
|
apiSecretServiceAuthConfiguration: {
|
|
@@ -1652,16 +1883,13 @@ class ManifestUpdater {
|
|
|
1652
1883
|
};
|
|
1653
1884
|
}
|
|
1654
1885
|
else if (Utils.isOAuthWithAuthCodeFlow(auth)) {
|
|
1886
|
+
// TODO: below schema is coming from design doc, may need to update when shcema is finalized
|
|
1655
1887
|
composeExtension.authorization = {
|
|
1656
1888
|
authType: "oAuth2.0",
|
|
1657
1889
|
oAuthConfiguration: {
|
|
1658
1890
|
oauthConfigurationId: `\${{${safeRegistrationIdName}}}`,
|
|
1659
1891
|
},
|
|
1660
1892
|
};
|
|
1661
|
-
updatedPart.webApplicationInfo = {
|
|
1662
|
-
id: "${{AAD_APP_CLIENT_ID}}",
|
|
1663
|
-
resource: "api://${{DOMAIN}}/${{AAD_APP_CLIENT_ID}}",
|
|
1664
|
-
};
|
|
1665
1893
|
}
|
|
1666
1894
|
}
|
|
1667
1895
|
updatedPart.composeExtensions = [composeExtension];
|
|
@@ -1699,12 +1927,17 @@ class ManifestUpdater {
|
|
|
1699
1927
|
command.parameters = command.parameters.filter((param) => param.isRequired);
|
|
1700
1928
|
}
|
|
1701
1929
|
else if (command.parameters && command.parameters.length > 0) {
|
|
1702
|
-
command.parameters
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1930
|
+
if (command.parameters.length > 1) {
|
|
1931
|
+
command.parameters = [command.parameters[0]];
|
|
1932
|
+
warnings.push({
|
|
1933
|
+
type: exports.WarningType.OperationOnlyContainsOptionalParam,
|
|
1934
|
+
content: Utils.format(ConstantString.OperationOnlyContainsOptionalParam, command.id),
|
|
1935
|
+
data: {
|
|
1936
|
+
commandId: command.id,
|
|
1937
|
+
parameterName: command.parameters[0].name,
|
|
1938
|
+
},
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1708
1941
|
}
|
|
1709
1942
|
if (adaptiveCardFolder) {
|
|
1710
1943
|
const adaptiveCardPath = path__default['default'].join(adaptiveCardFolder, command.id + ".json");
|
|
@@ -1782,7 +2015,13 @@ class SpecParser {
|
|
|
1782
2015
|
try {
|
|
1783
2016
|
try {
|
|
1784
2017
|
yield this.loadSpec();
|
|
1785
|
-
|
|
2018
|
+
if (!this.parser.$refs.circular) {
|
|
2019
|
+
yield this.parser.validate(this.spec);
|
|
2020
|
+
}
|
|
2021
|
+
else {
|
|
2022
|
+
const clonedUnResolveSpec = JSON.parse(JSON.stringify(this.unResolveSpec));
|
|
2023
|
+
yield this.parser.validate(clonedUnResolveSpec);
|
|
2024
|
+
}
|
|
1786
2025
|
}
|
|
1787
2026
|
catch (e) {
|
|
1788
2027
|
return {
|
|
@@ -1874,19 +2113,36 @@ class SpecParser {
|
|
|
1874
2113
|
isValid: isValid,
|
|
1875
2114
|
reason: reason,
|
|
1876
2115
|
};
|
|
1877
|
-
|
|
2116
|
+
// Try best to parse server url and auth type
|
|
2117
|
+
try {
|
|
1878
2118
|
const serverObj = Utils.getServerObject(spec, method.toLocaleLowerCase(), path);
|
|
1879
2119
|
if (serverObj) {
|
|
1880
|
-
apiResult.server =
|
|
2120
|
+
apiResult.server = serverObj.url;
|
|
1881
2121
|
}
|
|
2122
|
+
}
|
|
2123
|
+
catch (err) {
|
|
2124
|
+
// ignore
|
|
2125
|
+
}
|
|
2126
|
+
try {
|
|
1882
2127
|
const authArray = Utils.getAuthArray(operation.security, spec);
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2128
|
+
if (authArray.length !== 0) {
|
|
2129
|
+
for (const auths of authArray) {
|
|
2130
|
+
if (auths.length === 1) {
|
|
2131
|
+
apiResult.auth = auths[0];
|
|
2132
|
+
break;
|
|
2133
|
+
}
|
|
2134
|
+
else {
|
|
2135
|
+
apiResult.auth = {
|
|
2136
|
+
authScheme: { type: "multipleAuth" },
|
|
2137
|
+
name: auths.map((auth) => auth.name).join(", "),
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
1887
2140
|
}
|
|
1888
2141
|
}
|
|
1889
2142
|
}
|
|
2143
|
+
catch (err) {
|
|
2144
|
+
// ignore
|
|
2145
|
+
}
|
|
1890
2146
|
result.APIs.push(apiResult);
|
|
1891
2147
|
}
|
|
1892
2148
|
result.allAPICount = result.APIs.length;
|
|
@@ -1919,7 +2175,8 @@ class SpecParser {
|
|
|
1919
2175
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
1920
2176
|
throw new SpecParserError(ConstantString.CancelledMessage, exports.ErrorType.Cancelled);
|
|
1921
2177
|
}
|
|
1922
|
-
const
|
|
2178
|
+
const clonedUnResolveSpec = JSON.parse(JSON.stringify(newUnResolvedSpec));
|
|
2179
|
+
const newSpec = (yield this.parser.dereference(clonedUnResolveSpec));
|
|
1923
2180
|
return [newUnResolvedSpec, newSpec];
|
|
1924
2181
|
}
|
|
1925
2182
|
catch (err) {
|
|
@@ -1996,10 +2253,11 @@ class SpecParser {
|
|
|
1996
2253
|
const operation = newSpec.paths[url][method];
|
|
1997
2254
|
try {
|
|
1998
2255
|
const [card, jsonPath] = AdaptiveCardGenerator.generateAdaptiveCard(operation);
|
|
1999
|
-
const
|
|
2256
|
+
const safeAdaptiveCardName = operation.operationId.replace(/[^a-zA-Z0-9]/g, "_");
|
|
2257
|
+
const fileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.json`);
|
|
2000
2258
|
const wrappedCard = wrapAdaptiveCard(card, jsonPath);
|
|
2001
2259
|
yield fs__default['default'].outputJSON(fileName, wrappedCard, { spaces: 2 });
|
|
2002
|
-
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${
|
|
2260
|
+
const dataFileName = path__default['default'].join(adaptiveCardFolder, `${safeAdaptiveCardName}.data.json`);
|
|
2003
2261
|
yield fs__default['default'].outputJSON(dataFileName, {}, { spaces: 2 });
|
|
2004
2262
|
}
|
|
2005
2263
|
catch (err) {
|
|
@@ -2033,7 +2291,8 @@ class SpecParser {
|
|
|
2033
2291
|
loadSpec() {
|
|
2034
2292
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2035
2293
|
if (!this.spec) {
|
|
2036
|
-
|
|
2294
|
+
const spec = (yield this.parser.parse(this.pathOrSpec));
|
|
2295
|
+
this.unResolveSpec = this.resolveEnvForSpec(spec);
|
|
2037
2296
|
// Convert swagger 2.0 to openapi 3.0
|
|
2038
2297
|
if (!this.unResolveSpec.openapi && this.unResolveSpec.swagger === "2.0") {
|
|
2039
2298
|
const specObj = yield converter__default['default'].convert(this.unResolveSpec, {});
|
|
@@ -2070,6 +2329,11 @@ class SpecParser {
|
|
|
2070
2329
|
yield fs__default['default'].outputFile(outputSpecPath, resultStr);
|
|
2071
2330
|
});
|
|
2072
2331
|
}
|
|
2332
|
+
resolveEnvForSpec(spec) {
|
|
2333
|
+
const specString = JSON.stringify(spec);
|
|
2334
|
+
const specResolved = Utils.resolveEnv(specString);
|
|
2335
|
+
return JSON.parse(specResolved);
|
|
2336
|
+
}
|
|
2073
2337
|
}
|
|
2074
2338
|
|
|
2075
2339
|
exports.AdaptiveCardGenerator = AdaptiveCardGenerator;
|