import { FindPaths } from "./FindPaths.js"; import { Path } from "./types.js"; import { Next } from "./utils.js"; import { Type, Expect, A, B, C, Checked, _apply, Last } from "free-types-core"; import { Replace } from "./Replace.js"; import { Over } from "./Over.js"; export { FindReplace, $ReplaceTable, $Callback as $ReplaceCallback }; type $Callback = Type<[T, Path?]>; type FindReplace, From extends Path = [], Limit extends number = number> = FindPaths extends infer Queries ? [Queries] extends [never] ? T : Queries extends Path[] ? Fold : _V extends Expect ? IsUnary<_V> extends true ? $WithUnaryCallback<_V> : $WithBinaryCallback<_V> : never : never> : never : never; interface $WithValue extends Type<[unknown, Path, number]> { type: unknown extends this[1] ? unknown : Replace, A, LastAvailable>, any>; } interface $WithUnaryCallback> extends Type<[unknown, Path]> { type: unknown extends this[1] ? unknown : Over, A, V, any>; } interface $WithBinaryCallback> extends Type<[unknown, Path]> { type: unknown extends this[1] ? unknown : Over, A, $BindPath>, any>; } type IsUnary = V extends { constraints: infer C extends { length: unknown; }; } ? [C['length']] extends [1] ? true : false : false; interface $BindPath, P extends Path> extends Type<1> { type: _apply; } type Fold> | Expect>, Acc extends unknown = Init, I extends number = 0> = I extends T['length'] ? Acc : Fold, Next>; type LastAvailable = IsIndexOf extends true ? V[I] : Last; type IsIndexOf = `${I}` extends Extract ? true : false; type Entry = [needle: unknown, value: unknown]; type Needles = T[number][0]; type Lookup = T extends readonly [infer H extends Entry, ...infer R extends Entry[]] ? [V] extends [H[0]] ? H[1] : Lookup : never; interface $ReplaceTable extends $Callback> { type: Lookup>; }