Skip to content

Commit 807ffb9

Browse files
committed
Add improved types
* Add better support for different compile results, if you have custom results, add them to `CompileResultMap` * Better input/output of functions * Infer plugins better * Redo all docs
1 parent 1aa3494 commit 807ffb9

14 files changed

+1016
-737
lines changed

index.d.ts

+738-424
Large diffs are not rendered by default.

index.test-d.ts

+101-161
Large diffs are not rendered by default.

lib/index.js

+25-23
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
* @typedef {import('../index.js').Parser} Parser
99
* @typedef {import('../index.js').Pluggable} Pluggable
1010
* @typedef {import('../index.js').PluggableList} PluggableList
11+
* @typedef {import('../index.js').PluginTuple} PluginTuple
1112
* @typedef {import('../index.js').Plugin} Plugin
1213
* @typedef {import('../index.js').Preset} Preset
1314
* @typedef {import('../index.js').ProcessCallback} ProcessCallback
1415
* @typedef {import('../index.js').Processor} Processor
1516
* @typedef {import('../index.js').RunCallback} RunCallback
16-
* @typedef {import('../index.js').Transformer} Transformer
1717
*/
1818

1919
import structuredClone from '@ungap/structured-clone'
@@ -52,7 +52,6 @@ function base() {
5252

5353
// Plugins.
5454
processor.attachers = attachers
55-
// @ts-expect-error: overloads are handled.
5655
processor.use = use
5756

5857
// API.
@@ -75,7 +74,8 @@ function base() {
7574
let index = -1
7675

7776
while (++index < attachers.length) {
78-
destination.use(...attachers[index])
77+
const attacher = attachers[index]
78+
destination.use(...attacher)
7979
}
8080

8181
destination.data(structuredClone(namespace))
@@ -129,7 +129,6 @@ function base() {
129129
options[0] = undefined
130130
}
131131

132-
/** @type {Transformer | void} */
133132
const transformer = attacher.call(processor, ...options)
134133

135134
if (typeof transformer === 'function') {
@@ -144,7 +143,7 @@ function base() {
144143
}
145144

146145
/**
147-
* @param {Pluggable | null | undefined} [value]
146+
* @param {Exclude<Pluggable, PluginTuple> | PluggableList | null | undefined} [value]
148147
* @param {...unknown} options
149148
* @returns {Processor}
150149
*/
@@ -176,15 +175,16 @@ function base() {
176175
return processor
177176

178177
/**
179-
* @param {import('../index.js').Pluggable<Array<unknown>>} value
180-
* @returns {void}
178+
* @param {import('../index.js').Pluggable} value
179+
* @returns {undefined}
181180
*/
182181
function add(value) {
183182
if (typeof value === 'function') {
184183
addPlugin(value)
185184
} else if (typeof value === 'object') {
186185
if (Array.isArray(value)) {
187-
const [plugin, ...options] = value
186+
const [plugin, ...options] =
187+
/** @type {[Plugin, ...Array<unknown>]} */ (value)
188188
addPlugin(plugin, ...options)
189189
} else {
190190
addPreset(value)
@@ -196,7 +196,7 @@ function base() {
196196

197197
/**
198198
* @param {Preset} result
199-
* @returns {void}
199+
* @returns {undefined}
200200
*/
201201
function addPreset(result) {
202202
if (!('plugins' in result) && !('settings' in result)) {
@@ -215,7 +215,7 @@ function base() {
215215

216216
/**
217217
* @param {PluggableList | null | undefined} [plugins]
218-
* @returns {void}
218+
* @returns {undefined}
219219
*/
220220
function addList(plugins) {
221221
let index = -1
@@ -235,7 +235,7 @@ function base() {
235235
/**
236236
* @param {Plugin} plugin
237237
* @param {...unknown} [value]
238-
* @returns {void}
238+
* @returns {undefined}
239239
*/
240240
function addPlugin(plugin, value) {
241241
let index = -1
@@ -299,7 +299,7 @@ function base() {
299299
* @param {Node} node
300300
* @param {RunCallback | VFileCompatible} [doc]
301301
* @param {RunCallback} [callback]
302-
* @returns {Promise<Node> | void}
302+
* @returns {Promise<Node> | undefined}
303303
*/
304304
function run(node, doc, callback) {
305305
assertNode(node)
@@ -316,10 +316,11 @@ function base() {
316316

317317
executor(undefined, callback)
318318

319+
// Note: `void`s needed for TS.
319320
/**
320-
* @param {((node: Node) => void) | undefined} resolve
321-
* @param {(error: Error) => void} reject
322-
* @returns {void}
321+
* @param {((node: Node) => undefined | void) | undefined} resolve
322+
* @param {(error: Error) => undefined | void} reject
323+
* @returns {undefined}
323324
*/
324325
function executor(resolve, reject) {
325326
// @ts-expect-error: `doc` can’t be a callback anymore, we checked.
@@ -329,7 +330,7 @@ function base() {
329330
* @param {Error | undefined} error
330331
* @param {Node} tree
331332
* @param {VFile} file
332-
* @returns {void}
333+
* @returns {undefined}
333334
*/
334335
function done(error, tree, file) {
335336
tree = tree || node
@@ -362,7 +363,7 @@ function base() {
362363
/**
363364
* @param {Error | undefined} [error]
364365
* @param {Node} [tree]
365-
* @returns {void}
366+
* @returns {undefined}
366367
*/
367368
function done(error, tree) {
368369
bail(error)
@@ -387,10 +388,11 @@ function base() {
387388

388389
executor(undefined, callback)
389390

391+
// Note: `void`s needed for TS.
390392
/**
391-
* @param {((file: VFile) => void) | undefined} resolve
392-
* @param {(error?: Error | undefined) => void} reject
393-
* @returns {void}
393+
* @param {((file: VFile) => undefined | void) | undefined} resolve
394+
* @param {(error?: Error | undefined) => undefined | void} reject
395+
* @returns {undefined}
394396
*/
395397
function executor(resolve, reject) {
396398
const file = vfile(doc)
@@ -417,7 +419,7 @@ function base() {
417419
/**
418420
* @param {Error | undefined} [error]
419421
* @param {VFile | undefined} [file]
420-
* @returns {void}
422+
* @returns {undefined}
421423
*/
422424
function done(error, file) {
423425
if (error || !file) {
@@ -432,7 +434,7 @@ function base() {
432434
}
433435
}
434436

435-
/** @type {Processor['processSync']} */
437+
/** @type {import('../index.js').Processor['processSync']} */
436438
function processSync(doc) {
437439
/** @type {boolean | undefined} */
438440
let complete
@@ -451,7 +453,7 @@ function base() {
451453

452454
/**
453455
* @param {Error | undefined} [error]
454-
* @returns {void}
456+
* @returns {undefined}
455457
*/
456458
function done(error) {
457459
complete = true

package.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"xo": "^0.55.0"
6868
},
6969
"scripts": {
70-
"build": "tsc --build --clean && tsc --build && type-coverage",
70+
"build": "tsc --build --clean && tsc --build && type-coverage && tsd",
7171
"format": "remark . --frail --output --quiet && prettier . --log-level warn --write && xo --fix",
7272
"prepack": "npm run build && npm run format",
7373
"test": "npm run build && npm run format && npm run test-coverage",
@@ -95,10 +95,6 @@
9595
"atLeast": 100,
9696
"detail": true,
9797
"ignoreCatch": true,
98-
"#": "`type-coverage` currently barfs on inferring nodes in plugins, while TS gets it",
99-
"ignoreFiles": [
100-
"test/**/*.js"
101-
],
10298
"strict": true
10399
},
104100
"xo": {
@@ -109,6 +105,7 @@
109105
],
110106
"rules": {
111107
"@typescript-eslint/ban-types": "off",
108+
"@typescript-eslint/consistent-type-definitions": "off",
112109
"@typescript-eslint/naming-convention": "off"
113110
}
114111
}

readme.md

+26-15
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,8 @@ Parse text to a syntax tree.
460460
461461
###### Parameters
462462

463-
* `file` ([`VFile`][vfile]) — any value accepted as `x` in `new VFile(x)`
463+
* `file` ([`VFile`][vfile]) — file to parse; typically `string`; any value
464+
accepted as `x` in `new VFile(x)`
464465

465466
###### Returns
466467

@@ -497,14 +498,15 @@ Yields:
497498
#### `processor.Parser`
498499

499500
A **parser** handles the parsing of text to a syntax tree.
501+
500502
It is used in the [parse phase][overview] and is called with a `string` and
501503
[`VFile`][vfile] of the document to parse.
502504

503505
`Parser` can be a normal function, in which case it must return the syntax
504506
tree representation of the given file ([`Node`][node]).
505507

506-
`Parser` can also be a constructor function (a function with a `parse` field, or
507-
other fields, in its `prototype`), in which case it is constructed with `new`.
508+
`Parser` can also be a constructor function (a function with a `parse` field in
509+
its `prototype`), in which case it is constructed with `new`.
508510
Instances must have a `parse` method that is called without arguments and must
509511
return a [`Node`][node].
510512

@@ -521,8 +523,8 @@ Compile a syntax tree.
521523
###### Parameters
522524

523525
* `tree` ([`Node`][node]) — tree to compile
524-
* `file` ([`VFile`][vfile], optional) — any value accepted as `x` in
525-
`new VFile(x)`
526+
* `file` ([`VFile`][vfile], optional) — file associated with `node`; any
527+
value accepted as `x` in `new VFile(x)`
526528

527529
###### Returns
528530

@@ -562,14 +564,15 @@ Yields:
562564

563565
A **compiler** handles the compiling of a syntax tree to something else (in
564566
most cases, text).
567+
565568
It is used in the [stringify phase][overview] and called with a [`Node`][node]
566569
and [`VFile`][file] representation of the document to compile.
567570

568571
`Compiler` can be a normal function, in which case it should return the textual
569572
representation of the given tree (`string`).
570573

571574
`Compiler` can also be a constructor function (a function with a `compile`
572-
field, or other fields, in its `prototype`), in which case it is constructed
575+
field in its `prototype`), in which case it is constructed
573576
with `new`.
574577
Instances must have a `compile` method that is called without arguments and
575578
should return a `string`.
@@ -599,7 +602,7 @@ Run *[transformers][transformer]* on a syntax tree.
599602

600603
###### Returns
601604

602-
Nothing if `done` is given (`void`).
605+
Nothing if `done` is given (`undefined`).
603606
A [`Promise`][promise] otherwise.
604607
The promise is rejected with a fatal error or resolved with the transformed
605608
tree ([`Node`][node]).
@@ -639,6 +642,7 @@ Yields:
639642
#### `function done(err[, tree, file])`
640643

641644
Callback called when transformers are done.
645+
642646
Called with either an error or results.
643647

644648
###### Parameters
@@ -679,12 +683,13 @@ Process the given file as configured on the processor.
679683
680684
###### Parameters
681685

682-
* `file` ([`VFile`][vfile]) — any value accepted as `x` in `new VFile(x)`
686+
* `file` ([`VFile`][vfile]) — file; any value accepted as `x` in
687+
`new VFile(x)`
683688
* `done` ([`Function`][process-done], optional) — callback
684689

685690
###### Returns
686691

687-
Nothing if `done` is given (`void`).
692+
Nothing if `done` is given (`undefined`).
688693
A [`Promise`][promise] otherwise.
689694
The promise is rejected with a fatal error or resolved with the processed
690695
file ([`VFile`][vfile]).
@@ -742,6 +747,7 @@ Yields:
742747
#### `function done(err, file)`
743748

744749
Callback called when the process is done.
750+
745751
Called with either an error or a result.
746752

747753
###### Parameters
@@ -905,6 +911,7 @@ processor.data() // => {charlie: 'delta'}
905911
### `processor.freeze()`
906912

907913
Freeze a processor.
914+
908915
Frozen processors are meant to be extended and not to be configured directly.
909916

910917
When a processor is frozen it cannot be unfrozen.
@@ -1073,6 +1080,7 @@ Optional transform ([`Transformer`][transformer]).
10731080
### `function transformer(tree, file[, next])`
10741081

10751082
Transformers handle syntax trees and files.
1083+
10761084
They are functions that are called each time a syntax tree and file are passed
10771085
through the [run phase][overview].
10781086
When an error occurs in them (either because it’s thrown, returned, rejected,
@@ -1084,16 +1092,18 @@ exact semantics of these functions.
10841092
###### Parameters
10851093

10861094
* `tree` ([`Node`][node]) — tree to handle
1087-
* `file` ([`VFile`][vfile]) —file to handle
1088-
* `next` ([`Function`][next], optional)
1095+
* `file` ([`VFile`][vfile]) — file to handle
1096+
* `next` ([`Function`][next], optional) — callback
10891097

10901098
###### Returns
10911099

1092-
* `void` — the next transformer keeps using same tree
1100+
If you accept `next`, nothing.
1101+
Otherwise:
1102+
10931103
* `Error` — fatal error to stop the process
1094-
* [`Node`][node] — new, changed, tree
1095-
* `Promise<Node>` — resolved with a new, changed, tree or rejected with an
1096-
`Error`
1104+
* `Promise<undefined>` or `undefined` — the next transformer keeps using same
1105+
tree
1106+
* `Promise<Node>` or [`Node`][node] — new, changed, tree
10971107

10981108
#### `function next(err[, tree[, file]])`
10991109

@@ -1109,6 +1119,7 @@ may perform asynchronous operations, and must call `next()`.
11091119
## `Preset`
11101120

11111121
Presets are sharable configuration.
1122+
11121123
They can contain plugins and settings.
11131124

11141125
###### Example

0 commit comments

Comments
 (0)