@coana-tech/cli 13.19.2 → 13.19.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.js +139 -29
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -95630,7 +95630,9 @@ var init_constants3 = __esm({
|
|
|
95630
95630
|
"REACHABILITY_ANALYZERS_SCRIPT_PATH",
|
|
95631
95631
|
"JAVA_HOME",
|
|
95632
95632
|
"GRADLE_HOME",
|
|
95633
|
-
"SBT_HOME"
|
|
95633
|
+
"SBT_HOME",
|
|
95634
|
+
"HOME",
|
|
95635
|
+
"USER"
|
|
95634
95636
|
];
|
|
95635
95637
|
}
|
|
95636
95638
|
});
|
|
@@ -95800,7 +95802,7 @@ var init_other_modules_communicator = __esm({
|
|
|
95800
95802
|
}
|
|
95801
95803
|
async runInDocker(image, entryPoint, commandName, args2, subprojectPath, tmpDir, env = process.env) {
|
|
95802
95804
|
const envArgs = Object.keys(env).filter((key) => !DOCKER_ENV_VARS_BLACKLIST.includes(key)).flatMap((key) => ["-e", key]);
|
|
95803
|
-
const cmd = cmdt`docker run --pull always -v ${this.rootWorkingDir}:/project -v ${tmpDir}:${tmpDir}
|
|
95805
|
+
const cmd = cmdt`docker run --pull always --rm -v ${this.rootWorkingDir}:/project -v ${tmpDir}:${tmpDir}
|
|
95804
95806
|
-v=${this.options.coanaLogPath}:${this.options.coanaLogPath}
|
|
95805
95807
|
${envArgs} ${image} ${entryPoint} ${commandName} ${args2}`;
|
|
95806
95808
|
return await execPipeAndLogOnFailure(cmd, subprojectPath, { env });
|
|
@@ -130101,7 +130103,9 @@ __export(dashboard_integration_exports, {
|
|
|
130101
130103
|
getExperimentName: () => getExperimentName,
|
|
130102
130104
|
getPreviousAnalysisResults: () => getPreviousAnalysisResults,
|
|
130103
130105
|
sendCLIProgressToDashboard: () => sendCLIProgressToDashboard,
|
|
130106
|
+
sendDependencyTreesToDashboard: () => sendDependencyTreesToDashboard,
|
|
130104
130107
|
sendErrorReportToDashboard: () => sendErrorReportToDashboard,
|
|
130108
|
+
sendLogToDashboard: () => sendLogToDashboard,
|
|
130105
130109
|
sendRegressionsToDashboard: () => sendRegressionsToDashboard,
|
|
130106
130110
|
sendToDashboard: () => sendToDashboard,
|
|
130107
130111
|
sendWarningToDashboard: () => sendWarningToDashboard,
|
|
@@ -130249,6 +130253,22 @@ async function sendWarningToDashboard(message2, data2, additionalData, reportId,
|
|
|
130249
130253
|
logger.warn("Unable to send warning to dashboard:", error.message);
|
|
130250
130254
|
}
|
|
130251
130255
|
}
|
|
130256
|
+
async function sendDependencyTreesToDashboard(dependencyTrees, reportId, apiKey) {
|
|
130257
|
+
try {
|
|
130258
|
+
await sendPostRequest(
|
|
130259
|
+
coanaAPIUrls.SEND_DEPENDENCY_TREES.replace(":reportId", reportId),
|
|
130260
|
+
apiKey,
|
|
130261
|
+
{},
|
|
130262
|
+
dependencyTrees
|
|
130263
|
+
);
|
|
130264
|
+
} catch (e) {
|
|
130265
|
+
sendWarningToDashboard("Unable to send dependency trees", { reportId }, void 0, reportId, apiKey);
|
|
130266
|
+
logger.warn(
|
|
130267
|
+
"Unable to send dependency trees:",
|
|
130268
|
+
e.message
|
|
130269
|
+
);
|
|
130270
|
+
}
|
|
130271
|
+
}
|
|
130252
130272
|
async function sendToDashboard(report, writeReportToFile, reportId, apiKey) {
|
|
130253
130273
|
try {
|
|
130254
130274
|
if (writeReportToFile) {
|
|
@@ -130285,6 +130305,17 @@ async function sendErrorReportToDashboard(apiKey, stackTrace, shouldLogSharing,
|
|
|
130285
130305
|
console.log("Error submitting crash report to dashboard:", e);
|
|
130286
130306
|
}
|
|
130287
130307
|
}
|
|
130308
|
+
async function sendLogToDashboard(logContent, reportId, apiKey) {
|
|
130309
|
+
if (!logContent) return;
|
|
130310
|
+
logger.info("Sending log to Coana");
|
|
130311
|
+
try {
|
|
130312
|
+
await sendPostRequest(coanaAPIUrls.SEND_LOG.replace(":reportId", reportId), apiKey, { reportId }, {
|
|
130313
|
+
logContent
|
|
130314
|
+
});
|
|
130315
|
+
} catch (error) {
|
|
130316
|
+
logger.warn("Unable to send log to dashboard:", error.message);
|
|
130317
|
+
}
|
|
130318
|
+
}
|
|
130288
130319
|
async function sendPostRequest(url2, apiKey, params, data2) {
|
|
130289
130320
|
const axiosConfig = {
|
|
130290
130321
|
headers: {
|
|
@@ -130310,10 +130341,12 @@ var init_dashboard_integration = __esm({
|
|
|
130310
130341
|
CREATE_ANALYSIS_METADATA: `${coanaAPI}/reports/:reportId/analysis-metadata`,
|
|
130311
130342
|
REPORT_CLI_PROGRESS: `${coanaAPI}/reports/:reportId/cli-progress`,
|
|
130312
130343
|
CREATE_REGRESSIONS: `${coanaAPI}/reports/:reportId/regressions`,
|
|
130344
|
+
SEND_LOG: `${coanaAPI}/reports/:reportId/log`,
|
|
130313
130345
|
GET_LATEST_BUCKETS: `${coanaAPI}/latest-buckets`,
|
|
130314
130346
|
GET_LATEST_RESULTS: `${coanaAPI}/latest-results`,
|
|
130315
130347
|
GET_EXPERIMENT_NAME: `${coanaAPI}/experiment-name`,
|
|
130316
|
-
REPORT_WARNING: `${coanaAPI}/cli/warn
|
|
130348
|
+
REPORT_WARNING: `${coanaAPI}/cli/warn`,
|
|
130349
|
+
SEND_DEPENDENCY_TREES: `${coanaAPI}/reports/:reportId/dependency-trees`
|
|
130317
130350
|
};
|
|
130318
130351
|
reportSubmitEndpoint = process.env.COANA_CLI_SUBMIT_ENDPOINT ?? "https://app.coana.tech/api/v1/reports/submit";
|
|
130319
130352
|
errorSubmitEndpoint = process.env.COANA_CLI_ERROR_SUBMIT_ENDPOINT ?? "https://app.coana.tech/api/v1/cli/error";
|
|
@@ -189074,13 +189107,56 @@ var init_slack = __esm({
|
|
|
189074
189107
|
});
|
|
189075
189108
|
|
|
189076
189109
|
// ../web-compat-utils/src/dependency-tree.ts
|
|
189110
|
+
var dependency_tree_exports = {};
|
|
189111
|
+
__export(dependency_tree_exports, {
|
|
189112
|
+
ADVISORY_ECOSYSTEMS: () => ADVISORY_ECOSYSTEMS,
|
|
189113
|
+
ADVISORY_SEVERITIES: () => ADVISORY_SEVERITIES,
|
|
189114
|
+
PACKAGE_MANAGERS: () => PACKAGE_MANAGERS,
|
|
189115
|
+
getEcosystem: () => getEcosystem,
|
|
189116
|
+
mergeDependencyTrees: () => mergeDependencyTrees,
|
|
189117
|
+
toPlainDependencyTree: () => toPlainDependencyTree
|
|
189118
|
+
});
|
|
189077
189119
|
function getEcosystem({ ecosystem }) {
|
|
189078
189120
|
return ecosystem ?? "NPM";
|
|
189079
189121
|
}
|
|
189080
|
-
|
|
189122
|
+
function mergeDependencyTrees(dependencyTrees) {
|
|
189123
|
+
if (dependencyTrees.length === 1) return dependencyTrees[0];
|
|
189124
|
+
const newTree = {
|
|
189125
|
+
...dependencyTrees[0],
|
|
189126
|
+
transitiveDependencies: {},
|
|
189127
|
+
dependencies: []
|
|
189128
|
+
};
|
|
189129
|
+
for (const dependencyTree of dependencyTrees) {
|
|
189130
|
+
if (dependencyTree.dependencies)
|
|
189131
|
+
newTree.dependencies = i([...newTree.dependencies, ...dependencyTree.dependencies ?? []]);
|
|
189132
|
+
for (const [identifier, node] of Object.entries(dependencyTree.transitiveDependencies)) {
|
|
189133
|
+
if (!newTree.transitiveDependencies[identifier])
|
|
189134
|
+
newTree.transitiveDependencies[identifier] = { ...node, dependencies: [...node.dependencies ?? []] };
|
|
189135
|
+
else {
|
|
189136
|
+
const existingNode = newTree.transitiveDependencies[identifier];
|
|
189137
|
+
existingNode.dependencies = i([...existingNode.dependencies ?? [], ...node.dependencies ?? []]);
|
|
189138
|
+
}
|
|
189139
|
+
}
|
|
189140
|
+
}
|
|
189141
|
+
return newTree;
|
|
189142
|
+
}
|
|
189143
|
+
function toPlainDependencyTree(dependencyTree) {
|
|
189144
|
+
function pickNode(node) {
|
|
189145
|
+
return a(node, ["packageName", "version", "dependencies", "resolvedType"]);
|
|
189146
|
+
}
|
|
189147
|
+
return {
|
|
189148
|
+
...pickNode(dependencyTree),
|
|
189149
|
+
transitiveDependencies: Object.fromEntries(
|
|
189150
|
+
Object.entries(dependencyTree.transitiveDependencies).map(([key, value]) => [key, pickNode(value)])
|
|
189151
|
+
),
|
|
189152
|
+
ecosystem: dependencyTree.ecosystem
|
|
189153
|
+
};
|
|
189154
|
+
}
|
|
189155
|
+
var ADVISORY_ECOSYSTEMS, ADVISORY_SEVERITIES, PACKAGE_MANAGERS;
|
|
189081
189156
|
var init_dependency_tree = __esm({
|
|
189082
189157
|
"../web-compat-utils/src/dependency-tree.ts"() {
|
|
189083
189158
|
"use strict";
|
|
189159
|
+
init_dist();
|
|
189084
189160
|
ADVISORY_ECOSYSTEMS = [
|
|
189085
189161
|
"COMPOSER",
|
|
189086
189162
|
"ERLANG",
|
|
@@ -189095,6 +189171,24 @@ var init_dependency_tree = __esm({
|
|
|
189095
189171
|
"RUST",
|
|
189096
189172
|
"SWIFT"
|
|
189097
189173
|
];
|
|
189174
|
+
ADVISORY_SEVERITIES = ["info", "INFO", "low", "LOW", "moderate", "MODERATE", "high", "HIGH", "critical", "CRITICAL"];
|
|
189175
|
+
PACKAGE_MANAGERS = [
|
|
189176
|
+
"NPM",
|
|
189177
|
+
"PNPM",
|
|
189178
|
+
"YARN",
|
|
189179
|
+
"RUSH",
|
|
189180
|
+
"MAVEN",
|
|
189181
|
+
"GRADLE",
|
|
189182
|
+
"SBT",
|
|
189183
|
+
"POETRY",
|
|
189184
|
+
"PIP_REQUIREMENTS",
|
|
189185
|
+
"PIPENV",
|
|
189186
|
+
"GO",
|
|
189187
|
+
"CARGO",
|
|
189188
|
+
"NUGET",
|
|
189189
|
+
"RUBYGEMS",
|
|
189190
|
+
"COMPOSER"
|
|
189191
|
+
];
|
|
189098
189192
|
}
|
|
189099
189193
|
});
|
|
189100
189194
|
|
|
@@ -190036,7 +190130,7 @@ var require_version = __commonJS({
|
|
|
190036
190130
|
"use strict";
|
|
190037
190131
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
190038
190132
|
exports2.version = void 0;
|
|
190039
|
-
exports2.version = "13.19.
|
|
190133
|
+
exports2.version = "13.19.4";
|
|
190040
190134
|
}
|
|
190041
190135
|
});
|
|
190042
190136
|
|
|
@@ -190071,6 +190165,7 @@ var require_cli_core = __commonJS({
|
|
|
190071
190165
|
var dashboard_integration_1 = (init_dashboard_integration(), __toCommonJS(dashboard_integration_exports));
|
|
190072
190166
|
var vulnerability_scanning_1 = require_vulnerability_scanning();
|
|
190073
190167
|
var version_12 = require_version();
|
|
190168
|
+
var dependency_tree_1 = (init_dependency_tree(), __toCommonJS(dependency_tree_exports));
|
|
190074
190169
|
var CliCore = class {
|
|
190075
190170
|
options;
|
|
190076
190171
|
spinner;
|
|
@@ -190130,24 +190225,31 @@ var require_cli_core = __commonJS({
|
|
|
190130
190225
|
} catch (e) {
|
|
190131
190226
|
await this.spinner.fail();
|
|
190132
190227
|
logger_singleton_1.logger.error("CLI failed with error:", e);
|
|
190133
|
-
await this.
|
|
190228
|
+
await this.shareErrorLogWithDashboard(e, true);
|
|
190134
190229
|
throw e;
|
|
190135
190230
|
}
|
|
190136
190231
|
}
|
|
190137
|
-
async
|
|
190232
|
+
async getLogContent() {
|
|
190233
|
+
await logger_singleton_1.logger.finish();
|
|
190234
|
+
let logContent;
|
|
190235
|
+
try {
|
|
190236
|
+
logContent = await (0, promises_12.readFile)(this.coanaLogPath, "utf-8");
|
|
190237
|
+
} catch (e) {
|
|
190238
|
+
this.spinner.suspend(() => {
|
|
190239
|
+
console.error("Error reading log file", e);
|
|
190240
|
+
});
|
|
190241
|
+
}
|
|
190242
|
+
return logContent;
|
|
190243
|
+
}
|
|
190244
|
+
async shareErrorLogWithDashboard(e, shouldLogSharing) {
|
|
190138
190245
|
if (this.options.apiKey) {
|
|
190139
|
-
await
|
|
190140
|
-
let logContent;
|
|
190141
|
-
try {
|
|
190142
|
-
logContent = await (0, promises_12.readFile)(this.coanaLogPath, "utf-8");
|
|
190143
|
-
} catch (e2) {
|
|
190144
|
-
this.spinner.suspend(() => {
|
|
190145
|
-
console.error("Error reading log file", e2);
|
|
190146
|
-
});
|
|
190147
|
-
}
|
|
190148
|
-
await (0, dashboard_integration_1.sendErrorReportToDashboard)(this.options.apiKey, e.stack ?? e.message ?? "Unknown stack trace", shouldLogSharing, this.options.repoUrl, this.options.projectName, logContent);
|
|
190246
|
+
await (0, dashboard_integration_1.sendErrorReportToDashboard)(this.options.apiKey, e.stack ?? e.message ?? "Unknown stack trace", shouldLogSharing, this.options.repoUrl, this.options.projectName, await this.getLogContent());
|
|
190149
190247
|
}
|
|
190150
190248
|
}
|
|
190249
|
+
async shareLogWithDashboard() {
|
|
190250
|
+
if (this.options.apiKey && this.reportId)
|
|
190251
|
+
await (0, dashboard_integration_1.sendLogToDashboard)(await this.getLogContent(), this.reportId, this.options.apiKey);
|
|
190252
|
+
}
|
|
190151
190253
|
async outputAndShareReport(report) {
|
|
190152
190254
|
logger_singleton_1.logger.info("Report computed successfully");
|
|
190153
190255
|
const outputDir = this.options.outputDir;
|
|
@@ -190172,9 +190274,12 @@ var require_cli_core = __commonJS({
|
|
|
190172
190274
|
}
|
|
190173
190275
|
if (report.vulnerabilities.some((v) => v.codeAwareScanResult.type === "analysisError")) {
|
|
190174
190276
|
logger_singleton_1.logger.warn("Analysis error detected in the report - sharing log with Coana to help debug the issue");
|
|
190175
|
-
await this.
|
|
190277
|
+
await this.shareErrorLogWithDashboard(new Error("Sharing log due to analysis error"), false);
|
|
190176
190278
|
} else if (report.vulnerabilities.some((v) => v.ecosystem === "PIP")) {
|
|
190177
|
-
await this.
|
|
190279
|
+
await this.shareErrorLogWithDashboard(new Error("Sharing log file for run including a python project"), false);
|
|
190280
|
+
}
|
|
190281
|
+
if (this.options.runEnv === "MANAGED_SCAN") {
|
|
190282
|
+
this.shareLogWithDashboard();
|
|
190178
190283
|
}
|
|
190179
190284
|
if (this.options.printReport) {
|
|
190180
190285
|
logger_singleton_1.logger.info(JSON.stringify((0, lodash_1.omit)(report, "dependencyTrees"), null, 2));
|
|
@@ -190226,18 +190331,10 @@ var require_cli_core = __commonJS({
|
|
|
190226
190331
|
await this.spinner.setText(`Compiling report`);
|
|
190227
190332
|
const allVulnerabilities = workspacesOutput.flatMap(({ vulnerabilities }) => vulnerabilities);
|
|
190228
190333
|
this.spinner.stop();
|
|
190229
|
-
const dependencyTrees = workspacesOutput.map(({ subprojectPath, workspacePath, dependencyTree }) => ({
|
|
190230
|
-
treeType: "v1",
|
|
190231
|
-
dependencyTree,
|
|
190232
|
-
ecosystem: dependencyTree.ecosystem ?? "NPM",
|
|
190233
|
-
workspacePath,
|
|
190234
|
-
subprojectPath
|
|
190235
|
-
}));
|
|
190236
190334
|
const report = {
|
|
190237
|
-
reportType: "
|
|
190335
|
+
reportType: "v7",
|
|
190238
190336
|
vulnerabilities: allVulnerabilities,
|
|
190239
|
-
...await this.createMetadataForReport(manager, startTime)
|
|
190240
|
-
dependencyTrees: dependencyTrees.flat()
|
|
190337
|
+
...await this.createMetadataForReport(manager, startTime)
|
|
190241
190338
|
};
|
|
190242
190339
|
return report;
|
|
190243
190340
|
}
|
|
@@ -190365,6 +190462,19 @@ var require_cli_core = __commonJS({
|
|
|
190365
190462
|
this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", true, subprojectPath);
|
|
190366
190463
|
const projectInfo = await otherModulesCommunicator.prepareProjectAndGetProjectData(packageManagerName, subprojectPath, workspacePaths, this.options.lightweightReachability, this.options.providerProject ? await this.runOnProvider(this.options.providerProject) : void 0);
|
|
190367
190464
|
this.sendProgress("PREPARE_PROJECT_AND_GET_PROJECT_DATA", false, subprojectPath);
|
|
190465
|
+
const workspaceToPlainDependencyTree = Object.fromEntries(workspacePaths.map((workspacePath) => [
|
|
190466
|
+
workspacePath,
|
|
190467
|
+
(0, dependency_tree_1.toPlainDependencyTree)(projectInfo[workspacePath].dataForAnalysis.dependencyTree)
|
|
190468
|
+
]));
|
|
190469
|
+
const dependencyTrees = workspacePaths.map((workspacePath) => ({
|
|
190470
|
+
treeType: "v1",
|
|
190471
|
+
dependencyTree: workspaceToPlainDependencyTree[workspacePath],
|
|
190472
|
+
ecosystem: workspaceToPlainDependencyTree[workspacePath].ecosystem ?? "NPM",
|
|
190473
|
+
workspacePath,
|
|
190474
|
+
subprojectPath: (0, path_1.relative)(rootWorkingDirectory, subprojectPath) || "."
|
|
190475
|
+
}));
|
|
190476
|
+
if (this.shareWithDashboard)
|
|
190477
|
+
(0, dashboard_integration_1.sendDependencyTreesToDashboard)(dependencyTrees, this.reportId, this.options.apiKey);
|
|
190368
190478
|
const workspaceToVulnerabilities = Object.fromEntries(await (0, async_1.asyncMap)(workspacePaths, async (workspacePath) => this.spinner.wrap(`Scanning for vulnerabilities: (${subProjAndWsPath.packageManagerName}) ${(0, path_1.join)(subProjAndWsPath.subprojectPath, workspacePath)}`, async () => {
|
|
190369
190479
|
const dependencyTree = projectInfo[workspacePath].dataForAnalysis.dependencyTree;
|
|
190370
190480
|
this.sendProgress("SCAN_FOR_VULNERABILITIES", true, subprojectPath, workspacePath);
|