From c7c5e8eed15b6013ad20609a5142ae8cca9a6b65 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 4 Nov 2021 12:25:10 +0700 Subject: [PATCH] Require Node.js 12.20 and move to ESM --- .github/workflows/main.yml | 5 +- index.d.ts | 100 +++++++++++++++++-------------------- index.js | 11 ++-- index.test-d.ts | 18 +++---- license | 2 +- package.json | 19 ++++--- readme.md | 71 +++++++++++--------------- test.js | 46 ++++++++--------- 8 files changed, 127 insertions(+), 145 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 18531b3..3b8aa86 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,13 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 16 - 14 - 12 - - 10 - - 8 steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/index.d.ts b/index.d.ts index 63ba00f..6d17620 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,29 +1,27 @@ -declare namespace parseColumns { - interface Options { - /** - Separator to split columns on. +export interface Options { + /** + Separator to split columns on. - @default ' ' - */ - readonly separator?: string; + @default ' ' + */ + readonly separator?: string; - /** - Headers to use instead of the existing ones. - */ - readonly headers?: readonly string[]; + /** + Headers to use instead of the existing ones. + */ + readonly headers?: readonly string[]; - /** - Transform elements. + /** + Transform elements. - Useful for being able to cleanup or change the type of elements. - */ - readonly transform?: ( - element: string, - header: string, - columnIndex: number, - rowIndex: number - ) => ValuesType; - } + Useful for being able to cleanup or change the type of elements. + */ + readonly transform?: ( + element: string, + header: string, + columnIndex: number, + rowIndex: number + ) => Value; } /** @@ -33,42 +31,38 @@ Parse text columns, like the output of Unix commands. @example ``` -import {promisify} from 'util'; -import * as childProcess from 'child_process'; -import parseColumns = require('parse-columns'); +import {promisify} from 'node:util'; +import childProcess from 'node:child_process'; +import parseColumns from 'parse-columns'; const execFileP = promisify(childProcess.execFile); -(async () => { - const {stdout} = await execFileP('df', ['-kP']); - - console.log(parseColumns(stdout, { - transform: (item, header, columnIndex) => { - // Coerce elements in column index 1 to 3 to a number - if (columnIndex >= 1 && columnIndex <= 3) { - return Number(item); - } +const {stdout} = await execFileP('df', ['-kP']); - return item; +console.log(parseColumns(stdout, { + transform: (item, header, columnIndex) => { + // Coerce elements in column index 1 to 3 to a number + if (columnIndex >= 1 && columnIndex <= 3) { + return Number(item); } - })); - // [ - // { - // Filesystem: '/dev/disk1', - // '1024-blocks': 487350400, - // Used: 467528020, - // Available: 19566380, - // Capacity: '96%', - // 'Mounted on': '/' - // }, - // … - // ] -})(); + + return item; + } +})); +// [ +// { +// Filesystem: '/dev/disk1', +// '1024-blocks': 487350400, +// Used: 467528020, +// Available: 19566380, +// Capacity: '96%', +// 'Mounted on': '/' +// }, +// … +// ] ``` */ -declare function parseColumns( +export default function parseColumns( textColumns: string, - options?: parseColumns.Options -): Array<{[key: string]: ValuesType}>; - -export = parseColumns; + options?: Options +): Array>; diff --git a/index.js b/index.js index 6f8197d..b5d4fd6 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,6 @@ -'use strict'; -const execall = require('execall'); -const splitAt = require('split-at'); -const escapeStringRegexp = require('escape-string-regexp'); +import execall from 'execall'; +import splitAt from 'split-at'; +import escapeStringRegexp from 'escape-string-regexp'; /* Algorithm: @@ -46,7 +45,7 @@ const getSplits = (lines, separator) => { return splits; }; -module.exports = (input, options = {}) => { +export default function parseColumns(input, options = {}) { const lines = input.replace(/^\s*\n|\s+$/g, '').split('\n'); let splits = getSplits(lines, options.separator); const {transform} = options; @@ -83,4 +82,4 @@ module.exports = (input, options = {}) => { } return rows; -}; +} diff --git a/index.test-d.ts b/index.test-d.ts index f97ce1c..49d30df 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,14 +1,14 @@ import {expectType} from 'tsd'; -import parseColumns = require('.'); +import parseColumns from './index.js'; -expectType>(parseColumns('foo')); -expectType>( - parseColumns('foo', {separator: ' '}) +expectType>>(parseColumns('foo')); +expectType>>( + parseColumns('foo', {separator: ' '}), ); -expectType>( - parseColumns('foo', {headers: ['foo', 'bar']}) +expectType>>( + parseColumns('foo', {headers: ['foo', 'bar']}), ); -expectType>( +expectType>>( parseColumns('foo', { transform(element, header, columnIndex, rowIndex) { expectType(element); @@ -21,6 +21,6 @@ expectType>( } return element; - } - }) + }, + }), ); diff --git a/license b/license index e7af2f7..fa7ceba 100644 --- a/license +++ b/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus (sindresorhus.com) +Copyright (c) Sindre Sorhus (https://sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/package.json b/package.json index 45dd0bc..fd0b0ae 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,16 @@ "description": "Parse text columns, like the output of Unix commands", "license": "MIT", "repository": "sindresorhus/parse-columns", + "funding": "https://github.com/sponsors/sindresorhus", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" + "url": "https://sindresorhus.com" }, + "type": "module", + "exports": "./index.js", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "scripts": { "test": "xo && ava && tsd" @@ -37,13 +40,13 @@ "table" ], "dependencies": { - "escape-string-regexp": "^2.0.0", - "execall": "^2.0.0", - "split-at": "^2.0.0" + "escape-string-regexp": "^5.0.0", + "execall": "^3.0.0", + "split-at": "^3.0.0" }, "devDependencies": { - "ava": "^2.4.0", - "tsd": "^0.7.2", - "xo": "^0.24.0" + "ava": "^3.15.0", + "tsd": "^0.18.0", + "xo": "^0.46.4" } } diff --git a/readme.md b/readme.md index 7679092..34903c1 100644 --- a/readme.md +++ b/readme.md @@ -2,13 +2,11 @@ > Parse text columns, like the output of Unix commands - ## Install +```sh +npm install parse-columns ``` -$ npm install parse-columns -``` - ## Usage @@ -21,51 +19,48 @@ map -hosts 0 0 0 100% /net ``` ```js -const {promisify} = require('util'); -const childProcess = require('child_process'); -const parseColumns = require('parse-columns'); +import {promisify} from 'node:util'; +import childProcess from 'node:child_process'; +import parseColumns from 'parse-columns'; const execFileP = promisify(childProcess.execFile); -(async () => { - const {stdout} = await execFileP('df', ['-kP']); +const {stdout} = await execFileP('df', ['-kP']); - console.log(parseColumns(stdout, { - transform: (item, header, columnIndex) => { - // Coerce elements in column index 1 to 3 to a number - if (columnIndex >= 1 && columnIndex <= 3) { - return Number(item); - } - - return item; +console.log(parseColumns(stdout, { + transform: (item, header, columnIndex) => { + // Coerce elements in column index 1 to 3 to a number + if (columnIndex >= 1 && columnIndex <= 3) { + return Number(item); } - })); - /* - [ - { - Filesystem: '/dev/disk1', - '1024-blocks': 487350400, - Used: 467528020, - Available: 19566380, - Capacity: '96%', - 'Mounted on': '/' - }, - … - ] - */ -})(); -``` + return item; + } +})); +/* +[ + { + Filesystem: '/dev/disk1', + '1024-blocks': 487350400, + Used: 467528020, + Available: 19566380, + Capacity: '96%', + 'Mounted on': '/' + }, + … +] +*/ +``` ## API -### parseColumns(textColumns, [options]) +### parseColumns(textColumns, options?) #### textColumns Type: `string` -Text columns to parse. +The text columns to parse. #### options @@ -99,12 +94,6 @@ The supplied function gets the following arguments and is expected to return the - `columnIndex` *(number)* - `rowIndex` *(number)* - ## Related - [parse-columns-cli](https://github.com/sindresorhus/parse-columns-cli) - CLI for this module - - -## License - -MIT © [Sindre Sorhus](https://sindresorhus.com) diff --git a/test.js b/test.js index c41e6d6..9d509c8 100644 --- a/test.js +++ b/test.js @@ -1,6 +1,6 @@ -import fs from 'fs'; +import fs from 'node:fs'; import test from 'ava'; -import parseColumns from '.'; +import parseColumns from './index.js'; const fixture1 = fs.readFileSync('fixtures/ps.out', 'utf8'); const fixture2 = fs.readFileSync('fixtures/ps-2.out', 'utf8'); @@ -11,7 +11,7 @@ test.after('benchmark', () => { const count = 30; let total = 0; - for (let i = 0; i < count; i++) { + for (let index = 0; index < count; index++) { const start = Date.now(); parseColumns(fixture3); total += Date.now() - start; @@ -30,8 +30,8 @@ test('headers option', t => { headers: [ 'pid', 'name', - 'cmd' - ] + 'cmd', + ], }); t.is(fixture[0].pid, '238'); t.truthy(fixture[0].name); @@ -44,14 +44,14 @@ test('transform option', t => { t.is(typeof rowIndex, 'number'); t.is(typeof columnIndex, 'number'); return header === 'PID' ? Number(item) : item; - } + }, }); t.is(fixture[0].PID, 238); }); test('separator option', t => { const fixture = parseColumns(fixture2, { - separator: '|' + separator: '|', }); t.is(fixture[0].PID, '238'); }); @@ -60,9 +60,7 @@ test('differing line lengths', t => { const fixture = parseColumns(fixture3); const columns = 'COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME'.split(' '); - t.true(fixture.every(row => { - return Object.keys(row).length === columns.length && columns.every(column => Reflect.has(row, column)); - })); + t.true(fixture.every(row => Object.keys(row).length === columns.length && columns.every(column => Reflect.has(row, column)))); }); test('separators in values', t => { @@ -72,28 +70,28 @@ test('separators in values', t => { { PID: '5971', CMD: 'emacs -nw', - STARTED: 'Oct 29' + STARTED: 'Oct 29', }, { PID: '22678', CMD: 'emacs -nw foo.js', - STARTED: '13:10:36' + STARTED: '13:10:36', }, { PID: '28752', CMD: 'emacs -nw .', - STARTED: 'Oct 28' + STARTED: 'Oct 28', }, { PID: '31236', CMD: 'emacs -nw fixtures/ps-3.out', - STARTED: '17:10:10' + STARTED: '17:10:10', }, { PID: '32513', CMD: 'emacs -nw README.md', - STARTED: 'Oct 28' - } + STARTED: 'Oct 28', + }, ]); }); @@ -111,8 +109,8 @@ test('handles `df` output', t => { Used: '43008', Available: '198640107520', Capacity: '1%', - 'Mounted on': '/run/xo-server/mounts/cbb36e4c-3353-4126-8588-18ba25697403' - } + 'Mounted on': '/run/xo-server/mounts/cbb36e4c-3353-4126-8588-18ba25697403', + }, ]); }); @@ -130,8 +128,8 @@ test('handles `df` output with spaces', t => { Used: '137765660', Available: '105852128', Capacity: '57%', - 'Mounted on': '/media/foo1 2 3 4 5 999' - } + 'Mounted on': '/media/foo1 2 3 4 5 999', + }, ]); }); @@ -147,8 +145,8 @@ test.failing('handles `df` output with spaces and `headers` option', t => { 'used', 'available', 'capacity', - 'mountpoint' - ] + 'mountpoint', + ], }); t.deepEqual(data, [ @@ -159,7 +157,7 @@ test.failing('handles `df` output with spaces and `headers` option', t => { used: '137765660', available: '105852128', capacity: '57%', - mountpoint: '/media/foo1 2 3 4 5 999' - } + mountpoint: '/media/foo1 2 3 4 5 999', + }, ]); });