cloudburn 0.8.0 → 0.8.2
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 +2 -2
- package/dist/cli.js +116 -12
- package/package.json +2 -2
package/README.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -528,6 +528,9 @@ var flattenScanResult = (result) => result.providers.flatMap(
|
|
|
528
528
|
var countScanResultFindings = (result) => flattenScanResult(result).length;
|
|
529
529
|
|
|
530
530
|
// src/formatters/output.ts
|
|
531
|
+
var DEFAULT_TABLE_WIDTH = 200;
|
|
532
|
+
var MIN_COLUMN_WIDTH = 4;
|
|
533
|
+
var PREFERRED_MIN_COLUMN_WIDTH = 8;
|
|
531
534
|
var supportedOutputFormats = ["text", "json", "table"];
|
|
532
535
|
var scanColumns = [
|
|
533
536
|
{ key: "provider", header: "Provider" },
|
|
@@ -538,8 +541,8 @@ var scanColumns = [
|
|
|
538
541
|
{ key: "accountId", header: "AccountId" },
|
|
539
542
|
{ key: "region", header: "Region" },
|
|
540
543
|
{ key: "path", header: "Path" },
|
|
541
|
-
{ key: "
|
|
542
|
-
{ key: "
|
|
544
|
+
{ key: "line", header: "Line" },
|
|
545
|
+
{ key: "column", header: "Column" },
|
|
543
546
|
{ key: "message", header: "Message" }
|
|
544
547
|
];
|
|
545
548
|
var formatOptionDescription = "Options: table: human-readable terminal output.\ntext: tab-delimited output for grep, sed, and awk.\njson: machine-readable output for automation and downstream systems.";
|
|
@@ -645,8 +648,8 @@ var projectScanRows = (result) => flattenScanResult(result).map(({ finding, mess
|
|
|
645
648
|
ruleId,
|
|
646
649
|
service,
|
|
647
650
|
source,
|
|
648
|
-
|
|
649
|
-
|
|
651
|
+
column: finding.location?.column ?? "",
|
|
652
|
+
line: finding.location?.line ?? ""
|
|
650
653
|
}));
|
|
651
654
|
var renderTextRows = (rows, columns, emptyMessage) => {
|
|
652
655
|
if (rows.length === 0) {
|
|
@@ -694,17 +697,118 @@ var toTextCell = (value) => {
|
|
|
694
697
|
}
|
|
695
698
|
return JSON.stringify(value);
|
|
696
699
|
};
|
|
697
|
-
var toTableCell = (value) =>
|
|
698
|
-
|
|
699
|
-
|
|
700
|
+
var toTableCell = (value) => {
|
|
701
|
+
if (Array.isArray(value)) {
|
|
702
|
+
return value.map((item) => toTextCell(item)).join(", ").replace(/\r?\n/g, "\\n");
|
|
703
|
+
}
|
|
704
|
+
return toTextCell(value).replace(/\r?\n/g, "\\n");
|
|
705
|
+
};
|
|
706
|
+
var resolveTableColumns = (rows, columns) => {
|
|
707
|
+
const visibleColumns = columns.filter((column) => rows.some((row) => toTableCell(row[column.key]).length > 0));
|
|
708
|
+
return visibleColumns.length === 0 ? columns : visibleColumns;
|
|
709
|
+
};
|
|
710
|
+
var getTargetTableWidth = () => {
|
|
711
|
+
const terminalWidth = process.stdout.columns;
|
|
712
|
+
return typeof terminalWidth === "number" && Number.isFinite(terminalWidth) && terminalWidth > 0 ? terminalWidth : DEFAULT_TABLE_WIDTH;
|
|
713
|
+
};
|
|
714
|
+
var measureTableWidth = (widths) => widths.reduce((total, width) => total + width, 0) + widths.length * 3 + 1;
|
|
715
|
+
var fitColumnWidths = (columns, rows) => {
|
|
716
|
+
const maxWidths = columns.map(
|
|
700
717
|
(column) => Math.max(column.header.length, ...rows.map((row) => toTableCell(row[column.key]).length))
|
|
701
718
|
);
|
|
719
|
+
const minWidths = columns.map(
|
|
720
|
+
(column, index) => Math.min(
|
|
721
|
+
maxWidths[index] ?? MIN_COLUMN_WIDTH,
|
|
722
|
+
Math.max(MIN_COLUMN_WIDTH, Math.min(column.header.length, PREFERRED_MIN_COLUMN_WIDTH))
|
|
723
|
+
)
|
|
724
|
+
);
|
|
725
|
+
const widths = [...maxWidths];
|
|
726
|
+
const targetWidth = getTargetTableWidth();
|
|
727
|
+
while (measureTableWidth(widths) > targetWidth) {
|
|
728
|
+
let widestColumnIndex = -1;
|
|
729
|
+
for (let index = 0; index < widths.length; index += 1) {
|
|
730
|
+
if ((widths[index] ?? 0) <= (minWidths[index] ?? MIN_COLUMN_WIDTH)) {
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
if (widestColumnIndex === -1 || (widths[index] ?? 0) > (widths[widestColumnIndex] ?? 0)) {
|
|
734
|
+
widestColumnIndex = index;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
if (widestColumnIndex === -1) {
|
|
738
|
+
break;
|
|
739
|
+
}
|
|
740
|
+
widths[widestColumnIndex] = Math.max(MIN_COLUMN_WIDTH, (widths[widestColumnIndex] ?? MIN_COLUMN_WIDTH) - 1);
|
|
741
|
+
}
|
|
742
|
+
return widths;
|
|
743
|
+
};
|
|
744
|
+
var wrapToken = (token, width) => {
|
|
745
|
+
if (token.length <= width) {
|
|
746
|
+
return [token];
|
|
747
|
+
}
|
|
748
|
+
const segments = [];
|
|
749
|
+
for (let start = 0; start < token.length; start += width) {
|
|
750
|
+
segments.push(token.slice(start, start + width));
|
|
751
|
+
}
|
|
752
|
+
return segments;
|
|
753
|
+
};
|
|
754
|
+
var wrapCell = (value, width) => {
|
|
755
|
+
if (value.length <= width) {
|
|
756
|
+
return [value];
|
|
757
|
+
}
|
|
758
|
+
const words = value.split(/\s+/).filter((word) => word.length > 0);
|
|
759
|
+
if (words.length === 0) {
|
|
760
|
+
return [""];
|
|
761
|
+
}
|
|
762
|
+
const lines = [];
|
|
763
|
+
let currentLine = "";
|
|
764
|
+
for (const word of words) {
|
|
765
|
+
if (word.length > width) {
|
|
766
|
+
if (currentLine.length > 0) {
|
|
767
|
+
lines.push(currentLine);
|
|
768
|
+
currentLine = "";
|
|
769
|
+
}
|
|
770
|
+
lines.push(...wrapToken(word, width));
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
if (currentLine.length === 0) {
|
|
774
|
+
currentLine = word;
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
if (currentLine.length + 1 + word.length <= width) {
|
|
778
|
+
currentLine = `${currentLine} ${word}`;
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
lines.push(currentLine);
|
|
782
|
+
currentLine = word;
|
|
783
|
+
}
|
|
784
|
+
if (currentLine.length > 0) {
|
|
785
|
+
lines.push(currentLine);
|
|
786
|
+
}
|
|
787
|
+
return lines;
|
|
788
|
+
};
|
|
789
|
+
var renderTableLines = (cells, widths) => {
|
|
790
|
+
const wrappedCells = cells.map((cell, index) => wrapCell(cell, widths[index] ?? MIN_COLUMN_WIDTH));
|
|
791
|
+
const height = Math.max(...wrappedCells.map((lines) => lines.length));
|
|
792
|
+
return Array.from({ length: height }, (_, lineIndex) => {
|
|
793
|
+
const line = wrappedCells.map((lines, index) => (lines[lineIndex] ?? "").padEnd(widths[index] ?? MIN_COLUMN_WIDTH)).join(" | ");
|
|
794
|
+
return `| ${line} |`;
|
|
795
|
+
});
|
|
796
|
+
};
|
|
797
|
+
var renderAsciiTable = (rows, columns) => {
|
|
798
|
+
const visibleColumns = resolveTableColumns(rows, columns);
|
|
799
|
+
const widths = fitColumnWidths(visibleColumns, rows);
|
|
702
800
|
const border = `+${widths.map((width) => "-".repeat(width + 2)).join("+")}+`;
|
|
703
|
-
const header =
|
|
704
|
-
|
|
705
|
-
|
|
801
|
+
const header = renderTableLines(
|
|
802
|
+
visibleColumns.map((column) => column.header),
|
|
803
|
+
widths
|
|
804
|
+
);
|
|
805
|
+
const body = rows.flatMap(
|
|
806
|
+
(row) => renderTableLines(
|
|
807
|
+
visibleColumns.map((column) => toTableCell(row[column.key])),
|
|
808
|
+
widths
|
|
809
|
+
)
|
|
706
810
|
);
|
|
707
|
-
return [border, header, border, ...body, border].join("\n");
|
|
811
|
+
return [border, ...header, border, ...body, border].join("\n");
|
|
708
812
|
};
|
|
709
813
|
|
|
710
814
|
// src/commands/config-options.ts
|
|
@@ -1070,7 +1174,7 @@ var registerScanCommand = (program) => {
|
|
|
1070
1174
|
// src/cli.ts
|
|
1071
1175
|
var createProgram = () => {
|
|
1072
1176
|
const program = createCliCommand();
|
|
1073
|
-
program.name("cloudburn").usage("[command]").description("Know what you spend. Fix what you waste.").version("0.8.
|
|
1177
|
+
program.name("cloudburn").usage("[command]").description("Know what you spend. Fix what you waste.").version("0.8.2").option("--format <format>", OUTPUT_FORMAT_OPTION_DESCRIPTION, parseOutputFormat);
|
|
1074
1178
|
configureCliHelp(program);
|
|
1075
1179
|
registerCompletionCommand(program);
|
|
1076
1180
|
registerDiscoverCommand(program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudburn",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Cloudburn CLI for cloud cost optimization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"commander": "^13.1.0",
|
|
14
|
-
"@cloudburn/sdk": "0.
|
|
14
|
+
"@cloudburn/sdk": "0.13.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"@biomejs/biome": "^2.4.6",
|