Skip to content

Commit 2130916

Browse files
committed
Add JSDoc based types
1 parent 095ef8b commit 2130916

File tree

6 files changed

+104
-18
lines changed

6 files changed

+104
-18
lines changed

.!42543!.editorconfig

Whitespace-only changes.

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
coverage/
22
node_modules/
33
.DS_Store
4+
*.d.ts
45
*.log
56
yarn.lock

index.js

+66-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1+
/**
2+
* @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension
3+
* @typedef {import('mdast-util-from-markdown').Transform} FromMarkdownTransform
4+
* @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle
5+
* @typedef {import('mdast-util-to-markdown/lib/types.js').Options} ToMarkdownExtension
6+
* @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction
7+
* @typedef {import('mdast-util-find-and-replace').RegExpMatchObject} RegExpMatchObject
8+
* @typedef {import('mdast-util-find-and-replace').PhrasingContent} PhrasingContent
9+
*/
10+
111
import {ccount} from 'ccount'
212
import {findAndReplace} from 'mdast-util-find-and-replace'
3-
import unicodePunctuation from 'micromark/dist/character/unicode-punctuation.js'
4-
import unicodeWhitespace from 'micromark/dist/character/unicode-whitespace.js'
13+
import {unicodePunctuation, unicodeWhitespace} from 'micromark-util-character'
514

615
const inConstruct = 'phrasing'
716
const notInConstruct = ['autolink', 'link', 'image', 'label']
817

18+
/** @type {FromMarkdownExtension} */
919
export const gfmAutolinkLiteralFromMarkdown = {
1020
transforms: [transformGfmAutolinkLiterals],
1121
enter: {
@@ -22,6 +32,7 @@ export const gfmAutolinkLiteralFromMarkdown = {
2232
}
2333
}
2434

35+
/** @type {ToMarkdownExtension} */
2536
export const gfmAutolinkLiteralToMarkdown = {
2637
unsafe: [
2738
{
@@ -42,31 +53,39 @@ export const gfmAutolinkLiteralToMarkdown = {
4253
]
4354
}
4455

56+
/** @type {FromMarkdownHandle} */
4557
function enterLiteralAutolink(token) {
58+
// @ts-expect-error: `null` is fine.
4659
this.enter({type: 'link', title: null, url: '', children: []}, token)
4760
}
4861

62+
/** @type {FromMarkdownHandle} */
4963
function enterLiteralAutolinkValue(token) {
5064
this.config.enter.autolinkProtocol.call(this, token)
5165
}
5266

67+
/** @type {FromMarkdownHandle} */
5368
function exitLiteralAutolinkHttp(token) {
5469
this.config.exit.autolinkProtocol.call(this, token)
5570
}
5671

72+
/** @type {FromMarkdownHandle} */
5773
function exitLiteralAutolinkWww(token) {
5874
this.config.exit.data.call(this, token)
5975
this.stack[this.stack.length - 1].url = 'http://' + this.sliceSerialize(token)
6076
}
6177

78+
/** @type {FromMarkdownHandle} */
6279
function exitLiteralAutolinkEmail(token) {
6380
this.config.exit.autolinkEmail.call(this, token)
6481
}
6582

83+
/** @type {FromMarkdownHandle} */
6684
function exitLiteralAutolink(token) {
6785
this.exit(token)
6886
}
6987

88+
/** @type {FromMarkdownTransform} */
7089
function transformGfmAutolinkLiterals(tree) {
7190
findAndReplace(
7291
tree,
@@ -78,8 +97,16 @@ function transformGfmAutolinkLiterals(tree) {
7897
)
7998
}
8099

100+
/**
101+
* @type {ReplaceFunction}
102+
* @param {string} _
103+
* @param {string} protocol
104+
* @param {string} domain
105+
* @param {string} path
106+
* @param {RegExpMatchObject} match
107+
*/
81108
// eslint-disable-next-line max-params
82-
function findUrl($0, protocol, domain, path, match) {
109+
function findUrl(_, protocol, domain, path, match) {
83110
let prefix = ''
84111

85112
// Not an expected previous character.
@@ -102,34 +129,48 @@ function findUrl($0, protocol, domain, path, match) {
102129

103130
if (!parts[0]) return false
104131

105-
let result = {
132+
/** @type {PhrasingContent} */
133+
// @ts-expect-error: `null` is fine.
134+
const result = {
106135
type: 'link',
107136
title: null,
108137
url: prefix + protocol + parts[0],
109138
children: [{type: 'text', value: protocol + parts[0]}]
110139
}
111140

112141
if (parts[1]) {
113-
result = [result, {type: 'text', value: parts[1]}]
142+
return [result, {type: 'text', value: parts[1]}]
114143
}
115144

116145
return result
117146
}
118147

119-
function findEmail($0, atext, label, match) {
148+
/**
149+
* @type {ReplaceFunction}
150+
* @param {string} _
151+
* @param {string} atext
152+
* @param {string} label
153+
* @param {RegExpMatchObject} match
154+
*/
155+
function findEmail(_, atext, label, match) {
120156
// Not an expected previous character.
121157
if (!previous(match, true) || /[_-]$/.test(label)) {
122158
return false
123159
}
124160

125161
return {
126162
type: 'link',
163+
// @ts-expect-error: `null` is fine.
127164
title: null,
128165
url: 'mailto:' + atext + '@' + label,
129166
children: [{type: 'text', value: atext + '@' + label}]
130167
}
131168
}
132169

170+
/**
171+
* @param {string} domain
172+
* @returns {boolean}
173+
*/
133174
function isCorrectDomain(domain) {
134175
const parts = domain.split('.')
135176

@@ -148,15 +189,24 @@ function isCorrectDomain(domain) {
148189
return true
149190
}
150191

192+
/**
193+
* @param {string} url
194+
* @returns {[string, string|undefined]}
195+
*/
151196
function splitUrl(url) {
152-
let trail = /[!"&'),.:;<>?\]}]+$/.exec(url)
197+
const trailExec = /[!"&'),.:;<>?\]}]+$/.exec(url)
198+
/** @type {number} */
153199
let closingParenIndex
200+
/** @type {number} */
154201
let openingParens
202+
/** @type {number} */
155203
let closingParens
204+
/** @type {string|undefined} */
205+
let trail
156206

157-
if (trail) {
158-
url = url.slice(0, trail.index)
159-
trail = trail[0]
207+
if (trailExec) {
208+
url = url.slice(0, trailExec.index)
209+
trail = trailExec[0]
160210
closingParenIndex = trail.indexOf(')')
161211
openingParens = ccount(url, '(')
162212
closingParens = ccount(url, ')')
@@ -172,8 +222,14 @@ function splitUrl(url) {
172222
return [url, trail]
173223
}
174224

225+
/**
226+
* @param {RegExpMatchObject} match
227+
* @param {boolean} [email=false]
228+
* @returns {boolean}
229+
*/
175230
function previous(match, email) {
176231
const code = match.input.charCodeAt(match.index - 1)
232+
177233
return (
178234
(match.index === 0 ||
179235
unicodeWhitespace(code) ||

package.json

+18-5
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,39 @@
3232
"sideEffects": false,
3333
"type": "module",
3434
"main": "index.js",
35+
"types": "index.d.ts",
3536
"files": [
37+
"index.d.ts",
3638
"index.js"
3739
],
3840
"dependencies": {
3941
"ccount": "^2.0.0",
4042
"mdast-util-find-and-replace": "^2.0.0",
41-
"micromark": "^2.11.0"
43+
"micromark-util-character": "^1.0.0"
4244
},
4345
"devDependencies": {
46+
"@types/tape": "^4.0.0",
4447
"c8": "^7.0.0",
4548
"hast-util-to-html": "^8.0.0",
46-
"mdast-util-from-markdown": "^0.8.0",
49+
"mdast-util-from-markdown": "^1.0.0",
4750
"mdast-util-to-hast": "^11.0.0",
48-
"mdast-util-to-markdown": "^0.6.0",
49-
"micromark-extension-gfm-autolink-literal": "^0.5.6",
51+
"mdast-util-to-markdown": "^1.0.0",
52+
"micromark-extension-gfm-autolink-literal": "^1.0.0",
5053
"prettier": "^2.0.0",
5154
"remark-cli": "^9.0.0",
5255
"remark-preset-wooorm": "^8.0.0",
56+
"rimraf": "^3.0.0",
5357
"tape": "^5.0.0",
58+
"type-coverage": "^2.0.0",
59+
"typescript": "^4.0.0",
5460
"xo": "^0.39.0"
5561
},
5662
"scripts": {
63+
"build": "rimraf \"*.d.ts\" && tsc && type-coverage",
5764
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
5865
"test-api": "node --conditions development test/index.js",
5966
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --conditions development test/index.js",
60-
"test": "npm run format && npm run test-coverage"
67+
"test": "npm run build && npm run format && npm run test-coverage"
6168
},
6269
"prettier": {
6370
"tabWidth": 2,
@@ -74,5 +81,11 @@
7481
"plugins": [
7582
"preset-wooorm"
7683
]
84+
},
85+
"typeCoverage": {
86+
"atLeast": 100,
87+
"detail": true,
88+
"strict": true,
89+
"ignoreCatch": true
7790
}
7891
}

test/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import path from 'path'
33
import test from 'tape'
44
import {toHtml} from 'hast-util-to-html'
55
import {toHast} from 'mdast-util-to-hast'
6-
import fromMarkdown from 'mdast-util-from-markdown'
7-
import toMarkdown from 'mdast-util-to-markdown'
8-
import gfmAutolinkLiteral from 'micromark-extension-gfm-autolink-literal'
6+
import {fromMarkdown} from 'mdast-util-from-markdown'
7+
import {toMarkdown} from 'mdast-util-to-markdown'
8+
import {gfmAutolinkLiteral} from 'micromark-extension-gfm-autolink-literal'
99
import {
1010
gfmAutolinkLiteralFromMarkdown,
1111
gfmAutolinkLiteralToMarkdown

tsconfig.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
"strict": true
15+
}
16+
}

0 commit comments

Comments
 (0)