From 2666fd4e67ff90fcaca3c7530b46006c0430f221 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Thu, 18 Mar 2021 12:13:30 +0100 Subject: [PATCH] Add JSDoc based types --- .gitignore | 1 + index.js | 65 +++++++++++++++++++++++++++++++++++++++++---------- package.json | 20 +++++++++++----- readme.md | 2 +- test.js | 9 ++++++- tsconfig.json | 16 +++++++++++++ 6 files changed, 93 insertions(+), 20 deletions(-) create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index 735f4af..c977c85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +*.d.ts *.log coverage/ node_modules/ diff --git a/index.js b/index.js index cfa4e7a..2100909 100644 --- a/index.js +++ b/index.js @@ -1,26 +1,56 @@ import repeat from 'repeat-string' -// Create a table from a matrix of strings. +/** + * @typedef MarkdownTableOptions + * @property {string|string[]} [align] + * @property {boolean} [padding=true] + * @property {boolean} [delimiterStart=true] + * @property {boolean} [delimiterStart=true] + * @property {boolean} [delimiterEnd=true] + * @property {boolean} [alignDelimiters=true] + * @property {(value: string) => number} [stringLength] + */ + +/** + * Create a table from a matrix of strings. + * + * @param {string[][]} table + * @param {MarkdownTableOptions} [options] + * @returns {string} + */ export function markdownTable(table, options) { var settings = options || {} var align = (settings.align || []).concat() var stringLength = settings.stringLength || defaultStringLength + /** @type {number[]} Character codes as symbols for alignment per column. */ var alignments = [] var rowIndex = -1 + /** @type {string[][]} Cells per row. */ var cellMatrix = [] + /** @type {number[][]} Sizes of each cell per row. */ var sizeMatrix = [] + /** @type {number[]} */ var longestCellByColumn = [] var mostCellsPerRow = 0 + /** @type {number} */ var columnIndex + /** @type {string[]} Cells of current row */ var row + /** @type {number[]} Sizes of current row */ var sizes - var largest + /** @type {number} Sizes of current cell */ var size + /** @type {string} Current cell */ var cell + /** @type {string[]} */ var lines + /** @type {string[]} Chunks of current line. */ var line + /** @type {string} */ var before + /** @type {string} */ var after + /** @type {number} */ var code // This is a superfluous loop if we don’t align delimiters, but otherwise we’d @@ -41,9 +71,10 @@ export function markdownTable(table, options) { size = stringLength(cell) sizes[columnIndex] = size - largest = longestCellByColumn[columnIndex] - - if (largest === undefined || size > largest) { + if ( + longestCellByColumn[columnIndex] === undefined || + size > longestCellByColumn[columnIndex] + ) { longestCellByColumn[columnIndex] = size } } @@ -186,26 +217,36 @@ export function markdownTable(table, options) { } } - line = line.join('') - - if (settings.delimiterEnd === false) { - line = line.replace(/ +$/, '') - } - - lines.push(line) + lines.push( + settings.delimiterEnd === false + ? line.join('').replace(/ +$/, '') + : line.join('') + ) } return lines.join('\n') } +/** + * @param {string|null|undefined} [value] + * @returns {string} + */ function serialize(value) { return value === null || value === undefined ? '' : String(value) } +/** + * @param {string} value + * @returns {number} + */ function defaultStringLength(value) { return value.length } +/** + * @param {string} value + * @returns {number} + */ function toAlignment(value) { var code = typeof value === 'string' ? value.charCodeAt(0) : 0 diff --git a/package.json b/package.json index 6259508..083911b 100644 --- a/package.json +++ b/package.json @@ -24,28 +24,37 @@ "sideEffects": false, "type": "module", "main": "index.js", + "types": "index.d.ts", "files": [ + "index.d.ts", "index.js" ], "dependencies": { + "@types/repeat-string": "^1.0.0", "repeat-string": "^1.0.0" }, "devDependencies": { + "@types/tape": "^4.0.0", "c8": "^7.0.0", "chalk": "^4.0.0", "nyc": "^15.0.0", "prettier": "^2.0.0", "remark-cli": "^9.0.0", "remark-preset-wooorm": "^8.0.0", + "rimraf": "^3.0.0", "strip-ansi": "^6.0.0", "tape": "^5.0.0", + "type-coverage": "^2.0.0", + "typescript": "^4.0.0", "xo": "^0.38.0" }, "scripts": { + "prepack": "npm run build && npm run format", + "build": "rimraf \"*.d.ts\" && tsc && type-coverage", "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", "test-api": "node test.js", "test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js", - "test": "npm run format && npm run test-coverage" + "test": "npm run build && npm run format && npm run test-coverage" }, "remarkConfig": { "plugins": [ @@ -68,10 +77,9 @@ "prefer-arrow-callback": "off" } }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 + "typeCoverage": { + "atLeast": 100, + "detail": true, + "strict": true } } diff --git a/readme.md b/readme.md index a7cf92c..a3e0f68 100644 --- a/readme.md +++ b/readme.md @@ -81,7 +81,7 @@ Turns a given matrix of strings (an array of arrays of strings) into a table. ###### `options.align` One style for all columns, or styles for their respective columns (`string` or -`Array.`). +`string[]`). Each style is either `'l'` (left), `'r'` (right), or `'c'` (center). Other values are treated as `''`, which doesn’t place the colon in the alignment row but does align left. diff --git a/test.js b/test.js index 7953b30..4a41885 100644 --- a/test.js +++ b/test.js @@ -23,10 +23,13 @@ test('markdownTable()', function (t) { markdownTable([ ['Type', 'Value'], ['string', 'alpha'], + // @ts-ignore ['number', 1], + // @ts-ignore ['boolean', true], ['undefined', undefined], ['null', null], + // @ts-ignore ['Array', [1, 2, 3]] ]), [ @@ -285,7 +288,11 @@ test('markdownTable()', function (t) { t.end() }) -// Get the length of a string, minus ANSI color characters. +/** + * Get the length of a string, minus ANSI color characters. + * @param {string} value + * @returns {number} + */ function stringLength(value) { return strip(value).length } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8ac10fe --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,16 @@ +{ + "files": ["index.js"], + "include": ["*.js"], + "compilerOptions": { + "target": "ES2020", + "lib": ["ES2020"], + "module": "ES2020", + "moduleResolution": "node", + "allowJs": true, + "checkJs": true, + "declaration": true, + "emitDeclarationOnly": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true + } +}