Skip to content

Commit

Permalink
Fix type errors
Browse files Browse the repository at this point in the history
Since typical usage of `unified-lint-rule` involves inferring the type
based on a function call, the inferred type should be public. If private
types are used, TypeScript will generate types for dependant packages
that use relative paths.

To solve this, public types in `unified-lint-rule` were moved from
`lib/index.js` to `index.js`. `lintRule` only uses these public types.

The severity can be set as a boolean. To support this, the `Label` type
now accepts a boolean type.

Two tests explicitly test bad input. These are annotated with a
`@ts-expect-error` comment.
  • Loading branch information
remcohaszing committed Apr 23, 2024
1 parent a87a9d1 commit c1cdd52
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 55 deletions.
36 changes: 31 additions & 5 deletions packages/unified-lint-rule/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,41 @@
*/

/**
* @typedef {import('./lib/index.js').Label} Label
* @typedef {import('./lib/index.js').Meta} Meta
* @typedef {import('./lib/index.js').Severity} Severity
* @typedef {'error' | 'on' | 'off' | 'warn' | boolean} Label
* Severity label;
* `'off'`: `0`, `'on'` and `warn`: `1`, `'error'`: `2`.
*/

/**
* @typedef Meta
* Rule metadata.
* @property {string} origin
* Name of the lint rule.
* @property {string | null | undefined} [url]
* Link to documentation (optional).
*/

/**
* @typedef {0 | 1 | 2} Severity
* Severity number;
* `0`: `'off'`, `1`: `'on'` and `warn`, `2`: `'error'`.
*/

/**
* @template {Node} [Tree=Node]
* @template {any} [Options=unknown]
* @typedef {import('./lib/index.js').Rule<Tree, Options>} Rule
* Node kind (optional).
* @template {any} [Option=unknown]
* Parameter kind (optional).
* @callback Rule
* Rule.
* @param {Tree} tree
* Tree.
* @param {import('vfile').VFile} file
* File.
* @param {Option} option
* Parameter.
* @returns {Promise<undefined | void> | undefined | void}
* Nothing.
*/

export {lintRule} from './lib/index.js'
63 changes: 13 additions & 50 deletions packages/unified-lint-rule/lib/index.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,29 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('vfile').VFile} VFile
*/

/**
* @typedef {'error' | 'on' | 'off' | 'warn'} Label
* Severity label;
* `'off'`: `0`, `'on'` and `warn`: `1`, `'error'`: `2`.
*
* @typedef Meta
* Rule metadata.
* @property {string} origin
* Name of the lint rule.
* @property {string | null | undefined} [url]
* Link to documentation (optional).
*
* @typedef {0 | 1 | 2} Severity
* Severity number;
* `0`: `'off'`, `1`: `'on'` and `warn`, `2`: `'error'`.
*
* @typedef {[severity: Severity, ...parameters: Array<unknown>]} SeverityTuple
* @typedef {[severity: import('../index.js').Severity, ...parameters: Array<unknown>]} SeverityTuple
* Parsed severty and options.
*/

/**
* @template {Node} [Tree=Node]
* Node kind (optional).
* @template {any} [Option=unknown]
* Parameter kind (optional).
* @callback Rule
* Rule.
* @param {Tree} tree
* Tree.
* @param {VFile} file
* File.
* @param {Option} option
* Parameter.
* @returns {Promise<undefined | void> | undefined | void}
* Nothing.
*/

import {wrap} from 'trough'

/**
* @template {Node} [Tree=Node]
* Node kind.
* @template {any} [Option=unknown]
* @template {any} [Option=never]
* Parameter kind.
* @param {Meta | string} meta
* @param {import('../index.js').Meta | string} meta
* Info.
* @param {Rule<Tree, Option>} rule
* @param {import('../index.js').Rule<Tree, Option>} rule
* Rule.
* @returns
* @returns {import('unified').Plugin<[(
* | [level: import('../index.js').Label | import('../index.js').Severity, option?: Option]
* | import('../index.js').Label
* | Option
* | import('../index.js').Severity
* )?], Tree>}
* Plugin.
*/
export function lintRule(meta, rule) {
Expand All @@ -64,12 +36,13 @@ export function lintRule(meta, rule) {

Object.defineProperty(plugin, 'name', {value: id})

// @ts-expect-error Not sure what’s going on here, but it works.
return plugin

/**
* @param {[level: Label | Severity, option?: Option] | Label | Option | Severity} [config]
* @param {[level: import('../index.js').Label | import('../index.js').Severity, option?: Option] | import('../index.js').Label | Option | import('../index.js').Severity} [config]
* Config.
* @returns
* @returns {import('unified').Transformer<Tree> | undefined}
* Transform, if on.
*/
function plugin(config) {
Expand All @@ -79,16 +52,6 @@ export function lintRule(meta, rule) {

if (!severity) return

/**
* @param {Tree} tree
* Tree.
* @param {VFile} file
* File.
* @param {import('unified').TransformCallback<Tree>} next
* Next.
* @returns {undefined}
* Nothing.
*/
return function (tree, file, next) {
let index = file.messages.length - 1

Expand Down
2 changes: 2 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ test('remark-lint', async function (t) {
'should fail on incorrect severities (too high)',
async function () {
assert.throws(function () {
// @ts-expect-error This tests an incorrect severity.
remark().use(remarkLintFinalNewline, [3]).freeze()
}, /^Error: Incorrect severity `3` for `final-newline`, expected 0, 1, or 2$/)
}
Expand All @@ -241,6 +242,7 @@ test('remark-lint', async function (t) {
'should fail on incorrect severities (too low)',
async function () {
assert.throws(function () {
// @ts-expect-error This tests an incorrect severity.
remark().use(remarkLintFinalNewline, [-1]).freeze()
}, /^Error: Incorrect severity `-1` for `final-newline`, expected 0, 1, or 2$/)
}
Expand Down

0 comments on commit c1cdd52

Please sign in to comment.