[Utils] Fix findInTree (#32)
This commit is contained in:
parent
2201ff3a1d
commit
c54f9fe426
2 changed files with 38 additions and 30 deletions
7
src/def.d.ts
vendored
7
src/def.d.ts
vendored
|
@ -35,7 +35,8 @@ interface Logger {
|
|||
verbose: LoggerFunction;
|
||||
}
|
||||
|
||||
type SearchFilter = (tree: any) => boolean;
|
||||
type SearchTree = Record<string, any>;
|
||||
type SearchFilter = (tree: SearchTree) => boolean;
|
||||
interface FindInTreeOptions {
|
||||
walkable?: string[];
|
||||
ignore?: string[];
|
||||
|
@ -349,8 +350,8 @@ interface VendettaObject {
|
|||
};
|
||||
utils: {
|
||||
copyText: (content: string) => void;
|
||||
findInReactTree: (tree: { [key: string]: any }, filter: SearchFilter) => any;
|
||||
findInTree: (tree: { [key: string]: any }, filter: SearchFilter, options: FindInTreeOptions) => any;
|
||||
findInReactTree: (tree: SearchTree, filter: SearchFilter) => any;
|
||||
findInTree: (tree: SearchTree, filter: SearchFilter, options: FindInTreeOptions) => any;
|
||||
safeFetch: (input: RequestInfo, options: RequestInit) => Promise<Response>;
|
||||
unfreeze: (obj: object) => object;
|
||||
};
|
||||
|
|
|
@ -1,38 +1,45 @@
|
|||
// This has been completely reimplemented at this point, but the disclaimer at the end of disclaimers still counts.
|
||||
// https://github.com/Cordwood/Cordwood/blob/91c0b971bbf05e112927df75415df99fa105e1e7/src/lib/utils/findInTree.ts
|
||||
|
||||
import { FindInTreeOptions, SearchFilter } from "@types";
|
||||
|
||||
export default function findInTree(tree: { [key: string]: any }, filter: SearchFilter, { walkable = [], ignore = [], maxDepth = 100 }: FindInTreeOptions = {}): any {
|
||||
let iteration = 0;
|
||||
|
||||
function doSearch(tree: { [key: string]: any }, filter: SearchFilter, { walkable = [], ignore = [] }: FindInTreeOptions = {}): any {
|
||||
iteration += 1;
|
||||
if (iteration > maxDepth) return;
|
||||
|
||||
if (typeof filter === "string") {
|
||||
if (tree.hasOwnProperty(filter)) return tree[filter];
|
||||
} else if (filter(tree)) return tree;
|
||||
import { FindInTreeOptions, SearchTree, SearchFilter } from "@types";
|
||||
|
||||
function treeSearch(tree: SearchTree, filter: SearchFilter, opts: Required<FindInTreeOptions>, depth: number): any {
|
||||
if (depth > opts.maxDepth) return;
|
||||
if (!tree) return;
|
||||
|
||||
try {
|
||||
if (filter(tree)) return tree;
|
||||
} catch {}
|
||||
|
||||
if (Array.isArray(tree)) {
|
||||
for (const item of tree) {
|
||||
const found = doSearch(item, filter, { walkable, ignore });
|
||||
if (typeof item !== "object" || item === null) continue;
|
||||
|
||||
try {
|
||||
const found = treeSearch(item, filter, opts, depth + 1);
|
||||
if (found) return found;
|
||||
} catch {}
|
||||
}
|
||||
} else if (typeof tree === "object") {
|
||||
for (const key of Object.keys(tree)) {
|
||||
if (walkable != null && walkable.includes(key)) continue;
|
||||
|
||||
if (ignore.includes(key)) continue;
|
||||
if (typeof tree[key] !== "object" || tree[key] === null) continue;
|
||||
if (opts.walkable.length && !opts.walkable.includes(key)) continue;
|
||||
if (opts.ignore.includes(key)) continue;
|
||||
|
||||
try {
|
||||
const found = doSearch(tree[key], filter, { walkable, ignore });
|
||||
const found = treeSearch(tree[key], filter, opts, depth + 1);
|
||||
if (found) return found;
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return doSearch(tree, filter, { walkable, ignore });
|
||||
}
|
||||
export default (
|
||||
tree: SearchTree,
|
||||
filter: SearchFilter,
|
||||
{
|
||||
walkable = [],
|
||||
ignore = [],
|
||||
maxDepth = 100
|
||||
}: FindInTreeOptions = {},
|
||||
): any | undefined => treeSearch(tree, filter, { walkable, ignore, maxDepth }, 0);
|
||||
|
|
Loading…
Reference in a new issue