snyk-nuget-plugin
Version:
Snyk CLI NuGet plugin
219 lines • 8.57 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = parse;
const errors_1 = require("../../errors");
const debug_1 = __importDefault(require("debug"));
const _ = __importStar(require("lodash"));
const debug = (0, debug_1.default)('snyk');
const PACKAGE_DELIMITER = '@';
const freqDeps = {};
function initFreqDepsDict() {
freqDeps['Microsoft.NETCore.Platforms'] = false;
freqDeps['Microsoft.NETCore.Targets'] = false;
freqDeps['System.Runtime'] = false;
freqDeps['System.IO'] = false;
freqDeps['System.Text.Encoding'] = false;
freqDeps['System.Threading.Tasks'] = false;
freqDeps['System.Reflection'] = false;
freqDeps['System.Globalization'] = false;
}
function isScanned(nodes, pkg) {
const node = nodes.find((elem) => elem.name === pkg.name && elem.version === pkg.version);
return !!node;
}
function isFreqDep(packageName) {
return packageName in freqDeps;
}
function pick(obj, keys) {
const pickedObj = {};
Object.keys(obj).forEach((k) => {
if (keys.includes(k)) {
pickedObj[k] = obj[k];
}
});
return pickedObj;
}
function convertFromPathSyntax(path) {
let name = path.split('/').join('@'); // posix
name = name.split('\\').join('@'); // windows
return name;
}
function findPackage(targetDeps, depName) {
debug(`Looking for ${depName}`);
const depNameLowerCase = depName.toLowerCase();
for (const currentDep of Object.keys(targetDeps)) {
const currentResolvedName = convertFromPathSyntax(currentDep);
const [currentDepName, currentDepVersion] = currentResolvedName.split(PACKAGE_DELIMITER);
if (currentDepName.toLowerCase() === depNameLowerCase) {
return {
name: depName,
version: currentDepVersion,
dependencies: targetDeps[currentDep].dependencies,
};
}
}
debug(`Failed to find ${depName}`);
return undefined;
}
function constructTree(roots, nodes, links) {
const treeMap = {};
for (const node of nodes) {
const { name, version } = node;
const treeNode = { name, version, dependencies: {} };
treeMap[name] = treeNode;
}
for (const link of links) {
const parentName = link.from.name;
const childName = link.to.name;
const parentNode = treeMap[parentName];
const childNode = treeMap[childName];
if (!isFreqDep(childName)) {
parentNode.dependencies[childName] = {
...childNode,
};
}
}
const tree = pick(treeMap, roots);
const freqSysDeps = pick(treeMap, Object.keys(freqDeps));
if (Object.keys(freqSysDeps).length > 0) {
tree['freqSystemDependencies'] = {
name: 'freqSystemDependencies',
version: '0.0.0',
dependencies: freqSysDeps,
};
}
return tree;
}
function collectFlatList(targetObj) {
const names = Object.keys(targetObj);
return names.map((name) => {
name = convertFromPathSyntax(name);
return name;
});
}
function addPackageDepLinks(links, pkg) {
if (pkg && pkg.dependencies) {
const from = { name: pkg.name, version: pkg.version };
for (const name of Object.keys(pkg.dependencies)) {
const to = { name, version: pkg.dependencies[name] };
links.push({ from, to });
}
}
}
function buildBfsTree(targetDeps, roots) {
let queue = [...roots];
const nodes = [];
const links = [];
while (queue.length > 0) {
const dep = queue.shift();
const foundPackage = findPackage(targetDeps, dep);
if (foundPackage && !isScanned(nodes, foundPackage)) {
nodes.push(foundPackage);
if (foundPackage.dependencies) {
addPackageDepLinks(links, foundPackage);
queue = queue.concat(Object.keys(foundPackage.dependencies));
}
}
}
return constructTree(roots, nodes, links);
}
function getFrameworkToRun(manifest) {
const frameworks = manifest?.project?.frameworks;
debug(`Available frameworks: '${Object.keys(frameworks)}'`);
// not yet supporting multiple frameworks in the same assets file ->
// taking only the first 1
const selectedFrameworkKey = Object.keys(frameworks)[0];
debug(`Selected framework: '${selectedFrameworkKey}'`);
return selectedFrameworkKey;
}
function getTargetObjToRun(manifest) {
debug(`Available targets: '${Object.keys(manifest.targets)}'`);
const selectedTargetKey = Object.keys(manifest.targets)[0];
debug(`Selected target: '${selectedTargetKey}'`);
// not yet supporting multiple targets in the same assets file ->
// taking only the first 1
return manifest.targets[selectedTargetKey];
}
function validateManifest(manifest) {
if (!manifest.project) {
throw new errors_1.InvalidManifestError('Project field was not found in project.assets.json');
}
if (!manifest.project.frameworks) {
throw new errors_1.InvalidManifestError('No frameworks were found in project.assets.json');
}
if (!manifest.project.frameworks ||
Object.keys(manifest.project.frameworks).length === 0) {
throw new errors_1.InvalidManifestError('0 frameworks were found in project.assets.json');
}
if (!manifest.targets) {
throw new errors_1.InvalidManifestError('No targets were found in project.assets.json');
}
if (!manifest.targets || Object.keys(manifest.targets).length === 0) {
throw new errors_1.InvalidManifestError('0 targets were found in project.assets.json');
}
}
function parse(tree, manifest) {
debug('Trying to parse dot-net-cli manifest');
validateManifest(manifest);
if (manifest.project.version) {
tree.version = manifest.project.version;
}
// If a targetFramework was not found in the proj file, we will extract it from the lock file
// OR
// If the targetFramework is undefined, extract it from the lock file
// Fix for https://github.com/snyk/snyk-nuget-plugin/issues/75
if (!tree.meta.targetFramework ||
manifest.project.frameworks[tree.meta.targetFramework] === undefined) {
tree.meta.targetFramework = getFrameworkToRun(manifest);
}
const selectedFrameworkObj = manifest.project.frameworks[tree.meta.targetFramework];
// We currently ignore the found targetFramework when looking for target dependencies
const selectedTargetObj = getTargetObjToRun(manifest);
initFreqDepsDict();
const directDependencies = selectedFrameworkObj.dependencies
? collectFlatList(selectedFrameworkObj.dependencies)
: [];
debug(`directDependencies: '${directDependencies}'`);
tree.dependencies = buildBfsTree(selectedTargetObj, directDependencies);
// to disconnect the object references inside the tree
// cloneDeep is used here
tree.dependencies = _.cloneDeep(tree.dependencies);
return tree;
}
//# sourceMappingURL=dotnet-core-parser.js.map