import { GenericFree, IsAny, GetOrElse, IsArray } from "./utils"; import { Fn, NOT_FOUND, Path, self } from "./types"; import { Get } from "./Get"; import { apply, Checked, Lossy, At } from "free-types-core"; import { $Iterator, $Struct, $Tuple, $Array, $Fn, $Free } from "./Search/Iterators"; import { $DeepSearch, $SearchMode, IsNeedle, MatchAll } from "./Search/types"; import * as Standard from "./Search/StandardSearch"; import * as Exhaustive from "./Search/ExhaustiveSearch"; export { FindPaths }; type FindPaths> = [T] extends [T] ? From extends [] ? GetPaths extends infer P extends unknown[][] ? FormatSelf

: [] : GetPaths, Needle, Limit, $Search> extends infer P extends unknown[][] ? P extends [] ? From : FormatSelf<{ [K in keyof P]: [...From, ...P[K]]; }> : [] : never; type SelectSearchMode = MatchAll extends true ? Exhaustive.SearchMode> : Standard.SearchMode>; type GetPaths = Limit extends 0 | never ? Acc : IsAny extends true ? IsAny extends true ? [] : NOT_FOUND : IsNeedle extends true ? [] : IsArray extends true ? Search, $Search> : T extends readonly unknown[] ? Search, $Search> : T extends GenericFree ? Search, $Search> : T extends Fn ? Search, $Search> : T extends { [k: PropertyKey]: unknown; } ? Search, $Search> : NOT_FOUND; type Search = apply<$Seach['total'], [Acc, $I, apply<$Seach['shallow'], [Limit, $I]>]>; type LIMIT = 0; type VALUE = 2; type PATH = 3; type $SEARCH = 4; interface $DeepSearchImpl extends $DeepSearch { type: unknown extends this[LIMIT] ? unknown[][] : GetPaths, Needle, Lossy, Checked<$SEARCH, this>, []> extends infer Paths ? Paths extends NOT_FOUND ? this['Acc'] : [ ...this['Acc'], ...Spread<{ [K in keyof Paths]: [...Checked, ...Spread]; }> ] : never; Acc: Checked<1, this>; } type FormatSelf = GetOrElse; type Spread = GetOrElse;