powerplatform-review-tool
Version:
Evaluate Power Platform solution zip files based on best practice patterns
145 lines (144 loc) • 6.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getItemsFromDataset = getItemsFromDataset;
exports.generateSarifFromReview = generateSarifFromReview;
function getItemsFromDataset(dataset) {
if (dataset.error || dataset.paging.totalResultCount === undefined) {
// Dataset is not defined, return dummy items
return [];
}
const keyIndex = {};
return dataset.sortedRecordIds.map((id) => {
const record = dataset.records[id];
// Ensure we avoid duplicate keys by appending an index if necessary
let key = record.getValue("PatternID" /* ItemColumns.PatternID */);
if (keyIndex[key] !== undefined) {
keyIndex[key]++;
key += `_${keyIndex[key]}`;
}
else {
keyIndex[key] = 1;
}
return {
id: record.getRecordId(),
key: key,
text: record.getFormattedValue("PatternName" /* ItemColumns.PatternName */), // For display text, use PatternName
clickable: true, // Assuming all patterns are clickable
data: {
patternID: record.getValue("PatternID" /* ItemColumns.PatternID */),
patternName: record.getValue("PatternName" /* ItemColumns.PatternName */),
description: record.getValue("PatternDescription" /* ItemColumns.PatternDescription */),
recommendation: record.getValue("PatternRecommendation" /* ItemColumns.PatternRecommendation */),
docLinks: record.getValue("PatternDocLink" /* ItemColumns.PatternDocLink */),
severity: record.getValue("PatternSeverity" /* ItemColumns.PatternSeverity */),
category: record.getValue("PatternCategory" /* ItemColumns.PatternCategory */),
patternType: record.getValue("PatternType" /* ItemColumns.PatternType */),
patternScore: record.getValue("PatternScore" /* ItemColumns.PatternScore */),
patternActive: record.getValue("PatternActive" /* ItemColumns.PatternActive */),
},
};
});
}
function generateSarifFromReview(result) {
const convertItemToRun = (componentType, item) => {
const rules = new Map();
const results = [];
item.result.forEach((pattern) => {
if (!rules.has(pattern.patternID)) {
rules.set(pattern.patternID, {
id: pattern.patternID,
name: pattern.patternID,
shortDescription: {
text: pattern.description || 'No description provided.'
},
helpUri: Array.isArray(pattern.docLinks) ? pattern.docLinks[0] : pattern.docLinks
});
}
if (pattern.instanceValue) {
Array.isArray(pattern.instanceValue) && pattern.instanceValue.forEach((instance) => {
let messageText = pattern.description;
let locationRegion = { startLine: 1 };
if (componentType === 'PowerApps') {
const appInstance = instance;
if (appInstance.Code && appInstance.FailedPowerFxCode) {
const code = appInstance.Code;
const failed = appInstance.FailedPowerFxCode;
const start = code.indexOf(failed);
if (start !== -1) {
locationRegion = {
startLine: 1,
startColumn: start + 1,
endColumn: start + failed.length + 1,
snippet: { text: code }
};
}
messageText = `${pattern.description}: ${failed}`;
}
}
else if (componentType === 'PowerAutomate') {
const flowInstance = instance;
messageText = `${pattern.description}: ${flowInstance}`;
}
else if (componentType === 'Copilot') {
const agentInstance = instance;
messageText = `${pattern.description}: ${JSON.stringify(agentInstance)}`;
}
results.push({
ruleId: pattern.patternID,
level: pattern.status === "Pass" /* ManifestPropertyStatusNames.Pass */ ? "note" : pattern.status === "Fail" /* ManifestPropertyStatusNames.Fail */ ? "error" : "warning",
message: {
text: pattern.description,
markdown: componentType === 'PowerApps' && instance.FailedPowerFxCode
? `\`\`\`powerfx
${instance.FailedPowerFxCode}
\`\`\``
: undefined
},
locations: [
{
physicalLocation: {
artifactLocation: {
uri: `${componentType}/${item.name}` + (componentType === 'PowerApps' ? `/${instance.ScreenName}/${instance.ControlName}` : '')
},
region: locationRegion
}
}
],
properties: {
component: componentType,
name: item.name,
score: item.score
}
});
});
}
});
return {
tool: {
driver: {
name: `${componentType}: ${item.displayName || item.name}`,
informationUri: 'https://github.com/microsoft/Power-CAT-Tools',
rules: Array.from(rules.values())
}
},
properties: {
componentType,
componentName: item.displayName || item.name,
componentScore: item.score
},
results
};
};
return {
version: '2.1.0',
properties: {
solutionScore: result.SolutionScore
},
$schema: 'https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json',
runs: [
...result.PowerApps.items.map(app => convertItemToRun('PowerApps', app)),
...result.PowerAutomate.items.map(flow => convertItemToRun('PowerAutomate', flow)),
...result.Copilot.items.map(bot => convertItemToRun('Copilot', bot))
]
};
}