datocms-structured-text-utils
Version:
A set of Typescript types and helpers to work with DatoCMS Structured Text fields.
293 lines (292 loc) • 18.4 kB
TypeScript
/**
* Tree manipulation utilities for DatoCMS structured text documents.
*
* Provides a set of low-level utilities for visiting, transforming, and querying
* structured text trees. Works with all tree variants (regular, request, nested).
*/
/**
* Recursively extract all possible node types that can appear in a tree structure
*/
declare type AllNodesInTree<T, Depth extends number = 10> = Depth extends 0 ? T extends readonly unknown[] ? never : T : T extends readonly (infer U)[] ? AllNodesInTree<U, Prev<Depth>> : T extends {
children: infer Children;
} ? T | AllNodesInTree<Children, Prev<Depth>> : T;
declare type Prev<T extends number> = T extends 0 ? 0 : T extends 1 ? 0 : T extends 2 ? 1 : T extends 3 ? 2 : T extends 4 ? 3 : T extends 5 ? 4 : T extends 6 ? 5 : T extends 7 ? 6 : T extends 8 ? 7 : T extends 9 ? 8 : T extends 10 ? 9 : number;
/**
* Path through the Structured Text tree structure
*/
export declare type TreePath = readonly (string | number)[];
/**
* Input that can be either a node or a structured text field value
*/
declare type StructuredTextDocumentOrNode<T> = T | Document<T>;
/**
* Generic predicate function type for Structured Text tree node filtering
*/
export declare type NodePredicate<T, R> = (node: AllNodesInTree<T>, parent: AllNodesInTree<T> | null, path: TreePath) => R;
declare type Document<T> = {
schema: 'dast';
document: T;
};
/**
* Visit every node in the Structured Text tree, calling the visitor function for each.
* Uses pre-order traversal (parent is visited before its children).
*
* @template T - The type of the root node in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param visitor - Synchronous function called for each node. Receives the node, its parent, and path through the Structured Text tree
*/
export declare function forEachNode<T>(input: StructuredTextDocumentOrNode<T>, visitor: NodePredicate<T, void>, parent?: AllNodesInTree<T> | null, path?: TreePath): void;
/**
* Visit every node in the Structured Text tree, calling the visitor function for each.
* Uses pre-order traversal (parent is visited before its children).
*
* @template T - The type of the root node in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param visitor - Asynchronous function called for each node. Receives the node, its parent, and path through the Structured Text tree
* @returns Promise that resolves when all nodes have been visited
*/
export declare function forEachNodeAsync<T>(input: StructuredTextDocumentOrNode<T>, visitor: NodePredicate<T, Promise<void>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<void>;
/**
* Transform nodes in the Structured Text tree by applying a mapping function.
* Creates a new tree structure with transformed nodes while preserving the Structured Text tree hierarchy.
*
* @template T - The type of nodes in the input Structured Text tree
* @template R - The type of nodes in the output tree
* @param input - A structured text document
* @param mapper - Synchronous function that transforms each node. Receives the node, its parent, and path
* @returns The transformed document
*/
export declare function mapNodes<T, R>(input: Document<T>, mapper: NodePredicate<T, R>, parent?: AllNodesInTree<T> | null, path?: TreePath): Document<T>;
/**
* Transform nodes in the Structured Text tree by applying a mapping function.
* Creates a new tree structure with transformed nodes while preserving the Structured Text tree hierarchy.
*
* @template T - The type of nodes in the input Structured Text tree
* @template R - The type of nodes in the output tree
* @param input - A specific DAST node
* @param mapper - Synchronous function that transforms each node. Receives the node, its parent, and path
* @returns The transformed node
*/
export declare function mapNodes<T, R>(input: T, mapper: NodePredicate<T, R>, parent?: AllNodesInTree<T> | null, path?: TreePath): T;
/**
* Transform nodes in the Structured Text tree by applying a mapping function.
* Creates a new tree structure with transformed nodes while preserving the Structured Text tree hierarchy.
*
* @template T - The type of nodes in the input Structured Text tree
* @template R - The type of nodes in the output tree
* @param input - A structured text document
* @param mapper - Asynchronous function that transforms each node. Receives the node, its parent, and path
* @returns Promise that resolves to the transformed document
*/
export declare function mapNodesAsync<T, R>(input: Document<T>, mapper: NodePredicate<T, Promise<R>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<Document<R>>;
/**
* Transform nodes in the Structured Text tree by applying a mapping function.
* Creates a new tree structure with transformed nodes while preserving the Structured Text tree hierarchy.
*
* @template T - The type of nodes in the input Structured Text tree
* @template R - The type of nodes in the output tree
* @param input - A specific DAST node
* @param mapper - Asynchronous function that transforms each node. Receives the node, its parent, and path
* @returns Promise that resolves to the transformed node
*/
export declare function mapNodesAsync<T, R>(input: T, mapper: NodePredicate<T, Promise<R>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<R>;
/**
* Collect all nodes that match the type guard function using depth-first search.
* Returns an array containing all matching nodes along with their paths through the Structured Text tree.
*
* @template T - The type of nodes in the Structured Text tree
* @template U - The specific type that the type guard narrows to
* @param input - A structured text document, or a specific DAST node
* @param predicate - Type guard function that tests and narrows each node type
* @returns Array of objects, each containing a matching node (with narrowed type) and its path
*/
export declare function collectNodes<T, U extends AllNodesInTree<T>>(input: StructuredTextDocumentOrNode<T>, predicate: (node: AllNodesInTree<T>, parent: AllNodesInTree<T> | null, path: TreePath) => node is U, parent?: AllNodesInTree<T> | null, path?: TreePath): Array<{
node: U;
path: TreePath;
}>;
/**
* Collect all nodes that match the predicate function using depth-first search.
* Returns an array containing all matching nodes along with their paths through the Structured Text tree.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Synchronous function that tests each node. Should return true for desired nodes
* @returns Array of objects, each containing a matching node and its path
*/
export declare function collectNodes<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, boolean>, parent?: AllNodesInTree<T> | null, path?: TreePath): Array<{
node: AllNodesInTree<T>;
path: TreePath;
}>;
/**
* Collect all nodes that match the predicate function using depth-first search.
* Returns an array containing all matching nodes along with their paths through the Structured Text tree.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Asynchronous function that tests each node. Should return true for desired nodes
* @returns Promise that resolves to an array of objects, each containing a matching node and its path
*/
export declare function collectNodesAsync<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, Promise<boolean>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<Array<{
node: AllNodesInTree<T>;
path: TreePath;
}>>;
/**
* Find the first node that matches the type guard function using depth-first search.
* Returns the first matching node along with its path through the Structured Text tree, or null if no match is found.
*
* @template T - The type of nodes in the Structured Text tree
* @template U - The specific type that the type guard narrows to
* @param input - A structured text document, or a specific DAST node
* @param predicate - Type guard function that tests and narrows each node type
* @returns Object containing the first matching node (with narrowed type) and its path, or null if no match
*/
export declare function findFirstNode<T, U extends AllNodesInTree<T>>(input: StructuredTextDocumentOrNode<T>, predicate: (node: AllNodesInTree<T>, parent: AllNodesInTree<T> | null, path: TreePath) => node is U, parent?: AllNodesInTree<T> | null, path?: TreePath): {
node: U;
path: TreePath;
} | null;
/**
* Find the first node that matches the predicate function using depth-first search.
* Returns the first matching node along with its path through the Structured Text tree, or null if no match is found.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Synchronous function that tests each node. Should return true for desired nodes
* @returns Object containing the first matching node and its path, or null if no match
*/
export declare function findFirstNode<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, boolean>, parent?: AllNodesInTree<T> | null, path?: TreePath): {
node: AllNodesInTree<T>;
path: TreePath;
} | null;
/**
* Find the first node that matches the predicate function using depth-first search.
* Returns the first matching node along with its path through the Structured Text tree, or null if no match is found.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Asynchronous function that tests each node. Should return true for desired nodes
* @returns Promise that resolves to an object containing the first matching node and its path, or null if no match
*/
/**
* Find the first node that matches the predicate function using depth-first search.
* Returns the first matching node along with its path through the Structured Text tree, or null if no match is found.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Asynchronous function that tests each node. Should return true for desired nodes
* @returns Promise that resolves to an object containing the first matching node and its path, or null if no match
*/
export declare function findFirstNodeAsync<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, Promise<boolean>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<{
node: AllNodesInTree<T>;
path: TreePath;
} | null>;
/**
* Prune the Structured Text tree, removing nodes that don't match the predicate.
* Creates a new tree structure containing only nodes that pass the predicate test.
* Maintains the Structured Text tree hierarchy - if a parent node is kept, its structure is preserved.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document
* @param predicate - Synchronous function that tests each node. Nodes returning false are removed
* @returns The pruned document, or null if root node is filtered out
*/
export declare function filterNodes<T>(input: Document<T>, predicate: NodePredicate<T, boolean>, parent?: AllNodesInTree<T> | null, path?: TreePath): Document<T> | null;
/**
* Prune the Structured Text tree, removing nodes that don't match the predicate.
* Creates a new tree structure containing only nodes that pass the predicate test.
* Maintains the Structured Text tree hierarchy - if a parent node is kept, its structure is preserved.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A specific DAST node
* @param predicate - Synchronous function that tests each node. Nodes returning false are removed
* @returns The pruned node, or null if node is filtered out
*/
export declare function filterNodes<T>(input: T, predicate: NodePredicate<T, boolean>, parent?: AllNodesInTree<T> | null, path?: TreePath): T | null;
/**
* Prune the Structured Text tree, removing nodes that don't match the predicate.
* Creates a new tree structure containing only nodes that pass the predicate test.
* Maintains the Structured Text tree hierarchy - if a parent node is kept, its structure is preserved.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document
* @param predicate - Asynchronous function that tests each node. Nodes returning false are removed
* @returns Promise that resolves to the pruned document, or null if root node is filtered out
*/
export declare function filterNodesAsync<T>(input: Document<T>, predicate: NodePredicate<T, Promise<boolean>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<Document<T> | null>;
/**
* Prune the Structured Text tree, removing nodes that don't match the predicate.
* Creates a new tree structure containing only nodes that pass the predicate test.
* Maintains the Structured Text tree hierarchy - if a parent node is kept, its structure is preserved.
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A specific DAST node
* @param predicate - Asynchronous function that tests each node. Nodes returning false are removed
* @returns Promise that resolves to the pruned node, or null if node is filtered out
*/
export declare function filterNodesAsync<T>(input: T, predicate: NodePredicate<T, Promise<boolean>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<T | null>;
/**
* Reduce the Structured Text tree to a single value by applying a reducer function to each node.
* Uses pre-order traversal (parent is processed before its children).
* The reducer function is called for each node with the current accumulator value.
*
* @template T - The type of nodes in the Structured Text tree
* @template R - The type of the accumulated result
* @param input - A structured text document, or a specific DAST node
* @param reducer - Synchronous function that processes each node and updates the accumulator
* @param initialValue - The initial value for the accumulator
* @returns The final accumulated value
*/
export declare function reduceNodes<T, R>(input: StructuredTextDocumentOrNode<T>, reducer: (accumulator: R, node: AllNodesInTree<T>, parent: AllNodesInTree<T> | null, path: TreePath) => R, initialValue: R, parent?: AllNodesInTree<T> | null, path?: TreePath): R;
/**
* Reduce the Structured Text tree to a single value by applying a reducer function to each node.
* Uses pre-order traversal (parent is processed before its children).
* The reducer function is called for each node with the current accumulator value.
*
* @template T - The type of nodes in the Structured Text tree
* @template R - The type of the accumulated result
* @param input - A structured text document, or a specific DAST node
* @param reducer - Asynchronous function that processes each node and updates the accumulator
* @param initialValue - The initial value for the accumulator
* @returns Promise that resolves to the final accumulated value
*/
export declare function reduceNodesAsync<T, R>(input: StructuredTextDocumentOrNode<T>, reducer: (accumulator: R, node: AllNodesInTree<T>, parent: AllNodesInTree<T> | null, path: TreePath) => Promise<R>, initialValue: R, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<R>;
/**
* Check if any node in the Structured Text tree matches the predicate function.
* Returns true as soon as the first matching node is found (short-circuit evaluation).
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Synchronous function that tests each node. Should return true for matching nodes
* @returns True if any node matches, false otherwise
*/
export declare function someNode<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, boolean>, parent?: AllNodesInTree<T> | null, path?: TreePath): boolean;
/**
* Check if any node in the Structured Text tree matches the predicate function.
* Returns true as soon as the first matching node is found (short-circuit evaluation).
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Asynchronous function that tests each node. Should return true for matching nodes
* @returns Promise that resolves to true if any node matches, false otherwise
*/
export declare function someNodeAsync<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, Promise<boolean>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<boolean>;
/**
* Check if every node in the Structured Text tree matches the predicate function.
* Returns false as soon as the first non-matching node is found (short-circuit evaluation).
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Synchronous function that tests each node. Should return true for valid nodes
* @returns True if all nodes match, false otherwise
*/
export declare function everyNode<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, boolean>, parent?: AllNodesInTree<T> | null, path?: TreePath): boolean;
/**
* Check if every node in the Structured Text tree matches the predicate function.
* Returns false as soon as the first non-matching node is found (short-circuit evaluation).
*
* @template T - The type of nodes in the Structured Text tree
* @param input - A structured text document, or a specific DAST node
* @param predicate - Asynchronous function that tests each node. Should return true for valid nodes
* @returns Promise that resolves to true if all nodes match, false otherwise
*/
export declare function everyNodeAsync<T>(input: StructuredTextDocumentOrNode<T>, predicate: NodePredicate<T, Promise<boolean>>, parent?: AllNodesInTree<T> | null, path?: TreePath): Promise<boolean>;
export {};