Socket
Socket
Sign inDemoInstall

unist-util-is

Package Overview
Dependencies
0
Maintainers
2
Versions
19
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.1.1 to 5.2.0

lib/index.d.ts

122

index.d.ts

@@ -1,113 +0,13 @@

/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
*
* @typedef {string} Type
* @typedef {Object<string, unknown>} Props
*
* @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.<Type|Props|TestFunctionAnything>} Test
*/
/**
* Check if a node passes a test
*
* @callback TestFunctionAnything
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean|void}
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} X
* @callback TestFunctionPredicate
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is X}
*/
/**
* @callback AssertAnything
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean}
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} Y
* @callback AssertPredicate
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is Y}
*/
export const is: (<T extends import('unist').Node<import('unist').Data>>(
node: unknown,
test:
| T['type']
| Partial<T>
| TestFunctionPredicate<T>
| (T['type'] | Partial<T> | TestFunctionPredicate<T>)[],
index?: number | null | undefined,
parent?: Parent | null | undefined,
context?: unknown
) => node is T) &
((
node?: unknown,
test?: Test,
index?: number | null | undefined,
parent?: Parent | null | undefined,
context?: unknown
) => boolean)
export const convert: (<T extends import('unist').Node<import('unist').Data>>(
test: T['type'] | Partial<T> | TestFunctionPredicate<T>
) => AssertPredicate<T>) &
((test?: Test) => AssertAnything)
export type Node = import('unist').Node
export type Parent = import('unist').Parent
export type Type = string
export type Props = {
[x: string]: unknown
}
export type Test =
| null
| undefined
| Type
| Props
| TestFunctionAnything
| Array<Type | Props | TestFunctionAnything>
/**
* Check if a node passes a test
*/
export type TestFunctionAnything = (
node: Node,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => boolean | void
/**
* Check if a node passes a certain node test
*/
export type Test = import('./lib/index.js').Test
export type TestFunctionAnything = import('./lib/index.js').TestFunctionAnything
export type AssertAnything = import('./lib/index.js').AssertAnything
export type PredicateTest<
Kind extends import('unist').Node<import('unist').Data>
> = import('./lib/index.js').PredicateTest<Kind>
export type TestFunctionPredicate<
X extends import('unist').Node<import('unist').Data>
> = (
node: Node,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => node is X
export type AssertAnything = (
node?: unknown,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => boolean
/**
* Check if a node passes a certain node test
*/
Kind extends import('unist').Node<import('unist').Data>
> = import('./lib/index.js').TestFunctionPredicate<Kind>
export type AssertPredicate<
Y extends import('unist').Node<import('unist').Data>
> = (
node?: unknown,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => node is Y
Kind extends import('unist').Node<import('unist').Data>
> = import('./lib/index.js').AssertPredicate<Kind>
export {is, convert} from './lib/index.js'
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
*
* @typedef {string} Type
* @typedef {Object<string, unknown>} Props
*
* @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.<Type|Props|TestFunctionAnything>} Test
* @typedef {import('./lib/index.js').Test} Test
* @typedef {import('./lib/index.js').TestFunctionAnything} TestFunctionAnything
* @typedef {import('./lib/index.js').AssertAnything} AssertAnything
*/
/**
* Check if a node passes a test
*
* @callback TestFunctionAnything
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean|void}
* @template {import('unist').Node} Kind
* @typedef {import('./lib/index.js').PredicateTest<Kind>} PredicateTest
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} X
* @callback TestFunctionPredicate
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is X}
* @template {import('unist').Node} Kind
* @typedef {import('./lib/index.js').TestFunctionPredicate<Kind>} TestFunctionPredicate
*/
/**
* @callback AssertAnything
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean}
* @template {import('unist').Node} Kind
* @typedef {import('./lib/index.js').AssertPredicate<Kind>} AssertPredicate
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} Y
* @callback AssertPredicate
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is Y}
*/
export const is =
/**
* Check if a node passes a test.
* When a `parent` node is known the `index` of node should also be given.
*
* @type {(
* (<T extends Node>(node: unknown, test: T['type']|Partial<T>|TestFunctionPredicate<T>|Array.<T['type']|Partial<T>|TestFunctionPredicate<T>>, index?: number|null|undefined, parent?: Parent|null|undefined, context?: unknown) => node is T) &
* ((node?: unknown, test?: Test, index?: number|null|undefined, parent?: Parent|null|undefined, context?: unknown) => boolean)
* )}
*/
(
/**
* Check if a node passes a test.
* When a `parent` node is known the `index` of node should also be given.
*
* @param {unknown} [node] Node to check
* @param {Test} [test]
* When nullish, checks if `node` is a `Node`.
* When `string`, works like passing `function (node) {return node.type === test}`.
* When `function` checks if function passed the node is true.
* When `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
* When `array`, checks any one of the subtests pass.
* @param {number|null|undefined} [index] Position of `node` in `parent`
* @param {Parent|null|undefined} [parent] Parent of `node`
* @param {unknown} [context] Context object to invoke `test` with
* @returns {boolean} Whether test passed and `node` is a `Node` (object with `type` set to non-empty `string`).
*/
// eslint-disable-next-line max-params
function is(node, test, index, parent, context) {
const check = convert(test)
if (
index !== undefined &&
index !== null &&
(typeof index !== 'number' ||
index < 0 ||
index === Number.POSITIVE_INFINITY)
) {
throw new Error('Expected positive finite index')
}
if (
parent !== undefined &&
parent !== null &&
(!is(parent) || !parent.children)
) {
throw new Error('Expected parent node')
}
if (
(parent === undefined || parent === null) !==
(index === undefined || index === null)
) {
throw new Error('Expected both parent and index')
}
// @ts-expect-error Looks like a node.
return node && node.type && typeof node.type === 'string'
? Boolean(check.call(context, node, index, parent))
: false
}
)
export const convert =
/**
* @type {(
* (<T extends Node>(test: T['type']|Partial<T>|TestFunctionPredicate<T>) => AssertPredicate<T>) &
* ((test?: Test) => AssertAnything)
* )}
*/
(
/**
* Generate an assertion from a check.
* @param {Test} [test]
* When nullish, checks if `node` is a `Node`.
* When `string`, works like passing `function (node) {return node.type === test}`.
* When `function` checks if function passed the node is true.
* When `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
* When `array`, checks any one of the subtests pass.
* @returns {AssertAnything}
*/
function (test) {
if (test === undefined || test === null) {
return ok
}
if (typeof test === 'string') {
return typeFactory(test)
}
if (typeof test === 'object') {
return Array.isArray(test) ? anyFactory(test) : propsFactory(test)
}
if (typeof test === 'function') {
return castFactory(test)
}
throw new Error('Expected function, string, or object as test')
}
)
/**
* @param {Array.<Type|Props|TestFunctionAnything>} tests
* @returns {AssertAnything}
*/
function anyFactory(tests) {
/** @type {Array.<AssertAnything>} */
const checks = []
let index = -1
while (++index < tests.length) {
checks[index] = convert(tests[index])
}
return castFactory(any)
/**
* @this {unknown}
* @param {unknown[]} parameters
* @returns {boolean}
*/
function any(...parameters) {
let index = -1
while (++index < checks.length) {
if (checks[index].call(this, ...parameters)) return true
}
return false
}
}
/**
* Utility to assert each property in `test` is represented in `node`, and each
* values are strictly equal.
*
* @param {Props} check
* @returns {AssertAnything}
*/
function propsFactory(check) {
return castFactory(all)
/**
* @param {Node} node
* @returns {boolean}
*/
function all(node) {
/** @type {string} */
let key
for (key in check) {
// @ts-expect-error: hush, it sure works as an index.
if (node[key] !== check[key]) return false
}
return true
}
}
/**
* Utility to convert a string into a function which checks a given node’s type
* for said string.
*
* @param {Type} check
* @returns {AssertAnything}
*/
function typeFactory(check) {
return castFactory(type)
/**
* @param {Node} node
*/
function type(node) {
return node && node.type === check
}
}
/**
* Utility to convert a string into a function which checks a given node’s type
* for said string.
* @param {TestFunctionAnything} check
* @returns {AssertAnything}
*/
function castFactory(check) {
return assertion
/**
* @this {unknown}
* @param {Array.<unknown>} parameters
* @returns {boolean}
*/
function assertion(...parameters) {
// @ts-expect-error: spreading is fine.
return Boolean(check.call(this, ...parameters))
}
}
// Utility to return true.
function ok() {
return true
}
export {is, convert} from './lib/index.js'
{
"name": "unist-util-is",
"version": "5.1.1",
"version": "5.2.0",
"description": "unist utility to check if a node passes a test",

@@ -36,2 +36,3 @@ "license": "MIT",

"files": [
"lib/",
"index.d.ts",

@@ -43,23 +44,21 @@ "index.js"

"@types/mdast": "^3.0.0",
"@types/tape": "^4.0.0",
"@types/node": "^18.0.0",
"c8": "^7.0.0",
"fast-check": "^2.0.0",
"fast-check": "^3.0.0",
"lodash": "^4.0.0",
"prettier": "^2.0.0",
"remark-cli": "^9.0.0",
"remark-preset-wooorm": "^8.0.0",
"rimraf": "^3.0.0",
"tape": "^5.0.0",
"tsd": "^0.14.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"tsd": "^0.25.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"unified": "^9.0.0",
"xo": "^0.42.0"
"unified": "^10.0.0",
"xo": "^0.53.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{test/**,}*.d.ts\" && tsc && tsd && type-coverage",
"build": "tsc --build --clean && tsc --build && tsd && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node test/index.js",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js",
"test-api": "node --conditions development test/index.js",
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api",
"test": "npm run build && npm run format && npm run test-coverage"

@@ -80,3 +79,3 @@ },

"plugins": [
"preset-wooorm"
"remark-preset-wooorm"
]

@@ -83,0 +82,0 @@ },

@@ -11,11 +11,47 @@ # unist-util-is

[**unist**][unist] utility to check if a node passes a test.
[unist][] utility to check if nodes pass a test.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`is(node[, test[, index, parent[, context]]])`](#isnode-test-index-parent-context)
* [`convert(test)`](#converttest)
* [`AssertAnything`](#assertanything)
* [`AssertPredicate`](#assertpredicate)
* [`Test`](#test)
* [`TestFunctionAnything`](#testfunctionanything)
* [`PredicateTest`](#predicatetest)
* [`TestFunctionPredicate`](#testfunctionpredicate)
* [Examples](#examples)
* [Example of `convert`](#example-of-convert)
* [Types](#types)
* [Compatibility](#compatibility)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This package is a small utility that checks that a node is a certain node.
## When should I use this?
Use this small utility if you find yourself repeating code for checking what
nodes are.
A similar package, [`hast-util-is-element`][hast-util-is-element], works on hast
elements.
For more advanced tests, [`unist-util-select`][unist-util-select] can be used
to match against CSS selectors.
## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
This package is [ESM only][esm].
In Node.js (version 14.14+ and 16.0+), install with [npm][]:
[npm][]:
```sh

@@ -25,2 +61,16 @@ npm install unist-util-is

In Deno with [`esm.sh`][esmsh]:
```js
import {is} from 'https://esm.sh/unist-util-is@5'
```
In browsers with [`esm.sh`][esmsh]:
```html
<script type="module">
import {is} from 'https://esm.sh/unist-util-is@5?bundle'
</script>
```
## Use

@@ -34,6 +84,2 @@

function test(node, n) {
return n === 5
}
is() // => false

@@ -52,2 +98,6 @@ is({children: []}) // => false

is(node, test, 5, parent) // => true
function test(node, n) {
return n === 5
}
```

@@ -57,3 +107,3 @@

This package exports the following identifiers: `is`, `convert`.
This package exports the identifiers [`convert`][convert] and [`is`][is].
There is no default export.

@@ -63,55 +113,179 @@

Check if `node` is a `Node` and whether it passes the given test.
###### Parameters
* `node` ([`Node`][node]) — Node to check.
* `test` ([`Function`][test], `string`, `Object`, or `Array.<Test>`, optional)
— When nullish, checks if `node` is a [`Node`][node].
When `string`, works like passing `node => node.type === test`.
When `array`, checks if any one of the subtests pass.
When `object`, checks that all keys in `test` are in `node`,
and that they have strictly equal values
* `index` (`number`, optional) — [Index][] of `node` in `parent`
* `parent` ([`Node`][node], optional) — [Parent][] of `node`
* `context` (`*`, optional) — Context object to invoke `test` with
* `node` (`unknown`)
— thing to check, typically [`Node`][node]
* `test` ([`Test`][test] or [`PredicateTest`][predicatetest], optional)
— a check for a specific element
* `index` (`number`, optional)
— the node’s position in its parent
* `parent` ([`Node`][node], optional)
— the node’s parent
* `context` (`any`, optional)
— context object (`this`) to call `test` with
###### Returns
`boolean` — Whether `test` passed *and* `node` is a [`Node`][node] (object with
`type` set to a non-empty `string`).
Whether `node` is a [`Node`][node] and passes a test (`boolean`).
#### `function test(node[, index, parent])`
###### Throws
When an incorrect `test`, `index`, or `parent` is given.
There is no error thrown when `node` is not a node.
### `convert(test)`
Generate a check from a test.
Useful if you’re going to test many nodes, for example when creating a
utility where something else passes a compatible test.
The created function is a bit faster because it expects valid input only:
a `node`, `index`, and `parent`.
###### Parameters
* `node` ([`Node`][node]) — Node to check
* `index` (`number?`) — [Index][] of `node` in `parent`
* `parent` ([`Node?`][node]) — [Parent][] of `node`
* `test` ([`Test`][test] or [`PredicateTest`][predicatetest], optional)
— a check for a specific node
###### Context
###### Returns
`*` — The to `is` given `context`.
An assertion ([`AssertAnything`][assertanything] or
[`AssertPredicate`][assertpredicate]).
### `AssertAnything`
Check that an arbitrary value is a node, unaware of TypeScript inferral
(TypeScript type).
###### Parameters
* `node` (`unknown`)
— anything (typically a node)
* `index` (`number`, optional)
— the node’s position in its parent
* `parent` ([`Node`][node], optional)
— the node’s parent
###### Returns
`boolean?` — Whether `node` matches.
Whether this is a node and passes a test (`boolean`).
### `convert(test)`
### `AssertPredicate`
Create a test function from `test`, that can later be called with a `node`,
`index`, and `parent`.
Useful if you’re going to test many nodes, for example when creating a utility
where something else passes an is-compatible test.
Check that an arbitrary value is a specific node, aware of TypeScript
(TypeScript type).
The created function is slightly faster because it expects valid input only.
Therefore, passing invalid input, yields unexpected results.
###### Type parameters
For example:
* `Kind` ([`Node`][node])
— node type
###### Parameters
* `node` (`unknown`)
— anything (typically a node)
* `index` (`number`, optional)
— the node’s position in its parent
* `parent` ([`Node`][node], optional)
— the node’s parent
###### Returns
Whether this is a node and passes a test (`node is Kind`).
### `Test`
Check for an arbitrary node, unaware of TypeScript inferral (TypeScript
type).
###### Type
```ts
type Test =
| null
| undefined
| string
| Record<string, unknown>
| TestFunctionAnything
| Array<string | Record<string, unknown> | TestFunctionAnything>
```
Checks that the given thing is a node, and then:
* when `string`, checks that the node has that tag name
* when `function`, see [`TestFunctionAnything`][testfunctionanything]
* when `object`, checks that all keys in test are in node, and that they have
(strictly) equal values
* when `Array`, checks if one of the subtests pass
### `TestFunctionAnything`
Check if a node passes a test, unaware of TypeScript inferral (TypeScript
type).
###### Parameters
* `node` ([`Node`][node])
— a node
* `index` (`number`, optional)
— the node’s position in its parent
* `parent` ([`Node`][node], optional)
— the node’s parent
###### Returns
Whether this node passes the test (`boolean`).
### `PredicateTest`
Check for a node that can be inferred by TypeScript (TypeScript type).
###### Type
```ts
type PredicateTest<Kind extends Node> =
| Kind['type']
| Partial<Kind>
| TestFunctionPredicate<Kind>
| Array<Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind>>
```
See [`TestFunctionPredicate`][testfunctionpredicate].
### `TestFunctionPredicate`
Check if a node passes a certain node test (TypeScript type).
###### Type parameters
* `Kind` ([`Node`][node])
— node type
###### Parameters
* `node` ([`Node`][node])
— a node
* `index` (`number`, optional)
— the node’s position in its parent
* `parent` ([`Node`][node], optional)
— the node’s parent
###### Returns
Whether this node passes the test (`node is Kind`).
## Examples
### Example of `convert`
```js
import u from 'unist-builder'
import {u} from 'unist-builder'
import {convert} from 'unist-util-is'
var test = convert('leaf')
const test = convert('leaf')
var tree = u('tree', [
const tree = u('tree', [
u('node', [u('leaf', '1')]),

@@ -123,3 +297,3 @@ u('leaf', '2'),

var leafs = tree.children.filter((child, index) => test(child, index, tree))
const leafs = tree.children.filter((child, index) => test(child, index, tree))

@@ -135,23 +309,39 @@ console.log(leafs)

## Types
This package is fully typed with [TypeScript][].
It exports the additional types [`AssertAnything`][assertanything],
[`AssertPredicate`][assertpredicate], [`Test`][test],
[`TestFunctionAnything`][testfunctionanything],
[`TestFunctionPredicate`][testfunctionpredicate], and
[`PredicateTest`][predicatetest].
## Compatibility
Projects maintained by the unified collective are compatible with all 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.
## Related
* [`unist-util-find-after`](https://github.com/syntax-tree/unist-util-find-after)
— Find a node after another node
— find a node after another node
* [`unist-util-find-before`](https://github.com/syntax-tree/unist-util-find-before)
— Find a node before another node
— find a node before another node
* [`unist-util-find-all-after`](https://github.com/syntax-tree/unist-util-find-all-after)
— Find all nodes after another node
— find all nodes after another node
* [`unist-util-find-all-before`](https://github.com/syntax-tree/unist-util-find-all-before)
— Find all nodes before another node
— find all nodes before another node
* [`unist-util-find-all-between`](https://github.com/mrzmmr/unist-util-find-all-between)
— Find all nodes between two nodes
— find all nodes between two nodes
* [`unist-util-filter`](https://github.com/syntax-tree/unist-util-filter)
— Create a new tree with nodes that pass a check
— create a new tree with nodes that pass a check
* [`unist-util-remove`](https://github.com/syntax-tree/unist-util-remove)
— Remove nodes from tree
— remove nodes from tree
## Contribute
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for
ways to get started.
See [`support.md`][support] for ways to get help.

@@ -197,2 +387,8 @@

[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[esmsh]: https://esm.sh
[typescript]: https://www.typescriptlang.org
[license]: license

@@ -202,8 +398,10 @@

[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[health]: https://github.com/syntax-tree/.github
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[support]: https://github.com/syntax-tree/.github/blob/main/support.md
[coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist

@@ -213,6 +411,20 @@

[parent]: https://github.com/syntax-tree/unist#parent-1
[hast-util-is-element]: https://github.com/syntax-tree/hast-util-is-element
[index]: https://github.com/syntax-tree/unist#index
[unist-util-select]: https://github.com/syntax-tree/unist-util-select
[test]: #function-testnode-index-parent
[is]: #isnode-test-index-parent-context
[convert]: #converttest
[assertanything]: #assertanything
[assertpredicate]: #assertpredicate
[test]: #test
[testfunctionanything]: #testfunctionanything
[testfunctionpredicate]: #testfunctionpredicate
[predicatetest]: #predicatetest
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc