| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- /**
- * @typedef {import('unist').Node} UnistNode
- * @typedef {import('unist').Parent} UnistParent
- */
- /**
- * @typedef {Exclude<import('unist-util-is').Test, undefined> | undefined} Test
- * Test from `unist-util-is`.
- *
- * Note: we have remove and add `undefined`, because otherwise when generating
- * automatic `.d.ts` files, TS tries to flatten paths from a local perspective,
- * which doesn’t work when publishing on npm.
- */
- /**
- * @typedef {(
- * Fn extends (value: any) => value is infer Thing
- * ? Thing
- * : Fallback
- * )} Predicate
- * Get the value of a type guard `Fn`.
- * @template Fn
- * Value; typically function that is a type guard (such as `(x): x is Y`).
- * @template Fallback
- * Value to yield if `Fn` is not a type guard.
- */
- /**
- * @typedef {(
- * Check extends null | undefined // No test.
- * ? Value
- * : Value extends {type: Check} // String (type) test.
- * ? Value
- * : Value extends Check // Partial test.
- * ? Value
- * : Check extends Function // Function test.
- * ? Predicate<Check, Value> extends Value
- * ? Predicate<Check, Value>
- * : never
- * : never // Some other test?
- * )} MatchesOne
- * Check whether a node matches a primitive check in the type system.
- * @template Value
- * Value; typically unist `Node`.
- * @template Check
- * Value; typically `unist-util-is`-compatible test, but not arrays.
- */
- /**
- * @typedef {(
- * Check extends Array<any>
- * ? MatchesOne<Value, Check[keyof Check]>
- * : MatchesOne<Value, Check>
- * )} Matches
- * Check whether a node matches a check in the type system.
- * @template Value
- * Value; typically unist `Node`.
- * @template Check
- * Value; typically `unist-util-is`-compatible test.
- */
- /**
- * @typedef {(
- * Kind extends {children: Array<infer Child>}
- * ? Child
- * : never
- * )} Child
- * Collect nodes that can be parents of `Child`.
- * @template {UnistNode} Kind
- * All node types.
- */
- import {convert} from 'unist-util-is'
- /**
- * Find the first node in `parent` after another `node` or after an index,
- * that passes `test`.
- *
- * @param parent
- * Parent node.
- * @param index
- * Child node or index.
- * @param [test=undefined]
- * Test for child to look for (optional).
- * @returns
- * A child (matching `test`, if given) or `undefined`.
- */
- export const findAfter =
- // Note: overloads like this are needed to support optional generics.
- /**
- * @type {(
- * (<Kind extends UnistParent, Check extends Test>(parent: Kind, index: Child<Kind> | number, test: Check) => Matches<Child<Kind>, Check> | undefined) &
- * (<Kind extends UnistParent>(parent: Kind, index: Child<Kind> | number, test?: null | undefined) => Child<Kind> | undefined)
- * )}
- */
- (
- /**
- * @param {UnistParent} parent
- * @param {UnistNode | number} index
- * @param {Test} [test]
- * @returns {UnistNode | undefined}
- */
- function (parent, index, test) {
- const is = convert(test)
- if (!parent || !parent.type || !parent.children) {
- throw new Error('Expected parent node')
- }
- if (typeof index === 'number') {
- if (index < 0 || index === Number.POSITIVE_INFINITY) {
- throw new Error('Expected positive finite number as index')
- }
- } else {
- index = parent.children.indexOf(index)
- if (index < 0) {
- throw new Error('Expected child node or index')
- }
- }
- while (++index < parent.children.length) {
- if (is(parent.children[index], index, parent)) {
- return parent.children[index]
- }
- }
- return undefined
- }
- )
|