dbcat 0.0.12 → 0.0.14

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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/src/index.ts +21 -11
  3. package/src/table.ts +14 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbcat",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "description": "A simple CLI to view database tables. Supports PostgreSQL, MySQL, and SQLite.",
5
5
  "author": "RiskyMH",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
@@ -121,7 +121,7 @@ export function getTableData(
121
121
  tableName: string,
122
122
  limit?: number
123
123
  ): Promise<Record<string, unknown>[]> {
124
- if (limit === undefined) {
124
+ if (limit === undefined || limit === Infinity) {
125
125
  return sql`SELECT * FROM ${sql(tableName)}`;
126
126
  }
127
127
  return sql`SELECT * FROM ${sql(tableName)} LIMIT ${limit}`;
@@ -135,14 +135,15 @@ function displayTable(
135
135
  tableName: string,
136
136
  rows: Record<string, unknown>[],
137
137
  totalRows?: number,
138
- maxRows?: number
138
+ maxRows?: number,
139
+ fullContent?: boolean
139
140
  ) {
140
141
  console.log("");
141
- printTable(rows, { title: tableName, totalRows, maxRows });
142
+ printTable(rows, { title: tableName, totalRows, maxRows, fullContent });
142
143
  }
143
144
 
144
145
  function displayQueryResult(rows: Record<string, unknown>[]) {
145
- printTable(rows, { title: "Result", maxRows: Infinity });
146
+ printTable(rows, { title: "Result", maxRows: Infinity, fullContent: true });
146
147
  }
147
148
 
148
149
  async function readStdin(): Promise<string | null> {
@@ -162,12 +163,18 @@ function parseArgs() {
162
163
  const args = process.argv.slice(2);
163
164
  let input: string | undefined;
164
165
  let full = false;
165
- let help = false
166
+ let help = false;
166
167
  let json: false | "plain" | "color" = false;
168
+ let fullRows = false;
169
+ let fullContent = false;
167
170
 
168
171
  for (const arg of args) {
169
172
  if (arg === "--full" || arg === "-f") {
170
173
  full = true;
174
+ } else if (arg === "--full-rows") {
175
+ fullRows = true;
176
+ } else if (arg === "--full-content") {
177
+ fullContent = true;
171
178
  } else if (arg === "--help" || arg === "-h") {
172
179
  help = true;
173
180
  } else if (arg === "--json") {
@@ -179,7 +186,7 @@ function parseArgs() {
179
186
  }
180
187
  }
181
188
 
182
- return { input, full, json, help };
189
+ return { input, full, json, help, fullRows, fullContent };
183
190
  }
184
191
 
185
192
  const DEFAULT_LIMIT = 100;
@@ -212,7 +219,7 @@ function outputJson(data: unknown, color: boolean) {
212
219
  }
213
220
 
214
221
  async function main() {
215
- const { input, full, json, help } = parseArgs();
222
+ const { input, full, json, help, fullRows, fullContent } = parseArgs();
216
223
 
217
224
  if ((!input && !process.env.DATABASE_URL) || help) {
218
225
  showUsageAndExit();
@@ -300,15 +307,18 @@ async function main() {
300
307
  console.log(`${dim}No tables found.${reset}`);
301
308
  } else {
302
309
  for (const table of tables) {
303
- if (full) {
310
+ const maxRows = (full || fullRows) ? Infinity : DEFAULT_LIMIT;
311
+ const fullContentFlag = full || fullContent;
312
+
313
+ if (maxRows === Infinity) {
304
314
  const data = await getTableData(sql, table.name);
305
- displayTable(table.name, data, undefined, Infinity);
315
+ displayTable(table.name, data, undefined, Infinity, fullContentFlag);
306
316
  } else {
307
317
  const [count, data] = await Promise.all([
308
318
  getTableCount(sql, table.name),
309
- getTableData(sql, table.name, DEFAULT_LIMIT),
319
+ getTableData(sql, table.name, maxRows),
310
320
  ]);
311
- displayTable(table.name, data, count, DEFAULT_LIMIT);
321
+ displayTable(table.name, data, count, maxRows, fullContentFlag);
312
322
  }
313
323
  }
314
324
  }
package/src/table.ts CHANGED
@@ -74,6 +74,7 @@ export interface TableOptions {
74
74
  maxRows?: number;
75
75
  title?: string;
76
76
  totalRows?: number;
77
+ fullContent?: boolean;
77
78
  }
78
79
 
79
80
  function wrapLines(str: string, maxWidth: number): string[] {
@@ -118,6 +119,10 @@ function wrapLines(str: string, maxWidth: number): string[] {
118
119
  return lines;
119
120
  }
120
121
 
122
+ function wrapMultilineCell(str: string, maxWidth: number): string[] {
123
+ return String(str).split('\n').flatMap(line => wrapLines(line, maxWidth));
124
+ }
125
+
121
126
  export function printTable(
122
127
  rows: Record<string, unknown>[],
123
128
  options: TableOptions = {},
@@ -150,8 +155,7 @@ export function printTable(
150
155
  )} ${dim}${BOX.vertical}${reset}`,
151
156
  );
152
157
  console.log(
153
- `${dim}${BOX.bottomLeft}${BOX.horizontal.repeat(innerWidth)}${
154
- BOX.bottomRight
158
+ `${dim}${BOX.bottomLeft}${BOX.horizontal.repeat(innerWidth)}${BOX.bottomRight
155
159
  }${reset}`,
156
160
  );
157
161
  } else {
@@ -180,7 +184,7 @@ export function printTable(
180
184
  const colWidths: number[] = allColumns.map((col) => Bun.stringWidth(col));
181
185
  const formattedRows: string[][] = displayRows.map((row) =>
182
186
  allColumns.map((col, i) => {
183
- const formatted = formatValue(row[col]).replace(/\n/g, " ");
187
+ const formatted = options.fullContent ? formatValue(row[col]) : formatValue(row[col]).replace(/\n/g, `${dim}\\n${reset}`);
184
188
  colWidths[i] = Math.max(colWidths[i]!, Bun.stringWidth(formatted));
185
189
  return formatted;
186
190
  }),
@@ -303,11 +307,11 @@ export function printTable(
303
307
  `${dim}${BOX.headerLeft}${BOX.horizontal}${headerSep}${BOX.horizontal}${BOX.headerRight}${reset}`,
304
308
  );
305
309
 
306
- // If in --full mode, apply smart multiline rendering:
307
- if (maxRows === Infinity) {
310
+ if (options.fullContent) {
308
311
  for (let rowIdx = 0; rowIdx < visibleFormattedRows.length; rowIdx++) {
309
312
  const row = visibleFormattedRows[rowIdx] ?? [];
310
- const wrapped = row.map((val, i) => wrapLines(val, visibleColWidths[i]!));
313
+ const wrapped = row.map((val, i) => wrapMultilineCell(val, visibleColWidths[i]!));
314
+
311
315
  const rowHeight = Math.max(...wrapped.map(x => x.length));
312
316
  for (let lineIdx = 0; lineIdx < rowHeight; lineIdx++) {
313
317
  const pieces = wrapped.map((cellLines, i) => {
@@ -316,10 +320,10 @@ export function printTable(
316
320
  ? padLeft(truncate(part, visibleColWidths[i]!), visibleColWidths[i]!)
317
321
  : padRight(truncate(part, visibleColWidths[i]!), visibleColWidths[i]!);
318
322
  });
319
- const line = pieces.join(` ${dim}${BOX.vertical}${reset} `);
320
- console.log(`${dim}${BOX.vertical}${reset} ${line} ${dim}${BOX.vertical}${reset}`);
323
+ const line = pieces.join(` ${reset}${dim}${BOX.vertical}${reset} `);
324
+ console.log(`${reset}${dim}${BOX.vertical}${reset} ${line} ${reset}${dim}${BOX.vertical}${reset}`);
321
325
  }
322
- if (rowIdx < visibleFormattedRows.length - 1) {
326
+ if (rowIdx < visibleFormattedRows.length - 1 || (rowIdx === visibleFormattedRows.length - 1 && infoText)) {
323
327
  const rowSep = visibleColWidths
324
328
  .map((w) => BOX.horizontal.repeat(w))
325
329
  .join(`${BOX.horizontal}${BOX.headerCross}${BOX.horizontal}`);
@@ -327,7 +331,6 @@ export function printTable(
327
331
  }
328
332
  }
329
333
  } else {
330
- // Legacy single-line row rendering
331
334
  for (const row of visibleFormattedRows) {
332
335
  const line = row
333
336
  .map((val, i) => {
@@ -349,8 +352,7 @@ export function printTable(
349
352
  console.log(`${dim}${BOX.vertical} ${infoLine} ${BOX.vertical}${reset}`);
350
353
 
351
354
  console.log(
352
- `${dim}${BOX.bottomLeft}${BOX.horizontal.repeat(totalInnerWidth)}${
353
- BOX.bottomRight
355
+ `${dim}${BOX.bottomLeft}${BOX.horizontal.repeat(totalInnerWidth)}${BOX.bottomRight
354
356
  }${reset}`,
355
357
  );
356
358
  } else {