Skip to content

Commit a919bff

Browse files
committed
Add JSDoc based types
1 parent b2e8291 commit a919bff

File tree

5 files changed

+134
-38
lines changed

5 files changed

+134
-38
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: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('unist').Parent} Parent
4+
*/
5+
16
import {toString} from 'nlcst-to-string'
27

38
var single = [
@@ -37,8 +42,14 @@ var pairs = {
3742

3843
var open = Object.keys(pairs)
3944

40-
// Check if the node in `parent` at `position` is enclosed by matching
41-
// delimiters.
45+
/**
46+
* Check if the node in `parent` at `position` is enclosed by matching
47+
* delimiters.
48+
*
49+
* @param {Parent} parent
50+
* @param {number} index
51+
* @returns {boolean}
52+
*/
4253
export function isLiteral(parent, index) {
4354
if (!(parent && parent.children)) {
4455
throw new Error('Parent must be a node')
@@ -65,8 +76,13 @@ export function isLiteral(parent, index) {
6576
)
6677
}
6778

68-
// Check if the node in `parent` at `position` is enclosed by matching
69-
// delimiters.
79+
/**
80+
* Check if the node in `parent` at `position` is enclosed by matching
81+
* delimiters.
82+
* @param {Parent} parent
83+
* @param {number} position
84+
* @returns {Node|void}
85+
*/
7086
function isWrapped(parent, position) {
7187
var previous = siblingDelimiter(parent, position, -1, open)
7288

@@ -75,10 +91,19 @@ function isWrapped(parent, position) {
7591
}
7692
}
7793

78-
// Find the previous or next delimiter before or after `position` in `parent`.
79-
// Returns the delimiter node when found.
94+
/**
95+
* Find the previous or next delimiter before or after `position` in `parent`.
96+
* Returns the delimiter node when found.
97+
*
98+
* @param {Parent} parent
99+
* @param {number} position
100+
* @param {number} step
101+
* @param {Array.<string>} delimiters
102+
* @returns {Node|void}
103+
*/
80104
function siblingDelimiter(parent, position, step, delimiters) {
81105
var index = position + step
106+
/** @type {Node} */
82107
var sibling
83108

84109
while (index > -1 && index < parent.children.length) {
@@ -96,8 +121,14 @@ function siblingDelimiter(parent, position, step, delimiters) {
96121
}
97122
}
98123

99-
// Check if parent contains word-nodes between `start` and `end` (both
100-
// excluding).
124+
/**
125+
* Check if parent contains word-nodes between `start` and `end` (both
126+
* excluding).
127+
* @param {Parent} parent
128+
* @param {number} start
129+
* @param {number} end
130+
* @returns {boolean|void}
131+
*/
101132
function containsWord(parent, start, end) {
102133
while (++start < end) {
103134
if (parent.children[start].type === 'WordNode') {

package.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,36 @@
2525
"sideEffects": false,
2626
"type": "module",
2727
"main": "index.js",
28+
"types": "index.d.ts",
2829
"files": [
30+
"index.d.ts",
2931
"index.js"
3032
],
3133
"dependencies": {
34+
"@types/unist": "^2.0.0",
3235
"nlcst-to-string": "^3.0.0"
3336
},
3437
"devDependencies": {
38+
"@types/tape": "^4.0.0",
3539
"c8": "^7.0.0",
3640
"prettier": "^2.0.0",
3741
"remark-cli": "^9.0.0",
3842
"remark-preset-wooorm": "^8.0.0",
3943
"retext": "^7.0.0",
44+
"rimraf": "^3.0.0",
4045
"tape": "^5.0.0",
46+
"type-coverage": "^2.0.0",
47+
"typescript": "^4.0.0",
4148
"unist-util-visit": "^3.0.0",
4249
"xo": "^0.39.0"
4350
},
4451
"scripts": {
52+
"prepack": "npm run build && npm run format",
53+
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
4554
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
4655
"test-api": "node test.js",
4756
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js",
48-
"test": "npm run format && npm run test-coverage"
57+
"test": "npm run build && npm run format && npm run test-coverage"
4958
},
5059
"prettier": {
5160
"tabWidth": 2,
@@ -66,5 +75,10 @@
6675
"plugins": [
6776
"preset-wooorm"
6877
]
78+
},
79+
"typeCoverage": {
80+
"atLeast": 100,
81+
"detail": true,
82+
"strict": true
6983
}
7084
}

test.js

Lines changed: 64 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
/**
2+
* @typedef {import('unist').Node} Node
3+
* @typedef {import('unist-util-visit').Visitor<Node>} Visitor
4+
*/
5+
16
import assert from 'assert'
27
import test from 'tape'
8+
// @ts-ignore remove when typed.
39
import retext from 'retext'
410
import {visit} from 'unist-util-visit'
511
import {isLiteral} from './index.js'
612

713
test('isLiteral()', function (t) {
814
t.throws(
915
function () {
16+
// @ts-ignore runtime.
1017
isLiteral()
1118
},
1219
/Parent must be a node/,
@@ -15,6 +22,7 @@ test('isLiteral()', function (t) {
1522

1623
t.throws(
1724
function () {
25+
// @ts-ignore runtime.
1826
isLiteral({})
1927
},
2028
/Parent must be a node/,
@@ -23,6 +31,7 @@ test('isLiteral()', function (t) {
2331

2432
t.throws(
2533
function () {
34+
// @ts-ignore runtime.
2635
isLiteral({children: []})
2736
},
2837
/Index must be a number/,
@@ -31,6 +40,7 @@ test('isLiteral()', function (t) {
3140

3241
t.throws(
3342
function () {
43+
// @ts-ignore runtime.
3444
isLiteral({children: []}, {type: 'a'})
3545
},
3646
/Node must be a child of `parent`/,
@@ -39,13 +49,17 @@ test('isLiteral()', function (t) {
3949

4050
t.doesNotThrow(function () {
4151
var n = {type: 'a'}
52+
// @ts-ignore runtime.
4253
isLiteral({children: [n]}, n)
4354
}, 'should not throw if `node` is in `parent`')
4455

4556
t.doesNotThrow(function () {
46-
process('Well? Ha! Funky', function (node, index, parent) {
47-
assert.strictEqual(isLiteral(parent, index), false)
48-
})
57+
process(
58+
'Well? Ha! Funky',
59+
/** @type {Visitor} */ function (_, index, parent) {
60+
assert.strictEqual(isLiteral(parent, index), false)
61+
}
62+
)
4963
}, 'should work on single word sentences')
5064

5165
t.doesNotThrow(function () {
@@ -63,9 +77,16 @@ test('isLiteral()', function (t) {
6377
var index = -1
6478

6579
while (++index < fixtures.length) {
66-
process(fixtures[index], function (node, index, parent) {
67-
assert.strictEqual(isLiteral(parent, index), index === 0, index)
68-
})
80+
process(
81+
fixtures[index],
82+
/** @type {Visitor} */ function (_, index, parent) {
83+
assert.strictEqual(
84+
isLiteral(parent, index),
85+
index === 0,
86+
String(index)
87+
)
88+
}
89+
)
6990
}
7091
}, 'Initial')
7192

@@ -84,13 +105,16 @@ test('isLiteral()', function (t) {
84105
var index = -1
85106

86107
while (++index < fixtures.length) {
87-
process(fixtures[index], function (node, index, parent) {
88-
assert.strictEqual(
89-
isLiteral(parent, index),
90-
index === parent.children.length - 2,
91-
index
92-
)
93-
})
108+
process(
109+
fixtures[index],
110+
/** @type {Visitor} */ function (_, index, parent) {
111+
assert.strictEqual(
112+
isLiteral(parent, index),
113+
index === parent.children.length - 2,
114+
String(index)
115+
)
116+
}
117+
)
94118
}
95119
}, 'Final')
96120

@@ -126,29 +150,40 @@ test('isLiteral()', function (t) {
126150
var index = -1
127151

128152
while (++index < fixtures.length) {
129-
process(fixtures[index], function (node, place, parent) {
130-
var pos = 5
131-
132-
// Adjacent hyphens are part of the word.
133-
if (index === 1) {
134-
pos = 4
153+
process(
154+
fixtures[index],
155+
/** @type {Visitor} */ function (_, place, parent) {
156+
var pos = 5
157+
158+
// Adjacent hyphens are part of the word.
159+
if (index === 1) {
160+
pos = 4
161+
}
162+
163+
// Tests for extra spaces.
164+
if (index === 4 || index === 5 || index === 6) {
165+
pos = 6
166+
}
167+
168+
assert.strictEqual(
169+
isLiteral(parent, place),
170+
place === pos,
171+
String(index)
172+
)
135173
}
136-
137-
// Tests for extra spaces.
138-
if (index === 4 || index === 5 || index === 6) {
139-
pos = 6
140-
}
141-
142-
assert.strictEqual(isLiteral(parent, place), place === pos, index)
143-
})
174+
)
144175
}
145176
}, 'Internal')
146177

147178
t.end()
148179
})
149180

150-
// Shortcut to process a fixture and invoke `visitor` for each of its word
151-
// nodes.
181+
/**
182+
* Shortcut to process a fixture and invoke `visitor` for each of its word
183+
* nodes.
184+
* @param {string} fixture
185+
* @param {Visitor} visitor
186+
*/
152187
function process(fixture, visitor) {
153188
visit(retext().parse(fixture), 'WordNode', visitor)
154189
}

tsconfig.json

Lines changed: 15 additions & 0 deletions
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)