@seedcord/utils 0.6.1 → 0.7.0-next.1
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/LICENSE +1 -1
- package/README.md +5 -2
- package/dist/index.cjs +368 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +174 -6
- package/dist/index.mjs +368 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/LICENSE
CHANGED
|
@@ -175,7 +175,7 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
|
175
175
|
|
|
176
176
|
END OF TERMS AND CONDITIONS
|
|
177
177
|
|
|
178
|
-
Copyright
|
|
178
|
+
Copyright 2026 Dhruv Jain (materwelonDhruv)
|
|
179
179
|
|
|
180
180
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
181
|
you may not use this file except in compliance with the License.
|
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://cdn.seedcord.org/assets/wordmark-dark.webp" />
|
|
4
|
+
<img src="https://cdn.seedcord.org/assets/wordmark-light.webp" alt="seedcord" width="440" />
|
|
5
|
+
</picture>
|
|
3
6
|
</p>
|
|
4
7
|
|
|
5
8
|
---
|
|
@@ -7,7 +10,7 @@
|
|
|
7
10
|
_This repository is a work in progress._
|
|
8
11
|
|
|
9
12
|
- There are no stable releases yet but changes are being made actively.
|
|
10
|
-
-
|
|
13
|
+
- Until a major v1.0.0 release for seedcord, expect breaking changes in minor versions.
|
|
11
14
|
- Documentation will come soon as well!
|
|
12
15
|
|
|
13
16
|
If you'd like to try it out, you can check out the code in `mock`
|
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,19 @@ node_path = __toESM(node_path, 1);
|
|
|
35
35
|
* Exhaustiveness guard for discriminated unions. Place in the `default` branch of a `switch` over a
|
|
36
36
|
* union's discriminant: if a new variant is added without a matching case, the call fails to compile.
|
|
37
37
|
* Throws at runtime if reached with a value the types said was impossible.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* type Shape = { kind: 'circle' } | { kind: 'square' };
|
|
42
|
+
*
|
|
43
|
+
* function area(shape: Shape): number {
|
|
44
|
+
* switch (shape.kind) {
|
|
45
|
+
* case 'circle': return Math.PI;
|
|
46
|
+
* case 'square': return 1;
|
|
47
|
+
* default: return assertNever(shape); // compile error if a Shape variant is added
|
|
48
|
+
* }
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
38
51
|
*/
|
|
39
52
|
function assertNever(value) {
|
|
40
53
|
throw new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);
|
|
@@ -57,6 +70,17 @@ function isTsOrJsFile(entry) {
|
|
|
57
70
|
* @param dir - The directory path to traverse.
|
|
58
71
|
* @param callback - A function that will be called for each imported module. It receives the full file path, the file's relative path, and the imported module as arguments.
|
|
59
72
|
* @returns A Promise that resolves when the traversal is complete.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* await traverseDirectory(
|
|
77
|
+
* './commands',
|
|
78
|
+
* (fullPath, relativePath, imported) => {
|
|
79
|
+
* for (const exported of Object.values(imported)) register(exported);
|
|
80
|
+
* },
|
|
81
|
+
* logger
|
|
82
|
+
* );
|
|
83
|
+
* ```
|
|
60
84
|
*/
|
|
61
85
|
async function traverseDirectory(dir, callback, logger) {
|
|
62
86
|
let entries;
|
|
@@ -78,6 +102,14 @@ async function traverseDirectory(dir, callback, logger) {
|
|
|
78
102
|
* @param filePath - The file path to format.
|
|
79
103
|
* @param options - Formatting options.
|
|
80
104
|
* @returns The formatted file path.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* // cwd is /repo
|
|
109
|
+
* formatFilePath('/repo/src/Bot.ts'); // './src/Bot.ts'
|
|
110
|
+
* formatFilePath('/repo/src/Bot.ts', { onlyDir: true }); // './src'
|
|
111
|
+
* formatFilePath('/repo/src/Bot.ts', { prefix: '' }); // 'src/Bot.ts'
|
|
112
|
+
* ```
|
|
81
113
|
*/
|
|
82
114
|
function formatFilePath(filePath, options = {}) {
|
|
83
115
|
const { onlyDir = false, prefix = "./" } = options;
|
|
@@ -133,6 +165,11 @@ function currentTime() {
|
|
|
133
165
|
*
|
|
134
166
|
* @param digits - The number of digits for the generated code.
|
|
135
167
|
* @returns A random numeric code with the specified number of digits.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* generateCode(6); // e.g. 482915
|
|
172
|
+
* ```
|
|
136
173
|
*/
|
|
137
174
|
function generateCode(digits) {
|
|
138
175
|
const min = Math.pow(10, digits - 1);
|
|
@@ -186,6 +223,14 @@ const DURATION_PATTERN = new RegExp(`^(\\d+)(${Object.keys(UNIT_MS).join("|")})$
|
|
|
186
223
|
*
|
|
187
224
|
* @param input - The duration string to parse.
|
|
188
225
|
* @returns The duration in milliseconds, or `null` if `input` is not a well-formed positive duration.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```ts
|
|
229
|
+
* parseDuration('24h'); // 86400000
|
|
230
|
+
* parseDuration('30m'); // 1800000
|
|
231
|
+
* parseDuration('1.5h'); // null
|
|
232
|
+
* parseDuration('foo'); // null
|
|
233
|
+
* ```
|
|
189
234
|
*/
|
|
190
235
|
function parseDuration(input) {
|
|
191
236
|
const match = DURATION_PATTERN.exec(input);
|
|
@@ -203,6 +248,12 @@ function parseDuration(input) {
|
|
|
203
248
|
* @param num2 - The second number.
|
|
204
249
|
*
|
|
205
250
|
* @returns The percentage of the first number in the second number with two decimal places.
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* percentage(25, 200); // 12.5
|
|
255
|
+
* percentage(1, 3); // 33.33
|
|
256
|
+
* ```
|
|
206
257
|
*/
|
|
207
258
|
function percentage(num1, num2) {
|
|
208
259
|
return Number((num1 / num2 * 100).toFixed(2));
|
|
@@ -216,6 +267,12 @@ function percentage(num1, num2) {
|
|
|
216
267
|
* @param num - The number to be rounded.
|
|
217
268
|
* @param precision - The number of decimal places to round to.
|
|
218
269
|
* @returns The rounded number.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* ```ts
|
|
273
|
+
* round(3.14159, 2); // 3.14
|
|
274
|
+
* round(2.5, 0); // 3
|
|
275
|
+
* ```
|
|
219
276
|
*/
|
|
220
277
|
function round(num, precision) {
|
|
221
278
|
const factor = Math.pow(10, precision);
|
|
@@ -459,6 +516,11 @@ function keepDefined(source, ...keys) {
|
|
|
459
516
|
* Returns the word with its first letter capitalized and the rest in lowercase.
|
|
460
517
|
* @param word - The word to be formatted.
|
|
461
518
|
* @returns The formatted word.
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```ts
|
|
522
|
+
* capitalize('hELLO'); // 'Hello'
|
|
523
|
+
* ```
|
|
462
524
|
*/
|
|
463
525
|
function capitalize(word) {
|
|
464
526
|
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
@@ -471,55 +533,320 @@ function capitalize(word) {
|
|
|
471
533
|
*
|
|
472
534
|
* @param arr - The array of strings or numbers
|
|
473
535
|
* @returns The length of the longest element when converted to string
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```ts
|
|
539
|
+
* longestStringLength(['ab', 12345]); // 5
|
|
540
|
+
* ```
|
|
474
541
|
*/
|
|
475
542
|
function longestStringLength(arr) {
|
|
476
543
|
return Math.max(...arr.map((el) => el.toString().length));
|
|
477
544
|
}
|
|
478
545
|
|
|
479
546
|
//#endregion
|
|
480
|
-
//#region src/strings/
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
547
|
+
//#region src/strings/renderTable/borders.ts
|
|
548
|
+
const DOUBLE = {
|
|
549
|
+
top: {
|
|
550
|
+
left: "╔",
|
|
551
|
+
mid: "╦",
|
|
552
|
+
right: "╗",
|
|
553
|
+
fill: "═"
|
|
554
|
+
},
|
|
555
|
+
bottom: {
|
|
556
|
+
left: "╚",
|
|
557
|
+
mid: "╩",
|
|
558
|
+
right: "╝",
|
|
559
|
+
fill: "═"
|
|
560
|
+
},
|
|
561
|
+
sep: {
|
|
562
|
+
left: "╟",
|
|
563
|
+
mid: "╫",
|
|
564
|
+
right: "╢",
|
|
565
|
+
fill: "─"
|
|
566
|
+
},
|
|
567
|
+
headerSep: {
|
|
568
|
+
left: "╠",
|
|
569
|
+
mid: "╬",
|
|
570
|
+
right: "╣",
|
|
571
|
+
fill: "═"
|
|
572
|
+
},
|
|
573
|
+
vertical: "║"
|
|
574
|
+
};
|
|
575
|
+
const ROUNDED = {
|
|
576
|
+
top: {
|
|
577
|
+
left: "╭",
|
|
578
|
+
mid: "┬",
|
|
579
|
+
right: "╮",
|
|
580
|
+
fill: "─"
|
|
581
|
+
},
|
|
582
|
+
bottom: {
|
|
583
|
+
left: "╰",
|
|
584
|
+
mid: "┴",
|
|
585
|
+
right: "╯",
|
|
586
|
+
fill: "─"
|
|
587
|
+
},
|
|
588
|
+
sep: {
|
|
589
|
+
left: "├",
|
|
590
|
+
mid: "┼",
|
|
591
|
+
right: "┤",
|
|
592
|
+
fill: "─"
|
|
593
|
+
},
|
|
594
|
+
headerSep: {
|
|
595
|
+
left: "├",
|
|
596
|
+
mid: "┼",
|
|
597
|
+
right: "┤",
|
|
598
|
+
fill: "─"
|
|
599
|
+
},
|
|
600
|
+
vertical: "│"
|
|
601
|
+
};
|
|
602
|
+
const ASCII = {
|
|
603
|
+
top: {
|
|
604
|
+
left: "+",
|
|
605
|
+
mid: "+",
|
|
606
|
+
right: "+",
|
|
607
|
+
fill: "-"
|
|
608
|
+
},
|
|
609
|
+
bottom: {
|
|
610
|
+
left: "+",
|
|
611
|
+
mid: "+",
|
|
612
|
+
right: "+",
|
|
613
|
+
fill: "-"
|
|
614
|
+
},
|
|
615
|
+
sep: {
|
|
616
|
+
left: "+",
|
|
617
|
+
mid: "+",
|
|
618
|
+
right: "+",
|
|
619
|
+
fill: "-"
|
|
620
|
+
},
|
|
621
|
+
headerSep: {
|
|
622
|
+
left: "+",
|
|
623
|
+
mid: "+",
|
|
624
|
+
right: "+",
|
|
625
|
+
fill: "-"
|
|
626
|
+
},
|
|
627
|
+
vertical: "|"
|
|
628
|
+
};
|
|
629
|
+
const BORDERS = {
|
|
630
|
+
double: DOUBLE,
|
|
631
|
+
rounded: ROUNDED,
|
|
632
|
+
ascii: ASCII
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
//#endregion
|
|
636
|
+
//#region src/strings/renderTable/displayWidth.ts
|
|
637
|
+
const segmenter = new Intl.Segmenter();
|
|
638
|
+
const ZERO_WIDTH_RANGES = [
|
|
639
|
+
[8203, 8203],
|
|
640
|
+
[768, 879],
|
|
641
|
+
[6832, 6911],
|
|
642
|
+
[7616, 7679],
|
|
643
|
+
[8400, 8447],
|
|
644
|
+
[65056, 65071]
|
|
645
|
+
];
|
|
646
|
+
const WIDE_RANGES = [
|
|
647
|
+
[4352, 4447],
|
|
648
|
+
[11904, 12350],
|
|
649
|
+
[12353, 13311],
|
|
650
|
+
[13312, 19903],
|
|
651
|
+
[19968, 40959],
|
|
652
|
+
[40960, 42191],
|
|
653
|
+
[44032, 55203],
|
|
654
|
+
[63744, 64255],
|
|
655
|
+
[65072, 65103],
|
|
656
|
+
[65280, 65376],
|
|
657
|
+
[65504, 65510],
|
|
658
|
+
[127744, 129791],
|
|
659
|
+
[131072, 262141]
|
|
660
|
+
];
|
|
661
|
+
function inRanges(cp, ranges) {
|
|
662
|
+
return ranges.some(([lo, hi]) => cp >= lo && cp <= hi);
|
|
663
|
+
}
|
|
664
|
+
function segmentWidth(segment) {
|
|
665
|
+
const cp = segment.codePointAt(0) ?? 0;
|
|
666
|
+
if (inRanges(cp, ZERO_WIDTH_RANGES)) return 0;
|
|
667
|
+
return inRanges(cp, WIDE_RANGES) ? 2 : 1;
|
|
668
|
+
}
|
|
669
|
+
function displayWidth(text) {
|
|
670
|
+
let width = 0;
|
|
671
|
+
for (const { segment } of segmenter.segment(text)) width += segmentWidth(segment);
|
|
672
|
+
return width;
|
|
673
|
+
}
|
|
674
|
+
function segments(text) {
|
|
675
|
+
return Array.from(segmenter.segment(text), (entry) => entry.segment);
|
|
676
|
+
}
|
|
677
|
+
function takeWidth(text, maxColumns) {
|
|
678
|
+
let width = 0;
|
|
679
|
+
let taken = "";
|
|
680
|
+
for (const segment of segments(text)) {
|
|
681
|
+
const next = width + segmentWidth(segment);
|
|
682
|
+
if (next > maxColumns) break;
|
|
683
|
+
width = next;
|
|
684
|
+
taken += segment;
|
|
685
|
+
}
|
|
686
|
+
return taken;
|
|
687
|
+
}
|
|
688
|
+
function hardBreak(token, maxColumns) {
|
|
689
|
+
const pieces = [];
|
|
690
|
+
let rest = token;
|
|
691
|
+
while (displayWidth(rest) > maxColumns) {
|
|
692
|
+
const head = takeWidth(rest, maxColumns);
|
|
693
|
+
pieces.push(head);
|
|
694
|
+
rest = rest.slice(head.length);
|
|
695
|
+
}
|
|
696
|
+
if (rest.length > 0) pieces.push(rest);
|
|
697
|
+
return pieces;
|
|
698
|
+
}
|
|
699
|
+
function wrapText(text, maxColumns) {
|
|
700
|
+
const lines = [];
|
|
701
|
+
let current = "";
|
|
702
|
+
for (const token of text.split(" ")) {
|
|
703
|
+
const candidate = current === "" ? token : `${current} ${token}`;
|
|
704
|
+
if (displayWidth(candidate) <= maxColumns) {
|
|
705
|
+
current = candidate;
|
|
706
|
+
continue;
|
|
707
|
+
}
|
|
708
|
+
if (current !== "") lines.push(current);
|
|
709
|
+
if (displayWidth(token) <= maxColumns) {
|
|
710
|
+
current = token;
|
|
711
|
+
continue;
|
|
498
712
|
}
|
|
499
|
-
|
|
713
|
+
const pieces = hardBreak(token, maxColumns);
|
|
714
|
+
current = pieces.pop() ?? "";
|
|
715
|
+
lines.push(...pieces);
|
|
500
716
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
717
|
+
if (current !== "" || lines.length === 0) lines.push(current);
|
|
718
|
+
return lines;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
//#endregion
|
|
722
|
+
//#region src/strings/renderTable/cells.ts
|
|
723
|
+
const ELLIPSIS = "…";
|
|
724
|
+
function wrapFence(content) {
|
|
725
|
+
return `\`\`\`\n${content}\`\`\``;
|
|
726
|
+
}
|
|
727
|
+
function truncate(content, maxWidth) {
|
|
728
|
+
if (displayWidth(content) <= maxWidth) return content;
|
|
729
|
+
return takeWidth(content, maxWidth - displayWidth(ELLIPSIS)) + ELLIPSIS;
|
|
730
|
+
}
|
|
731
|
+
function isNumericColumn(grid, col, header) {
|
|
732
|
+
const cells = (header ? grid.slice(1) : grid).map((row) => row[col] ?? "").filter((cell) => cell !== "");
|
|
733
|
+
return cells.length > 0 && cells.every((cell) => !Number.isNaN(Number(cell)));
|
|
734
|
+
}
|
|
735
|
+
function padCell(content, columnWidth, align) {
|
|
736
|
+
const slack = columnWidth - displayWidth(content);
|
|
737
|
+
if (align === "right") return " ".repeat(slack) + content;
|
|
738
|
+
if (align === "center") {
|
|
739
|
+
const left = Math.floor(slack / 2);
|
|
740
|
+
return " ".repeat(left) + content + " ".repeat(slack - left);
|
|
741
|
+
}
|
|
742
|
+
return content + " ".repeat(slack);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
//#endregion
|
|
746
|
+
//#region src/strings/renderTable/markdown.ts
|
|
747
|
+
function renderMarkdown(grid, columnCount, alignments, pad) {
|
|
748
|
+
const escapeCell = (value) => value.replace(/\\/g, "\\\\").replace(/\|/g, "\\|");
|
|
749
|
+
const escaped = grid.map((row) => Array.from({ length: columnCount }, (_, col) => escapeCell(row[col] ?? "")));
|
|
750
|
+
const columnWidths = Array.from({ length: columnCount }, (_, col) => escaped.reduce((max, row) => Math.max(max, displayWidth(row[col] ?? "")), 0));
|
|
751
|
+
const cell = (content, col) => pad + padCell(content, columnWidths[col] ?? 0, alignments[col] ?? "left") + pad;
|
|
752
|
+
const row = (cells) => `|${columnWidths.map((_, col) => cell(cells[col] ?? "", col)).join("|")}|`;
|
|
753
|
+
const delimiterCell = (col) => {
|
|
754
|
+
const align = alignments[col] ?? "left";
|
|
755
|
+
if (align === "center") return " :---: ";
|
|
756
|
+
if (align === "right") return " ---: ";
|
|
757
|
+
return " --- ";
|
|
510
758
|
};
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
row
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
759
|
+
const [head = [], ...body] = escaped;
|
|
760
|
+
const delimiter = `|${columnWidths.map((_, col) => delimiterCell(col)).join("|")}|`;
|
|
761
|
+
return `${[
|
|
762
|
+
row(head),
|
|
763
|
+
delimiter,
|
|
764
|
+
...body.map(row)
|
|
765
|
+
].join("\n")}\n`;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
//#endregion
|
|
769
|
+
//#region src/strings/renderTable/renderSingle.ts
|
|
770
|
+
function renderSingle(data, options) {
|
|
771
|
+
if (data.length === 0) return "";
|
|
772
|
+
const { align, border = "rounded", header = true, padding = 1, emptyCell = "", numericAlign = false, maxWidth, overflow = "wrap", fence } = options ?? {};
|
|
773
|
+
const columnCount = data.reduce((max, row) => Math.max(max, row.length), 0);
|
|
774
|
+
if (columnCount === 0) return "";
|
|
775
|
+
const grid = data.map((row) => Array.from({ length: columnCount }, (_, i) => {
|
|
776
|
+
const cell = (row[i] ?? "").replace(/\r?\n/g, " ");
|
|
777
|
+
const filled = cell === "" ? emptyCell : cell;
|
|
778
|
+
if (maxWidth === void 0 || overflow !== "truncate") return filled;
|
|
779
|
+
return truncate(filled, maxWidth);
|
|
780
|
+
}));
|
|
781
|
+
const alignments = Array.from({ length: columnCount }, (_, col) => {
|
|
782
|
+
const explicit = typeof align === "string" ? align : align?.[col];
|
|
783
|
+
if (explicit) return explicit;
|
|
784
|
+
if (numericAlign && isNumericColumn(grid, col, header)) return "right";
|
|
785
|
+
return "left";
|
|
521
786
|
});
|
|
522
|
-
|
|
787
|
+
const pad = " ".repeat(padding);
|
|
788
|
+
if (border === "markdown") {
|
|
789
|
+
const md = renderMarkdown(grid, columnCount, alignments, pad);
|
|
790
|
+
return fence ? wrapFence(md) : md;
|
|
791
|
+
}
|
|
792
|
+
const wrap = maxWidth !== void 0 && overflow === "wrap";
|
|
793
|
+
const rows = grid.map((row) => row.map((cell) => wrap ? wrapText(cell, maxWidth) : [cell]));
|
|
794
|
+
const columnWidths = Array.from({ length: columnCount }, (_, col) => rows.reduce((max, row) => Math.max(max, (row[col] ?? []).reduce((w, line) => Math.max(w, displayWidth(line)), 0)), 0));
|
|
795
|
+
const chars = BORDERS[border];
|
|
796
|
+
function drawLine(part) {
|
|
797
|
+
const segments = columnWidths.map((width) => part.fill.repeat(width + padding * 2));
|
|
798
|
+
return part.left + segments.join(part.mid) + part.right;
|
|
799
|
+
}
|
|
800
|
+
function renderRow(row) {
|
|
801
|
+
const lineCount = row.reduce((max, cellLines) => Math.max(max, cellLines.length), 1);
|
|
802
|
+
return Array.from({ length: lineCount }, (_, line) => columnWidths.map((width, col) => pad + padCell(row[col]?.[line] ?? "", width, alignments[col] ?? "left") + pad).join(chars.vertical)).map((line) => chars.vertical + line + chars.vertical).join("\n");
|
|
803
|
+
}
|
|
804
|
+
const lines = [drawLine(chars.top)];
|
|
805
|
+
rows.forEach((row, rowIndex) => {
|
|
806
|
+
lines.push(renderRow(row));
|
|
807
|
+
if (rowIndex >= rows.length - 1) return;
|
|
808
|
+
lines.push(drawLine(header && rowIndex === 0 ? chars.headerSep : chars.sep));
|
|
809
|
+
});
|
|
810
|
+
lines.push(drawLine(chars.bottom));
|
|
811
|
+
const body = `${lines.join("\n")}\n`;
|
|
812
|
+
return fence ? wrapFence(body) : body;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
//#endregion
|
|
816
|
+
//#region src/strings/renderTable/pagination.ts
|
|
817
|
+
const DEFAULT_BUDGET = 2e3;
|
|
818
|
+
function paginate(data, options) {
|
|
819
|
+
if (data.length === 0) return [];
|
|
820
|
+
const { budget = DEFAULT_BUDGET, ...tableOptions } = options;
|
|
821
|
+
const header = tableOptions.header === false ? void 0 : data[0];
|
|
822
|
+
const body = header ? data.slice(1) : data;
|
|
823
|
+
const render = (rows) => renderSingle(header ? [header, ...rows] : rows, tableOptions);
|
|
824
|
+
if (body.length === 0) return [render([])];
|
|
825
|
+
const pages = [];
|
|
826
|
+
let current = [];
|
|
827
|
+
for (const row of body) {
|
|
828
|
+
if (current.length === 0 || render([...current, row]).length <= budget) {
|
|
829
|
+
current.push(row);
|
|
830
|
+
continue;
|
|
831
|
+
}
|
|
832
|
+
pages.push(render(current));
|
|
833
|
+
current = [row];
|
|
834
|
+
}
|
|
835
|
+
pages.push(render(current));
|
|
836
|
+
return pages;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
//#endregion
|
|
840
|
+
//#region src/strings/renderTable/renderTable.ts
|
|
841
|
+
function renderTable(data, options) {
|
|
842
|
+
if (options) validateOptions(options);
|
|
843
|
+
if (options && "budget" in options) return paginate(data, options);
|
|
844
|
+
return renderSingle(data, options);
|
|
845
|
+
}
|
|
846
|
+
function validateOptions(options) {
|
|
847
|
+
const { maxWidth, padding } = options;
|
|
848
|
+
if (maxWidth !== void 0 && (!Number.isInteger(maxWidth) || maxWidth < 1)) throw new RangeError(`renderTable maxWidth must be a positive integer, got ${maxWidth}`);
|
|
849
|
+
if (padding !== void 0 && (!Number.isInteger(padding) || padding < 0)) throw new RangeError(`renderTable padding must be a non-negative integer, got ${padding}`);
|
|
523
850
|
}
|
|
524
851
|
|
|
525
852
|
//#endregion
|
|
@@ -569,7 +896,7 @@ function prettyDifference(numBefore, numAfter) {
|
|
|
569
896
|
//#endregion
|
|
570
897
|
//#region src/index.ts
|
|
571
898
|
/** Package version */
|
|
572
|
-
const version = "0.
|
|
899
|
+
const version = "0.7.0-next.1";
|
|
573
900
|
|
|
574
901
|
//#endregion
|
|
575
902
|
exports.assertNever = assertNever;
|
|
@@ -578,7 +905,6 @@ exports.currentTime = currentTime;
|
|
|
578
905
|
exports.filterCirculars = filterCirculars;
|
|
579
906
|
exports.formatFilePath = formatFilePath;
|
|
580
907
|
exports.fyShuffle = fyShuffle;
|
|
581
|
-
exports.generateAsciiTable = generateAsciiTable;
|
|
582
908
|
exports.generateCode = generateCode;
|
|
583
909
|
exports.hasKeys = hasKeys;
|
|
584
910
|
exports.isTsOrJsFile = isTsOrJsFile;
|
|
@@ -589,6 +915,7 @@ exports.parseDuration = parseDuration;
|
|
|
589
915
|
exports.percentage = percentage;
|
|
590
916
|
exports.prettify = prettify;
|
|
591
917
|
exports.prettyDifference = prettyDifference;
|
|
918
|
+
exports.renderTable = renderTable;
|
|
592
919
|
exports.round = round;
|
|
593
920
|
exports.roundToDenomination = roundToDenomination;
|
|
594
921
|
exports.toEpochSeconds = toEpochSeconds;
|