hast-util-excerpt
Advanced tools
Comparing version 1.0.2 to 2.0.0
@@ -1,2 +0,2 @@ | ||
export {excerpt} from './lib/index.js' | ||
export type Options = import('./lib/index.js').Options | ||
export { excerpt } from "./lib/index.js"; | ||
export type Options = import('./lib/index.js').Options; |
/** | ||
* Truncate `tree` to a certain comment. | ||
* | ||
* @template {Node} Tree | ||
* Type of tree. | ||
* @template {Nodes} Tree | ||
* Tree kind. | ||
* @param {Tree} tree | ||
* Tree to truncate. | ||
* @param {Options | null | undefined} [options] | ||
* Configuration (optional) | ||
* @param {Readonly<Options> | null | undefined} [options] | ||
* Configuration (optional). | ||
* @returns {Tree | undefined} | ||
* Truncated copy of `tree` when a comment is found, `undefined` otherwise. | ||
* Truncated clone of `tree` when a comment is found, `undefined` otherwise. | ||
*/ | ||
export function excerpt<Tree extends Node>( | ||
tree: Tree, | ||
options?: Options | null | undefined | ||
): Tree | undefined | ||
export type Root = import('hast').Root | ||
export type Content = import('hast').Content | ||
export type Node = Root | Content | ||
export function excerpt<Tree extends import("hast").Nodes>(tree: Tree, options?: Readonly<Options> | null | undefined): Tree | undefined; | ||
export type Nodes = import('hast').Nodes; | ||
export type RootContent = import('hast').RootContent; | ||
/** | ||
@@ -24,19 +20,21 @@ * Configuration. | ||
export type Options = { | ||
/** | ||
* Comment value to search for. | ||
*/ | ||
comment?: string | null | undefined | ||
/** | ||
* How far to search for the comment before bailing. | ||
* The goal of this project is to find user-defined explicit excerpts, that | ||
* are assumed to be somewhat reasonably placed. | ||
* This option prevents searching giant documents for some comment | ||
* that probably won’t be found at the end. | ||
*/ | ||
maxSearchSize?: number | null | undefined | ||
/** | ||
* Nodes to exclude from the resulting tree. | ||
* These are not counted towards `size`. | ||
*/ | ||
ignore?: Array<Content> | null | undefined | ||
} | ||
/** | ||
* Comment value to search for (default: `'more'`). | ||
*/ | ||
comment?: string | null | undefined; | ||
/** | ||
* Nodes to exclude from the resulting tree (default: `[]`). | ||
* | ||
* These are not counted towards `size`. | ||
*/ | ||
ignore?: Array<RootContent> | null | undefined; | ||
/** | ||
* How far to search for the comment before bailing (default: `2048`). | ||
* | ||
* The goal of this project is to find user-defined explicit excerpts, that | ||
* are assumed to be somewhat reasonably placed. | ||
* This option prevents searching giant documents for some comment that | ||
* probably won’t be found at the end. | ||
*/ | ||
maxSearchSize?: number | null | undefined; | ||
}; |
/** | ||
* @typedef {import('hast').Root} Root | ||
* @typedef {import('hast').Content} Content | ||
* @typedef {import('hast').Nodes} Nodes | ||
* @typedef {import('hast').RootContent} RootContent | ||
*/ | ||
/** | ||
* @typedef {Root | Content} Node | ||
* | ||
* @typedef Options | ||
* Configuration. | ||
* @property {string | null | undefined} [comment='more'] | ||
* Comment value to search for. | ||
* Comment value to search for (default: `'more'`). | ||
* @property {Array<RootContent> | null | undefined} [ignore=[]] | ||
* Nodes to exclude from the resulting tree (default: `[]`). | ||
* | ||
* These are not counted towards `size`. | ||
* @property {number | null | undefined} [maxSearchSize=2048] | ||
* How far to search for the comment before bailing. | ||
* How far to search for the comment before bailing (default: `2048`). | ||
* | ||
* The goal of this project is to find user-defined explicit excerpts, that | ||
* are assumed to be somewhat reasonably placed. | ||
* This option prevents searching giant documents for some comment | ||
* that probably won’t be found at the end. | ||
* @property {Array<Content> | null | undefined} [ignore=[]] | ||
* Nodes to exclude from the resulting tree. | ||
* These are not counted towards `size`. | ||
* This option prevents searching giant documents for some comment that | ||
* probably won’t be found at the end. | ||
*/ | ||
@@ -26,16 +26,19 @@ | ||
/** @type {Readonly<Options>} */ | ||
const emptyOptions = {} | ||
/** | ||
* Truncate `tree` to a certain comment. | ||
* | ||
* @template {Node} Tree | ||
* Type of tree. | ||
* @template {Nodes} Tree | ||
* Tree kind. | ||
* @param {Tree} tree | ||
* Tree to truncate. | ||
* @param {Options | null | undefined} [options] | ||
* Configuration (optional) | ||
* @param {Readonly<Options> | null | undefined} [options] | ||
* Configuration (optional). | ||
* @returns {Tree | undefined} | ||
* Truncated copy of `tree` when a comment is found, `undefined` otherwise. | ||
* Truncated clone of `tree` when a comment is found, `undefined` otherwise. | ||
*/ | ||
export function excerpt(tree, options) { | ||
const config = options || {} | ||
const config = options || emptyOptions | ||
const comment = config.comment || 'more' | ||
@@ -45,2 +48,3 @@ const maxSearchSize = | ||
let found = false | ||
// Note: `truncate` returns a deep clone. | ||
const result = preorder( | ||
@@ -50,3 +54,2 @@ truncate(tree, {ignore: config.ignore, size: maxSearchSize}) | ||
// @ts-expect-error: `result` is most likely a clone of `tree` | ||
return found ? result : undefined | ||
@@ -57,8 +60,12 @@ | ||
* | ||
* @param {Node} node | ||
* @template {Nodes} Kind | ||
* Node kind. | ||
* @param {Kind} node | ||
* Node to truncate. | ||
* @returns {Node | undefined} | ||
* @returns {Kind | undefined} | ||
* Copy of `node` or `undefined` when done. | ||
*/ | ||
function preorder(node) { | ||
/** @typedef {Kind extends import('unist').Parent ? Kind['children'][number] : never} Child */ | ||
if (node.type === 'comment' && node.value.trim() === comment) { | ||
@@ -76,3 +83,5 @@ found = true | ||
node.data.estree.comments && | ||
node.data.estree.comments.some((node) => node.value.trim() === comment) | ||
node.data.estree.comments.some(function (node) { | ||
return node.value.trim() === comment | ||
}) | ||
) { | ||
@@ -83,19 +92,16 @@ found = true | ||
/** @type {Node} */ | ||
/** @type {Kind} */ | ||
const replacement = {...node} | ||
if ('children' in node) { | ||
/** @type {Array<Content>} */ | ||
if ('children' in replacement) { | ||
/** @type {Array<Child>} */ | ||
const children = [] | ||
let index = -1 | ||
while (++index < node.children.length && !found) { | ||
const child = node.children[index] | ||
// @ts-expect-error: children in JSX are transformed to `hast`. | ||
while (++index < replacement.children.length && !found) { | ||
const child = /** @type {Child} */ (replacement.children[index]) | ||
const result = preorder(child) | ||
// @ts-expect-error: assume content model matches. | ||
if (result) children.push(result) | ||
} | ||
// @ts-expect-error: assume content model matches. | ||
replacement.children = children | ||
@@ -102,0 +108,0 @@ } |
{ | ||
"name": "hast-util-excerpt", | ||
"version": "1.0.2", | ||
"version": "2.0.0", | ||
"description": "hast utility to excerpt the tree to a comment", | ||
@@ -29,4 +29,3 @@ "license": "MIT", | ||
"type": "module", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"exports": "./index.js", | ||
"files": [ | ||
@@ -38,22 +37,22 @@ "lib/", | ||
"dependencies": { | ||
"@types/hast": "^2.0.0", | ||
"hast-util-truncate": "^1.0.0" | ||
"@types/hast": "^3.0.0", | ||
"hast-util-truncate": "^2.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.0.0", | ||
"c8": "^7.0.0", | ||
"hast-util-select": "^5.0.0", | ||
"hastscript": "^7.0.0", | ||
"mdast-util-from-markdown": "^1.0.0", | ||
"mdast-util-mdx": "^2.0.0", | ||
"mdast-util-to-hast": "^12.0.0", | ||
"micromark-extension-mdxjs": "^1.0.0", | ||
"prettier": "^2.0.0", | ||
"@types/node": "^20.0.0", | ||
"c8": "^8.0.0", | ||
"hast-util-select": "^6.0.0", | ||
"hastscript": "^8.0.0", | ||
"mdast-util-from-markdown": "^2.0.0", | ||
"mdast-util-mdx": "^3.0.0", | ||
"mdast-util-to-hast": "^13.0.0", | ||
"micromark-extension-mdxjs": "^2.0.0", | ||
"prettier": "^3.0.0", | ||
"remark-cli": "^11.0.0", | ||
"remark-preset-wooorm": "^9.0.0", | ||
"type-coverage": "^2.0.0", | ||
"typescript": "^4.0.0", | ||
"unist-builder": "^3.0.0", | ||
"unist-util-remove-position": "^4.0.0", | ||
"xo": "^0.53.0" | ||
"typescript": "^5.0.0", | ||
"unist-builder": "^4.0.0", | ||
"unist-util-remove-position": "^5.0.0", | ||
"xo": "^0.55.0" | ||
}, | ||
@@ -63,21 +62,18 @@ "scripts": { | ||
"build": "tsc --build --clean && tsc --build && type-coverage", | ||
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", | ||
"format": "remark . -qfo && prettier . -w --log-level warn && xo --fix", | ||
"test-api": "node --conditions development test.js", | ||
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", | ||
"test-coverage": "c8 --100 --reporter lcov npm run test-api", | ||
"test": "npm run build && npm run format && npm run test-coverage" | ||
}, | ||
"prettier": { | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"singleQuote": true, | ||
"bracketSpacing": false, | ||
"semi": false, | ||
"trailingComma": "none" | ||
"singleQuote": true, | ||
"tabWidth": 2, | ||
"trailingComma": "none", | ||
"useTabs": false | ||
}, | ||
"xo": { | ||
"prettier": true | ||
}, | ||
"remarkConfig": { | ||
"plugins": [ | ||
"preset-wooorm" | ||
"remark-preset-wooorm" | ||
] | ||
@@ -88,5 +84,8 @@ }, | ||
"detail": true, | ||
"strict": true, | ||
"ignoreCatch": true | ||
"ignoreCatch": true, | ||
"strict": true | ||
}, | ||
"xo": { | ||
"prettier": true | ||
} | ||
} |
@@ -52,3 +52,3 @@ # hast-util-excerpt | ||
This package is [ESM only][esm]. | ||
In Node.js (version 14.14+ or 16.0+), install with [npm][]: | ||
In Node.js (version 16+), install with [npm][]: | ||
@@ -62,3 +62,3 @@ ```sh | ||
```js | ||
import {excerpt} from "https://esm.sh/hast-util-excerpt@1" | ||
import {excerpt} from 'https://esm.sh/hast-util-excerpt@2' | ||
``` | ||
@@ -70,3 +70,3 @@ | ||
<script type="module"> | ||
import {excerpt} from "https://esm.sh/hast-util-excerpt@1?bundle" | ||
import {excerpt} from 'https://esm.sh/hast-util-excerpt@2?bundle' | ||
</script> | ||
@@ -121,3 +121,3 @@ ``` | ||
This package exports the identifier [`excerpt`][excerpt]. | ||
This package exports the identifier [`excerpt`][api-excerpt]. | ||
There is no default export. | ||
@@ -133,3 +133,3 @@ | ||
— tree to truncate | ||
* `options` ([`Options`][options]) | ||
* `options` ([`Options`][api-options]) | ||
— configuration (optional) | ||
@@ -139,3 +139,3 @@ | ||
Truncated copy of `tree` ([`Node`][node]) when a comment is found, `undefined` | ||
Truncated clone of `tree` ([`Node`][node]) when a comment is found, `undefined` | ||
otherwise. | ||
@@ -173,11 +173,14 @@ | ||
This package is fully typed with [TypeScript][]. | ||
It exports the additional type [`Options`][options]. | ||
It exports the additional type [`Options`][api-options]. | ||
## Compatibility | ||
Projects maintained by the unified collective are compatible with all maintained | ||
Projects maintained by the unified collective are compatible with maintained | ||
versions of Node.js. | ||
As of now, that is Node.js 14.14+ and 16.0+. | ||
Our projects sometimes work with older versions, but this is not guaranteed. | ||
When we cut a new major release, we drop support for unmaintained versions of | ||
Node. | ||
This means we try to keep the current release line, `hast-util-excerpt@^2`, | ||
compatible with Node.js 16. | ||
## Security | ||
@@ -226,5 +229,5 @@ | ||
[size-badge]: https://img.shields.io/bundlephobia/minzip/hast-util-excerpt.svg | ||
[size-badge]: https://img.shields.io/badge/dynamic/json?label=minzipped%20size&query=$.size.compressedSize&url=https://deno.bundlejs.com/?q=hast-util-excerpt | ||
[size]: https://bundlephobia.com/result?p=hast-util-excerpt | ||
[size]: https://bundlejs.com/?q=hast-util-excerpt | ||
@@ -271,6 +274,6 @@ [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg | ||
[excerpt]: #excerpttree-options | ||
[node]: https://github.com/syntax-tree/hast#nodes | ||
[options]: #options | ||
[api-excerpt]: #excerpttree-options | ||
[node]: https://github.com/syntax-tree/hast#nodes | ||
[api-options]: #options |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
14929
138
271
0
+ Added@types/hast@3.0.4(transitive)
+ Added@types/unist@3.0.3(transitive)
+ Added@ungap/structured-clone@1.2.1(transitive)
+ Addedhast-util-truncate@2.0.0(transitive)
+ Addedmicromark-util-character@2.1.1(transitive)
+ Addedmicromark-util-symbol@2.0.1(transitive)
+ Addedmicromark-util-types@2.0.1(transitive)
- Removed@types/hast@2.3.10(transitive)
- Removed@types/unist@2.0.11(transitive)
- Removedhast-util-truncate@1.0.2(transitive)
- Removedmicromark-util-character@1.2.0(transitive)
- Removedmicromark-util-symbol@1.1.0(transitive)
- Removedmicromark-util-types@1.1.0(transitive)
Updated@types/hast@^3.0.0
Updatedhast-util-truncate@^2.0.0