DEV Community

foxgem
foxgem

Posted on

st2: a fork of "string-table" with more enhancements.

st2 is string-table refactored in TypeScirpt with more enhancements:

  • add type information, then it can be used in modern IDE like vscode to work with IntelliSense.
  • return an empty string for null, undefined, '', {}, [] and [{}] by default.
  • accept a single object input, ie, treat it as an array including only one element.
  • support object properties.
  • filter out "empty" items (null, undefined, {} and '') in the input array automatically.
  • rewrite all tests in TypeScirpt, using ava and c8.

Installation

npm install @dteam/st2
Enter fullscreen mode Exit fullscreen mode

Example

import {createTable} from '@dteam/st2';

const users = [
  {name: 'Dan', gender: 'M', age: 29},
  {name: 'Adam', gender: 'M', age: 31},
  {name: 'Lauren', gender: 'F', age: 33},
];

createTable(users);

/*
 * Result:
 *
 * | name   | gender | age |
 * -------------------------
 * | Dan    | M      |  29 |
 * | Adam   | M      |  31 |
 * | Lauren | F      |  33 |
 */
Enter fullscreen mode Exit fullscreen mode

For the input of createTable, please note:

  • a single object will be treat as [object].
  • null, undefined, '', {}, [] and [{}] will return an empty string.
  • "empty" items in the input will be removed, fox examples:
createTable([null, undefined, '', {}, {foo: 3, bar: 4}]);

/*
 * Result:
 *
 * | foo | bar |
 * -------------
 * |   3 |   4 |
 */
Enter fullscreen mode Exit fullscreen mode

Please check the test files for all usage examples.

Options

You can also specify options to customize how the table is formatted:

const table = createTable(users, options);
Enter fullscreen mode Exit fullscreen mode

The available options are summarized below.

headers

An array of strings indicating which column headers to include (and in what order)

Default: every property from the first object in the list

Example

createTable(users, {headers: ['age', 'name']});

/*
 * Result:
 *
 * | age | name   |
 * ----------------
 * |  29 | Dan    |
 * |  31 | Adam   |
 * |  33 | Lauren |
 */
Enter fullscreen mode Exit fullscreen mode

capitalizeHeaders

Whether or not to capitalize the table's column headers

Default: false

Example

createTable(users, {capitalizeHeaders: true});

/*
 * Result:
 *
 * | Name   | Gender | Age |
 * -------------------------
 * | Dan    | M      |  29 |
 * | Adam   | M      |  31 |
 * | Lauren | F      |  33 |
 */
Enter fullscreen mode Exit fullscreen mode

formatters

An object mapping column names to formatter functions, which will accept (value, header) arguments

Default: none

Example

createTable(users, {
  formatters: {
    name: function (value, header) {
      return value.toUpperCase();
    },
  },
});

/*
 * Result:
 *
 * | name   | gender | age |
 * -------------------------
 * | DAN    | M      |  29 |
 * | ADAM   | M      |  31 |
 * | LAUREN | F      |  33 |
 */
Enter fullscreen mode Exit fullscreen mode

A formatter may also return an object with the properties { value, format }, where format in turn can have the properties { color, alignment }.

NOTE: color output required colors package:

npm i colors

More details can be found in: https://www.npmjs.com/package/colors#colors-and-styles

// don't forget to import colors
include 'colors';

createTable(users, {
  formatters: {
    gender: function (value, header) {
      return {
        value: value,
        format: {
          // All supported colors and styles can be found in official doc: https://www.npmjs.com/package/colors
          color: value === 'M' ? 'cyan' : 'magenta',
          alignment: 'right',
        },
      };
    },
  },
});

/*
 * Result:
 *
 * | name   | gender |    age |
 * ----------------------------
 * | Dan    |      M |  29.00 |
 * | Adam   |      M |  31.00 |
 * | Lauren |      F |  33.00 |
 *
 * (Imagine the Ms are cyan and the F is magenta above.)
 */
Enter fullscreen mode Exit fullscreen mode

For internal objects properties, you can use formatters too.

const numbers = [
  {outValue: 1, insideValue: {a: 1, b: 'a1'}},
  {outValue: 2, insideValue: {a: 2, b: 'a2'}},
  {outValue: 3, insideValue: {a: 3, b: 'a3'}},
];

createTable(numbers, {
  formatters: {
    insideValue: {
      a: (value: number) => value.toFixed(2),
      b: (value: string) => value.toUpperCase(),
    },
  },
  rowSeparator: '-',
});

/*
 * Result:
 *
 * | outValue | insideValue   |
 * ----------------------------
 * |        1 | | a    | b  | |
 * |          | ------------- |
 * |          | | 1.00 | A1 | |
 * ----------------------------
 * |        2 | | a    | b  | |
 * |          | ------------- |
 * |          | | 2.00 | A2 | |
 * ----------------------------
 * |        3 | | a    | b  | |
 * |          | ------------- |
 * |          | | 3.00 | A3 | |
 *
 */
Enter fullscreen mode Exit fullscreen mode

typeFormatters

An object mapping data types ('string', 'number', 'boolean', etc.) to formatter functions (has lower precedence than formatters option)

Default: none

Example

createTable(users, {
  typeFormatters: {
    number: function (value, header) {
      return value.toFixed(2);
    },
  },
});

/*
 * Result:
 *
 * | name   | gender |    age |
 * ----------------------------
 * | Dan    | M      |  29.00 |
 * | Adam   | M      |  31.00 |
 * | Lauren | F      |  33.00 |
 */
Enter fullscreen mode Exit fullscreen mode

A type formatters will also be applied for the values in the internal objects with the same type.

const numbers = [
  {outValue: 1, insideValue: {value: 1}},
  {outValue: 2, insideValue: {value: 2}},
  {outValue: 3, insideValue: {value: 3}},
];

createTable(numbers, {
  typeFormatters: {
    number: (value: number) => value.toFixed(2),
  },
  rowSeparator: '-',
});

/*
 * Result:
 *
 * | outValue | insideValue |
 * --------------------------
 * | 1.00     | | value |   |
 * |          | ---------   |
 * |          | | 1.00  |   |
 * --------------------------
 * | 2.00     | | value |   |
 * |          | ---------   |
 * |          | | 2.00  |   |
 * --------------------------
 * | 3.00     | | value |   |
 * |          | ---------   |
 * |          | | 3.00  |   |
 */
Enter fullscreen mode Exit fullscreen mode

outerBorder and innerBorder

The character(s) used to enclose the table and to delimit cells within the table, respectively

Defaults: '|' for both

Example

createTable(users, {
  outerBorder: '%',
  innerBorder: '$',
});

/*
 * Result:
 *
 * % name   $ gender $ age %
 * -------------------------
 * % Dan    $ M      $  29 %
 * % Adam   $ M      $  31 %
 * % Lauren $ F      $  33 %
 */
Enter fullscreen mode Exit fullscreen mode

rowSeparator

The character used to separate rows in the table

Default: none

Example

createTable(users, {rowSeparator: '~'});

/*
 * Result:
 *
 * | name   | gender | age |
 * -------------------------
 * | Dan    | M      |  29 |
 * ~~~~~~~~~~~~~~~~~~~~~~~~~
 * | Adam   | M      |  31 |
 * ~~~~~~~~~~~~~~~~~~~~~~~~~
 * | Lauren | F      |  33 |
 */
Enter fullscreen mode Exit fullscreen mode

headerSeparator

The character used to separate the header row from the table body

Default: '-'

Example

createTable(users, {headerSeparator: '*'});

/*
 * Result:
 *
 * | name   | gender | age |
 * *************************
 * | Dan    | M      |  29 |
 * | Adam   | M      |  31 |
 * | Lauren | F      |  33 |
 */
Enter fullscreen mode Exit fullscreen mode

Again, the test files shows all examples with different options.

How to deploy

  1. npm login
  2. npm run build
  3. npm publish

Note: if you changed registry in your ~/.npmrc, you need to comment it out before deployment.

Thanks

Finally, we want to thank string-table for providing a great way to show a list of structure data in cli. Without it, st2 will not happen.

Top comments (0)