Skip to content

Commit 2c6a29c

Browse files
committed
Add JSDoc based types
1 parent efad048 commit 2c6a29c

File tree

5 files changed

+141
-19
lines changed

5 files changed

+141
-19
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
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

Lines changed: 87 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,48 @@
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('unist').Parent} Parent
4+
* @typedef {import('unist').Point} Point
5+
* @typedef {import('mdast').Content} Content
6+
* @typedef {import('vfile').VFile} VFile
7+
* @typedef {import('vfile-location').Location} LocationInterface
8+
* @typedef {{
9+
* parse(nodes: Node[]): Node
10+
* tokenizeSource(value: string): Node
11+
* tokenizeWhiteSpace(value: string): Node
12+
* tokenize(value: string): Node[]
13+
* }} ParserInstance
14+
* @typedef {new () => ParserInstance} ParserConstructor
15+
*
16+
* @typedef Options
17+
* @property {Array.<string>} [ignore]
18+
* @property {Array.<string>} [source]
19+
*
20+
* @typedef Context
21+
* @property {string} doc
22+
* @property {LocationInterface} location
23+
* @property {ParserInstance} parser
24+
* @property {Array.<string>} ignore
25+
* @property {Array.<string>} source
26+
*/
27+
128
import repeat from 'repeat-string'
229
import {toString} from 'nlcst-to-string'
330
import {pointStart, pointEnd} from 'unist-util-position'
431
import vfileLocation from 'vfile-location'
532

6-
// Transform a `tree` in mdast to nlcst.
7-
export function toNlcst(tree, file, Parser, options) {
8-
var settings = options || {}
33+
/**
34+
* Transform a `tree` in mdast to nlcst.
35+
*
36+
* @param {Node} tree
37+
* @param {VFile} file
38+
* @param {ParserInstance|ParserConstructor} Parser
39+
* @param {Options} [options]
40+
*/
41+
export function toNlcst(tree, file, Parser, options = {}) {
42+
/** @type {ParserInstance} */
943
var parser
1044

11-
// Warn for invalid parameters.
45+
// Crash on invalid parameters.
1246
if (!tree || !tree.type) {
1347
throw new Error('mdast-util-to-nlcst expected node')
1448
}
@@ -45,18 +79,26 @@ export function toNlcst(tree, file, Parser, options) {
4579
'table',
4680
'tableRow',
4781
'tableCell',
48-
settings.ignore || []
82+
options.ignore || []
4983
),
50-
source: [].concat('inlineCode', settings.source || [])
84+
source: [].concat('inlineCode', options.source || [])
5185
},
86+
// @ts-ignore assume mdast node.
5287
tree
5388
)
5489
)
5590
}
5691

57-
// Transform a single node.
92+
/**
93+
* Transform a single node.
94+
* @param {Context} config
95+
* @param {Content} node
96+
* @returns {Array.<Node>|undefined}
97+
*/
5898
function one(config, node) {
99+
/** @type {number} */
59100
var start
101+
/** @type {number} */
60102
var end
61103

62104
if (!config.ignore.includes(node.type)) {
@@ -73,7 +115,8 @@ function one(config, node) {
73115
)
74116
}
75117

76-
if (node.children) {
118+
if ('children' in node) {
119+
// @ts-ignore looks like a parent.
77120
return all(config, node)
78121
}
79122

@@ -86,22 +129,37 @@ function one(config, node) {
86129
}
87130

88131
// To do: next major — remove `escape`.
89-
if (node.type === 'text' || node.type === 'escape') {
132+
if (
133+
node.type === 'text' ||
134+
// @ts-ignore legacy.
135+
node.type === 'escape'
136+
) {
90137
return patch(config, config.parser.tokenize(node.value), start)
91138
}
92139
}
93140
}
94141

95-
// Transform all nodes in `parent`.
142+
/**
143+
* Transform all nodes in `parent`.
144+
* @param {Context} config
145+
* @param {Parent} parent
146+
* @returns {Array.<Node>}
147+
*/
96148
function all(config, parent) {
149+
/** @type {Array.<Node>} */
97150
var result = []
98151
var index = -1
152+
/** @type {Node} */
99153
var lineEnding
154+
/** @type {Content} */
100155
var child
156+
/** @type {Point} */
101157
var end
158+
/** @type {Point} */
102159
var start
103160

104161
while (++index < parent.children.length) {
162+
// @ts-ignore Assume `parent` is an mdast parent.
105163
child = parent.children[index]
106164
start = pointStart(child)
107165

@@ -111,7 +169,11 @@ function all(config, parent) {
111169
)
112170
patch(config, [lineEnding], end.offset)
113171

114-
if (lineEnding.value.length < 2) {
172+
if (
173+
'value' in lineEnding &&
174+
typeof lineEnding.value === 'string' &&
175+
lineEnding.value.length < 2
176+
) {
115177
lineEnding.value = '\n\n'
116178
}
117179

@@ -125,18 +187,29 @@ function all(config, parent) {
125187
return result
126188
}
127189

128-
// Patch a position on each node in `nodes`.
129-
// `offset` is the offset in `file` this run of content starts at.
190+
/**
191+
* Patch a position on each node in `nodes`.
192+
* `offset` is the offset in `file` this run of content starts at.
193+
*
194+
* @template {Array.<Node>} T
195+
* @param {Context} config
196+
* @param {T} nodes
197+
* @param {number} offset
198+
* @returns {T}
199+
*/
130200
function patch(config, nodes, offset) {
131201
var index = -1
132202
var start = offset
203+
/** @type {number} */
133204
var end
205+
/** @type {Node} */
134206
var node
135207

136208
while (++index < nodes.length) {
137209
node = nodes[index]
138210

139-
if (node.children) {
211+
if ('children' in node) {
212+
// @ts-ignore looks like a parent.
140213
patch(config, node.children, start)
141214
}
142215

package.json

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,22 @@
2828
"sideEffects": false,
2929
"type": "module",
3030
"main": "index.js",
31+
"types": "index.d.ts",
3132
"files": [
33+
"index.d.ts",
3234
"index.js"
3335
],
3436
"dependencies": {
37+
"@types/mdast": "^3.0.0",
38+
"@types/repeat-string": "^1.0.0",
39+
"@types/unist": "^2.0.0",
3540
"nlcst-to-string": "^3.0.0",
3641
"repeat-string": "^1.0.0",
3742
"unist-util-position": "^4.0.0",
3843
"vfile-location": "^3.1.0"
3944
},
4045
"devDependencies": {
46+
"@types/tape": "^4.0.0",
4147
"c8": "^7.0.0",
4248
"is-hidden": "^2.0.0",
4349
"parse-dutch": "^5.0.0",
@@ -49,15 +55,20 @@
4955
"remark-frontmatter": "^3.0.0",
5056
"remark-gfm": "^1.0.0",
5157
"remark-preset-wooorm": "^8.0.0",
58+
"rimraf": "^3.0.0",
5259
"tape": "^5.0.0",
53-
"to-vfile": "^6.1.0",
60+
"to-vfile": "^6.0.0",
61+
"type-coverage": "^2.0.0",
62+
"typescript": "^4.0.0",
5463
"xo": "^0.39.0"
5564
},
5665
"scripts": {
66+
"prepack": "npm run build && npm run format",
67+
"build": "rimraf \"{test/**,}*.d.ts\" && tsc && type-coverage",
5768
"format": "remark . -qfo --ignore-pattern test/ && prettier . -w --loglevel warn && xo --fix",
5869
"test-api": "node test/index.js",
5970
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js",
60-
"test": "npm run format && npm run test-coverage"
71+
"test": "npm run build && npm run format && npm run test-coverage"
6172
},
6273
"prettier": {
6374
"tabWidth": 2,
@@ -78,5 +89,10 @@
7889
"plugins": [
7990
"preset-wooorm"
8091
]
92+
},
93+
"typeCoverage": {
94+
"atLeast": 100,
95+
"detail": true,
96+
"strict": true
8197
}
8298
}

test/index.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('vfile').VFile} VFile
4+
*/
5+
16
import fs from 'fs'
27
import path from 'path'
38
import test from 'tape'
@@ -14,6 +19,7 @@ import {toNlcst} from '../index.js'
1419
test('mdast-util-to-nlcst', function (t) {
1520
t.throws(
1621
function () {
22+
// @ts-ignore runtime.
1723
toNlcst()
1824
},
1925
/mdast-util-to-nlcst expected node/,
@@ -22,6 +28,7 @@ test('mdast-util-to-nlcst', function (t) {
2228

2329
t.throws(
2430
function () {
31+
// @ts-ignore runtime.
2532
toNlcst({})
2633
},
2734
/mdast-util-to-nlcst expected node/,
@@ -30,6 +37,7 @@ test('mdast-util-to-nlcst', function (t) {
3037

3138
t.throws(
3239
function () {
40+
// @ts-ignore runtime.
3341
toNlcst({type: 'foo'})
3442
},
3543
/mdast-util-to-nlcst expected file/,
@@ -38,6 +46,7 @@ test('mdast-util-to-nlcst', function (t) {
3846

3947
t.throws(
4048
function () {
49+
// @ts-ignore runtime.
4150
toNlcst({type: 'foo'})
4251
},
4352
/mdast-util-to-nlcst expected file/,
@@ -46,6 +55,7 @@ test('mdast-util-to-nlcst', function (t) {
4655

4756
t.throws(
4857
function () {
58+
// @ts-ignore runtime.
4959
toNlcst({type: 'text', value: 'foo'}, {foo: 'bar'})
5060
},
5161
/mdast-util-to-nlcst expected file/,
@@ -54,6 +64,7 @@ test('mdast-util-to-nlcst', function (t) {
5464

5565
t.throws(
5666
function () {
67+
// @ts-ignore runtime.
5768
toNlcst({type: 'text', value: 'foo'}, vfile({contents: 'foo'}))
5869
},
5970
/mdast-util-to-nlcst expected parser/,
@@ -98,6 +109,7 @@ test('mdast-util-to-nlcst', function (t) {
98109
{
99110
type: 'text',
100111
value: 'foo',
112+
// @ts-ignore runtime.
101113
position: {start: {}, end: {}}
102114
},
103115
vfile(),
@@ -132,10 +144,15 @@ test('Fixtures', function (t) {
132144
var base = path.join('test', 'fixtures')
133145
var files = fs.readdirSync(base)
134146
var index = -1
147+
/** @type {string} */
135148
var name
149+
/** @type {VFile} */
136150
var input
151+
/** @type {Node} */
137152
var expected
153+
/** @type {Node} */
138154
var mdast
155+
/** @type {Object.<string, unknown>} */
139156
var options
140157

141158
while (++index < files.length) {
@@ -151,12 +168,12 @@ test('Fixtures', function (t) {
151168
vfile.readSync(path.join(base, name, 'options.json'))
152169
)
153170
} catch {
154-
options = null
171+
options = undefined
155172
}
156173

157174
mdast = remark()
158-
.use(options && options.useRemarkGfm ? gfm : [])
159-
.use(options && options.useRemarkFrontmatter ? frontmatter : [])
175+
.use(options && options.useRemarkGfm ? gfm : undefined)
176+
.use(options && options.useRemarkFrontmatter ? frontmatter : undefined)
160177
.parse(input)
161178

162179
t.deepEqual(

tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"include": ["*.js", "test/**/*.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)