dbn-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 +41 -0
- package/bin/dbn.ts +9 -0
- package/package.json +40 -0
- package/src/adapter/base.ts +46 -0
- package/src/adapter/sqlite.ts +110 -0
- package/src/index.ts +250 -0
- package/src/types.ts +109 -0
- package/src/ui/navigator.ts +254 -0
- package/src/ui/renderer.ts +499 -0
- package/src/ui/screen.ts +101 -0
- package/src/ui/theme.ts +58 -0
- package/src/utils/format.ts +137 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formatting utilities for displaying data
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Format a number with thousand separators
|
|
7
|
+
* @param num - Number to format
|
|
8
|
+
* @returns Formatted number string
|
|
9
|
+
*/
|
|
10
|
+
export function formatNumber(num: number): string {
|
|
11
|
+
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Truncate a string to a specific visible width with ellipsis
|
|
16
|
+
* @param str - String to truncate
|
|
17
|
+
* @param maxWidth - Maximum visible width (accounting for double-width chars)
|
|
18
|
+
* @returns Truncated string
|
|
19
|
+
*/
|
|
20
|
+
import stringWidth from 'string-width';
|
|
21
|
+
|
|
22
|
+
export function truncate(str: string, maxWidth: number): string {
|
|
23
|
+
if (!str) return '';
|
|
24
|
+
const s = String(str);
|
|
25
|
+
|
|
26
|
+
const currentWidth = getVisibleWidth(s);
|
|
27
|
+
if (currentWidth <= maxWidth) return s;
|
|
28
|
+
|
|
29
|
+
// Need to truncate - build string character by character
|
|
30
|
+
let result = '';
|
|
31
|
+
let width = 0;
|
|
32
|
+
const ellipsis = '...';
|
|
33
|
+
const ellipsisWidth = 3; // '...' is 3 single-width chars
|
|
34
|
+
|
|
35
|
+
// Use grapheme-aware widths using string-width
|
|
36
|
+
for (const ch of Array.from(s)) {
|
|
37
|
+
const charWidth = stringWidth(ch);
|
|
38
|
+
|
|
39
|
+
if (width + charWidth + ellipsisWidth > maxWidth) break;
|
|
40
|
+
|
|
41
|
+
result += ch;
|
|
42
|
+
width += charWidth;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return result + ellipsis;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Pad a string to a specific visible width
|
|
50
|
+
* @param str - String to pad
|
|
51
|
+
* @param targetWidth - Target visible width (accounting for double-width chars)
|
|
52
|
+
* @param align - Alignment: 'left', 'right', or 'center'
|
|
53
|
+
* @returns Padded string
|
|
54
|
+
*/
|
|
55
|
+
export function pad(str: string, targetWidth: number, align: 'left' | 'right' | 'center' = 'left'): string {
|
|
56
|
+
const s = String(str || '');
|
|
57
|
+
const currentWidth = getVisibleWidth(s);
|
|
58
|
+
|
|
59
|
+
if (currentWidth >= targetWidth) {
|
|
60
|
+
// Need to truncate
|
|
61
|
+
let result = '';
|
|
62
|
+
let width = 0;
|
|
63
|
+
|
|
64
|
+
// Build using string-width for grapheme-aware sizing
|
|
65
|
+
for (const char of Array.from(s)) {
|
|
66
|
+
const charWidth = stringWidth(char);
|
|
67
|
+
|
|
68
|
+
if (width + charWidth > targetWidth) break;
|
|
69
|
+
|
|
70
|
+
result += char;
|
|
71
|
+
width += charWidth;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// If we stopped before a double-width char and have 1 space left, add a space
|
|
75
|
+
if (width < targetWidth) {
|
|
76
|
+
result += ' '.repeat(targetWidth - width);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const padding = targetWidth - currentWidth;
|
|
83
|
+
|
|
84
|
+
if (align === 'right') {
|
|
85
|
+
return ' '.repeat(padding) + s;
|
|
86
|
+
} else if (align === 'center') {
|
|
87
|
+
const leftPad = Math.floor(padding / 2);
|
|
88
|
+
const rightPad = padding - leftPad;
|
|
89
|
+
return ' '.repeat(leftPad) + s + ' '.repeat(rightPad);
|
|
90
|
+
} else {
|
|
91
|
+
return s + ' '.repeat(padding);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Format a value for display (handle null, undefined, etc.)
|
|
97
|
+
* @param value - Value to format
|
|
98
|
+
* @returns Formatted string
|
|
99
|
+
*/
|
|
100
|
+
export function formatValue(value: any): string {
|
|
101
|
+
if (value === null) return 'NULL';
|
|
102
|
+
if (value === undefined) return '';
|
|
103
|
+
if (typeof value === 'boolean') return value ? 'true' : 'false';
|
|
104
|
+
if (typeof value === 'object') return JSON.stringify(value);
|
|
105
|
+
|
|
106
|
+
// Convert to string and remove control characters (newlines, tabs, etc.)
|
|
107
|
+
const str = String(value);
|
|
108
|
+
return str.replace(/[\n\r\t\v\f]/g, ' ').replace(/\s+/g, ' ');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Check if a character is double-width (CJK, emoji, etc.)
|
|
113
|
+
* @param char - Single character or code point
|
|
114
|
+
* @returns True if character is double-width
|
|
115
|
+
*/
|
|
116
|
+
// Deprecated: custom double-width detection replaced by `string-width`.
|
|
117
|
+
// Keep function stub for backward compatibility if other modules import it.
|
|
118
|
+
function isDoubleWidth(_char: string): boolean {
|
|
119
|
+
return false; // use string-width instead
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get the visible width of a string (accounting for ANSI codes, CJK characters, and emoji)
|
|
124
|
+
* @param str - String to measure
|
|
125
|
+
* @returns Visible width
|
|
126
|
+
*/
|
|
127
|
+
export function getVisibleWidth(str: string): number {
|
|
128
|
+
// Remove ANSI escape codes
|
|
129
|
+
const cleanStr = str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
130
|
+
|
|
131
|
+
let width = 0;
|
|
132
|
+
for (const ch of Array.from(cleanStr)) {
|
|
133
|
+
width += stringWidth(ch);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return width;
|
|
137
|
+
}
|