@microsoft/m365-spec-parser 0.2.2-alpha.ca8431921.0 → 0.2.2-alpha.db6b164d0.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 +2 -2
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +159 -4
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +2 -2
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +159 -4
- package/dist/index.node.cjs.js.map +1 -1
- package/dist/src/specOptimizer.d.ts +18 -0
- package/package.json +3 -3
package/dist/index.node.cjs.js
CHANGED
|
@@ -1147,6 +1147,161 @@ class ValidatorFactory {
|
|
|
1147
1147
|
}
|
|
1148
1148
|
}
|
|
1149
1149
|
|
|
1150
|
+
// Copyright (c) Microsoft Corporation.
|
|
1151
|
+
class SpecOptimizer {
|
|
1152
|
+
static optimize(spec, options) {
|
|
1153
|
+
const mergedOptions = Object.assign(Object.assign({}, SpecOptimizer.defaultOptions), (options !== null && options !== void 0 ? options : {}));
|
|
1154
|
+
const newSpec = JSON.parse(JSON.stringify(spec));
|
|
1155
|
+
if (mergedOptions.removeUserDefinedRootProperty) {
|
|
1156
|
+
SpecOptimizer.removeUserDefinedRootProperty(newSpec);
|
|
1157
|
+
}
|
|
1158
|
+
if (mergedOptions.removeUnusedComponents) {
|
|
1159
|
+
SpecOptimizer.removeUnusedComponents(newSpec);
|
|
1160
|
+
}
|
|
1161
|
+
if (mergedOptions.removeUnusedTags) {
|
|
1162
|
+
SpecOptimizer.removeUnusedTags(newSpec);
|
|
1163
|
+
}
|
|
1164
|
+
if (mergedOptions.removeUnusedSecuritySchemas) {
|
|
1165
|
+
SpecOptimizer.removeUnusedSecuritySchemas(newSpec);
|
|
1166
|
+
}
|
|
1167
|
+
return newSpec;
|
|
1168
|
+
}
|
|
1169
|
+
static removeUnusedSecuritySchemas(spec) {
|
|
1170
|
+
if (!spec.components || !spec.components.securitySchemes) {
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
const usedSecuritySchemas = new Set();
|
|
1174
|
+
for (const pathKey in spec.paths) {
|
|
1175
|
+
for (const methodKey in spec.paths[pathKey]) {
|
|
1176
|
+
const operation = spec.paths[pathKey][methodKey];
|
|
1177
|
+
if (operation.security) {
|
|
1178
|
+
operation.security.forEach((securityReq) => {
|
|
1179
|
+
for (const schemaKey in securityReq) {
|
|
1180
|
+
usedSecuritySchemas.add(schemaKey);
|
|
1181
|
+
}
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
if (spec.security) {
|
|
1187
|
+
spec.security.forEach((securityReq) => {
|
|
1188
|
+
for (const schemaKey in securityReq) {
|
|
1189
|
+
usedSecuritySchemas.add(schemaKey);
|
|
1190
|
+
}
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
for (const schemaKey in spec.components.securitySchemes) {
|
|
1194
|
+
if (!usedSecuritySchemas.has(schemaKey)) {
|
|
1195
|
+
delete spec.components.securitySchemes[schemaKey];
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
if (Object.keys(spec.components.securitySchemes).length === 0) {
|
|
1199
|
+
delete spec.components.securitySchemes;
|
|
1200
|
+
}
|
|
1201
|
+
if (Object.keys(spec.components).length === 0) {
|
|
1202
|
+
delete spec.components;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
static removeUnusedTags(spec) {
|
|
1206
|
+
if (!spec.tags) {
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
const usedTags = new Set();
|
|
1210
|
+
for (const pathKey in spec.paths) {
|
|
1211
|
+
for (const methodKey in spec.paths[pathKey]) {
|
|
1212
|
+
const operation = spec.paths[pathKey][methodKey];
|
|
1213
|
+
if (operation.tags) {
|
|
1214
|
+
operation.tags.forEach((tag) => usedTags.add(tag));
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
spec.tags = spec.tags.filter((tagObj) => usedTags.has(tagObj.name));
|
|
1219
|
+
}
|
|
1220
|
+
static removeUserDefinedRootProperty(spec) {
|
|
1221
|
+
for (const key in spec) {
|
|
1222
|
+
if (key.startsWith("x-")) {
|
|
1223
|
+
delete spec[key];
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
static removeUnusedComponents(spec) {
|
|
1228
|
+
const components = spec.components;
|
|
1229
|
+
if (!components) {
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
delete spec.components;
|
|
1233
|
+
const usedComponentsSet = new Set();
|
|
1234
|
+
const specString = JSON.stringify(spec);
|
|
1235
|
+
const componentReferences = SpecOptimizer.getComponentReferences(specString);
|
|
1236
|
+
for (const reference of componentReferences) {
|
|
1237
|
+
this.addComponent(reference, usedComponentsSet, components);
|
|
1238
|
+
}
|
|
1239
|
+
const newComponents = {};
|
|
1240
|
+
for (const componentName of usedComponentsSet) {
|
|
1241
|
+
const parts = componentName.split("/");
|
|
1242
|
+
const component = this.getComponent(componentName, components);
|
|
1243
|
+
if (component) {
|
|
1244
|
+
let current = newComponents;
|
|
1245
|
+
for (let i = 2; i < parts.length; i++) {
|
|
1246
|
+
if (i === parts.length - 1) {
|
|
1247
|
+
current[parts[i]] = component;
|
|
1248
|
+
}
|
|
1249
|
+
else if (!current[parts[i]]) {
|
|
1250
|
+
current[parts[i]] = {};
|
|
1251
|
+
}
|
|
1252
|
+
current = current[parts[i]];
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
// securitySchemes are referenced directly by name, to void issue, just keep them all and use removeUnusedSecuritySchemas to remove unused ones
|
|
1257
|
+
if (components.securitySchemes) {
|
|
1258
|
+
newComponents.securitySchemes = components.securitySchemes;
|
|
1259
|
+
}
|
|
1260
|
+
if (Object.keys(newComponents).length !== 0) {
|
|
1261
|
+
spec.components = newComponents;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
static getComponentReferences(specString) {
|
|
1265
|
+
const matches = Array.from(specString.matchAll(/['"](#\/components\/.+?)['"]/g));
|
|
1266
|
+
const matchResult = matches.map((match) => match[1]);
|
|
1267
|
+
return matchResult;
|
|
1268
|
+
}
|
|
1269
|
+
static getComponent(componentPath, components) {
|
|
1270
|
+
const parts = componentPath.split("/");
|
|
1271
|
+
let current = components;
|
|
1272
|
+
for (const part of parts) {
|
|
1273
|
+
if (part === "#" || part === "components") {
|
|
1274
|
+
continue;
|
|
1275
|
+
}
|
|
1276
|
+
current = current[part];
|
|
1277
|
+
if (!current) {
|
|
1278
|
+
return null;
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
return current;
|
|
1282
|
+
}
|
|
1283
|
+
static addComponent(componentName, usedComponentsSet, components) {
|
|
1284
|
+
if (usedComponentsSet.has(componentName)) {
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1287
|
+
usedComponentsSet.add(componentName);
|
|
1288
|
+
const component = this.getComponent(componentName, components);
|
|
1289
|
+
if (component) {
|
|
1290
|
+
const componentString = JSON.stringify(component);
|
|
1291
|
+
const componentReferences = SpecOptimizer.getComponentReferences(componentString);
|
|
1292
|
+
for (const reference of componentReferences) {
|
|
1293
|
+
this.addComponent(reference, usedComponentsSet, components);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
SpecOptimizer.defaultOptions = {
|
|
1299
|
+
removeUnusedComponents: true,
|
|
1300
|
+
removeUnusedTags: true,
|
|
1301
|
+
removeUserDefinedRootProperty: true,
|
|
1302
|
+
removeUnusedSecuritySchemas: true,
|
|
1303
|
+
};
|
|
1304
|
+
|
|
1150
1305
|
// Copyright (c) Microsoft Corporation.
|
|
1151
1306
|
class SpecFilter {
|
|
1152
1307
|
static specFilter(filter, unResolveSpec, resolvedSpec, options) {
|
|
@@ -1180,7 +1335,7 @@ class SpecFilter {
|
|
|
1180
1335
|
}
|
|
1181
1336
|
}
|
|
1182
1337
|
newSpec.paths = newPaths;
|
|
1183
|
-
return newSpec;
|
|
1338
|
+
return SpecOptimizer.optimize(newSpec);
|
|
1184
1339
|
}
|
|
1185
1340
|
catch (err) {
|
|
1186
1341
|
throw new SpecParserError(err.toString(), exports.ErrorType.FilterSpecFailed);
|
|
@@ -1303,7 +1458,7 @@ class AdaptiveCardGenerator {
|
|
|
1303
1458
|
{
|
|
1304
1459
|
type: "Image",
|
|
1305
1460
|
url: `\${${name}}`,
|
|
1306
|
-
$when: `\${${name} != null}`,
|
|
1461
|
+
$when: `\${${name} != null && ${name} != ''}`,
|
|
1307
1462
|
},
|
|
1308
1463
|
];
|
|
1309
1464
|
}
|
|
@@ -1312,7 +1467,7 @@ class AdaptiveCardGenerator {
|
|
|
1312
1467
|
{
|
|
1313
1468
|
type: "Image",
|
|
1314
1469
|
url: "${$data}",
|
|
1315
|
-
$when: "${$data != null}",
|
|
1470
|
+
$when: "${$data != null && $data != ''}",
|
|
1316
1471
|
},
|
|
1317
1472
|
];
|
|
1318
1473
|
}
|
|
@@ -1405,7 +1560,7 @@ function inferPreviewCardTemplate(card) {
|
|
|
1405
1560
|
result.image = {
|
|
1406
1561
|
url: `\${${inferredProperties.imageUrl}}`,
|
|
1407
1562
|
alt: `\${if(${inferredProperties.imageUrl}, ${inferredProperties.imageUrl}, 'N/A')}`,
|
|
1408
|
-
$when: `\${${inferredProperties.imageUrl} != null}`,
|
|
1563
|
+
$when: `\${${inferredProperties.imageUrl} != null && ${inferredProperties.imageUrl} != ''}`,
|
|
1409
1564
|
};
|
|
1410
1565
|
}
|
|
1411
1566
|
return result;
|