Skip to content

Commit 780659d

Browse files
committed
Add JSDoc based types
1 parent 20528b4 commit 780659d

File tree

5 files changed

+104
-12
lines changed

5 files changed

+104
-12
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
2+
*.d.ts
23
*.log
34
coverage/
45
node_modules/

index.js

+56-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,56 @@
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('unist').Parent} Parent
4+
* @typedef {import('mdast').Heading} Heading
5+
*
6+
* @typedef {(value: string, node: Heading) => boolean} TestFunction
7+
* @typedef {string|RegExp|TestFunction} Test
8+
*
9+
* @typedef Options
10+
* @property {Test} test
11+
* @property {boolean} [ignoreFinalDefinitions=false]
12+
*
13+
* @typedef ZoneInfo
14+
* @property {number} start
15+
* @property {number} end
16+
* @property {Parent|null} parent
17+
*
18+
* @callback Handler
19+
* @param {Heading|undefined} start
20+
* @param {Array.<Node>} between
21+
* @param {Node|undefined} end
22+
* @param {ZoneInfo} info
23+
*/
24+
125
import {toString} from 'mdast-util-to-string'
226

3-
// Search `node` with `options` and invoke `callback`.
27+
/**
28+
* Search `node` with `options` and invoke `callback`.
29+
*
30+
* @param {Node} node
31+
* @param {Test|Options} options
32+
* @param {Handler} handler
33+
*/
434
// eslint-disable-next-line complexity
5-
export function headingRange(node, options, callback) {
35+
export function headingRange(node, options, handler) {
636
var test = options
7-
var children = node.children
37+
/** @type {Array.<Node>} */
38+
// @ts-ignore looks like children.
39+
var children = node.children || []
840
var index = -1
41+
/** @type {boolean} */
942
var ignoreFinalDefinitions
43+
/** @type {number} */
1044
var depth
45+
/** @type {number} */
1146
var start
47+
/** @type {number} */
1248
var end
49+
/** @type {Array.<Node>} */
1350
var nodes
51+
/** @type {Array.<Node>} */
1452
var result
53+
/** @type {Node} */
1554
var child
1655

1756
// Object, not regex.
@@ -48,7 +87,9 @@ export function headingRange(node, options, callback) {
4887
break
4988
}
5089

90+
// @ts-ignore looks like a heading.
5191
if (!depth && test(toString(child), child)) {
92+
// @ts-ignore looks like a heading.
5293
depth = child.depth
5394
start = index
5495
// Assume no end heading is found.
@@ -68,7 +109,8 @@ export function headingRange(node, options, callback) {
68109
}
69110
}
70111

71-
nodes = callback(
112+
nodes = handler(
113+
// @ts-ignore `start` points to a heading.
72114
children[start],
73115
children.slice(start + 1, end),
74116
children[end],
@@ -94,11 +136,19 @@ export function headingRange(node, options, callback) {
94136
}
95137
}
96138

97-
// Wrap an expression into an assertion function.
139+
/**
140+
* Wrap an expression into an assertion function.
141+
* @param {RegExp} expression
142+
* @returns {(value: string) => boolean}
143+
*/
98144
function wrapExpression(expression) {
99145
return assertion
100146

101-
// Assert `value` matches the bound `expression`.
147+
/**
148+
* Assert `value` matches the bound `expression`.
149+
* @param {string} value
150+
* @returns {boolean}
151+
*/
102152
function assertion(value) {
103153
return expression.test(value)
104154
}

package.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,36 @@
2727
"sideEffects": false,
2828
"type": "module",
2929
"main": "index.js",
30+
"types": "index.d.ts",
3031
"files": [
32+
"index.d.ts",
3133
"index.js"
3234
],
3335
"dependencies": {
36+
"@types/mdast": "^3.0.0",
37+
"@types/unist": "^2.0.0",
3438
"mdast-util-to-string": "^3.0.0"
3539
},
3640
"devDependencies": {
41+
"@types/tape": "^4.0.0",
3742
"c8": "^7.0.0",
3843
"prettier": "^2.0.0",
3944
"remark": "^13.0.0",
4045
"remark-cli": "^9.0.0",
4146
"remark-preset-wooorm": "^8.0.0",
47+
"rimraf": "^3.0.0",
4248
"tape": "^5.0.0",
49+
"type-coverage": "^2.0.0",
50+
"typescript": "^4.0.0",
4351
"xo": "^0.39.0"
4452
},
4553
"scripts": {
54+
"prepack": "npm run build && npm run format",
55+
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
4656
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
4757
"test-api": "node test.js",
4858
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
49-
"test": "npm run format && npm run test-coverage"
59+
"test": "npm run build && npm run format && npm run test-coverage"
5060
},
5161
"prettier": {
5262
"tabWidth": 2,
@@ -67,5 +77,10 @@
6777
"plugins": [
6878
"preset-wooorm"
6979
]
80+
},
81+
"typeCoverage": {
82+
"atLeast": 100,
83+
"detail": true,
84+
"strict": true
7085
}
7186
}

test.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* @typedef {import('tape').Test} Test
3+
* @typedef {import('unist').Node} Node
4+
* @typedef {import('./index.js').Test | import('./index.js').Options} Options
5+
*/
6+
17
import test from 'tape'
28
import remark from 'remark'
39
import {headingRange} from './index.js'
@@ -47,6 +53,7 @@ test('mdast-util-heading-range()', function (t) {
4753
process(
4854
t,
4955
['# Fo', '', '## Fooooo', '', 'Bar', '', '# Fo', ''].join('\n'),
56+
/** @type {Options} */
5057
function (value) {
5158
return value.toLowerCase().indexOf('foo') === 0
5259
}
@@ -161,7 +168,7 @@ test('mdast-util-heading-range()', function (t) {
161168
remark()
162169
.use(function () {
163170
return function (node) {
164-
headingRange(node, 'foo', function (start, nodes, end) {
171+
headingRange(node, 'foo', function (start, _, end) {
165172
return [start, {type: 'thematicBreak'}, end]
166173
})
167174
}
@@ -184,8 +191,7 @@ test('mdast-util-heading-range()', function (t) {
184191
return function (node) {
185192
headingRange(node, 'foo', function (start, nodes, end) {
186193
t.equal(nodes.length, 3)
187-
188-
return [start].concat(nodes, end)
194+
return [start, ...nodes, end]
189195
})
190196
}
191197
})
@@ -303,15 +309,20 @@ test('mdast-util-heading-range()', function (t) {
303309
)
304310
})
305311

312+
/**
313+
* @param {Test} t
314+
* @param {string} value
315+
* @param {Options} options
316+
*/
306317
function process(t, value, options) {
307318
return remark()
308319
.use(function () {
309320
return function (node) {
310-
headingRange(node, options, function (start, nodes, end, scope) {
321+
headingRange(node, options, function (start, _, end, scope) {
311322
t.equal(typeof scope.start, 'number')
312323
t.assert(typeof scope.end === 'number' || scope.end === null)
313324
t.equal(scope.parent.type, 'root')
314-
return [start].concat([end])
325+
return [start, end]
315326
})
316327
}
317328
})

tsconfig.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"include": ["*.js"],
3+
"compilerOptions": {
4+
"target": "ES2020",
5+
"lib": ["ES2020"],
6+
"module": "ES2020",
7+
"moduleResolution": "node",
8+
"allowJs": true,
9+
"checkJs": true,
10+
"declaration": true,
11+
"emitDeclarationOnly": true,
12+
"allowSyntheticDefaultImports": true,
13+
"skipLibCheck": true
14+
}
15+
}

0 commit comments

Comments
 (0)