From 1e3e7d534dfacb51703d2af9abb170b736e39c3f Mon Sep 17 00:00:00 2001 From: Titus Date: Thu, 1 Jul 2021 09:37:31 +0200 Subject: [PATCH] Refactor to improve types Reviewed-by: Merlijn Vos Reviewed-by: Christian Murphy Related to GH-6. Closes GH-7. --- index.js | 47 ++++++++++++++++++----------------------------- package.json | 12 ++++++++++-- test.js | 20 +++++++++++++++++--- tsconfig.json | 3 ++- 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/index.js b/index.js index a2cdfaa..e16398f 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ 'use strict' + /** - * @typedef {import('unified').FrozenProcessor} FrozenProcessor + * @typedef {import('unified').Processor} Processor * @typedef {import('unified').RunCallback} RunCallback * @typedef {import('unified').Transformer} Transformer * @typedef {import('unist').Node} Node @@ -15,40 +16,33 @@ var hast2mdast = require('hast-util-to-mdast') * tree (bridge-mode). Without destination, returns the mdast tree: further * plugins run on that tree (mutate-mode). * + * @param destination Optional unified processor. + * @param options Options passed to `hast-util-to-mdast`. */ -var attacher = +module.exports = /** - * @type {( - * ((destination?: FrozenProcessor, options?: Options) => Transformer) & - * ((options?: Options) => Transformer) - * )} + * @type {import('unified').Plugin<[Options?]|[Processor, Options?]>} */ ( /** - * @param {FrozenProcessor | Options} [destination] + * @param {Processor|Options} [destination] * @param {Options} [options] */ function (destination, options) { - /** @type {Options | undefined} */ + /** @type {Options|undefined} */ var settings - /** @type {FrozenProcessor | undefined} */ + /** @type {Processor|undefined} */ var processor - if ( - destination && - !(/** @type {FrozenProcessor} */ (destination).process) - ) { - // Overload: 'options' passed to first parameter - settings = /** @type {Options} */ (destination) - destination = null + if (typeof destination === 'function') { + processor = destination + settings = options || {} } else { - processor = /** @type {FrozenProcessor | undefined} */ (destination) + settings = destination || {} } - settings = settings || options || {} - if (settings.document === undefined || settings.document === null) { - settings.document = true + settings = Object.assign({}, settings, {document: true}) } return processor ? bridge(processor, settings) : mutate(settings) @@ -58,7 +52,7 @@ var attacher = /** * Bridge-mode. * Runs the destination with the new mdast tree. - * @param {FrozenProcessor} destination + * @param {Processor} destination * @param {Options} [options] * @returns {Transformer} */ @@ -69,12 +63,9 @@ function bridge(destination, options) { destination.run(hast2mdast(node, options), file, done) /** @type {RunCallback} */ function done(err) { - // Cast to proper type - remove when upstream typing of Transformer is fixed. - // Note: `next` only requires one parameter: https://github.com/unifiedjs/unified#function-nexterr-tree-file - var typefixedNext = - /** @type {(error: Error | null, node?: Node, file?: import('vfile').VFile) => void} */ - (next) - typefixedNext(err) + // @ts-expect-error: `unified` should accept 1 arg for next. + // See: + next(err) } } } @@ -94,8 +85,6 @@ function mutate(options) { } } -module.exports = attacher - // Remove the following JSDoc block when upgrading hast-util-to-mdast to version 8. // Import these types from hast-util-to-mdast when version 8 released. /** diff --git a/package.json b/package.json index 7d6308e..4906797 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,16 @@ "Titus Wormer (https://wooorm.com)" ], "dependencies": { + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", "hast-util-to-mdast": "^7.0.0" }, "files": [ "index.js" ], "devDependencies": { + "@types/tape": "^4.0.0", "browserify": "^17.0.0", "nyc": "^15.0.0", "prettier": "^2.0.0", @@ -39,6 +43,7 @@ "remark-cli": "^9.0.0", "remark-preset-wooorm": "^8.0.0", "remark-stringify": "^9.0.0", + "rimraf": "^3.0.0", "tape": "^5.0.0", "tinyify": "^3.0.0", "type-coverage": "^2.0.0", @@ -48,7 +53,7 @@ }, "scripts": { "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", - "build-types": "tsc -b && type-coverage", + "build-types": "rimraf \"*.d.ts\" && tsc && type-coverage", "build-bundle": "browserify . -s rehypeRemark -o rehype-remark.js", "build-mangle": "browserify . -s rehypeRemark -o rehype-remark.min.js -p tinyify", "build": "npm run build-types && npm run build-bundle && npm run build-mangle", @@ -86,6 +91,9 @@ "atLeast": 100, "detail": true, "strict": true, - "ignoreCatch": true + "ignoreCatch": true, + "ignoreFiles": [ + "index.d.ts" + ] } } diff --git a/test.js b/test.js index 5abbeca..1f6937d 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,12 @@ 'use strict' +/** + * @typedef {import('./index.js').Options} Options + * @typedef {import('./index.js').Handle} Handle + * @typedef {import('hast').Element} Element + * @typedef {import('hast').Text} Text + */ + var test = require('tape') var unified = require('unified') var parse = require('rehype-parse') @@ -60,12 +67,19 @@ test('rehype2remark()', function (t) { }) test('handlers option', function (t) { + /** @type {Options} */ var options = { handlers: { + /** + * @type {Handle} + * @param {Element & {tagName: 'div'}} node + */ div: function (h, node) { - node.children[0].value = 'changed' - node.type = 'paragraph' - return h(node, 'paragraph', node.children) + /** @type {Text} */ + // @ts-expect-error: there’s one text child. + const child = node.children[0] + child.value = 'changed' + return h(node, 'paragraph', child) } } } diff --git a/tsconfig.json b/tsconfig.json index b2cc50b..bc16834 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,6 @@ "*.js" ], "exclude": [ - "test.js", "rehype-remark.js", "*.min.js" ], @@ -18,5 +17,7 @@ "checkJs": true, "declaration": true, "emitDeclarationOnly": true, + "allowSyntheticDefaultImports": true, + "skipLibCheck": true } }