Urara-Blog/node_modules/.pnpm-store/v3/files/d6/f275fcc20b28ffcd86449ccdc5c2c72355fd115e7cdfe21cb1ed8b519047be13e79b263852ee8a77d550d47645d17cc388193db62e76904ae0115ed2eee122
2022-08-14 01:14:53 +08:00

112 lines
3 KiB
Text

/* eslint-disable @typescript-eslint/ban-types */
import type {Node, Parent} from 'unist'
import type {Test} from 'unist-util-is'
/**
* Union of the action types
*/
export type Action = boolean | 'skip'
/**
* Move to the sibling at index next (after node itself is completely
* traversed).
* Useful if mutating the tree, such as removing the node the visitor is
* currently on, or any of its previous siblings (or next siblings, in case of
* reverse) Results less than 0 or greater than or equal to `children.length`
* stop traversing the parent.
*/
export type Index = number
/**
* List with one or two values, the first an action, the second an index.
*/
export type ActionTuple = [
(Action | null | undefined | void)?,
(Index | null | undefined)?
]
/**
* Any value that can be returned from a visitor
*/
export type VisitorResult =
| null
| undefined
| Action
| Index
| ActionTuple
| void
/**
* Internal utility to collect all descendants of in `Tree`.
*/
export type InclusiveDescendant<
Tree extends Node = never,
Found = void
> = Tree extends Parent
?
| Tree
| InclusiveDescendant<
Exclude<Tree['children'][number], Found | Tree>,
Found | Tree
>
: Tree
type Predicate<Fn, Fallback = never> = Fn extends (
value: any
) => value is infer Thing
? Thing
: Fallback
type MatchesOne<Value, Check> =
// Is this a node?
Value extends Node
? // No test.
Check extends null
? Value
: // No test.
Check extends undefined
? Value
: // Function test.
Check extends Function
? Extract<Value, Predicate<Check, Value>>
: // String (type) test.
Value['type'] extends Check
? Value
: // Partial test.
Value extends Check
? Value
: never
: never
export type Matches<Value, Check> =
// Is this a list?
Check extends any[]
? MatchesOne<Value, Check[keyof Check]>
: MatchesOne<Value, Check>
/**
* Invoked when a node (matching test, if given) is found.
* Visitors are free to transform node.
* They can also transform the parent of node (the last of ancestors).
* Replacing node itself, if `SKIP` is not returned, still causes its descendants to be visited.
* If adding or removing previous siblings (or next siblings, in case of reverse) of node,
* visitor should return a new index (number) to specify the sibling to traverse after node is traversed.
* Adding or removing next siblings of node (or previous siblings, in case of reverse)
* is handled as expected without needing to return a new index.
* Removing the children property of an ancestor still results in them being traversed.
*/
export type Visitor<
Visited extends Node = Node,
Ancestor extends Parent = Parent
> = (node: Visited, ancestors: Ancestor[]) => VisitorResult
export type BuildVisitor<
Tree extends Node = Node,
Check extends Test = string
> = Visitor<
Matches<InclusiveDescendant<Tree>, Check>,
Extract<InclusiveDescendant<Tree>, Parent>
>
/* eslint-enable @typescript-eslint/ban-types */