@candrewsintegralblue/snyk
Version:
snyk library and cli utility
1,314 lines (1,215 loc) • 75.2 kB
JavaScript
exports.id = 196;
exports.ids = [196];
exports.modules = {
/***/ 61452:
/***/ ((module) => {
function webpackEmptyContext(req) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
webpackEmptyContext.keys = () => ([]);
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = 61452;
module.exports = webpackEmptyContext;
/***/ }),
/***/ 3196:
/***/ ((module) => {
function webpackEmptyContext(req) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
webpackEmptyContext.keys = () => ([]);
webpackEmptyContext.resolve = webpackEmptyContext;
webpackEmptyContext.id = 3196;
module.exports = webpackEmptyContext;
/***/ }),
/***/ 52369:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.processCommandArgs = void 0;
function processCommandArgs(...args) {
let options = {};
if (typeof args[args.length - 1] === 'object') {
options = args.pop();
}
args = args.filter(Boolean);
// For repository scanning, populate with default path (cwd) if no path given
if (args.length === 0 && !options.docker) {
args.unshift(process.cwd());
}
return { options, paths: args };
}
exports.processCommandArgs = processCommandArgs;
/***/ }),
/***/ 55246:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TestCommandResult = exports.ClientSbomCommandResult = exports.CommandResult = void 0;
class CommandResult {
constructor(result) {
this.result = result;
}
toString() {
return this.result;
}
getDisplayResults() {
return this.result;
}
}
exports.CommandResult = CommandResult;
class ClientSbomCommandResult extends CommandResult {
getCyclonedxJsonResult() {
return this.cyclonedxJsonResult;
}
constructor(stdout, cyclonedxJsonResult) {
super(stdout);
this.cyclonedxJsonResult = cyclonedxJsonResult;
}
static createClientSbomCommandResult(stdout, cyclonedxJsonResult) {
return new ClientSbomCommandResult(stdout, cyclonedxJsonResult);
}
}
exports.ClientSbomCommandResult = ClientSbomCommandResult;
class TestCommandResult extends CommandResult {
constructor() {
super(...arguments);
this.jsonResult = '';
this.sarifResult = '';
this.jsonData = {};
}
getJsonResult() {
return this.jsonResult;
}
getSarifResult() {
return this.sarifResult;
}
getJsonData() {
return this.jsonData;
}
static createHumanReadableTestCommandResult(humanReadableResult, jsonResult, sarifResult, jsonData) {
return new HumanReadableTestCommandResult(humanReadableResult, jsonResult, sarifResult, jsonData);
}
static createJsonTestCommandResult(stdout, jsonResult, sarifResult, jsonPayload) {
return new JsonTestCommandResult(stdout, jsonResult, sarifResult, jsonPayload);
}
}
exports.TestCommandResult = TestCommandResult;
class HumanReadableTestCommandResult extends TestCommandResult {
constructor(humanReadableResult, jsonResult, sarifResult, jsonData) {
super(humanReadableResult);
this.jsonResult = '';
this.sarifResult = '';
this.jsonData = {};
this.jsonResult = jsonResult;
if (sarifResult) {
this.sarifResult = sarifResult;
}
if (jsonData) {
this.jsonData = jsonData;
}
}
getJsonResult() {
return this.jsonResult;
}
getSarifResult() {
return this.sarifResult;
}
getJsonData() {
return this.jsonData;
}
}
class JsonTestCommandResult extends TestCommandResult {
constructor(stdout, jsonResult, sarifResult, jsonData) {
super(stdout);
if (jsonResult) {
this.jsonResult = jsonResult;
}
if (sarifResult) {
this.sarifResult = sarifResult;
}
else {
this.jsonResult = stdout;
}
if (jsonData) {
this.jsonData = jsonData;
}
}
getJsonResult() {
return this.jsonResult;
}
getSarifResult() {
return this.sarifResult;
}
}
/***/ }),
/***/ 94501:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.checkOSSPaths = void 0;
const errors_1 = __webpack_require__(55191);
const detect_1 = __webpack_require__(45318);
// Throw error if user specifies package file name as part of path,
// and if user specifies multiple paths and used project-name option.
function checkOSSPaths(paths, options) {
let count = 0;
for (const path of paths) {
if (typeof path === 'string' && (0, detect_1.isPathToPackageFile)(path)) {
throw (0, errors_1.MissingTargetFileError)(path);
}
else if (typeof path === 'string') {
if (++count > 1 && options['project-name']) {
throw new errors_1.UnsupportedOptionCombinationError([
'multiple paths',
'project-name',
]);
}
}
}
}
exports.checkOSSPaths = checkOSSPaths;
/***/ }),
/***/ 46123:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.find = exports.getStats = exports.readDirectory = void 0;
const fs = __webpack_require__(57147);
const pathLib = __webpack_require__(71017);
const sortBy = __webpack_require__(58254);
const groupBy = __webpack_require__(20276);
const assign = __webpack_require__(31730);
const detect_1 = __webpack_require__(45318);
const debugModule = __webpack_require__(15158);
const package_managers_1 = __webpack_require__(53847);
const debug = debugModule('snyk:find-files');
// TODO: use util.promisify once we move to node 8
/**
* Returns files inside given file path.
*
* @param path file path.
*/
async function readDirectory(path) {
return await new Promise((resolve, reject) => {
fs.readdir(path, (err, files) => {
if (err) {
reject(err);
}
resolve(files);
});
});
}
exports.readDirectory = readDirectory;
/**
* Returns file stats object for given file path.
*
* @param path path to file or directory.
*/
async function getStats(path) {
return await new Promise((resolve, reject) => {
fs.stat(path, (err, stats) => {
if (err) {
reject(err);
}
resolve(stats);
});
});
}
exports.getStats = getStats;
const ignoreFolders = ['node_modules', '.build'];
const defaultFindConfig = {
path: '',
ignore: [],
filter: [],
levelsDeep: 4,
featureFlags: new Set(),
};
/**
* Find all files in given search path. Returns paths to files found.
*
* @param path file path to search.
* @param ignore (optional) files to ignore. Will always ignore node_modules.
* @param filter (optional) file names to find. If not provided all files are returned.
* @param levelsDeep (optional) how many levels deep to search, defaults to two, this path and one sub directory.
*/
async function find(findConfig) {
const config = assign({}, defaultFindConfig, findConfig);
const found = [];
const foundAll = [];
// ensure we ignore find against node_modules path and .build folder for swift.
if (config.path.endsWith('node_modules') || config.path.endsWith('/.build')) {
return { files: found, allFilesFound: foundAll };
}
// ensure dependencies folders is always ignored
for (const folder of ignoreFolders) {
if (!config.ignore.includes(folder)) {
config.ignore.push(folder);
}
}
try {
if (config.levelsDeep < 0) {
return { files: found, allFilesFound: foundAll };
}
else {
config.levelsDeep--;
}
const fileStats = await getStats(config.path);
if (fileStats.isDirectory()) {
const { files, allFilesFound } = await findInDirectory(config);
found.push(...files);
foundAll.push(...allFilesFound);
}
else if (fileStats.isFile()) {
const fileFound = findFile(config.path, config.filter);
if (fileFound) {
found.push(fileFound);
foundAll.push(fileFound);
}
}
const filteredOutFiles = foundAll.filter((f) => !found.includes(f));
if (filteredOutFiles.length) {
debug(`Filtered out ${filteredOutFiles.length}/${foundAll.length} files: ${filteredOutFiles.join(', ')}`);
}
return {
files: filterForDefaultManifests(found, config.featureFlags),
allFilesFound: foundAll,
};
}
catch (err) {
throw new Error(`Error finding files in path '${config.path}'.\n${err.message}`);
}
}
exports.find = find;
function findFile(path, filter = []) {
if (filter.length > 0) {
const filename = pathLib.basename(path);
if (filter.includes(filename)) {
return path;
}
}
else {
return path;
}
return null;
}
async function findInDirectory(findConfig) {
const config = assign({}, defaultFindConfig, findConfig);
const files = await readDirectory(config.path);
const toFind = files
.filter((file) => !config.ignore.includes(file))
.map((file) => {
const resolvedPath = pathLib.resolve(config.path, file);
if (!fs.existsSync(resolvedPath)) {
debug('File does not seem to exist, skipping: ', file);
return { files: [], allFilesFound: [] };
}
const findconfig = {
...config,
path: resolvedPath,
};
return find(findconfig);
});
const found = await Promise.all(toFind);
return {
files: Array.prototype.concat.apply([], found.map((f) => f.files)),
allFilesFound: Array.prototype.concat.apply([], found.map((f) => f.allFilesFound)),
};
}
function filterForDefaultManifests(files, featureFlags = new Set()) {
// take all the files in the same dir & filter out
// based on package Manager
if (files.length <= 1) {
return files;
}
const filteredFiles = [];
const beforeSort = files
.filter(Boolean)
.filter((p) => fs.existsSync(p))
.map((p) => ({
path: p,
...pathLib.parse(p),
packageManager: detectProjectTypeFromFile(p, featureFlags),
}));
const sorted = sortBy(beforeSort, 'dir');
const foundFiles = groupBy(sorted, 'dir');
for (const directory of Object.keys(foundFiles)) {
const filesInDirectory = foundFiles[directory];
const beforeGroup = filesInDirectory.filter((p) => !!p.packageManager);
const groupedFiles = groupBy(beforeGroup, 'packageManager');
for (const packageManager of Object.keys(groupedFiles)) {
const filesPerPackageManager = groupedFiles[packageManager];
if (filesPerPackageManager.length <= 1) {
const shouldSkip = shouldSkipAddingFile(packageManager, filesPerPackageManager[0].path, filteredFiles);
if (shouldSkip) {
continue;
}
filteredFiles.push(filesPerPackageManager[0].path);
continue;
}
const defaultManifestFileName = chooseBestManifest(filesPerPackageManager, packageManager, featureFlags);
if (defaultManifestFileName) {
const shouldSkip = shouldSkipAddingFile(packageManager, filesPerPackageManager[0].path, // defaultManifestFileName?
filteredFiles);
if (shouldSkip) {
continue;
}
filteredFiles.push(defaultManifestFileName);
}
}
}
return filteredFiles;
}
function detectProjectTypeFromFile(file, featureFlags = new Set()) {
try {
const packageManager = (0, detect_1.detectPackageManagerFromFile)(file, featureFlags);
if (['yarn', 'npm'].includes(packageManager)) {
return 'node';
}
if (featureFlags.has(package_managers_1.PNPM_FEATURE_FLAG) && packageManager === 'pnpm') {
return 'node';
}
return packageManager;
}
catch (error) {
return null;
}
}
function shouldSkipAddingFile(packageManager, filePath, filteredFiles) {
if (['gradle'].includes(packageManager) && filePath) {
const rootGradleFile = filteredFiles
.filter((targetFile) => targetFile.endsWith('build.gradle') ||
targetFile.endsWith('build.gradle.kts'))
.filter((targetFile) => {
const parsedPath = pathLib.parse(targetFile);
const relativePath = pathLib.relative(parsedPath.dir, filePath);
return !relativePath.startsWith(`..${pathLib.sep}`);
});
return !!rootGradleFile.length;
}
return false;
}
function chooseBestManifest(files, projectType, featureFlags = new Set([])) {
switch (projectType) {
case 'node': {
const nodeLockfiles = [
package_managers_1.SUPPORTED_MANIFEST_FILES.PACKAGE_LOCK_JSON,
package_managers_1.SUPPORTED_MANIFEST_FILES.YARN_LOCK,
];
if (featureFlags.has(package_managers_1.PNPM_FEATURE_FLAG)) {
nodeLockfiles.push(package_managers_1.SUPPORTED_MANIFEST_FILES.PNPM_LOCK);
}
const lockFile = files.filter((path) => nodeLockfiles.includes(path.base))[0];
debug(`Encountered multiple node lockfiles files, defaulting to ${lockFile.path}`);
if (lockFile) {
return lockFile.path;
}
const packageJson = files.filter((path) => ['package.json'].includes(path.base))[0];
debug(`Encountered multiple npm manifest files, defaulting to ${packageJson.path}`);
return packageJson.path;
}
case 'rubygems': {
const defaultManifest = files.filter((path) => ['Gemfile.lock'].includes(path.base))[0];
debug(`Encountered multiple gem manifest files, defaulting to ${defaultManifest.path}`);
return defaultManifest.path;
}
case 'cocoapods': {
const defaultManifest = files.filter((path) => ['Podfile'].includes(path.base))[0];
debug(`Encountered multiple cocoapods manifest files, defaulting to ${defaultManifest.path}`);
return defaultManifest.path;
}
case 'pip': {
const defaultManifest = files.filter((path) => ['Pipfile'].includes(path.base))[0];
debug(`Encountered multiple pip manifest files, defaulting to ${defaultManifest.path}`);
return defaultManifest.path;
}
case 'gradle': {
const defaultManifest = files.filter((path) => ['build.gradle'].includes(path.base))[0];
debug(`Encountered multiple gradle manifest files, defaulting to ${defaultManifest.path}`);
return defaultManifest.path;
}
case 'poetry': {
const defaultManifest = files.filter((path) => ['pyproject.toml'].includes(path.base))[0];
debug(`Encountered multiple poetry manifest files, defaulting to ${defaultManifest.path}`);
return defaultManifest.path;
}
case 'hex': {
const defaultManifest = files.filter((path) => ['mix.exs'].includes(path.base))[0];
debug(`Encountered multiple hex manifest files, defaulting to ${defaultManifest.path}`);
return defaultManifest.path;
}
default: {
return null;
}
}
}
/***/ }),
/***/ 84210:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getFileContents = void 0;
const fs = __webpack_require__(57147);
const path = __webpack_require__(71017);
function getFileContents(root, fileName) {
const fullPath = path.resolve(root, fileName);
if (!fs.existsSync(fullPath)) {
throw new Error('Manifest ' + fileName + ' not found at location: ' + fileName);
}
const content = fs.readFileSync(fullPath, 'utf-8');
return {
content,
fileName,
};
}
exports.getFileContents = getFileContents;
/***/ }),
/***/ 62435:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.isMultiProjectScan = void 0;
function isMultiProjectScan(options) {
return !!(options.allProjects || options.yarnWorkspaces);
}
exports.isMultiProjectScan = isMultiProjectScan;
/***/ }),
/***/ 80777:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ModuleInfo = void 0;
const merge = __webpack_require__(72378);
const Debug = __webpack_require__(15158);
const debug = Debug('snyk-module-info');
function ModuleInfo(plugin, policy) {
return {
async inspect(root, targetFile, options, snykHttpClient) {
const pluginOptions = merge({
args: options._doubleDashArgs,
}, options);
debug('calling plugin inspect()', { root, targetFile, pluginOptions });
const info = await plugin.inspect(root, targetFile, pluginOptions, snykHttpClient);
debug('plugin inspect() done');
// attach policy if not provided by plugin
if (policy && !info.package.policy) {
info.package.policy = policy.toString();
}
return info;
},
};
}
exports.ModuleInfo = ModuleInfo;
/***/ }),
/***/ 23110:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.convertMultiResultToMultiCustom = void 0;
const convert_scanned_projects_to_custom_1 = __webpack_require__(92909);
function convertMultiResultToMultiCustom(inspectRes, packageManager, targetFile) {
// convert all results from the same plugin to MultiProjectResultCustom
// and annotate each scannedProject with packageManager
return {
plugin: inspectRes.plugin,
scannedProjects: (0, convert_scanned_projects_to_custom_1.convertScannedProjectsToCustom)(inspectRes.scannedProjects, inspectRes.plugin, inspectRes.plugin.packageManager ||
packageManager, targetFile),
};
}
exports.convertMultiResultToMultiCustom = convertMultiResultToMultiCustom;
/***/ }),
/***/ 92909:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.convertScannedProjectsToCustom = void 0;
function convertScannedProjectsToCustom(scannedProjects, pluginMeta, packageManager, targetFile) {
// annotate the package manager & targetFile to be used
// for test & monitor
return scannedProjects.map((a) => {
a.plugin =
a.plugin || pluginMeta;
a.targetFile = a.targetFile || targetFile;
a.packageManager = a
.packageManager
? a.packageManager
: packageManager;
a.meta = a.meta;
return a;
});
}
exports.convertScannedProjectsToCustom = convertScannedProjectsToCustom;
/***/ }),
/***/ 99695:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.convertSingleResultToMultiCustom = void 0;
function convertSingleResultToMultiCustom(inspectRes, packageManager) {
if (!packageManager) {
packageManager = inspectRes.plugin
.packageManager;
}
if (inspectRes.dependencyGraph) {
return convertDepGraphResult(inspectRes, packageManager);
}
else {
return convertDepTreeResult(inspectRes, packageManager);
}
}
exports.convertSingleResultToMultiCustom = convertSingleResultToMultiCustom;
function convertDepGraphResult(inspectRes, packageManager) {
const { plugin, meta, dependencyGraph: depGraph, callGraph } = inspectRes;
return {
plugin,
scannedProjects: [
{
plugin: plugin,
depGraph,
callGraph: callGraph,
meta,
targetFile: plugin.targetFile,
packageManager,
},
],
};
}
/**
* @deprecated @boost: delete me when all languages uses depGraph
*/
function convertDepTreeResult(inspectRes, packageManager) {
if (inspectRes.package &&
!inspectRes.package.targetFile &&
inspectRes.plugin) {
inspectRes.package.targetFile = inspectRes.plugin.targetFile;
}
const { plugin, meta, package: depTree, callGraph } = inspectRes;
if (depTree && !depTree.targetFile && plugin) {
depTree.targetFile = plugin.targetFile;
}
return {
plugin,
scannedProjects: [
{
plugin: plugin,
depTree,
callGraph: callGraph,
meta,
targetFile: plugin.targetFile,
packageManager,
},
],
};
}
/***/ }),
/***/ 22805:
/***/ ((__unused_webpack_module, exports) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.extractPackageManager = void 0;
function extractPackageManager(scannedProject, pluginRes, options) {
// try and use the package Manager from the plugin
// result if present
const packageManager = scannedProject.packageManager ||
(pluginRes.plugin && pluginRes.plugin.packageManager);
if (packageManager) {
return packageManager;
}
if (!packageManager && options.packageManager) {
// fallback to Options packageManager
return options.packageManager;
}
// for example: docker
return undefined;
}
exports.extractPackageManager = extractPackageManager;
/***/ }),
/***/ 4842:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.warnSomeGradleManifestsNotScanned = exports.getDepsFromPlugin = void 0;
const debugModule = __webpack_require__(15158);
const pathLib = __webpack_require__(71017);
const chalk_1 = __webpack_require__(32589);
const theme_1 = __webpack_require__(86988);
const cli_interface_1 = __webpack_require__(65266);
const find_files_1 = __webpack_require__(46123);
const errors_1 = __webpack_require__(55191);
const get_multi_plugin_result_1 = __webpack_require__(66058);
const get_single_plugin_result_1 = __webpack_require__(8598);
const detect_1 = __webpack_require__(45318);
const analytics = __webpack_require__(82744);
const convert_single_splugin_res_to_multi_custom_1 = __webpack_require__(99695);
const convert_multi_plugin_res_to_multi_custom_1 = __webpack_require__(23110);
const yarn_workspaces_parser_1 = __webpack_require__(27326);
const debug = debugModule('snyk-test');
const multiProjectProcessors = {
yarnWorkspaces: {
handler: yarn_workspaces_parser_1.processYarnWorkspaces,
files: ['package.json'],
},
allProjects: {
handler: get_multi_plugin_result_1.getMultiPluginResult,
files: detect_1.AUTO_DETECTABLE_FILES,
},
};
// Force getDepsFromPlugin to return scannedProjects for processing
async function getDepsFromPlugin(root, options, featureFlags = new Set()) {
if (Object.keys(multiProjectProcessors).some((key) => options[key])) {
const scanType = options.yarnWorkspaces ? 'yarnWorkspaces' : 'allProjects';
const levelsDeep = options.detectionDepth;
const ignore = options.exclude ? options.exclude.split(',') : [];
const { files: targetFiles, allFilesFound } = await (0, find_files_1.find)({
path: root,
ignore,
filter: multiProjectProcessors[scanType].files,
featureFlags,
levelsDeep,
});
debug(`auto detect manifest files, found ${targetFiles.length}`, targetFiles);
if (targetFiles.length === 0) {
throw (0, errors_1.NoSupportedManifestsFoundError)([root]);
}
// enable full sub-project scan for gradle
options.allSubProjects = true;
const inspectRes = await multiProjectProcessors[scanType].handler(root, options, targetFiles, featureFlags);
const scannedProjects = inspectRes.scannedProjects;
const analyticData = {
scannedProjects: scannedProjects.length,
targetFiles,
packageManagers: targetFiles.map((file) => (0, detect_1.detectPackageManagerFromFile)(file, featureFlags)),
levelsDeep,
ignore,
};
analytics.add(scanType, analyticData);
debug(`Found ${scannedProjects.length} projects from ${allFilesFound.length} detected manifests`);
const userWarningMessage = warnSomeGradleManifestsNotScanned(scannedProjects, allFilesFound, root);
if (!options.json && !options.quiet && userWarningMessage) {
console.warn(chalk_1.default.bold.red(userWarningMessage));
}
return inspectRes;
}
// TODO: is this needed for the auto detect handling above?
// don't override options.file if scanning multiple files at once
if (!options.scanAllUnmanaged) {
options.file = options.file || (0, detect_1.detectPackageFile)(root, featureFlags);
}
if (!options.docker && !(options.file || options.packageManager)) {
throw (0, errors_1.NoSupportedManifestsFoundError)([...root]);
}
const inspectRes = await (0, get_single_plugin_result_1.getSinglePluginResult)(root, options);
if (!cli_interface_1.legacyPlugin.isMultiResult(inspectRes)) {
if (!inspectRes.package && !inspectRes.dependencyGraph) {
// something went wrong if both are not present...
throw Error(`error getting dependencies from ${options.docker ? 'docker' : options.packageManager} ` + "plugin: neither 'package' nor 'scannedProjects' were found");
}
return (0, convert_single_splugin_res_to_multi_custom_1.convertSingleResultToMultiCustom)(inspectRes, options.packageManager);
}
// We are using "options" to store some information returned from plugin that we need to use later,
// but don't want to send to Registry in the Payload.
// TODO(kyegupov): decouple inspect and payload so that we don't need this hack
options.projectNames = inspectRes.scannedProjects.map((scannedProject) => { var _a; return (_a = scannedProject === null || scannedProject === void 0 ? void 0 : scannedProject.depTree) === null || _a === void 0 ? void 0 : _a.name; });
return (0, convert_multi_plugin_res_to_multi_custom_1.convertMultiResultToMultiCustom)(inspectRes, options.packageManager);
}
exports.getDepsFromPlugin = getDepsFromPlugin;
function warnSomeGradleManifestsNotScanned(scannedProjects, allFilesFound, root) {
const gradleTargetFilesFilter = (targetFile) => targetFile &&
(targetFile.endsWith('build.gradle') ||
targetFile.endsWith('build.gradle.kts'));
const scannedGradleFiles = scannedProjects
.map((p) => {
var _a;
const targetFile = ((_a = p.meta) === null || _a === void 0 ? void 0 : _a.targetFile) || p.targetFile;
return targetFile ? pathLib.resolve(root, targetFile) : null;
})
.filter(gradleTargetFilesFilter);
const detectedGradleFiles = allFilesFound.filter(gradleTargetFilesFilter);
const diff = detectedGradleFiles.filter((file) => !scannedGradleFiles.includes(file));
if (diff.length > 0) {
debug(`These Gradle manifests did not return any dependency results:\n${diff.join(',\n')}`);
return `${theme_1.icon.ISSUE} ${diff.length}/${detectedGradleFiles.length} detected Gradle manifests did not return dependencies. They may have errored or were not included as part of a multi-project build. You may need to scan them individually with --file=path/to/file. Run with \`-d\` for more info.`;
}
return null;
}
exports.warnSomeGradleManifestsNotScanned = warnSomeGradleManifestsNotScanned;
/***/ }),
/***/ 66058:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.filterOutProcessedWorkspaces = exports.getMultiPluginResult = void 0;
const cloneDeep = __webpack_require__(83465);
const pathLib = __webpack_require__(71017);
const cliInterface = __webpack_require__(65266);
const chalk_1 = __webpack_require__(32589);
const theme_1 = __webpack_require__(86988);
const debugModule = __webpack_require__(15158);
const detect_1 = __webpack_require__(45318);
const package_managers_1 = __webpack_require__(53847);
const get_single_plugin_result_1 = __webpack_require__(8598);
const convert_single_splugin_res_to_multi_custom_1 = __webpack_require__(99695);
const convert_multi_plugin_res_to_multi_custom_1 = __webpack_require__(23110);
const errors_1 = __webpack_require__(55191);
const yarn_workspaces_parser_1 = __webpack_require__(27326);
const npm_workspaces_parser_1 = __webpack_require__(31744);
const snyk_nodejs_plugin_1 = __webpack_require__(12608);
const debug = debugModule('snyk-test');
const NODE_WORKSPACES_MAP = {
pnpm: {
processingFunction: snyk_nodejs_plugin_1.processPnpmWorkspaces,
lockFile: package_managers_1.SUPPORTED_MANIFEST_FILES.PNPM_LOCK,
},
npm: {
processingFunction: npm_workspaces_parser_1.processNpmWorkspaces,
lockFile: package_managers_1.SUPPORTED_MANIFEST_FILES.PACKAGE_LOCK_JSON,
},
yarn: {
processingFunction: yarn_workspaces_parser_1.processYarnWorkspaces,
lockFile: package_managers_1.SUPPORTED_MANIFEST_FILES.YARN_LOCK,
},
};
async function getMultiPluginResult(root, options, targetFiles, featureFlags = new Set()) {
var _a;
const allResults = [];
const failedResults = [];
// process any workspaces first
// the files need to be proceeded together as they provide context to each other
let unprocessedFilesfromWorkspaces = targetFiles;
if (featureFlags.has(package_managers_1.PNPM_FEATURE_FLAG)) {
const { scannedProjects: scannedPnpmResults, unprocessedFiles } = await processWorkspacesProjects(root, options, targetFiles, 'pnpm');
unprocessedFilesfromWorkspaces = unprocessedFiles;
allResults.push(...scannedPnpmResults);
}
const { scannedProjects: scannedYarnResults, unprocessedFiles: unprocessedFilesFromYarn, } = await processWorkspacesProjects(root, options, unprocessedFilesfromWorkspaces, 'yarn');
allResults.push(...scannedYarnResults);
const { scannedProjects: scannedNpmResults, unprocessedFiles } = await processWorkspacesProjects(root, options, unprocessedFilesFromYarn, 'npm');
allResults.push(...scannedNpmResults);
debug(`Not part of a workspace: ${unprocessedFiles.join(', ')}}`);
// process the rest 1 by 1 sent to relevant plugins
for (const targetFile of unprocessedFiles) {
const optionsClone = cloneDeep(options);
optionsClone.file = pathLib.relative(root, targetFile);
optionsClone.packageManager = (0, detect_1.detectPackageManagerFromFile)(pathLib.basename(targetFile), featureFlags);
try {
const inspectRes = await (0, get_single_plugin_result_1.getSinglePluginResult)(root, optionsClone, optionsClone.file);
let resultWithScannedProjects;
if (!cliInterface.legacyPlugin.isMultiResult(inspectRes)) {
resultWithScannedProjects = (0, convert_single_splugin_res_to_multi_custom_1.convertSingleResultToMultiCustom)(inspectRes, optionsClone.packageManager);
}
else {
resultWithScannedProjects = inspectRes;
}
const pluginResultWithCustomScannedProjects = (0, convert_multi_plugin_res_to_multi_custom_1.convertMultiResultToMultiCustom)(resultWithScannedProjects, optionsClone.packageManager, optionsClone.file);
// annotate the package manager, project name & targetFile to be used
// for test & monitor
// TODO: refactor how we display meta to not have to do this
options.projectNames =
resultWithScannedProjects.scannedProjects.map((scannedProject) => { var _a; return (_a = scannedProject === null || scannedProject === void 0 ? void 0 : scannedProject.depTree) === null || _a === void 0 ? void 0 : _a.name; });
allResults.push(...pluginResultWithCustomScannedProjects.scannedProjects);
}
catch (error) {
const errMessage = (_a = error.message) !== null && _a !== void 0 ? _a : 'Something went wrong getting dependencies';
// TODO: propagate this all the way back and include in --json output
failedResults.push({
targetFile,
error,
errMessage: errMessage,
});
debug(chalk_1.default.bold.red(`\n${theme_1.icon.ISSUE} Failed to get dependencies for ${targetFile}\nERROR: ${errMessage}\n`));
}
}
if (!allResults.length) {
throw new errors_1.FailedToRunTestError((0, errors_1.errorMessageWithRetry)(`Failed to get dependencies for all ${targetFiles.length} potential projects.`));
}
return {
plugin: {
name: 'custom-auto-detect',
},
scannedProjects: allResults,
failedResults,
};
}
exports.getMultiPluginResult = getMultiPluginResult;
async function processWorkspacesProjects(root, options, targetFiles, packageManager) {
try {
const { scannedProjects } = await NODE_WORKSPACES_MAP[packageManager].processingFunction(root, {
strictOutOfSync: options.strictOutOfSync,
dev: options.dev,
}, targetFiles);
const unprocessedFiles = filterOutProcessedWorkspaces(root, scannedProjects, targetFiles, NODE_WORKSPACES_MAP[packageManager].lockFile);
return { scannedProjects, unprocessedFiles };
}
catch (e) {
debug(`Error during detecting or processing ${packageManager} Workspaces: `, e);
return { scannedProjects: [], unprocessedFiles: targetFiles };
}
}
function filterOutProcessedWorkspaces(root, scannedProjects, allTargetFiles, lockFile) {
const targetFiles = [];
const scanned = scannedProjects
.map((p) => p.targetFile)
.map((p) => pathLib.resolve(process.cwd(), root, p));
const all = allTargetFiles.map((p) => ({
path: pathLib.resolve(process.cwd(), root, p),
original: p,
}));
for (const entry of all) {
const { path, original } = entry;
const { base } = pathLib.parse(path);
if (!['package.json', lockFile].includes(base)) {
targetFiles.push(original);
continue;
}
// standardise to package.json
// we discover the lockfiles but targetFile is package.json
if (!scanned.includes(path.replace(lockFile, 'package.json'))) {
targetFiles.push(original);
continue;
}
}
return targetFiles;
}
exports.filterOutProcessedWorkspaces = filterOutProcessedWorkspaces;
/***/ }),
/***/ 8598:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getSinglePluginResult = void 0;
const plugins = __webpack_require__(45632);
const module_info_1 = __webpack_require__(80777);
const snyk_http_client_1 = __webpack_require__(85690);
async function getSinglePluginResult(root, options, targetFile) {
const plugin = plugins.loadPlugin(options.packageManager);
const moduleInfo = (0, module_info_1.ModuleInfo)(plugin, options.policy);
const inspectRes = await moduleInfo.inspect(root, targetFile || options.file, { ...options }, snyk_http_client_1.snykHttpClient);
return inspectRes;
}
exports.getSinglePluginResult = getSinglePluginResult;
/***/ }),
/***/ 45632:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.loadPlugin = void 0;
const rubygemsPlugin = __webpack_require__(92632);
const mvnPlugin = __webpack_require__(29615);
const gradlePlugin = __webpack_require__(71673);
const sbtPlugin = __webpack_require__(1444);
const pythonPlugin = __webpack_require__(85054);
const goPlugin = __webpack_require__(29376);
const nugetPlugin = __webpack_require__(82843);
const phpPlugin = __webpack_require__(18630);
const legacyNodejsPlugin = __webpack_require__(59947);
const nodejsPlugin = __webpack_require__(12608);
const cocoapodsPlugin = __webpack_require__(49556);
const hexPlugin = __webpack_require__(1649);
const swiftPlugin = __webpack_require__(42939);
const errors_1 = __webpack_require__(55191);
function loadPlugin(packageManager) {
switch (packageManager) {
case 'npm': {
return legacyNodejsPlugin;
}
case 'rubygems': {
return rubygemsPlugin;
}
case 'maven': {
return mvnPlugin;
}
case 'gradle': {
return gradlePlugin;
}
case 'sbt': {
return sbtPlugin;
}
case 'yarn': {
return legacyNodejsPlugin;
}
case 'pip':
case 'poetry': {
return pythonPlugin;
}
case 'golangdep':
case 'gomodules':
case 'govendor': {
return goPlugin;
}
case 'nuget': {
return nugetPlugin;
}
case 'paket': {
return nugetPlugin;
}
case 'composer': {
return phpPlugin;
}
case 'cocoapods': {
return cocoapodsPlugin;
}
case 'hex': {
return hexPlugin;
}
case 'swift': {
return swiftPlugin;
}
case 'pnpm': {
return nodejsPlugin;
}
default: {
throw new errors_1.UnsupportedPackageManagerError(packageManager);
}
}
}
exports.loadPlugin = loadPlugin;
/***/ }),
/***/ 59947:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.inspect = void 0;
const modulesParser = __webpack_require__(85994);
const lockParser = __webpack_require__(82791);
const analytics = __webpack_require__(82744);
const missing_targetfile_error_1 = __webpack_require__(56775);
const snyk_nodejs_lockfile_parser_1 = __webpack_require__(423);
const path = __webpack_require__(71017);
async function inspect(root, targetFile, options = {}) {
if (!targetFile) {
throw (0, missing_targetfile_error_1.MissingTargetFileError)(root);
}
const isLockFileBased = targetFile.endsWith('package-lock.json') ||
targetFile.endsWith('yarn.lock');
const getLockFileDeps = isLockFileBased && !options.traverseNodeModules;
const depRes = getLockFileDeps
? await lockParser.parse(root, targetFile, options)
: await modulesParser.parse(root, targetFile, options);
let scannedProjects = [];
if (isResDepGraph(depRes)) {
scannedProjects = [{ depGraph: depRes }];
}
else {
scannedProjects = [{ depTree: depRes }];
}
if (isLockFileBased) {
const lockFileFullPath = path.resolve(root, targetFile);
const lockfileVersion = (0, snyk_nodejs_lockfile_parser_1.getLockfileVersionFromFile)(lockFileFullPath);
switch (lockfileVersion) {
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.NpmLockV1:
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.YarnLockV1:
analytics.add('lockfileVersion', 1);
break;
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.NpmLockV2:
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.YarnLockV2:
analytics.add('lockfileVersion', 2);
break;
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.NpmLockV3:
analytics.add('lockfileVersion', 3);
break;
default:
break;
}
}
return {
plugin: {
name: 'snyk-nodejs-lockfile-parser',
runtime: process.version,
},
scannedProjects,
};
}
exports.inspect = inspect;
function isResDepGraph(depRes) {
return 'rootPkg' in depRes;
}
/***/ }),
/***/ 82791:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parse = void 0;
const baseDebug = __webpack_require__(15158);
const debug = baseDebug('snyk-test');
const path = __webpack_require__(71017);
const spinner_1 = __webpack_require__(86766);
const analytics = __webpack_require__(82744);
const fs = __webpack_require__(57147);
const lockFileParser = __webpack_require__(423);
const snyk_nodejs_lockfile_parser_1 = __webpack_require__(423);
async function parse(root, targetFile, options) {
const lockFileFullPath = path.resolve(root, targetFile);
if (!fs.existsSync(lockFileFullPath)) {
throw new Error('Lockfile ' + targetFile + ' not found at location: ' + lockFileFullPath);
}
const fullPath = path.parse(lockFileFullPath);
const manifestFileFullPath = path.resolve(fullPath.dir, 'package.json');
const shrinkwrapFullPath = path.resolve(fullPath.dir, 'npm-shrinkwrap.json');
if (!fs.existsSync(manifestFileFullPath)) {
throw new Error(`Could not find package.json at ${manifestFileFullPath} ` +
`(lockfile found at ${targetFile})`);
}
if (fs.existsSync(shrinkwrapFullPath)) {
throw new Error('Both `npm-shrinkwrap.json` and `package-lock.json` were found in ' +
fullPath.dir +
'.\n' +
'Please run your command again specifying `--file=package.json` flag.');
}
analytics.add('local', true);
analytics.add('generating-node-dependency-tree', {
lockFile: true,
targetFile,
});
const resolveModuleSpinnerLabel = `Analyzing npm dependencies for ${lockFileFullPath}`;
debug(resolveModuleSpinnerLabel);
const strictOutOfSync = options.strictOutOfSync !== false;
const lockfileVersion = lockFileParser.getLockfileVersionFromFile(lockFileFullPath);
if (lockfileVersion === snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.YarnLockV1 ||
lockfileVersion === snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.YarnLockV2 ||
lockfileVersion === snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.NpmLockV2 ||
lockfileVersion === snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.NpmLockV3) {
return await buildDepGraph(root, manifestFileFullPath, lockFileFullPath, lockfileVersion, {
includeDevDeps: options.dev || false,
includeOptionalDeps: true,
strictOutOfSync,
pruneCycles: true,
});
}
try {
await (0, spinner_1.spinner)(resolveModuleSpinnerLabel);
return lockFileParser.buildDepTreeFromFiles(root, manifestFileFullPath, lockFileFullPath, options.dev, strictOutOfSync);
}
finally {
await spinner_1.spinner.clear(resolveModuleSpinnerLabel)();
}
}
exports.parse = parse;
async function buildDepGraph(root, manifestFilePath, lockfilePath, lockfileVersion, options) {
const manifestFileFullPath = path.resolve(root, manifestFilePath);
const lockFileFullPath = path.resolve(root, lockfilePath);
if (!fs.existsSync(manifestFileFullPath)) {
throw new snyk_nodejs_lockfile_parser_1.InvalidUserInputError('Target file package.json not found at ' +
`location: ${manifestFileFullPath}`);
}
if (!fs.existsSync(lockFileFullPath)) {
throw new snyk_nodejs_lockfile_parser_1.InvalidUserInputError('Lockfile not found at location: ' + lockFileFullPath);
}
const manifestFileContents = fs.readFileSync(manifestFileFullPath, 'utf-8');
const lockFileContents = fs.readFileSync(lockFileFullPath, 'utf-8');
switch (lockfileVersion) {
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.YarnLockV1:
return await lockFileParser.parseYarnLockV1Project(manifestFileContents, lockFileContents, {
includeDevDeps: options.includeDevDeps,
includeOptionalDeps: options.includeOptionalDeps,
includePeerDeps: options.includePeerDeps || false,
pruneLevel: 'withinTopLevelDeps',
strictOutOfSync: options.strictOutOfSync,
});
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.YarnLockV2:
return await lockFileParser.parseYarnLockV2Project(manifestFileContents, lockFileContents, {
includeDevDeps: options.includeDevDeps,
includeOptionalDeps: options.includeOptionalDeps,
pruneWithinTopLevelDeps: true,
strictOutOfSync: options.strictOutOfSync,
});
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.NpmLockV2:
case snyk_nodejs_lockfile_parser_1.NodeLockfileVersion.NpmLockV3:
return await lockFileParser.parseNpmLockV2Project(manifestFileContents, lockFileContents, options);
}
throw new Error('Failed to build dep graph from current project');
}
/***/ }),
/***/ 85994:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parse = void 0;
const path = __webpack_require__(71017);
const fs = __webpack_require__(57147);
const resolveDeps = __webpack_require__(40068);
const baseDebug = __webpack_require__(15158);
const isEmpty = __webpack_require__(99245);
const spinner_1 = __webpack_require__(86766);
const analytics = __webpack_require__(82744);
const get_file_contents_1 = __webpack_require__(84210);
const debug = baseDebug('snyk-nodejs-plugin');
async function parse(root, targetFile, options) {
if (targetFile.endsWith('yarn.lock')) {
options.file =
options.file && options.file.replace('yarn.lock', 'package.json');
}
// package-lock.json falls back to package.json (used in wizard code)
if (targetFile.endsWith('package-lock.json')) {
options.file =
options.file && options.file.replace('package-lock.json', 'package.json');
}
// check if there any dependencies
const packageJsonFileName = path.resolve(root, options.file);
const packageManager = options.packageManager || 'npm';
try {
const packageJson = JSON.parse((0, get_file_contents_1.getFileContents)(root, packageJsonFileName).content);
let dependencies = packageJson.dependencies;
if (options.dev) {
dependencies = { ...dependencies, ...packageJson.devDependencies };
}
if (isEmpty(dependencies)) {
return new Promise((resolve) => resolve({
name: packageJson.name || 'package.json',
dependencies: {},
version: packageJson.version,
}));
}
}
catch (e) {
debug(`Failed to read ${packageJsonFileName}: Error: ${e}`);
throw new Error(`Failed to read ${packageJsonFileName}. Error: ${e.message}`);
}
const nodeModulesPath = path.join(path.dirname(path.resolve(root, targetFile)), 'node_modules');
if (!fs.existsSync(nodeModulesPath)) {
// throw a custom error
throw new Error("Missing node_modules folder: we can't test " +
`without dependencies.\nPlease run '${packageManager} install' first.`);
}
analytics.add('local', true);
analytics.add('generating-node-dependency-tree', {
lockFile: false,
targetFile,
});
const resolveModuleSpinnerLabel = 'Analyzing npm dependencies for ' +
path.dirname(path.resolve(root, targetFile));
try {
await spinner_1.spinner.clear(resolveModuleSpinnerLabel)();
await (0, spinner_1.spinner)(resolveModuleSpinnerLabel);
return resolveDeps(root, Object.assign({}, options, { noFromArrays: true }));
}
finally {
await spinner_1.spinner.clear(resolveModuleSpinnerLabel)();
}
}
exports.parse = parse;
/***/ }),
/***/ 31744:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.packageJsonBelongsToWorkspace = exports.getWorkspacesMap = exports.processNpmWorkspaces = void 0;
const baseDebug = __webpack_require__(15158);
const pathUtil = __webpack_require__(71017);
const sortBy = __webpack_require__(58254);
const groupBy = __webpack_require__(20276);
const micromatch = __webpack_require__(70850);
const debug = baseDebug('snyk-npm-workspaces');
const lockFileParser = __webpack_require__(423);
const get_file_contents_1 = __webpack_require__(84210);
const errors_1 = __webpack_require__(55191);
async function processNpmWorkspaces(root, settings, targetFiles) {
// the order of npmTargetFiles folders is important
// must have the root level most folders at the top
const mappedAndFiltered = targetFiles
.map((p) => ({ path: p, ...pathUtil.parse(p) }))
.filter((res) => ['package.json', 'package-lock.json'].includes(res.base));
const sorted = sortBy(mappedAndFiltered, 'dir');
c