Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add makeTable method #649

Merged
merged 1 commit into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/ux/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T extends Record<string, unknown>> = {
extended: boolean;
Expand Down Expand Up @@ -56,3 +57,48 @@ export function convertToNewTableAPI<T extends Record<string, unknown>>(

return { data: d, title: options?.title, borderStyle: 'headers-only-with-underline', columns: cols };
}

export function getDefaults<T extends Record<string, unknown>>(options: TableOptions<T>): Partial<TableOptions<T>> {
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<T>['borderStyle'] => {
const envVar = env.getString('SF_TABLE_BORDER_STYLE', defaultStyle);
if (borderStyles.includes(envVar)) {
return envVar as TableOptions<T>['borderStyle'];
}

return defaultStyle;
};

const overflowOptions = ['wrap', 'truncate', 'truncate-middle', 'truncate-start', 'truncate-end'];
const determineOverflow = (): TableOptions<T>['overflow'] => {
const envVar = env.getString('SF_TABLE_OVERFLOW');
if (envVar && overflowOptions.includes(envVar)) {
return envVar as TableOptions<T>['overflow'];
}

return options.overflow;
};

return {
borderStyle: determineBorderStyle(),
noStyle: env.getBoolean('SF_NO_TABLE_STYLE', false),
headerOptions: {
...options.headerOptions,
formatter: 'capitalCase',
},
overflow: determineOverflow(),
};
}
60 changes: 17 additions & 43 deletions src/ux/ux.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -76,54 +76,28 @@ export class Ux extends UxBase {
* @param options Table properties
*/
public table<T extends Record<string, unknown>>(options: TableOptions<T>): 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<T>['borderStyle'] => {
const envVar = env.getString('SF_TABLE_BORDER_STYLE', defaultStyle);
if (borderStyles.includes(envVar)) {
return envVar as TableOptions<T>['borderStyle'];
}

return defaultStyle;
};

const overflowOptions = ['wrap', 'truncate', 'truncate-middle', 'truncate-start', 'truncate-end'];
const determineOverflow = (): TableOptions<T>['overflow'] => {
const envVar = env.getString('SF_TABLE_OVERFLOW');
if (envVar && overflowOptions.includes(envVar)) {
return envVar as TableOptions<T>['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<T>(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<T extends Record<string, unknown>>(options: TableOptions<T>): string {
return makeTable({
...options,
...getDefaults<T>(options),
});
}

/**
* Display a url to the console. This will be automatically suppressed if output is disabled.
*
Expand Down
14 changes: 6 additions & 8 deletions test/unit/ux/ux.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand All @@ -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 () => {
Expand Down
Loading