UNPKG

@candrewsintegralblue/snyk

Version:

snyk library and cli utility

1,314 lines (1,215 loc) 75.2 kB
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