diff --git a/package.json b/package.json index e806561..e658c2d 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,10 @@ ], "files": [ "lib", - "index.js" + "index.js", + "types/index.d.ts" ], + "types": "types/index.d.ts", "dependencies": { "ccount": "^1.0.0", "comma-separated-tokens": "^1.0.1", @@ -30,12 +32,14 @@ "html-void-elements": "^1.0.0", "property-information": "^5.2.0", "space-separated-tokens": "^1.0.0", - "stringify-entities": "^2.0.0", + "stringify-entities": "^3.0.0", "unist-util-is": "^3.0.0", "xtend": "^4.0.1" }, "devDependencies": { + "@types/unist": "^2.0.3", "browserify": "^16.0.0", + "dtslint": "^2.0.5", "hastscript": "^5.0.0", "nyc": "^14.0.0", "prettier": "^1.0.0", @@ -47,13 +51,14 @@ "xo": "^0.25.0" }, "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", + "format": "remark . -qfo && prettier --write \"**/*.{js,ts}\" && xo --fix", "build-bundle": "browserify . -s hastUtilToHtml > hast-util-to-html.js", "build-mangle": "browserify . -s hastUtilToHtml -p tinyify > hast-util-to-html.min.js", "build": "npm run build-bundle && npm run build-mangle", "test-api": "node test", "test-coverage": "nyc --reporter lcov tape test/index.js", - "test": "npm run format && npm run build && npm run test-coverage" + "test-types": "dtslint types", + "test": "npm run format && npm run build && npm run test-coverage && npm run test-types" }, "prettier": { "tabWidth": 2, diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..3e58d65 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,182 @@ +// TypeScript Version: 3.5 + +import {Node} from 'unist' +import {StringifyEntitiesOptions} from 'stringify-entities' + +declare namespace hastUtilToHtml { + interface HastUtilToHtmlOptions { + /** + * Whether the *root* of the *tree* is in the `'html'` or `'svg'` space. + * + * If an `svg` element is found in the HTML space, `toHtml` automatically switches to the SVG space when entering the element, and switches back when exiting. + * + * @defaultValue 'html' + */ + space: 'html' | 'svg' + + /** + * Configuration for `stringify-entities`. + * Do not use `escapeOnly`, `attribute`, or `subset` (`toHtml` already passes those, so they won’t work). + * However, `useNamedReferences`, `useShortestReferences`, and `omitOptionalSemicolons` are all fine. + * + * @defaultValue {} + */ + entities: Partial< + Omit + > + + /** + * Tag names of *elements* to stringify without closing tag. + * + * Not used in the SVG space. + * + * @defaultValue `require('html-void-elements')` + */ + voids: string[] + + /** + * Use an `
  • one
  • two
  • `, both `` closing tags can be omitted. + * The first because it’s followed by another `li`, the last because it’s followed by nothing. + * + * Not used in the SVG space. + * + * @defaultValue false + */ + omitOptionalTags: boolean + + /** + * Collapse empty attributes: `class=""` is stringified as `class` instead. + * **Note**: boolean attributes, such as `hidden`, are always collapsed. + * + * Not used in the SVG space. + * + * @defaultValue false + */ + collapseEmptyAttributes: boolean + + /** + * Close self-closing nodes with an extra slash (`/`): `` instead of ``. + * See `tightSelfClosing` to control whether a space is used before the slash. + * + * Not used in the SVG space. + * + * @defaultValue false + */ + closeSelfClosing: boolean + + /** + * Close SVG elements without any content with slash (`/`) on the opening tag instead of an end tag: `` instead of ``. + * See `tightSelfClosing` to control whether a space is used before the slash. + * + * Not used in the HTML space. + * + * @defaultValue false + */ + closeEmptyElements: boolean + + /** + * Do not use an extra space when closing self-closing elements: `` instead of ``. + * **Note**: Only used if `closeSelfClosing: true` or `closeEmptyElements: true`. + * + * @defaultValue false + */ + tightSelfClosing: boolean + + /** + * Join known comma-separated attribute values with just a comma (`,`), instead of padding them on the right as well (`,·`, where `·` represents a space). + * + * @defaultValue false + */ + tightCommaSeparatedLists: boolean + + /** + * Join attributes together, without white-space, if possible: `class="a b" title="c d"` is stringified as `class="a b"title="c d"` instead to save bytes. + * **Note**: creates invalid (but working) markup. + * + * Not used in the SVG space. + * + * @defaultValue false + */ + tightAttributes: boolean + + /** + * Drop unneeded spaces in doctypes: `` instead of `` to save bytes. + * **Note**: creates invalid (but working) markup. + * + * @defaultValue false + */ + tightDoctype: boolean + + /** + * Do not encode characters which cause parse errors (even though they work), to save bytes. + * **Note**: creates invalid (but working) markup. + * + * Not used in the SVG space. + * + * @defaultValue false + */ + allowParseErrors: boolean + + /** + * Do not encode some characters which cause XSS vulnerabilities in older browsers. + * **Note**: Only set this if you completely trust the content. + * + * @defaultValue false + */ + allowDangerousCharacters: boolean + + /** + * Allow `raw` nodes and insert them as raw HTML. + * When falsey, encodes `raw` nodes. + * **Note**: Only set this if you completely trust the content. + * + * @defaultValue false + */ + allowDangerousHTML: boolean + } +} + +/** + * Stringify the given **hast** *tree*. + * + * @param tree given hast tree + * @param options configuration for stringifier + */ +declare function hastUtilToHtml( + tree: Node, + options?: Partial +): string + +export = hastUtilToHtml diff --git a/types/tests.ts b/types/tests.ts new file mode 100644 index 0000000..d998c61 --- /dev/null +++ b/types/tests.ts @@ -0,0 +1,73 @@ +import toHtml = require('hast-util-to-html') +import {Node} from 'unist' + +const node: Node = { + type: 'element', + tagName: 'div' +} + +const result: string = toHtml(node) +toHtml(node, { + space: 'html' +}) +toHtml(node, { + space: 'svg' +}) +toHtml(node, { + space: 'svg' +}) +toHtml(node, {entities: {useNamedReferences: true}}) +// $ExpectError +toHtml(node, {entities: {escapeOnly: true}}) +// $ExpectError +toHtml(node, {entities: {attribute: true}}) +// $ExpectError +toHtml(node, {entities: {subset: ['subset']}}) +toHtml(node, { + voids: ['hr'] +}) +toHtml(node, { + upperDoctype: true +}) +toHtml(node, { + quote: "'" +}) +toHtml(node, { + quoteSmart: true +}) +toHtml(node, { + preferUnquoted: true +}) +toHtml(node, { + omitOptionalTags: true +}) +toHtml(node, { + collapseEmptyAttributes: true +}) +toHtml(node, { + closeSelfClosing: true +}) +toHtml(node, { + closeEmptyElements: true +}) +toHtml(node, { + tightSelfClosing: true +}) +toHtml(node, { + tightCommaSeparatedLists: true +}) +toHtml(node, { + tightAttributes: true +}) +toHtml(node, { + tightDoctype: true +}) +toHtml(node, { + allowParseErrors: true +}) +toHtml(node, { + allowDangerousCharacters: true +}) +toHtml(node, { + allowDangerousHTML: true +}) diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 0000000..633d2fe --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "lib": ["es2015"], + "strict": true, + "baseUrl": ".", + "paths": { + "hast-util-to-html": ["index.d.ts"] + } + } +} diff --git a/types/tslint.json b/types/tslint.json new file mode 100644 index 0000000..70c4494 --- /dev/null +++ b/types/tslint.json @@ -0,0 +1,7 @@ +{ + "extends": "dtslint/dtslint.json", + "rules": { + "semicolon": false, + "whitespace": false + } +}