diff --git a/src/render.ts b/src/render.ts index cd73695..40c42f1 100644 --- a/src/render.ts +++ b/src/render.ts @@ -1,45 +1,42 @@ -import type { RenderItemsFn } from './types.js'; +import type { Item, RenderItemsFn } from './types.js'; import { stringify } from 'csv-stringify/sync'; import columnify from 'columnify'; +type Row = Record; + +const toRow = (item: Item, show_tags: string[]): Row => { + return show_tags.reduce((acc, tag) => { + acc[tag] = item.tags[tag]; + return acc; + }, Object.create(null)); +}; + +const toRows = (items: Item[], show_tags: string[]): Row[] => { + return items.map(item => toRow(item, show_tags)); +}; + export const renderTabular: RenderItemsFn = (items, show_tags) => { - const data = items.map((task) => { - const row: Record = {}; - show_tags.forEach((tag) => { - row[tag] = task.tags[tag] ?? ''; - }); - return row; - }); - data.unshift(show_tags.reduce((acc, col) => { + const rows = toRows(items, show_tags); + rows.unshift(show_tags.reduce((acc, col) => { acc[col] = ''.padStart(col.length, '-'); return acc; }, {} as any)); - const opts: columnify.GlobalOptions = { + return columnify(rows, { columns: show_tags, columnSplitter: ' | ', - headingTransform: data => data, - }; - return columnify(data, opts); + headingTransform: heading => heading, + }); }; export const renderCSV: RenderItemsFn = (items, show_tags) => { - return stringify(items.map((task) => { - const row: Record = {}; - show_tags.forEach((tag) => { - row[tag] = task.tags[tag] ?? ''; - }); - return row; - }), { columns: show_tags, header: true }); + return stringify( + toRows(items, show_tags), + { columns: show_tags, header: true }, + ); }; export const renderJSON: RenderItemsFn = (items, show_tags) => { - return JSON.stringify(items.map((task) => { - const entry: Record = {}; - show_tags.forEach((tag) => { - entry[tag] = task.tags[tag]; - }); - return entry; - })); + return JSON.stringify(toRows(items, show_tags)); };