From 19251fc5ab01bd7143f11562a9954606f28e8113 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Mon, 13 Nov 2023 16:14:01 +0100 Subject: [PATCH] Refactor code-style --- doc/create-a-custom-rule.md | 2 +- package.json | 1 + .../index.js | 37 +++--- .../package.json | 5 +- .../index.js | 37 +++--- .../package.json | 1 - .../index.js | 20 +-- .../package.json | 1 - .../remark-lint-code-block-style/index.js | 41 ++++--- .../remark-lint-code-block-style/package.json | 4 +- packages/remark-lint-definition-case/index.js | 21 ++-- .../remark-lint-definition-case/package.json | 1 - .../remark-lint-definition-spacing/index.js | 21 ++-- .../package.json | 1 - packages/remark-lint-emphasis-marker/index.js | 21 +++- .../remark-lint-emphasis-marker/package.json | 4 +- .../remark-lint-fenced-code-flag/index.js | 51 ++++---- .../remark-lint-fenced-code-flag/package.json | 1 - .../remark-lint-fenced-code-marker/index.js | 25 ++-- .../package.json | 4 +- packages/remark-lint-file-extension/index.js | 14 ++- .../remark-lint-file-extension/package.json | 4 +- .../remark-lint-final-definition/index.js | 16 ++- .../remark-lint-final-definition/package.json | 1 - packages/remark-lint-final-newline/index.js | 10 +- .../remark-lint-final-newline/package.json | 1 - .../remark-lint-first-heading-level/index.js | 48 ++++---- .../package.json | 6 +- .../remark-lint-hard-break-spaces/index.js | 13 +- .../package.json | 1 - .../remark-lint-heading-increment/index.js | 21 ++-- .../package.json | 3 +- packages/remark-lint-heading-style/index.js | 35 ++++-- .../remark-lint-heading-style/package.json | 6 +- packages/remark-lint-linebreak-style/index.js | 14 ++- .../remark-lint-linebreak-style/package.json | 4 +- .../remark-lint-link-title-style/index.js | 38 +++--- .../remark-lint-link-title-style/package.json | 1 - .../index.js | 29 +++-- .../package.json | 2 +- .../index.js | 21 ++-- .../package.json | 1 - .../remark-lint-list-item-indent/index.js | 27 ++-- .../remark-lint-list-item-indent/package.json | 2 - .../remark-lint-list-item-spacing/index.js | 76 +++++++----- .../package.json | 2 - .../index.js | 30 +++-- .../package.json | 6 +- .../remark-lint-maximum-line-length/index.js | 51 ++++---- .../package.json | 1 - .../index.js | 17 ++- .../package.json | 1 - .../index.js | 15 ++- .../package.json | 1 - .../index.js | 24 ++-- .../package.json | 1 - .../index.js | 29 +++-- .../package.json | 2 - .../index.js | 30 +++-- .../package.json | 2 - .../index.js | 42 ++++--- .../package.json | 2 - .../index.js | 31 +++-- .../package.json | 2 - .../index.js | 18 ++- .../package.json | 3 +- packages/remark-lint-no-empty-url/index.js | 23 ++-- .../remark-lint-no-empty-url/package.json | 3 +- .../index.js | 9 +- .../package.json | 1 - .../index.js | 9 +- .../package.json | 1 - .../index.js | 15 ++- .../package.json | 1 - .../index.js | 9 +- .../package.json | 1 - .../index.js | 9 +- .../package.json | 1 - .../index.js | 17 ++- .../package.json | 1 - .../remark-lint-no-heading-indent/index.js | 17 ++- .../package.json | 1 - .../index.js | 19 ++- .../package.json | 3 +- .../index.js | 25 ++-- .../package.json | 3 +- packages/remark-lint-no-html/index.js | 18 ++- packages/remark-lint-no-html/package.json | 3 +- .../remark-lint-no-inline-padding/index.js | 24 ++-- .../package.json | 3 +- packages/remark-lint-no-literal-urls/index.js | 25 ++-- .../remark-lint-no-literal-urls/package.json | 1 - .../index.js | 25 ++-- .../package.json | 2 - .../index.js | 30 +++-- .../package.json | 5 +- .../index.js | 15 ++- .../package.json | 1 - .../index.js | 30 +++-- .../package.json | 3 +- .../remark-lint-no-shell-dollars/index.js | 27 ++-- .../remark-lint-no-shell-dollars/package.json | 3 +- .../index.js | 18 ++- .../package.json | 3 +- .../index.js | 18 ++- .../package.json | 3 +- .../remark-lint-no-table-indentation/index.js | 34 +++-- .../package.json | 1 - packages/remark-lint-no-tabs/index.js | 9 +- packages/remark-lint-no-tabs/package.json | 1 - .../index.js | 116 ++++++++++-------- .../package.json | 2 - .../readme.md | 2 +- .../index.js | 22 ++-- .../package.json | 3 +- .../index.js | 20 +-- .../package.json | 3 +- .../index.js | 86 ++++++++----- .../package.json | 3 +- .../readme.md | 21 ++++ .../index.js | 29 +++-- .../package.json | 1 - .../index.js | 30 +++-- .../package.json | 1 - packages/remark-lint-rule-style/index.js | 32 +++-- packages/remark-lint-rule-style/package.json | 1 - .../remark-lint-strikethrough-marker/index.js | 22 +++- .../package.json | 1 - packages/remark-lint-strong-marker/index.js | 21 +++- .../remark-lint-strong-marker/package.json | 1 - .../remark-lint-table-cell-padding/index.js | 65 ++++++---- .../package.json | 4 +- .../remark-lint-table-cell-padding/readme.md | 4 +- .../remark-lint-table-pipe-alignment/index.js | 13 +- .../package.json | 1 - packages/remark-lint-table-pipes/index.js | 13 +- packages/remark-lint-table-pipes/package.json | 1 - .../index.js | 33 +++-- .../package.json | 1 - packages/remark-lint/index.js | 11 +- packages/remark-lint/readme.md | 16 ++- .../package.json | 1 - .../package.json | 1 - .../package.json | 1 - packages/unified-lint-rule/lib/index.js | 91 ++++++++++---- packages/unified-lint-rule/readme.md | 20 ++- script/build-plugins.js | 27 ++-- script/info.js | 8 +- 148 files changed, 1349 insertions(+), 852 deletions(-) diff --git a/doc/create-a-custom-rule.md b/doc/create-a-custom-rule.md index 9d6ea1b3..e727cef0 100644 --- a/doc/create-a-custom-rule.md +++ b/doc/create-a-custom-rule.md @@ -40,7 +40,7 @@ npm install remark-lint remark-cli We will also use some utilities: ```sh -npm install unified-lint-rule unist-util-generated unist-util-visit +npm install unified-lint-rule unist-util-visit ``` These will help us creating and managing our custom rules. diff --git a/package.json b/package.json index 5d44ce93..a2377d0e 100644 --- a/package.json +++ b/package.json @@ -134,6 +134,7 @@ "type-coverage": "^2.0.0", "type-fest": "^4.0.0", "typescript": "^5.0.0", + "unified": "^11.0.0", "unist-builder": "^4.0.0", "unist-util-remove-position": "^5.0.0", "vfile": "^6.0.0", diff --git a/packages/remark-lint-blockquote-indentation/index.js b/packages/remark-lint-blockquote-indentation/index.js index 9d679f1c..50d42ddd 100644 --- a/packages/remark-lint-blockquote-indentation/index.js +++ b/packages/remark-lint-blockquote-indentation/index.js @@ -79,39 +79,42 @@ */ /** - * @typedef {import('mdast').Blockquote} Blockquote * @typedef {import('mdast').Root} Root */ /** - * @typedef {'consistent' | number} Options - * Options. + * @typedef {number | 'consistent'} Options + * Configuration. */ +import pluralize from 'pluralize' import {lintRule} from 'unified-lint-rule' -import plural from 'pluralize' -import {visit} from 'unist-util-visit' import {pointStart} from 'unist-util-position' -import {generated} from 'unist-util-generated' +import {visit} from 'unist-util-visit' const remarkLintBlockquoteIndentation = lintRule( { origin: 'remark-lint:blockquote-indentation', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-blockquote-indentation#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - visit(tree, 'blockquote', (node) => { - if (generated(node) || node.children.length === 0) { - return - } + /** + * @param {Root} tree + * Tree. + * @param {Options | null | undefined} [options='consistent'] + * Configuration (default: `'consistent'`). + * @returns {undefined} + * Nothing. + */ + function (tree, file, options) { + let option = options || 'consistent' + visit(tree, 'blockquote', function (node) { const start = pointStart(node) const head = pointStart(node.children[0]) - /* c8 ignore next -- we get here if we have offsets. */ - const count = head && start ? head.column - start.column : undefined - if (typeof count === 'number') { + if (head && start) { + const count = head.column - start.column + if (option === 'consistent') { option = count } else { @@ -125,9 +128,9 @@ const remarkLintBlockquoteIndentation = lintRule( ' ' + abs + ' ' + - plural('space', abs) + + pluralize('space', abs) + ' between block quote and content', - pointStart(node.children[0]) + head ) } } diff --git a/packages/remark-lint-blockquote-indentation/package.json b/packages/remark-lint-blockquote-indentation/package.json index d642e9b7..3760f89a 100644 --- a/packages/remark-lint-blockquote-indentation/package.json +++ b/packages/remark-lint-blockquote-indentation/package.json @@ -38,9 +38,7 @@ "dependencies": { "@types/mdast": "^4.0.0", "pluralize": "^8.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", - "unist-util-generated": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" }, @@ -54,7 +52,8 @@ "xo": { "prettier": true, "rules": { - "capitalized-comments": "off" + "capitalized-comments": "off", + "unicorn/prefer-default-parameters": "off" } } } diff --git a/packages/remark-lint-checkbox-character-style/index.js b/packages/remark-lint-checkbox-character-style/index.js index 86f662ac..fb2be875 100644 --- a/packages/remark-lint-checkbox-character-style/index.js +++ b/packages/remark-lint-checkbox-character-style/index.js @@ -92,37 +92,44 @@ */ /** + * @typedef {Styles | 'consistent'} Options + * Configuration. + * * @typedef Styles * Styles. - * @property {'x' | 'X' | 'consistent'} [checked='consistent'] + * @property {'X' | 'x' | 'consistent' | null | undefined} [checked='consistent'] * Preferred style to use for checked checkboxes (default: `'consistent'`). - * @property {' ' | '\t' | 'consistent'} [unchecked='consistent'] + * @property {'\t' | ' ' | 'consistent' | null | undefined} [unchecked='consistent'] * Preferred style to use for unchecked checkboxes (default: `'consistent'`). - * - * @typedef {'consistent' | Styles} Options - * Options. */ import {lintRule} from 'unified-lint-rule' -import {visit} from 'unist-util-visit' import {pointStart} from 'unist-util-position' +import {visit} from 'unist-util-visit' const remarkLintCheckboxCharacterStyle = lintRule( { origin: 'remark-lint:checkbox-character-style', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-character-style#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { + /** + * @param {Root} tree + * Tree. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {undefined} + * Nothing. + */ + function (tree, file, options) { const value = String(file) - /** @type {'x' | 'X' | 'consistent'} */ + /** @type {'X' | 'x' | 'consistent'} */ let checked = 'consistent' - /** @type {' ' | '\x09' | 'consistent'} */ + /** @type {'\x09' | ' ' | 'consistent'} */ let unchecked = 'consistent' - if (typeof option === 'object') { - checked = option.checked || 'consistent' - unchecked = option.unchecked || 'consistent' + if (options && typeof options === 'object') { + checked = options.checked || 'consistent' + unchecked = options.unchecked || 'consistent' } if (unchecked !== 'consistent' && unchecked !== ' ' && unchecked !== '\t') { @@ -141,7 +148,7 @@ const remarkLintCheckboxCharacterStyle = lintRule( ) } - visit(tree, 'listItem', (node) => { + visit(tree, 'listItem', function (node) { const head = node.children[0] const point = pointStart(head) @@ -149,8 +156,8 @@ const remarkLintCheckboxCharacterStyle = lintRule( // A list item cannot be checked and empty, according to GFM. if ( !point || - typeof node.checked !== 'boolean' || !head || + typeof node.checked !== 'boolean' || typeof point.offset !== 'number' ) { return diff --git a/packages/remark-lint-checkbox-character-style/package.json b/packages/remark-lint-checkbox-character-style/package.json index e322c68f..71c41486 100644 --- a/packages/remark-lint-checkbox-character-style/package.json +++ b/packages/remark-lint-checkbox-character-style/package.json @@ -38,7 +38,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" diff --git a/packages/remark-lint-checkbox-content-indent/index.js b/packages/remark-lint-checkbox-content-indent/index.js index 3a19ca7a..09355d29 100644 --- a/packages/remark-lint-checkbox-content-indent/index.js +++ b/packages/remark-lint-checkbox-content-indent/index.js @@ -66,21 +66,26 @@ */ import {lintRule} from 'unified-lint-rule' -import {location} from 'vfile-location' -import {visit} from 'unist-util-visit' import {pointStart} from 'unist-util-position' +import {visit} from 'unist-util-visit' +import {location} from 'vfile-location' const remarkLintCheckboxContentIndent = lintRule( { origin: 'remark-lint:checkbox-content-indent', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-content-indent#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { + /** + * @param {Root} tree + * Tree. + * @returns {undefined} + * Nothing. + */ + function (tree, file) { const value = String(file) const loc = location(file) - visit(tree, 'listItem', (node) => { + visit(tree, 'listItem', function (node) { const head = node.children[0] const point = pointStart(head) @@ -88,8 +93,8 @@ const remarkLintCheckboxContentIndent = lintRule( // A list item cannot be checked and empty, according to GFM. if ( !point || - typeof node.checked !== 'boolean' || !head || + typeof node.checked !== 'boolean' || typeof point.offset !== 'number' ) { return @@ -100,8 +105,7 @@ const remarkLintCheckboxContentIndent = lintRule( value.slice(point.offset - 4, point.offset + 1) ) - // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. - /* c8 ignore next */ + /* c8 ignore next -- make sure we don’t crash if there actually isn’t a checkbox. */ if (!match) return // Move past checkbox. diff --git a/packages/remark-lint-checkbox-content-indent/package.json b/packages/remark-lint-checkbox-content-indent/package.json index 122b8cc2..91ff5e87 100644 --- a/packages/remark-lint-checkbox-content-indent/package.json +++ b/packages/remark-lint-checkbox-content-indent/package.json @@ -38,7 +38,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", diff --git a/packages/remark-lint-code-block-style/index.js b/packages/remark-lint-code-block-style/index.js index ce71701e..7edff7c7 100644 --- a/packages/remark-lint-code-block-style/index.js +++ b/packages/remark-lint-code-block-style/index.js @@ -131,29 +131,38 @@ */ /** - * @typedef {'fenced' | 'indented'} Style + * @typedef {Style | 'consistent'} Options + * Configuration. + * + * @typedef {'indented' | 'fenced'} Style * Styles. - * @typedef {'consistent' | Style} Options - * Options. */ import {lintRule} from 'unified-lint-rule' +import {pointEnd, pointStart} from 'unist-util-position' import {visit} from 'unist-util-visit' -import {pointStart, pointEnd} from 'unist-util-position' const remarkLintCodeBlockStyle = lintRule( { origin: 'remark-lint:code-block-style', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-code-block-style#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { + /** + * @param {Root} tree + * Tree. + * @param {Options | null | undefined} [options='consistent'] + * Configuration (default: `'consistent'`). + * @returns {undefined} + * Nothing. + */ + function (tree, file, options) { + let option = options || 'consistent' const value = String(file) if ( option !== 'consistent' && - option !== 'fenced' && - option !== 'indented' + option !== 'indented' && + option !== 'fenced' ) { file.fail( 'Incorrect code block style `' + @@ -162,22 +171,22 @@ const remarkLintCodeBlockStyle = lintRule( ) } - visit(tree, 'code', (node) => { - const initial = pointStart(node) - const final = pointEnd(node) + visit(tree, 'code', function (node) { + const end = pointEnd(node) + const start = pointStart(node) if ( - !initial || - !final || - typeof initial.offset !== 'number' || - typeof final.offset !== 'number' + !start || + !end || + typeof start.offset !== 'number' || + typeof end.offset !== 'number' ) { return } const current = node.lang || - /^\s*([~`])\1{2,}/.test(value.slice(initial.offset, final.offset)) + /^\s*([~`])\1{2,}/.test(value.slice(start.offset, end.offset)) ? 'fenced' : 'indented' diff --git a/packages/remark-lint-code-block-style/package.json b/packages/remark-lint-code-block-style/package.json index a76a9c96..e4f69f98 100644 --- a/packages/remark-lint-code-block-style/package.json +++ b/packages/remark-lint-code-block-style/package.json @@ -36,7 +36,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" @@ -51,7 +50,8 @@ "xo": { "prettier": true, "rules": { - "capitalized-comments": "off" + "capitalized-comments": "off", + "unicorn/prefer-default-parameters": "off" } } } diff --git a/packages/remark-lint-definition-case/index.js b/packages/remark-lint-definition-case/index.js index 1c0207eb..1dda3045 100644 --- a/packages/remark-lint-definition-case/index.js +++ b/packages/remark-lint-definition-case/index.js @@ -42,8 +42,8 @@ */ import {lintRule} from 'unified-lint-rule' +import {pointEnd, pointStart} from 'unist-util-position' import {visit} from 'unist-util-visit' -import {pointStart, pointEnd} from 'unist-util-position' const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/ @@ -52,20 +52,25 @@ const remarkLintDefinitionCase = lintRule( origin: 'remark-lint:definition-case', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-definition-case#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { + /** + * @param {Root} tree + * Tree. + * @returns {undefined} + * Nothing. + */ + function (tree, file) { const value = String(file) - visit(tree, (node) => { + visit(tree, function (node) { if (node.type === 'definition' || node.type === 'footnoteDefinition') { - const start = pointStart(node) const end = pointEnd(node) + const start = pointStart(node) if ( - start && end && - typeof start.offset === 'number' && - typeof end.offset === 'number' + start && + typeof end.offset === 'number' && + typeof start.offset === 'number' ) { const match = value.slice(start.offset, end.offset).match(label) diff --git a/packages/remark-lint-definition-case/package.json b/packages/remark-lint-definition-case/package.json index 2fc4ef09..0148cae5 100644 --- a/packages/remark-lint-definition-case/package.json +++ b/packages/remark-lint-definition-case/package.json @@ -36,7 +36,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" diff --git a/packages/remark-lint-definition-spacing/index.js b/packages/remark-lint-definition-spacing/index.js index 3e31393f..a7fd345d 100644 --- a/packages/remark-lint-definition-spacing/index.js +++ b/packages/remark-lint-definition-spacing/index.js @@ -44,8 +44,8 @@ */ import {lintRule} from 'unified-lint-rule' -import {visit} from 'unist-util-visit' import {pointStart, pointEnd} from 'unist-util-position' +import {visit} from 'unist-util-visit' const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/ @@ -54,20 +54,25 @@ const remarkLintDefinitionSpacing = lintRule( origin: 'remark-lint:definition-spacing', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-definition-spacing#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { + /** + * @param {Root} tree + * Tree. + * @returns {undefined} + * Nothing. + */ + function (tree, file) { const value = String(file) - visit(tree, (node) => { + visit(tree, function (node) { if (node.type === 'definition' || node.type === 'footnoteDefinition') { - const start = pointStart(node) const end = pointEnd(node) + const start = pointStart(node) if ( - start && end && - typeof start.offset === 'number' && - typeof end.offset === 'number' + start && + typeof end.offset === 'number' && + typeof start.offset === 'number' ) { const match = value.slice(start.offset, end.offset).match(label) diff --git a/packages/remark-lint-definition-spacing/package.json b/packages/remark-lint-definition-spacing/package.json index e1021375..3b488d22 100644 --- a/packages/remark-lint-definition-spacing/package.json +++ b/packages/remark-lint-definition-spacing/package.json @@ -36,7 +36,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" diff --git a/packages/remark-lint-emphasis-marker/index.js b/packages/remark-lint-emphasis-marker/index.js index 3bcc5abb..8312725b 100644 --- a/packages/remark-lint-emphasis-marker/index.js +++ b/packages/remark-lint-emphasis-marker/index.js @@ -93,22 +93,31 @@ /** * @typedef {'*' | '_'} Marker * Styles. - * @typedef {'consistent' | Marker} Options - * Options. + * + * @typedef {Marker | 'consistent'} Options + * Configuration. */ import {lintRule} from 'unified-lint-rule' -import {visit} from 'unist-util-visit' import {pointStart} from 'unist-util-position' +import {visit} from 'unist-util-visit' const remarkLintEmphasisMarker = lintRule( { origin: 'remark-lint:emphasis-marker', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-emphasis-marker#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { + /** + * @param {Root} tree + * Tree. + * @param {Options | null | undefined} [options='consistent'] + * Configuration (default: `'consistent`'). + * @returns {undefined} + * Nothing. + */ + function (tree, file, options) { const value = String(file) + let option = options || 'consistent' if (option !== '*' && option !== '_' && option !== 'consistent') { file.fail( @@ -118,7 +127,7 @@ const remarkLintEmphasisMarker = lintRule( ) } - visit(tree, 'emphasis', (node) => { + visit(tree, 'emphasis', function (node) { const start = pointStart(node) if (start && typeof start.offset === 'number') { diff --git a/packages/remark-lint-emphasis-marker/package.json b/packages/remark-lint-emphasis-marker/package.json index 6c619890..04a1e834 100644 --- a/packages/remark-lint-emphasis-marker/package.json +++ b/packages/remark-lint-emphasis-marker/package.json @@ -36,7 +36,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" @@ -51,7 +50,8 @@ "xo": { "prettier": true, "rules": { - "capitalized-comments": "off" + "capitalized-comments": "off", + "unicorn/prefer-default-parameters": "off" } } } diff --git a/packages/remark-lint-fenced-code-flag/index.js b/packages/remark-lint-fenced-code-flag/index.js index 5b9e52e5..8e10c16f 100644 --- a/packages/remark-lint-fenced-code-flag/index.js +++ b/packages/remark-lint-fenced-code-flag/index.js @@ -100,23 +100,23 @@ */ /** - * @typedef {Array} Flags - * Language flags. - * * @typedef FlagMap * Configuration. - * @property {Flags} [flags] - * Language flags. - * @property {boolean} [allowEmpty=false] + * @property {boolean | null | undefined} [allowEmpty=false] * Allow language flags to be omitted (default: `false`). + * @property {Flags | null | undefined} [flags] + * Language flags (optional). + * + * @typedef {Array} Flags + * Language flags. * - * @typedef {Flags | FlagMap} Options - * Options. + * @typedef {FlagMap | Flags} Options + * Configuration. */ import {lintRule} from 'unified-lint-rule' +import {pointEnd, pointStart} from 'unist-util-position' import {visit} from 'unist-util-visit' -import {pointStart, pointEnd} from 'unist-util-position' const fence = /^ {0,3}([~`])\1{2,}/ @@ -125,34 +125,41 @@ const remarkLintFencedCodeFlag = lintRule( origin: 'remark-lint:fenced-code-flag', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-flag#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option) => { + /** + * @param {Root} tree + * Tree. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {undefined} + * Nothing. + */ + function (tree, file, options) { const value = String(file) let allowEmpty = false /** @type {Array} */ let allowed = [] - if (typeof option === 'object') { - if (Array.isArray(option)) { - allowed = option + if (options && typeof options === 'object') { + if (Array.isArray(options)) { + allowed = options } else { - allowEmpty = Boolean(option.allowEmpty) + allowEmpty = Boolean(options.allowEmpty) - if (option.flags) { - allowed = option.flags + if (options.flags) { + allowed = options.flags } } } - visit(tree, 'code', (node) => { - const start = pointStart(node) + visit(tree, 'code', function (node) { const end = pointEnd(node) + const start = pointStart(node) if ( - start && end && - typeof start.offset === 'number' && - typeof end.offset === 'number' + start && + typeof end.offset === 'number' && + typeof start.offset === 'number' ) { if (node.lang) { if (allowed.length > 0 && !allowed.includes(node.lang)) { diff --git a/packages/remark-lint-fenced-code-flag/package.json b/packages/remark-lint-fenced-code-flag/package.json index d7814d3f..feeda9c6 100644 --- a/packages/remark-lint-fenced-code-flag/package.json +++ b/packages/remark-lint-fenced-code-flag/package.json @@ -38,7 +38,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" diff --git a/packages/remark-lint-fenced-code-marker/index.js b/packages/remark-lint-fenced-code-marker/index.js index adbd0022..663f12b8 100644 --- a/packages/remark-lint-fenced-code-marker/index.js +++ b/packages/remark-lint-fenced-code-marker/index.js @@ -105,23 +105,32 @@ */ /** - * @typedef {'~' | '`'} Marker + * @typedef {'`' | '~'} Marker * Styles. - * @typedef {'consistent' | Marker} Options - * Options. + * + * @typedef {Marker | 'consistent'} Options + * Configuration. */ import {lintRule} from 'unified-lint-rule' -import {visit} from 'unist-util-visit' import {pointStart} from 'unist-util-position' +import {visit} from 'unist-util-visit' const remarkLintFencedCodeMarker = lintRule( { origin: 'remark-lint:fenced-code-marker', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-marker#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { + /** + * @param {Root} tree + * Tree. + * @param {Options | null | undefined} [options='consistent'] + * Configuration (default: `'consistent'`). + * @returns {undefined} + * Nothing. + */ + function (tree, file, options) { + let option = options || 'consistent' const contents = String(file) if (option !== 'consistent' && option !== '~' && option !== '`') { @@ -132,7 +141,7 @@ const remarkLintFencedCodeMarker = lintRule( ) } - visit(tree, 'code', (node) => { + visit(tree, 'code', function (node) { const start = pointStart(node) if (start && typeof start.offset === 'number') { @@ -142,7 +151,7 @@ const remarkLintFencedCodeMarker = lintRule( .charAt(0) // Ignore unfenced code blocks. - if (marker === '~' || marker === '`') { + if (marker === '`' || marker === '~') { if (option === 'consistent') { option = marker } else if (marker !== option) { diff --git a/packages/remark-lint-fenced-code-marker/package.json b/packages/remark-lint-fenced-code-marker/package.json index 16af4eb7..966d0275 100644 --- a/packages/remark-lint-fenced-code-marker/package.json +++ b/packages/remark-lint-fenced-code-marker/package.json @@ -37,7 +37,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0" @@ -52,7 +51,8 @@ "xo": { "prettier": true, "rules": { - "capitalized-comments": "off" + "capitalized-comments": "off", + "unicorn/prefer-default-parameters": "off" } } } diff --git a/packages/remark-lint-file-extension/index.js b/packages/remark-lint-file-extension/index.js index 3b6134cc..79bb33d3 100644 --- a/packages/remark-lint-file-extension/index.js +++ b/packages/remark-lint-file-extension/index.js @@ -47,7 +47,7 @@ /** * @typedef {string} Options - * Options. + * Configuration. */ import {lintRule} from 'unified-lint-rule' @@ -57,8 +57,16 @@ const remarkLintFileExtension = lintRule( origin: 'remark-lint:file-extension', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-file-extension#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (_, file, option = 'md') => { + /** + * @param {Root} _ + * Tree. + * @param {Options | null | undefined} [options] + * Configuration (default: `'md'`). + * @returns {undefined} + * Nothing. + */ + function (_, file, options) { + const option = options || 'md' const ext = file.extname if (ext && ext.slice(1) !== option) { diff --git a/packages/remark-lint-file-extension/package.json b/packages/remark-lint-file-extension/package.json index 008017c7..2fb46df2 100644 --- a/packages/remark-lint-file-extension/package.json +++ b/packages/remark-lint-file-extension/package.json @@ -37,7 +37,6 @@ ], "dependencies": { "@types/mdast": "^4.0.0", - "unified": "^11.0.0", "unified-lint-rule": "^2.0.0" }, "scripts": {}, @@ -50,7 +49,8 @@ "xo": { "prettier": true, "rules": { - "capitalized-comments": "off" + "capitalized-comments": "off", + "unicorn/prefer-default-parameters": "off" } } } diff --git a/packages/remark-lint-final-definition/index.js b/packages/remark-lint-final-definition/index.js index 3ee95667..aca1c8d8 100644 --- a/packages/remark-lint-final-definition/index.js +++ b/packages/remark-lint-final-definition/index.js @@ -59,27 +59,33 @@ */ import {lintRule} from 'unified-lint-rule' -import {visit} from 'unist-util-visit' import {pointStart} from 'unist-util-position' +import {visit} from 'unist-util-visit' const remarkLintFinalDefinition = lintRule( { origin: 'remark-lint:final-definition', url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-final-definition#readme' }, - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { + /** + * @param {Root} tree + * Tree. + * @returns {undefined} + * Nothing. + */ + function (tree, file) { let last = 0 visit( tree, - (node) => { + function (node) { const start = pointStart(node) + // To do: ignore MDX comments? // Ignore generated and HTML comment nodes. if ( - node.type === 'root' || !start || + node.type === 'root' || (node.type === 'html' && /^\s*`). * All rules are in their own packages and presets. * * @this {import('unified').Processor} - * @type {import('unified').Plugin, Root>} */ export default function remarkLint() { this.use(lintMessageControl) } -/** @type {import('unified').Plugin, Root>} */ +/** + * @returns + * Transform. + */ function lintMessageControl() { return remarkMessageControl({name: 'lint', source: 'remark-lint'}) } diff --git a/packages/remark-lint/readme.md b/packages/remark-lint/readme.md index 7df05975..a3f7e5fe 100644 --- a/packages/remark-lint/readme.md +++ b/packages/remark-lint/readme.md @@ -64,20 +64,18 @@ In browsers with [`esm.sh`][esmsh]: On the API: ```js -import {read} from 'to-vfile' -import {reporter} from 'vfile-reporter' import {remark} from 'remark' import remarkLint from 'remark-lint' +import {read} from 'to-vfile' +import {reporter} from 'vfile-reporter' -main() +const file = await read('example.md') -async function main() { - const file = await remark() - .use(remarkLint) - .process(await read('example.md')) +await remark() + .use(remarkLint) + .process(file) - console.error(reporter(file)) -} +console.error(reporter(file)) ``` On the CLI: diff --git a/packages/remark-preset-lint-consistent/package.json b/packages/remark-preset-lint-consistent/package.json index 8ea80da5..83388cd9 100644 --- a/packages/remark-preset-lint-consistent/package.json +++ b/packages/remark-preset-lint-consistent/package.json @@ -34,7 +34,6 @@ "index.js" ], "dependencies": { - "@types/mdast": "^4.0.0", "remark-lint": "^9.0.0", "remark-lint-blockquote-indentation": "^3.0.0", "remark-lint-checkbox-character-style": "^4.0.0", diff --git a/packages/remark-preset-lint-markdown-style-guide/package.json b/packages/remark-preset-lint-markdown-style-guide/package.json index 8af58cac..dac4f5f7 100644 --- a/packages/remark-preset-lint-markdown-style-guide/package.json +++ b/packages/remark-preset-lint-markdown-style-guide/package.json @@ -35,7 +35,6 @@ "index.js" ], "dependencies": { - "@types/mdast": "^4.0.0", "remark-lint": "^9.0.0", "remark-lint-blockquote-indentation": "^3.0.0", "remark-lint-code-block-style": "^3.0.0", diff --git a/packages/remark-preset-lint-recommended/package.json b/packages/remark-preset-lint-recommended/package.json index f70e418c..0a6f9596 100644 --- a/packages/remark-preset-lint-recommended/package.json +++ b/packages/remark-preset-lint-recommended/package.json @@ -33,7 +33,6 @@ "index.js" ], "dependencies": { - "@types/mdast": "^4.0.0", "remark-lint": "^9.0.0", "remark-lint-final-newline": "^2.0.0", "remark-lint-hard-break-spaces": "^3.0.0", diff --git a/packages/unified-lint-rule/lib/index.js b/packages/unified-lint-rule/lib/index.js index 59102845..36545ae9 100644 --- a/packages/unified-lint-rule/lib/index.js +++ b/packages/unified-lint-rule/lib/index.js @@ -4,39 +4,53 @@ */ /** - * @typedef {0 | 1 | 2} Severity - * Numeric severity (`0`: `'off'`, `1`: `'on'`, `2`: `'error'`). - * @typedef {'warn' | 'on' | 'off' | 'error'} Label + * @typedef {'error' | 'on' | 'off' | 'warn'} Label * Severity label (`'off'`: `0`, `'on'`: `1`, `'error'`: `2`). - * @typedef {[Severity, ...Array]} SeverityTuple - * Parsed severty and options. * * @typedef RuleMeta * Rule metadata. * @property {string} origin * Name of the lint rule. * @property {string | null | undefined} [url] - * Link to documentation. + * Link to documentation (optional). + * + * @typedef {0 | 1 | 2} Severity + * Numeric severity (`0`: `'off'`, `1`: `'on'`, `2`: `'error'`). + * + * @typedef {[severity: Severity, ...parameters: Array]} SeverityTuple + * Parsed severty and options. */ /** * @template {Node} [Tree=Node] - * @template {any} [Options=unknown] + * Node kind (optional). + * @template {any} [Option=unknown] + * Parameter kind (optional). * @callback Rule + * Rule. * @param {Tree} tree + * Tree. * @param {VFile} file - * @param {Options} options + * File. + * @param {Option} option + * Parameter. * @returns {Promise | Tree | undefined | void} + * Result. */ import {wrap} from 'trough' /** * @template {Node} [Tree=Node] - * @template {any} [Options=unknown] - * @param {string | RuleMeta} meta - * @param {Rule} rule - * @returns {import('unified').Plugin | [Options | [boolean | Label | Severity, (Options | undefined)?]], Tree>} + * Node kind. + * @template {any} [Option=unknown] + * Parameter kind. + * @param {RuleMeta | string} meta + * Info. + * @param {Rule} rule + * Rule. + * @returns + * Plugin. */ export function lintRule(meta, rule) { const id = typeof meta === 'string' ? meta : meta.origin @@ -49,21 +63,35 @@ export function lintRule(meta, rule) { Object.defineProperty(plugin, 'name', {value: id}) - // @ts-expect-error: to do: fix. return plugin - /** @type {import('unified').Plugin<[unknown] | Array>} */ + /** + * @param {Option | [level: Label | Severity, option?: Option]} [config] + * Config. + * @returns + * Transform, if on. + */ function plugin(config) { const [severity, options] = coerce(ruleId, config) - if (!severity) return - const fatal = severity === 2 - return (tree, file, next) => { + if (!severity) return + + /** + * @param {Tree} tree + * Tree. + * @param {VFile} file + * File. + * @param {import('unified').TransformCallback} next + * Next. + * @returns {undefined} + * Nothing. + */ + return function (tree, file, next) { let index = file.messages.length - 1 - wrap(rule, (error) => { + wrap(rule, function (error) { const messages = file.messages // Add the error, if not already properly added. @@ -77,7 +105,7 @@ export function lintRule(meta, rule) { } while (++index < messages.length) { - Object.assign(messages[index], {ruleId, source, fatal, url}) + Object.assign(messages[index], {fatal, ruleId, source, url}) } next() @@ -90,34 +118,43 @@ export function lintRule(meta, rule) { * Coerce a value to a severity--options tuple. * * @param {string} name + * Rule name. * @param {unknown} config + * Configuration. * @returns {SeverityTuple} + * Severity and options. */ function coerce(name, config) { - if (!Array.isArray(config)) return [1, config] + if (!Array.isArray(config)) { + return [1, config] + } + /** @type {Array} */ const [severity, ...options] = config switch (severity) { case false: - case 'off': - case 0: { + case 0: + case 'off': { return [0, ...options] } case true: + case 1: case 'on': - case 'warn': - case 1: { + case 'warn': { return [1, ...options] } - case 'error': - case 2: { + case 2: + case 'error': { return [2, ...options] } default: { - if (typeof severity !== 'number') return [1, config] + if (typeof severity !== 'number') { + return [1, config] + } + throw new Error( 'Incorrect severity `' + severity + diff --git a/packages/unified-lint-rule/readme.md b/packages/unified-lint-rule/readme.md index 3421575b..3d5c5148 100644 --- a/packages/unified-lint-rule/readme.md +++ b/packages/unified-lint-rule/readme.md @@ -63,12 +63,28 @@ In browsers with [`esm.sh`][esmsh]: ## Use ```js +/** + * @typedef {import('mdast').Root} Root + */ + +/** + * @typedef {string} Options + * Configuration. + */ + import {lintRule} from 'unified-lint-rule' const remarkLintFileExtension = lintRule( 'remark-lint:file-extension', - (tree, file, option = 'md') => { - var ext = file.extname + /** + * @param {Root} tree + * Tree. + * @param {Options | null | undefined} options + * Configuration (default: `'md'`). + */ + function (tree, file, options) { + const ext = file.extname + const option = options || 'md' if (ext && ext.slice(1) !== option) { file.message('Incorrect extension: use `' + option + '`') diff --git a/script/build-plugins.js b/script/build-plugins.js index 9fedc6f4..f1b36d56 100644 --- a/script/build-plugins.js +++ b/script/build-plugins.js @@ -72,8 +72,8 @@ while (++index < plugins.length) { assert.equal(info.name, pack.name, 'expected correct package name') - /** @type {Record>} */ - const categories = {} + /** @type {Map>} */ + const categories = new Map() let category = 'Intro' let contentIndex = -1 @@ -84,11 +84,14 @@ while (++index < plugins.length) { category = githubSlug(toString(node)) } - if (!(category in categories)) { - categories[category] = [] + let list = categories.get(category) + + if (!list) { + list = [] + categories.set(category, list) } - categories[category].push(node) + list.push(node) } const includes = presets.filter(function (preset) { @@ -255,7 +258,7 @@ while (++index < plugins.length) { } ] }, - ...(categories['when-should-i-use-this'] || []), + ...(categories.get('when-should-i-use-this') || []), { type: 'heading', depth: 2, @@ -495,8 +498,10 @@ while (++index < plugins.length) { } ) - if ('api' in categories) { - const [apiHeading, ...apiBody] = categories.api + const apiCategory = categories.get('api') + + if (apiCategory) { + const [apiHeading, ...apiBody] = apiCategory children.push( apiHeading, @@ -541,9 +546,9 @@ while (++index < plugins.length) { } children.push( - ...(categories.recommendation || []), - ...(categories.fix || []), - ...(categories.example || []) + ...(categories.get('recommendation') || []), + ...(categories.get('fix') || []), + ...(categories.get('example') || []) ) let first = true diff --git a/script/info.js b/script/info.js index ce459fbd..2a897d1d 100644 --- a/script/info.js +++ b/script/info.js @@ -21,13 +21,13 @@ * @typedef ExampleInfo * Example. * @property {unknown} [config] - * Configuration. + * Configuration (optional). * @property {boolean} [gfm] - * Whether to use GFM. + * Whether to use GFM (optional). * @property {'input' | 'output'} [label] - * Label. + * Label (optional). * @property {boolean} [positionless] - * Whether this check also applies without positions. + * Whether this check also applies without positions (optional). * @property {string} name * Name. *