From 90e4de770365a579719b1cb83188f8f2fa70d4f9 Mon Sep 17 00:00:00 2001 From: Mike Donnalley Date: Wed, 20 Nov 2024 15:14:12 -0700 Subject: [PATCH] feat: add makeTable method --- src/ux/table.ts | 46 +++++++++++++++++++++++++++++++ src/ux/ux.ts | 60 ++++++++++++----------------------------- test/unit/ux/ux.test.ts | 14 +++++----- 3 files changed, 69 insertions(+), 51 deletions(-) diff --git a/src/ux/table.ts b/src/ux/table.ts index c7790819..a3e67c9b 100644 --- a/src/ux/table.ts +++ b/src/ux/table.ts @@ -5,6 +5,7 @@ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import { TableOptions } from '@oclif/table'; +import { env } from '@salesforce/kit'; type Column> = { extended: boolean; @@ -56,3 +57,48 @@ export function convertToNewTableAPI>( return { data: d, title: options?.title, borderStyle: 'headers-only-with-underline', columns: cols }; } + +export function getDefaults>(options: TableOptions): Partial> { + const borderStyles = [ + 'all', + 'headers-only-with-outline', + 'headers-only-with-underline', + 'headers-only', + 'horizontal-with-outline', + 'horizontal', + 'none', + 'outline', + 'vertical-with-outline', + 'vertical', + ]; + + const defaultStyle = 'vertical-with-outline'; + const determineBorderStyle = (): TableOptions['borderStyle'] => { + const envVar = env.getString('SF_TABLE_BORDER_STYLE', defaultStyle); + if (borderStyles.includes(envVar)) { + return envVar as TableOptions['borderStyle']; + } + + return defaultStyle; + }; + + const overflowOptions = ['wrap', 'truncate', 'truncate-middle', 'truncate-start', 'truncate-end']; + const determineOverflow = (): TableOptions['overflow'] => { + const envVar = env.getString('SF_TABLE_OVERFLOW'); + if (envVar && overflowOptions.includes(envVar)) { + return envVar as TableOptions['overflow']; + } + + return options.overflow; + }; + + return { + borderStyle: determineBorderStyle(), + noStyle: env.getBoolean('SF_NO_TABLE_STYLE', false), + headerOptions: { + ...options.headerOptions, + formatter: 'capitalCase', + }, + overflow: determineOverflow(), + }; +} diff --git a/src/ux/ux.ts b/src/ux/ux.ts index 51c11af3..7e1f0805 100644 --- a/src/ux/ux.ts +++ b/src/ux/ux.ts @@ -9,11 +9,11 @@ import ansis from 'ansis'; import { ux } from '@oclif/core'; import { AnyJson } from '@salesforce/ts-types'; import terminalLink from 'terminal-link'; -import { printTable, TableOptions } from '@oclif/table'; -import { env } from '@salesforce/kit'; +import { makeTable, printTable, TableOptions } from '@oclif/table'; import { UxBase } from './base.js'; import { Spinner } from './spinner.js'; import styledObject from './styledObject.js'; +import { getDefaults } from './table.js'; /** * UX methods for plugins. Automatically suppress console output if outputEnabled is set to false. @@ -76,54 +76,28 @@ export class Ux extends UxBase { * @param options Table properties */ public table>(options: TableOptions): void { - const borderStyles = [ - 'all', - 'headers-only-with-outline', - 'headers-only-with-underline', - 'headers-only', - 'horizontal-with-outline', - 'horizontal', - 'none', - 'outline', - 'vertical-with-outline', - 'vertical', - ]; - - const defaultStyle = 'vertical-with-outline'; - const determineBorderStyle = (): TableOptions['borderStyle'] => { - const envVar = env.getString('SF_TABLE_BORDER_STYLE', defaultStyle); - if (borderStyles.includes(envVar)) { - return envVar as TableOptions['borderStyle']; - } - - return defaultStyle; - }; - - const overflowOptions = ['wrap', 'truncate', 'truncate-middle', 'truncate-start', 'truncate-end']; - const determineOverflow = (): TableOptions['overflow'] => { - const envVar = env.getString('SF_TABLE_OVERFLOW'); - if (envVar && overflowOptions.includes(envVar)) { - return envVar as TableOptions['overflow']; - } - - return options.overflow; - }; - this.maybeNoop(() => printTable({ ...options, - // Don't allow anyone to override these properties - borderStyle: determineBorderStyle(), - noStyle: env.getBoolean('SF_NO_TABLE_STYLE', false), - headerOptions: { - ...options.headerOptions, - formatter: 'capitalCase', - }, - overflow: determineOverflow(), + ...getDefaults(options), }) ); } + /** + * Return a string rendering of a table. + * + * @param options Table properties + * @returns string rendering of a table + */ + // eslint-disable-next-line class-methods-use-this + public makeTable>(options: TableOptions): string { + return makeTable({ + ...options, + ...getDefaults(options), + }); + } + /** * Display a url to the console. This will be automatically suppressed if output is disabled. * diff --git a/test/unit/ux/ux.test.ts b/test/unit/ux/ux.test.ts index 1344e04f..8bfca9c8 100644 --- a/test/unit/ux/ux.test.ts +++ b/test/unit/ux/ux.test.ts @@ -31,10 +31,9 @@ describe('Ux', () => { const ux = new Ux(); ux.table({ data: [{ key: 'foo', value: 'bar' }], title: 'Title' }); }); - expect(stdout.replaceAll(' \n', '\n').trimEnd()).to.equal(`Title - Key Value ------------- - foo bar`); + expect(stdout).to.include('Title'); + expect(stdout).to.match(/Key.+Value/); + expect(stdout).to.match(/foo.+bar/); }); it('should not log anything if output is not enabled', async () => { @@ -53,10 +52,9 @@ describe('Ux', () => { const opts = convertToNewTableAPI([{ key: 'foo', value: 'bar' }], { key: {}, value: {} }, { title: 'Title' }); ux.table(opts); }); - expect(stdout.replaceAll(' \n', '\n').trimEnd()).to.equal(`Title - Key Value ------------- - foo bar`); + expect(stdout).to.include('Title'); + expect(stdout).to.match(/Key.+Value/); + expect(stdout).to.match(/foo.+bar/); }); it('should not log anything if output is not enabled', async () => {