@vertaaux/cli 0.2.0
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/README.md +345 -0
- package/dist/auth/ci-token.d.ts +49 -0
- package/dist/auth/ci-token.d.ts.map +1 -0
- package/dist/auth/ci-token.js +83 -0
- package/dist/auth/device-flow.d.ts +66 -0
- package/dist/auth/device-flow.d.ts.map +1 -0
- package/dist/auth/device-flow.js +156 -0
- package/dist/auth/token-store.d.ts +53 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/auth/token-store.js +78 -0
- package/dist/baseline/diff.d.ts +57 -0
- package/dist/baseline/diff.d.ts.map +1 -0
- package/dist/baseline/diff.js +152 -0
- package/dist/baseline/hash.d.ts +54 -0
- package/dist/baseline/hash.d.ts.map +1 -0
- package/dist/baseline/hash.js +66 -0
- package/dist/baseline/manager.d.ts +89 -0
- package/dist/baseline/manager.d.ts.map +1 -0
- package/dist/baseline/manager.js +157 -0
- package/dist/cache/index.d.ts +8 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +7 -0
- package/dist/cache/route-cache.d.ts +119 -0
- package/dist/cache/route-cache.d.ts.map +1 -0
- package/dist/cache/route-cache.js +213 -0
- package/dist/ci/changed-routes.d.ts +95 -0
- package/dist/ci/changed-routes.d.ts.map +1 -0
- package/dist/ci/changed-routes.js +304 -0
- package/dist/ci/github-api.d.ts +68 -0
- package/dist/ci/github-api.d.ts.map +1 -0
- package/dist/ci/github-api.js +138 -0
- package/dist/ci/gitlab-api.d.ts +75 -0
- package/dist/ci/gitlab-api.d.ts.map +1 -0
- package/dist/ci/gitlab-api.js +180 -0
- package/dist/ci/index.d.ts +6 -0
- package/dist/ci/index.d.ts.map +1 -0
- package/dist/ci/index.js +4 -0
- package/dist/commands/audit.d.ts +58 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +862 -0
- package/dist/commands/baseline.d.ts +22 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +210 -0
- package/dist/commands/comment.d.ts +14 -0
- package/dist/commands/comment.d.ts.map +1 -0
- package/dist/commands/comment.js +363 -0
- package/dist/commands/diff.d.ts +24 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +196 -0
- package/dist/commands/doctor.d.ts +58 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +338 -0
- package/dist/commands/download.d.ts +12 -0
- package/dist/commands/download.d.ts.map +1 -0
- package/dist/commands/download.js +183 -0
- package/dist/commands/explain.d.ts +62 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +302 -0
- package/dist/commands/init.d.ts +12 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +212 -0
- package/dist/commands/login.d.ts +14 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +222 -0
- package/dist/commands/policy.d.ts +13 -0
- package/dist/commands/policy.d.ts.map +1 -0
- package/dist/commands/policy.js +347 -0
- package/dist/commands/upload.d.ts +12 -0
- package/dist/commands/upload.d.ts.map +1 -0
- package/dist/commands/upload.js +158 -0
- package/dist/config/defaults.d.ts +21 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +49 -0
- package/dist/config/loader.d.ts +66 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +167 -0
- package/dist/config/schema.d.ts +55 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +6 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1090 -0
- package/dist/interactive/fix-wizard.d.ts +44 -0
- package/dist/interactive/fix-wizard.d.ts.map +1 -0
- package/dist/interactive/fix-wizard.js +286 -0
- package/dist/interactive/init-wizard.d.ts +32 -0
- package/dist/interactive/init-wizard.d.ts.map +1 -0
- package/dist/interactive/init-wizard.js +193 -0
- package/dist/interactive/prompts.d.ts +62 -0
- package/dist/interactive/prompts.d.ts.map +1 -0
- package/dist/interactive/prompts.js +78 -0
- package/dist/monorepo/detector.d.ts +70 -0
- package/dist/monorepo/detector.d.ts.map +1 -0
- package/dist/monorepo/detector.js +278 -0
- package/dist/monorepo/index.d.ts +9 -0
- package/dist/monorepo/index.d.ts.map +1 -0
- package/dist/monorepo/index.js +8 -0
- package/dist/monorepo/workspace.d.ts +142 -0
- package/dist/monorepo/workspace.d.ts.map +1 -0
- package/dist/monorepo/workspace.js +171 -0
- package/dist/output/envelope.d.ts +21 -0
- package/dist/output/envelope.d.ts.map +1 -0
- package/dist/output/envelope.js +27 -0
- package/dist/output/factory.d.ts +73 -0
- package/dist/output/factory.d.ts.map +1 -0
- package/dist/output/factory.js +60 -0
- package/dist/output/formats.d.ts +11 -0
- package/dist/output/formats.d.ts.map +1 -0
- package/dist/output/formats.js +41 -0
- package/dist/output/html.d.ts +45 -0
- package/dist/output/html.d.ts.map +1 -0
- package/dist/output/html.js +607 -0
- package/dist/output/human.d.ts +41 -0
- package/dist/output/human.d.ts.map +1 -0
- package/dist/output/human.js +274 -0
- package/dist/output/json.d.ts +42 -0
- package/dist/output/json.d.ts.map +1 -0
- package/dist/output/json.js +37 -0
- package/dist/output/junit.d.ts +56 -0
- package/dist/output/junit.d.ts.map +1 -0
- package/dist/output/junit.js +135 -0
- package/dist/output/markdown.d.ts +77 -0
- package/dist/output/markdown.d.ts.map +1 -0
- package/dist/output/markdown.js +411 -0
- package/dist/output/sarif.d.ts +160 -0
- package/dist/output/sarif.d.ts.map +1 -0
- package/dist/output/sarif.js +207 -0
- package/dist/policy/evaluator.d.ts +111 -0
- package/dist/policy/evaluator.d.ts.map +1 -0
- package/dist/policy/evaluator.js +362 -0
- package/dist/policy/index.d.ts +15 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +11 -0
- package/dist/policy/loader.d.ts +97 -0
- package/dist/policy/loader.d.ts.map +1 -0
- package/dist/policy/loader.js +281 -0
- package/dist/policy/schema.d.ts +297 -0
- package/dist/policy/schema.d.ts.map +1 -0
- package/dist/policy/schema.js +230 -0
- package/dist/quality-gate/evaluator.d.ts +58 -0
- package/dist/quality-gate/evaluator.d.ts.map +1 -0
- package/dist/quality-gate/evaluator.js +274 -0
- package/dist/quality-gate/index.d.ts +10 -0
- package/dist/quality-gate/index.d.ts.map +1 -0
- package/dist/quality-gate/index.js +7 -0
- package/dist/quality-gate/types.d.ts +103 -0
- package/dist/quality-gate/types.d.ts.map +1 -0
- package/dist/quality-gate/types.js +23 -0
- package/dist/templates/azure-devops.d.ts +25 -0
- package/dist/templates/azure-devops.d.ts.map +1 -0
- package/dist/templates/azure-devops.js +109 -0
- package/dist/templates/circleci.d.ts +28 -0
- package/dist/templates/circleci.d.ts.map +1 -0
- package/dist/templates/circleci.js +86 -0
- package/dist/templates/github-actions.d.ts +81 -0
- package/dist/templates/github-actions.d.ts.map +1 -0
- package/dist/templates/github-actions.js +393 -0
- package/dist/templates/gitlab-ci.d.ts +26 -0
- package/dist/templates/gitlab-ci.d.ts.map +1 -0
- package/dist/templates/gitlab-ci.js +70 -0
- package/dist/templates/index.d.ts +72 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +112 -0
- package/dist/templates/jenkins.d.ts +26 -0
- package/dist/templates/jenkins.d.ts.map +1 -0
- package/dist/templates/jenkins.js +110 -0
- package/dist/ui/banner.d.ts +31 -0
- package/dist/ui/banner.d.ts.map +1 -0
- package/dist/ui/banner.js +84 -0
- package/dist/ui/diagnostics.d.ts +39 -0
- package/dist/ui/diagnostics.d.ts.map +1 -0
- package/dist/ui/diagnostics.js +153 -0
- package/dist/ui/spinner.d.ts +61 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +101 -0
- package/dist/ui/table.d.ts +63 -0
- package/dist/ui/table.d.ts.map +1 -0
- package/dist/ui/table.js +236 -0
- package/dist/utils/client.d.ts +82 -0
- package/dist/utils/client.d.ts.map +1 -0
- package/dist/utils/client.js +128 -0
- package/dist/utils/detect-env.d.ts +59 -0
- package/dist/utils/detect-env.d.ts.map +1 -0
- package/dist/utils/detect-env.js +115 -0
- package/dist/utils/exit-codes.d.ts +47 -0
- package/dist/utils/exit-codes.d.ts.map +1 -0
- package/dist/utils/exit-codes.js +61 -0
- package/dist/utils/logger.d.ts +87 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +185 -0
- package/dist/utils/sanitize.d.ts +36 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sanitize.js +64 -0
- package/dist/utils/validators.d.ts +41 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +123 -0
- package/package.json +63 -0
- package/schemas/vertaaux.config.schema.json +103 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/ui/table.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuCH,MAAM,WAAW,KAAK;IACpB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0CAA0C;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAqCD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAWrE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAWrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,KAAK,EAAE,EACf,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAoER;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,CAyClF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAkC1D"}
|
package/dist/ui/table.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table formatting utilities for CLI output.
|
|
3
|
+
*
|
|
4
|
+
* Uses cli-table3 for clean table rendering with severity-based coloring.
|
|
5
|
+
* Respects terminal width and provides truncation for long content.
|
|
6
|
+
*/
|
|
7
|
+
import Table from "cli-table3";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { shouldUseColor, getTerminalWidth } from "../utils/detect-env.js";
|
|
10
|
+
// Severity colors matching brand palette
|
|
11
|
+
const SEVERITY_COLORS = {
|
|
12
|
+
critical: "#FF6B6B", // Red
|
|
13
|
+
error: "#FF6B6B", // Red (alias)
|
|
14
|
+
serious: "#FFD93D", // Yellow
|
|
15
|
+
warning: "#FFD93D", // Yellow (alias)
|
|
16
|
+
minor: "#6BCEFF", // Cyan
|
|
17
|
+
moderate: "#6BCEFF", // Cyan (alias)
|
|
18
|
+
info: "#888888", // Dim gray
|
|
19
|
+
};
|
|
20
|
+
// Severity display labels
|
|
21
|
+
const SEVERITY_LABELS = {
|
|
22
|
+
critical: "CRITICAL",
|
|
23
|
+
error: "ERROR",
|
|
24
|
+
serious: "SERIOUS",
|
|
25
|
+
warning: "WARNING",
|
|
26
|
+
minor: "MINOR",
|
|
27
|
+
moderate: "MODERATE",
|
|
28
|
+
info: "INFO",
|
|
29
|
+
};
|
|
30
|
+
// Severity sort order (highest first)
|
|
31
|
+
const SEVERITY_ORDER = {
|
|
32
|
+
critical: 0,
|
|
33
|
+
error: 1,
|
|
34
|
+
serious: 2,
|
|
35
|
+
warning: 3,
|
|
36
|
+
minor: 4,
|
|
37
|
+
moderate: 5,
|
|
38
|
+
info: 6,
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Truncate text to fit within max width, adding ellipsis if truncated.
|
|
42
|
+
*/
|
|
43
|
+
function truncate(text, maxWidth) {
|
|
44
|
+
if (!text)
|
|
45
|
+
return "";
|
|
46
|
+
if (text.length <= maxWidth)
|
|
47
|
+
return text;
|
|
48
|
+
return text.slice(0, maxWidth - 3) + "...";
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get colored severity label.
|
|
52
|
+
*/
|
|
53
|
+
function colorSeverity(severity) {
|
|
54
|
+
const normalized = severity.toLowerCase();
|
|
55
|
+
const label = SEVERITY_LABELS[normalized] || severity.toUpperCase();
|
|
56
|
+
if (!shouldUseColor()) {
|
|
57
|
+
return label;
|
|
58
|
+
}
|
|
59
|
+
const color = SEVERITY_COLORS[normalized] || "#888888";
|
|
60
|
+
return chalk.hex(color).bold(label);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Sort issues by severity (highest first).
|
|
64
|
+
*/
|
|
65
|
+
function sortBySeverity(issues) {
|
|
66
|
+
return [...issues].sort((a, b) => {
|
|
67
|
+
const orderA = SEVERITY_ORDER[a.severity?.toLowerCase() || "info"] ?? 6;
|
|
68
|
+
const orderB = SEVERITY_ORDER[b.severity?.toLowerCase() || "info"] ?? 6;
|
|
69
|
+
return orderA - orderB;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Group issues by severity.
|
|
74
|
+
*/
|
|
75
|
+
export function groupBySeverity(issues) {
|
|
76
|
+
const groups = new Map();
|
|
77
|
+
for (const issue of issues) {
|
|
78
|
+
const severity = issue.severity?.toLowerCase() || "info";
|
|
79
|
+
const group = groups.get(severity) || [];
|
|
80
|
+
group.push(issue);
|
|
81
|
+
groups.set(severity, group);
|
|
82
|
+
}
|
|
83
|
+
return groups;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Group issues by category.
|
|
87
|
+
*/
|
|
88
|
+
export function groupByCategory(issues) {
|
|
89
|
+
const groups = new Map();
|
|
90
|
+
for (const issue of issues) {
|
|
91
|
+
const category = issue.category || "Uncategorized";
|
|
92
|
+
const group = groups.get(category) || [];
|
|
93
|
+
group.push(issue);
|
|
94
|
+
groups.set(category, group);
|
|
95
|
+
}
|
|
96
|
+
return groups;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Format issues into a table string.
|
|
100
|
+
*
|
|
101
|
+
* Columns: Severity | ID | Description | Selector (optional)
|
|
102
|
+
* Issues are sorted by severity (critical -> info).
|
|
103
|
+
*
|
|
104
|
+
* @param issues - Array of issues to format
|
|
105
|
+
* @param options - Formatting options
|
|
106
|
+
* @returns Formatted table string
|
|
107
|
+
*/
|
|
108
|
+
export function formatIssuesTable(issues, options = {}) {
|
|
109
|
+
if (!issues.length) {
|
|
110
|
+
return shouldUseColor()
|
|
111
|
+
? chalk.green("No issues found.")
|
|
112
|
+
: "No issues found.";
|
|
113
|
+
}
|
|
114
|
+
const termWidth = getTerminalWidth();
|
|
115
|
+
const { maxDescriptionWidth = Math.min(50, Math.floor(termWidth * 0.4)), maxSelectorWidth = Math.min(30, Math.floor(termWidth * 0.2)), showSelector = true, showCategory = false, } = options;
|
|
116
|
+
// Calculate column widths
|
|
117
|
+
const severityWidth = 10;
|
|
118
|
+
const idWidth = 20;
|
|
119
|
+
// Build header
|
|
120
|
+
const header = ["Severity", "ID", "Description"];
|
|
121
|
+
const colWidths = [severityWidth, idWidth, maxDescriptionWidth];
|
|
122
|
+
if (showCategory) {
|
|
123
|
+
header.push("Category");
|
|
124
|
+
colWidths.push(15);
|
|
125
|
+
}
|
|
126
|
+
if (showSelector) {
|
|
127
|
+
header.push("Selector");
|
|
128
|
+
colWidths.push(maxSelectorWidth);
|
|
129
|
+
}
|
|
130
|
+
const useColor = shouldUseColor();
|
|
131
|
+
const table = new Table({
|
|
132
|
+
head: useColor
|
|
133
|
+
? header.map((h) => chalk.bold(h))
|
|
134
|
+
: header,
|
|
135
|
+
colWidths,
|
|
136
|
+
style: {
|
|
137
|
+
head: useColor ? ["cyan"] : [],
|
|
138
|
+
border: useColor ? ["dim"] : [],
|
|
139
|
+
},
|
|
140
|
+
wordWrap: true,
|
|
141
|
+
});
|
|
142
|
+
// Sort and add rows
|
|
143
|
+
const sortedIssues = sortBySeverity(issues);
|
|
144
|
+
for (const issue of sortedIssues) {
|
|
145
|
+
const row = [
|
|
146
|
+
colorSeverity(issue.severity || "info"),
|
|
147
|
+
truncate(issue.id || "-", idWidth - 2),
|
|
148
|
+
truncate(issue.description || issue.title || "-", maxDescriptionWidth - 2),
|
|
149
|
+
];
|
|
150
|
+
if (showCategory) {
|
|
151
|
+
row.push(truncate(issue.category || "-", 13));
|
|
152
|
+
}
|
|
153
|
+
if (showSelector) {
|
|
154
|
+
row.push(truncate(issue.selector || "-", maxSelectorWidth - 2));
|
|
155
|
+
}
|
|
156
|
+
table.push(row);
|
|
157
|
+
}
|
|
158
|
+
return table.toString();
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Format scores into a table string.
|
|
162
|
+
*
|
|
163
|
+
* @param scores - Object mapping category names to scores
|
|
164
|
+
* @returns Formatted table string
|
|
165
|
+
*/
|
|
166
|
+
export function formatScoresTable(scores) {
|
|
167
|
+
const entries = Object.entries(scores).filter(([, value]) => typeof value === "number");
|
|
168
|
+
if (!entries.length) {
|
|
169
|
+
return shouldUseColor()
|
|
170
|
+
? chalk.dim("No scores available.")
|
|
171
|
+
: "No scores available.";
|
|
172
|
+
}
|
|
173
|
+
const useColor = shouldUseColor();
|
|
174
|
+
const table = new Table({
|
|
175
|
+
head: useColor
|
|
176
|
+
? [chalk.bold("Category"), chalk.bold("Score")]
|
|
177
|
+
: ["Category", "Score"],
|
|
178
|
+
colWidths: [20, 10],
|
|
179
|
+
style: {
|
|
180
|
+
head: useColor ? ["cyan"] : [],
|
|
181
|
+
border: useColor ? ["dim"] : [],
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
for (const [category, score] of entries) {
|
|
185
|
+
const numScore = score;
|
|
186
|
+
let scoreStr = String(numScore);
|
|
187
|
+
if (useColor) {
|
|
188
|
+
if (numScore >= 90) {
|
|
189
|
+
scoreStr = chalk.green.bold(scoreStr);
|
|
190
|
+
}
|
|
191
|
+
else if (numScore >= 70) {
|
|
192
|
+
scoreStr = chalk.yellow(scoreStr);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
scoreStr = chalk.red(scoreStr);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
table.push([category, scoreStr]);
|
|
199
|
+
}
|
|
200
|
+
return table.toString();
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Format a summary line showing issue counts by severity.
|
|
204
|
+
*
|
|
205
|
+
* @param issues - Array of issues
|
|
206
|
+
* @returns Summary string like "3 critical, 5 serious, 12 minor issues"
|
|
207
|
+
*/
|
|
208
|
+
export function formatIssueSummary(issues) {
|
|
209
|
+
const counts = {};
|
|
210
|
+
for (const issue of issues) {
|
|
211
|
+
const severity = issue.severity?.toLowerCase() || "info";
|
|
212
|
+
counts[severity] = (counts[severity] || 0) + 1;
|
|
213
|
+
}
|
|
214
|
+
const useColor = shouldUseColor();
|
|
215
|
+
const parts = [];
|
|
216
|
+
// Order: critical, serious, minor, info
|
|
217
|
+
const order = ["critical", "error", "serious", "warning", "minor", "moderate", "info"];
|
|
218
|
+
for (const severity of order) {
|
|
219
|
+
const count = counts[severity];
|
|
220
|
+
if (count) {
|
|
221
|
+
const label = count === 1 ? severity : severity;
|
|
222
|
+
const text = `${count} ${label}`;
|
|
223
|
+
if (useColor) {
|
|
224
|
+
const color = SEVERITY_COLORS[severity] || "#888888";
|
|
225
|
+
parts.push(chalk.hex(color)(text));
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
parts.push(text);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (!parts.length) {
|
|
233
|
+
return useColor ? chalk.green("No issues") : "No issues";
|
|
234
|
+
}
|
|
235
|
+
return parts.join(", ") + " issues";
|
|
236
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client utilities for VertaaUX CLI.
|
|
3
|
+
*
|
|
4
|
+
* Provides helper functions for making authenticated API requests.
|
|
5
|
+
* Handles API key resolution and error formatting.
|
|
6
|
+
*/
|
|
7
|
+
import type { VertaauxConfig } from "../config/schema.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the API base URL from various sources.
|
|
10
|
+
*
|
|
11
|
+
* Priority: flag > env > config > default
|
|
12
|
+
*
|
|
13
|
+
* @param flagBase - Base URL from command line flag
|
|
14
|
+
* @param configBase - Base URL from config file
|
|
15
|
+
* @returns Resolved API base URL (without trailing slash)
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveApiBase(flagBase?: string, configBase?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get API key from environment or config.
|
|
20
|
+
*
|
|
21
|
+
* @param configApiKey - API key from config file
|
|
22
|
+
* @returns API key string
|
|
23
|
+
* @throws Error if no API key is available
|
|
24
|
+
*/
|
|
25
|
+
export declare function getApiKey(configApiKey?: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Check if API key is available without throwing.
|
|
28
|
+
*
|
|
29
|
+
* @param config - Optional config with apiKey
|
|
30
|
+
* @returns true if API key is available
|
|
31
|
+
*/
|
|
32
|
+
export declare function hasApiKey(config?: VertaauxConfig): boolean;
|
|
33
|
+
export interface ApiRequestOptions {
|
|
34
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
35
|
+
body?: unknown;
|
|
36
|
+
headers?: Record<string, string>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Make an authenticated API request.
|
|
40
|
+
*
|
|
41
|
+
* @param base - API base URL
|
|
42
|
+
* @param path - Request path (e.g., "/audit")
|
|
43
|
+
* @param options - Request options (method, body, headers)
|
|
44
|
+
* @param apiKey - API key for authentication
|
|
45
|
+
* @returns Parsed JSON response
|
|
46
|
+
* @throws Error on HTTP errors with details
|
|
47
|
+
*/
|
|
48
|
+
export declare function apiRequest<T>(base: string, path: string, options: ApiRequestOptions, apiKey: string): Promise<T>;
|
|
49
|
+
/**
|
|
50
|
+
* Sleep for a specified duration.
|
|
51
|
+
*
|
|
52
|
+
* @param ms - Milliseconds to sleep
|
|
53
|
+
* @returns Promise that resolves after the duration
|
|
54
|
+
*/
|
|
55
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
56
|
+
export interface AuditResponse {
|
|
57
|
+
job_id?: string;
|
|
58
|
+
status?: string;
|
|
59
|
+
url?: string;
|
|
60
|
+
mode?: string;
|
|
61
|
+
progress?: number;
|
|
62
|
+
created_at?: string;
|
|
63
|
+
started_at?: string;
|
|
64
|
+
completed_at?: string;
|
|
65
|
+
scores?: Record<string, unknown>;
|
|
66
|
+
issues?: unknown;
|
|
67
|
+
error?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Wait for an audit to complete, polling at intervals.
|
|
71
|
+
*
|
|
72
|
+
* @param base - API base URL
|
|
73
|
+
* @param jobId - Audit job ID
|
|
74
|
+
* @param timeoutMs - Maximum time to wait
|
|
75
|
+
* @param intervalMs - Poll interval
|
|
76
|
+
* @param apiKey - API key for authentication
|
|
77
|
+
* @param onProgress - Optional callback for progress updates
|
|
78
|
+
* @returns Completed audit response
|
|
79
|
+
* @throws Error on timeout or failure
|
|
80
|
+
*/
|
|
81
|
+
export declare function waitForAudit(base: string, jobId: string, timeoutMs: number, intervalMs: number, apiKey: string, onProgress?: (progress: number, status: string) => void): Promise<AuditResponse>;
|
|
82
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/utils/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAI1D;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAOR;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAQvD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAE1D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,CA+BZ;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GACtD,OAAO,CAAC,aAAa,CAAC,CA2BxB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client utilities for VertaaUX CLI.
|
|
3
|
+
*
|
|
4
|
+
* Provides helper functions for making authenticated API requests.
|
|
5
|
+
* Handles API key resolution and error formatting.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_API_BASE = "https://vertaaux.ai/v1";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the API base URL from various sources.
|
|
10
|
+
*
|
|
11
|
+
* Priority: flag > env > config > default
|
|
12
|
+
*
|
|
13
|
+
* @param flagBase - Base URL from command line flag
|
|
14
|
+
* @param configBase - Base URL from config file
|
|
15
|
+
* @returns Resolved API base URL (without trailing slash)
|
|
16
|
+
*/
|
|
17
|
+
export function resolveApiBase(flagBase, configBase) {
|
|
18
|
+
const raw = flagBase ||
|
|
19
|
+
process.env.VERTAAUX_API_BASE ||
|
|
20
|
+
configBase ||
|
|
21
|
+
DEFAULT_API_BASE;
|
|
22
|
+
return raw.replace(/\/$/, "");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get API key from environment or config.
|
|
26
|
+
*
|
|
27
|
+
* @param configApiKey - API key from config file
|
|
28
|
+
* @returns API key string
|
|
29
|
+
* @throws Error if no API key is available
|
|
30
|
+
*/
|
|
31
|
+
export function getApiKey(configApiKey) {
|
|
32
|
+
const key = process.env.VERTAAUX_API_KEY || configApiKey;
|
|
33
|
+
if (!key) {
|
|
34
|
+
throw new Error("VERTAAUX_API_KEY is required. Set it via environment variable or config file.");
|
|
35
|
+
}
|
|
36
|
+
return key;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if API key is available without throwing.
|
|
40
|
+
*
|
|
41
|
+
* @param config - Optional config with apiKey
|
|
42
|
+
* @returns true if API key is available
|
|
43
|
+
*/
|
|
44
|
+
export function hasApiKey(config) {
|
|
45
|
+
return Boolean(process.env.VERTAAUX_API_KEY || config?.apiKey);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Make an authenticated API request.
|
|
49
|
+
*
|
|
50
|
+
* @param base - API base URL
|
|
51
|
+
* @param path - Request path (e.g., "/audit")
|
|
52
|
+
* @param options - Request options (method, body, headers)
|
|
53
|
+
* @param apiKey - API key for authentication
|
|
54
|
+
* @returns Parsed JSON response
|
|
55
|
+
* @throws Error on HTTP errors with details
|
|
56
|
+
*/
|
|
57
|
+
export async function apiRequest(base, path, options, apiKey) {
|
|
58
|
+
const url = `${base}${path}`;
|
|
59
|
+
const res = await fetch(url, {
|
|
60
|
+
method: options.method,
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
"X-API-Key": apiKey,
|
|
64
|
+
...options.headers,
|
|
65
|
+
},
|
|
66
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
67
|
+
});
|
|
68
|
+
if (!res.ok) {
|
|
69
|
+
let detail = res.statusText;
|
|
70
|
+
try {
|
|
71
|
+
const data = (await res.json());
|
|
72
|
+
detail =
|
|
73
|
+
(data && (data.error || data.message)) ||
|
|
74
|
+
JSON.stringify(data) ||
|
|
75
|
+
detail;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
try {
|
|
79
|
+
detail = await res.text();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// ignore
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
throw new Error(`HTTP ${res.status}: ${detail}`);
|
|
86
|
+
}
|
|
87
|
+
return (await res.json().catch(() => ({})));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Sleep for a specified duration.
|
|
91
|
+
*
|
|
92
|
+
* @param ms - Milliseconds to sleep
|
|
93
|
+
* @returns Promise that resolves after the duration
|
|
94
|
+
*/
|
|
95
|
+
export function sleep(ms) {
|
|
96
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Wait for an audit to complete, polling at intervals.
|
|
100
|
+
*
|
|
101
|
+
* @param base - API base URL
|
|
102
|
+
* @param jobId - Audit job ID
|
|
103
|
+
* @param timeoutMs - Maximum time to wait
|
|
104
|
+
* @param intervalMs - Poll interval
|
|
105
|
+
* @param apiKey - API key for authentication
|
|
106
|
+
* @param onProgress - Optional callback for progress updates
|
|
107
|
+
* @returns Completed audit response
|
|
108
|
+
* @throws Error on timeout or failure
|
|
109
|
+
*/
|
|
110
|
+
export async function waitForAudit(base, jobId, timeoutMs, intervalMs, apiKey, onProgress) {
|
|
111
|
+
const start = Date.now();
|
|
112
|
+
while (true) {
|
|
113
|
+
const status = await apiRequest(base, `/audit/${jobId}`, { method: "GET" }, apiKey);
|
|
114
|
+
// Call progress callback if provided
|
|
115
|
+
if (onProgress && typeof status.progress === "number") {
|
|
116
|
+
onProgress(status.progress, status.status || "unknown");
|
|
117
|
+
}
|
|
118
|
+
if (status.status === "completed")
|
|
119
|
+
return status;
|
|
120
|
+
if (status.status === "failed") {
|
|
121
|
+
throw new Error(status.error || `Audit ${jobId} failed`);
|
|
122
|
+
}
|
|
123
|
+
if (Date.now() - start > timeoutMs) {
|
|
124
|
+
throw new Error(`Timed out waiting for audit ${jobId}`);
|
|
125
|
+
}
|
|
126
|
+
await sleep(intervalMs);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment detection utilities for CLI.
|
|
3
|
+
*
|
|
4
|
+
* Auto-detects appropriate output format, color support, and CI environment.
|
|
5
|
+
* Follows established patterns from ci-info and terminal detection.
|
|
6
|
+
*/
|
|
7
|
+
export type OutputFormat = "json" | "sarif" | "junit" | "html" | "human";
|
|
8
|
+
/**
|
|
9
|
+
* Detect if running in a CI environment.
|
|
10
|
+
* Checks for common CI environment variables.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isCI(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Check if running in GitHub Actions.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isGitHubActions(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if running in GitLab CI.
|
|
19
|
+
*/
|
|
20
|
+
export declare function isGitLabCI(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if running in a TTY (interactive terminal).
|
|
23
|
+
*/
|
|
24
|
+
export declare function isTTY(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Check if output is being piped.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isPiped(): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Determine if colors should be used in output.
|
|
31
|
+
*
|
|
32
|
+
* Priority:
|
|
33
|
+
* 1. NO_COLOR env var (disable)
|
|
34
|
+
* 2. FORCE_COLOR env var (enable)
|
|
35
|
+
* 3. TTY detection
|
|
36
|
+
* 4. CI environment (usually disable)
|
|
37
|
+
*/
|
|
38
|
+
export declare function shouldUseColor(): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Detect the appropriate output format based on environment and explicit override.
|
|
41
|
+
*
|
|
42
|
+
* @param explicit - Explicit format override (from --format flag)
|
|
43
|
+
* @returns The resolved output format
|
|
44
|
+
*
|
|
45
|
+
* Priority:
|
|
46
|
+
* 1. Explicit format (if not "auto")
|
|
47
|
+
* 2. GitHub Actions -> sarif (CI-specific takes precedence)
|
|
48
|
+
* 3. GitLab/Jenkins/CircleCI -> junit
|
|
49
|
+
* 4. Other CI -> json
|
|
50
|
+
* 5. Piped output (non-CI) -> json
|
|
51
|
+
* 6. Interactive terminal -> human
|
|
52
|
+
*/
|
|
53
|
+
export declare function detectOutputFormat(explicit?: string): OutputFormat;
|
|
54
|
+
/**
|
|
55
|
+
* Get terminal width for formatting.
|
|
56
|
+
* Falls back to 80 columns if not detectable.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getTerminalWidth(): number;
|
|
59
|
+
//# sourceMappingURL=detect-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect-env.d.ts","sourceRoot":"","sources":["../../src/utils/detect-env.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAY9B;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,OAAO,CAE/B;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAkBxC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,CA0BlE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment detection utilities for CLI.
|
|
3
|
+
*
|
|
4
|
+
* Auto-detects appropriate output format, color support, and CI environment.
|
|
5
|
+
* Follows established patterns from ci-info and terminal detection.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Detect if running in a CI environment.
|
|
9
|
+
* Checks for common CI environment variables.
|
|
10
|
+
*/
|
|
11
|
+
export function isCI() {
|
|
12
|
+
return Boolean(process.env.CI ||
|
|
13
|
+
process.env.CONTINUOUS_INTEGRATION ||
|
|
14
|
+
process.env.BUILD_NUMBER ||
|
|
15
|
+
process.env.GITHUB_ACTIONS ||
|
|
16
|
+
process.env.GITLAB_CI ||
|
|
17
|
+
process.env.CIRCLECI ||
|
|
18
|
+
process.env.JENKINS_URL ||
|
|
19
|
+
process.env.TRAVIS ||
|
|
20
|
+
process.env.BUILDKITE);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if running in GitHub Actions.
|
|
24
|
+
*/
|
|
25
|
+
export function isGitHubActions() {
|
|
26
|
+
return Boolean(process.env.GITHUB_ACTIONS);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if running in GitLab CI.
|
|
30
|
+
*/
|
|
31
|
+
export function isGitLabCI() {
|
|
32
|
+
return Boolean(process.env.GITLAB_CI);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if running in a TTY (interactive terminal).
|
|
36
|
+
*/
|
|
37
|
+
export function isTTY() {
|
|
38
|
+
return Boolean(process.stdout.isTTY);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if output is being piped.
|
|
42
|
+
*/
|
|
43
|
+
export function isPiped() {
|
|
44
|
+
return !process.stdout.isTTY;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Determine if colors should be used in output.
|
|
48
|
+
*
|
|
49
|
+
* Priority:
|
|
50
|
+
* 1. NO_COLOR env var (disable)
|
|
51
|
+
* 2. FORCE_COLOR env var (enable)
|
|
52
|
+
* 3. TTY detection
|
|
53
|
+
* 4. CI environment (usually disable)
|
|
54
|
+
*/
|
|
55
|
+
export function shouldUseColor() {
|
|
56
|
+
// NO_COLOR takes highest priority (https://no-color.org/)
|
|
57
|
+
if (process.env.NO_COLOR !== undefined) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
// FORCE_COLOR overrides TTY detection
|
|
61
|
+
if (process.env.FORCE_COLOR !== undefined) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
// No color in CI by default
|
|
65
|
+
if (isCI()) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
// Use color if interactive TTY
|
|
69
|
+
return isTTY();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Detect the appropriate output format based on environment and explicit override.
|
|
73
|
+
*
|
|
74
|
+
* @param explicit - Explicit format override (from --format flag)
|
|
75
|
+
* @returns The resolved output format
|
|
76
|
+
*
|
|
77
|
+
* Priority:
|
|
78
|
+
* 1. Explicit format (if not "auto")
|
|
79
|
+
* 2. GitHub Actions -> sarif (CI-specific takes precedence)
|
|
80
|
+
* 3. GitLab/Jenkins/CircleCI -> junit
|
|
81
|
+
* 4. Other CI -> json
|
|
82
|
+
* 5. Piped output (non-CI) -> json
|
|
83
|
+
* 6. Interactive terminal -> human
|
|
84
|
+
*/
|
|
85
|
+
export function detectOutputFormat(explicit) {
|
|
86
|
+
// Explicit format takes precedence
|
|
87
|
+
if (explicit && explicit !== "auto") {
|
|
88
|
+
return explicit;
|
|
89
|
+
}
|
|
90
|
+
// CI environment: default to appropriate format for CI platform
|
|
91
|
+
// Check CI first because CI outputs are always piped but we want
|
|
92
|
+
// SARIF for GitHub Actions, JUnit for GitLab/Jenkins
|
|
93
|
+
if (isCI()) {
|
|
94
|
+
if (isGitHubActions()) {
|
|
95
|
+
return "sarif";
|
|
96
|
+
}
|
|
97
|
+
if (isGitLabCI() || process.env.JENKINS_URL || process.env.CIRCLECI) {
|
|
98
|
+
return "junit";
|
|
99
|
+
}
|
|
100
|
+
return "json";
|
|
101
|
+
}
|
|
102
|
+
// Piped output (non-CI): use JSON for machine parsing
|
|
103
|
+
if (isPiped()) {
|
|
104
|
+
return "json";
|
|
105
|
+
}
|
|
106
|
+
// Interactive terminal: human-readable
|
|
107
|
+
return "human";
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get terminal width for formatting.
|
|
111
|
+
* Falls back to 80 columns if not detectable.
|
|
112
|
+
*/
|
|
113
|
+
export function getTerminalWidth() {
|
|
114
|
+
return process.stdout.columns || 80;
|
|
115
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic exit codes for CLI commands (CLI-12).
|
|
3
|
+
*
|
|
4
|
+
* CI tools depend on exit codes for gating decisions.
|
|
5
|
+
* These codes allow distinguishing between:
|
|
6
|
+
* - Success (no issues)
|
|
7
|
+
* - Issues found (but not necessarily a failure)
|
|
8
|
+
* - Runtime errors
|
|
9
|
+
* - Threshold/score failures
|
|
10
|
+
*/
|
|
11
|
+
export declare const ExitCode: {
|
|
12
|
+
/** Audit passed, no issues above threshold */
|
|
13
|
+
readonly SUCCESS: 0;
|
|
14
|
+
/** Issues found at or above specified severity */
|
|
15
|
+
readonly ISSUES_FOUND: 1;
|
|
16
|
+
/** Runtime error, invalid input, network failure */
|
|
17
|
+
readonly ERROR: 2;
|
|
18
|
+
/** Score below threshold */
|
|
19
|
+
readonly THRESHOLD_BREACH: 3;
|
|
20
|
+
};
|
|
21
|
+
export type ExitCodeType = (typeof ExitCode)[keyof typeof ExitCode];
|
|
22
|
+
export interface AuditResultForExitCode {
|
|
23
|
+
error?: unknown;
|
|
24
|
+
scores?: {
|
|
25
|
+
overall?: number;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
};
|
|
28
|
+
issues?: Array<{
|
|
29
|
+
severity?: string;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
export interface ExitCodeOptions {
|
|
34
|
+
/** Minimum score threshold (0-100) */
|
|
35
|
+
threshold?: number;
|
|
36
|
+
/** Fail if issues at or above this severity */
|
|
37
|
+
failOn?: "error" | "warning" | "info";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Determine the appropriate exit code based on audit results and options.
|
|
41
|
+
*
|
|
42
|
+
* @param result - The audit result
|
|
43
|
+
* @param options - Exit code determination options
|
|
44
|
+
* @returns The semantic exit code
|
|
45
|
+
*/
|
|
46
|
+
export declare function determineExitCode(result: AuditResultForExitCode, options?: ExitCodeOptions): ExitCodeType;
|
|
47
|
+
//# sourceMappingURL=exit-codes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../../src/utils/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,eAAO,MAAM,QAAQ;IACnB,8CAA8C;;IAE9C,kDAAkD;;IAElD,oDAAoD;;IAEpD,4BAA4B;;CAEpB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAiBpE,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;CACvC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,sBAAsB,EAC9B,OAAO,GAAE,eAAoB,GAC5B,YAAY,CA4Bd"}
|