@enspirit/bmg-js 1.1.0 → 1.1.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.
@@ -1,6 +1,102 @@
1
1
  import { Relation, Tuple } from '../types';
2
2
  import { isRelation } from '../sync/operators/isRelation';
3
3
 
4
+ /**
5
+ * Characters used for table borders
6
+ */
7
+ export interface BorderChars {
8
+ topLeft: string;
9
+ topCenter: string;
10
+ topRight: string;
11
+ midLeft: string;
12
+ midCenter: string;
13
+ midRight: string;
14
+ bottomLeft: string;
15
+ bottomCenter: string;
16
+ bottomRight: string;
17
+ horizontal: string;
18
+ vertical: string;
19
+ }
20
+
21
+ /** ASCII border style (default) - maximum compatibility */
22
+ export const ASCII_BORDER: BorderChars = {
23
+ topLeft: '+',
24
+ topCenter: '+',
25
+ topRight: '+',
26
+ midLeft: '+',
27
+ midCenter: '+',
28
+ midRight: '+',
29
+ bottomLeft: '+',
30
+ bottomCenter: '+',
31
+ bottomRight: '+',
32
+ horizontal: '-',
33
+ vertical: '|',
34
+ };
35
+
36
+ /** Unicode single-line border style */
37
+ export const SINGLE_BORDER: BorderChars = {
38
+ topLeft: '┌',
39
+ topCenter: '┬',
40
+ topRight: '┐',
41
+ midLeft: '├',
42
+ midCenter: '┼',
43
+ midRight: '┤',
44
+ bottomLeft: '└',
45
+ bottomCenter: '┴',
46
+ bottomRight: '┘',
47
+ horizontal: '─',
48
+ vertical: '│',
49
+ };
50
+
51
+ /** Unicode double-line border style */
52
+ export const DOUBLE_BORDER: BorderChars = {
53
+ topLeft: '╔',
54
+ topCenter: '╦',
55
+ topRight: '╗',
56
+ midLeft: '╠',
57
+ midCenter: '╬',
58
+ midRight: '╣',
59
+ bottomLeft: '╚',
60
+ bottomCenter: '╩',
61
+ bottomRight: '╝',
62
+ horizontal: '═',
63
+ vertical: '║',
64
+ };
65
+
66
+ /** Unicode rounded corners border style */
67
+ export const ROUNDED_BORDER: BorderChars = {
68
+ topLeft: '╭',
69
+ topCenter: '┬',
70
+ topRight: '╮',
71
+ midLeft: '├',
72
+ midCenter: '┼',
73
+ midRight: '┤',
74
+ bottomLeft: '╰',
75
+ bottomCenter: '┴',
76
+ bottomRight: '╯',
77
+ horizontal: '─',
78
+ vertical: '│',
79
+ };
80
+
81
+ /** Border style preset names */
82
+ export type BorderStyleName = 'ascii' | 'single' | 'double' | 'rounded';
83
+
84
+ const BORDER_PRESETS: Record<BorderStyleName, BorderChars> = {
85
+ ascii: ASCII_BORDER,
86
+ single: SINGLE_BORDER,
87
+ double: DOUBLE_BORDER,
88
+ rounded: ROUNDED_BORDER,
89
+ };
90
+
91
+ /** Resolve border option to BorderChars */
92
+ const resolveBorder = (
93
+ border: BorderStyleName | BorderChars | undefined
94
+ ): BorderChars => {
95
+ if (border === undefined) return ASCII_BORDER;
96
+ if (typeof border === 'string') return BORDER_PRESETS[border];
97
+ return border;
98
+ };
99
+
4
100
  /**
5
101
  * Options for text rendering
6
102
  */
@@ -9,6 +105,8 @@ export interface TextOptions {
9
105
  floatPrecision?: number;
10
106
  /** Maximum width to trim output at */
11
107
  trimAt?: number;
108
+ /** Border style: preset name or custom BorderChars object */
109
+ border?: BorderStyleName | BorderChars;
12
110
  }
13
111
 
14
112
  // Type guards
@@ -138,7 +236,8 @@ class Row {
138
236
  return this.cells.map(cell => cell.minWidth);
139
237
  }
140
238
 
141
- renderingLines(sizes: number[]): string[] {
239
+ renderingLines(sizes: number[], border: BorderChars): string[] {
240
+ const v = border.vertical;
142
241
  let nbLines = 0;
143
242
  const byCell = this.cells.map((cell, i) => {
144
243
  const lines = cell.renderingLines(sizes[i]);
@@ -150,11 +249,11 @@ class Row {
150
249
  for (let lineI = 0; lineI < nbLines; lineI++) {
151
250
  const lineContent = byCell
152
251
  .map((cellLines, i) => cellLines[lineI] ?? ' '.repeat(sizes[i]))
153
- .join(' | ');
154
- grid.push('| ' + lineContent + ' |');
252
+ .join(` ${v} `);
253
+ grid.push(`${v} ` + lineContent + ` ${v}`);
155
254
  }
156
255
 
157
- return grid.length === 0 ? ['| |'] : grid;
256
+ return grid.length === 0 ? [`${v} ${v}`] : grid;
158
257
  }
159
258
  }
160
259
 
@@ -163,13 +262,14 @@ class Row {
163
262
  */
164
263
  class Table {
165
264
  private renderer: TextWriter;
265
+ private border: BorderChars;
166
266
  private header: Row;
167
267
  private rows: Row[];
168
268
  private _sizes: number[] | null = null;
169
- private _sep: string | null = null;
170
269
 
171
270
  constructor(renderer: TextWriter, records: unknown[][], attributes: string[]) {
172
271
  this.renderer = renderer;
272
+ this.border = resolveBorder(renderer.options.border);
173
273
  this.header = new Row(renderer, attributes);
174
274
  this.rows = records.map(r => new Row(renderer, r));
175
275
  }
@@ -185,11 +285,21 @@ class Table {
185
285
  return this._sizes;
186
286
  }
187
287
 
188
- get sep(): string {
189
- if (this._sep === null) {
190
- this._sep = '+-' + this.sizes.map(s => '-'.repeat(s)).join('-+-') + '-+';
191
- }
192
- return this._sep;
288
+ private makeSep(left: string, center: string, right: string): string {
289
+ const h = this.border.horizontal;
290
+ return left + h + this.sizes.map(s => h.repeat(s)).join(h + center + h) + h + right;
291
+ }
292
+
293
+ get topSep(): string {
294
+ return this.makeSep(this.border.topLeft, this.border.topCenter, this.border.topRight);
295
+ }
296
+
297
+ get midSep(): string {
298
+ return this.makeSep(this.border.midLeft, this.border.midCenter, this.border.midRight);
299
+ }
300
+
301
+ get bottomSep(): string {
302
+ return this.makeSep(this.border.bottomLeft, this.border.bottomCenter, this.border.bottomRight);
193
303
  }
194
304
 
195
305
  *eachLine(): Generator<string> {
@@ -205,15 +315,15 @@ class Table {
205
315
  }
206
316
 
207
317
  private *eachLineRaw(): Generator<string> {
208
- yield this.sep;
209
- yield this.header.renderingLines(this.sizes)[0];
210
- yield this.sep;
318
+ yield this.topSep;
319
+ yield this.header.renderingLines(this.sizes, this.border)[0];
320
+ yield this.midSep;
211
321
  for (const row of this.rows) {
212
- for (const line of row.renderingLines(this.sizes)) {
322
+ for (const line of row.renderingLines(this.sizes, this.border)) {
213
323
  yield line;
214
324
  }
215
325
  }
216
- yield this.sep;
326
+ yield this.bottomSep;
217
327
  }
218
328
 
219
329
  *[Symbol.iterator](): Generator<string> {