UNPKG

@bjoerge/mutiny

Version:

Tiny toolkit for working with Sanity mutations in JavaScript & TypeScript

318 lines (259 loc) 8.58 kB
export declare type AnyArray<T = any> = T[] | readonly T[] export declare type AnyEmptyArray = [] | readonly [] export declare type ByIndex<P extends number, T extends AnyArray> = T[P] export declare type Concat< R extends Result<any, any>, Arr extends any[], > = R[1] extends any[] ? Ok<[...R[1], ...Arr]> : R export declare type ConcatInner< R extends Result<any, any>, R2 extends Result<any, any>, > = R2[1] extends any[] ? Concat<R, R2[1]> : R2 export declare type Digit = | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' export declare type ElementType<T extends AnyArray> = T extends AnyArray<infer E> ? E : unknown export declare type Err<E> = Result<E, null> export declare type FindBy<P, T extends AnyArray> = T extends AnyEmptyArray ? undefined : T[0] extends P ? T[0] : T extends [any, ...infer Tail] | readonly [any, ...infer Tail] ? FindBy<P, Tail> : ElementType<T> export declare type FindInArray< P extends KeyedPathElement | number, T extends AnyArray, > = P extends KeyedPathElement ? FindBy<P, T> : P extends number ? ByIndex<P, T> : never export declare type Get< P extends number | KeyedPathElement | Readonly<KeyedPathElement> | string, T, > = T extends AnyArray ? P extends KeyedPathElement | Readonly<KeyedPathElement> | number ? FindInArray<P, T> : undefined : P extends keyof T ? T[P] : never export declare type GetAtPath< P extends readonly PathElement[], T, > = P extends [] ? T : P extends [infer Head, ...infer Tail] ? Head extends PathElement ? Tail extends PathElement[] ? GetAtPath<Tail, Get<Head, T>> : undefined : undefined : undefined export declare function getAtPath<const Head extends PathElement, const T>( path: [head: Head], value: T, ): Get<Head, T> export declare function getAtPath< const Head extends PathElement, const Tail extends PathElement[], T, >(path: [head: Head, ...tail: Tail], value: T): GetAtPath<[Head, ...Tail], T> export declare function getAtPath<T>(path: [], value: T): T export declare function getAtPath(path: Path, value: unknown): unknown export declare type Index = number export declare function isArrayElement( element: PathElement, ): element is KeyedPathElement | number export declare function isElementEqual( segmentA: PathElement, segmentB: PathElement, ): boolean export declare function isEqual(path: Path, otherPath: Path): boolean export declare function isIndexElement(segment: PathElement): segment is number export declare function isKeyedElement( element: PathElement, ): element is KeyedPathElement export declare function isKeyElement( segment: PathElement, ): segment is KeyedPathElement export declare function isPropertyElement( element: PathElement, ): element is string export declare type KeyedPathElement = { _key: string } export declare type Merge<R extends Result<any, any>, E> = R[0] extends null ? Ok<R[1] & E> : R export declare type MergeInner< R extends Result<any, any>, R2 extends Result<any, any>, > = R2[0] extends null ? Merge<R, R2[1]> : R export declare function normalize(path: string | Readonly<Path>): Readonly<Path> export declare type Ok<V> = Result<null, V> export declare type OnlyDigits<S> = S extends `${infer Head}${infer Tail}` ? Head extends Digit ? Tail extends '' ? true : OnlyDigits<Tail> extends true ? true : false : false : false export declare function parse<const T extends string>(path: T): StringToPath<T> export declare type ParseAllProps<Props extends string[]> = Props extends [ `${infer Head}`, ...infer Tail, ] ? Tail extends string[] ? ConcatInner<ParseProperty<Trim<Head>>, ParseAllProps<Tail>> : ParseProperty<Trim<Head>> : Ok<[]> export declare type ParseError<T extends string = 'unknown'> = T & { error: true } export declare type ParseExpressions<S extends string> = S extends `[${infer Expr}]${infer Remainder}` ? Trim<Remainder> extends '' ? ToArray<ParseInnerExpression<Trim<Expr>>> : ConcatInner< ToArray<ParseInnerExpression<Trim<Expr>>>, ParseExpressions<Remainder> > : Err<ParseError<`Cannot parse object from "${S}"`>> export declare type ParseInnerExpression<S extends string> = S extends '' ? Err<ParseError<'Saw an empty expression'>> : Try<ParseNumber<S>, ParseObject<S>> export declare type ParseKVPair<S extends string> = Split<S, '=='> extends [`${infer LHS}`, `${infer RHS}`] ? ParseValue<Trim<RHS>> extends infer Res ? Res extends [null, infer Value] ? Ok<{ [P in Trim<LHS>]: Value }> : Err< ParseError<`Can't parse right hand side as a value in "${S}" (Invalid value ${RHS})`> > : never : Err<ParseError<`Can't parse key value pair from ${S}`>> export declare type ParseNumber<S extends string> = S extends `${infer Head}${infer Tail}` ? Head extends '-' ? OnlyDigits<Tail> extends true ? Ok<ToNumber<S>> : Err<ParseError<`Invalid integer value "${S}"`>> : OnlyDigits<S> extends true ? Ok<ToNumber<S>> : Err<ParseError<`Invalid integer value "${S}"`>> : Err<ParseError<`Invalid integer value "${S}"`>> export declare type ParseObject<S extends string> = S extends `${infer Pair},${infer Remainder}` ? Trim<Remainder> extends '' ? Ok<Record<never, never>> : MergeInner<ParseKVPair<Pair>, ParseObject<Remainder>> : ParseKVPair<S> export declare type ParseProperty<S extends string> = Trim<S> extends '' ? Err<ParseError<'Empty property'>> : Split<Trim<S>, '[', true> extends [`${infer Prop}`, `${infer Expression}`] ? Trim<Prop> extends '' ? ParseExpressions<Trim<Expression>> : ConcatInner<Ok<[Trim<Prop>]>, ParseExpressions<Trim<Expression>>> : Ok<[Trim<S>]> export declare type ParseValue<S extends string> = string extends S ? Err<ParseError<'ParseValue got generic string type'>> : S extends 'null' ? Ok<null> : S extends 'true' ? Ok<true> : S extends 'false' ? Ok<false> : S extends `"${infer Value}"` ? Ok<Value> : Try< ParseNumber<S>, Err< ParseError<`ParseValue failed. Can't parse "${S}" as a value.`> > > export declare type Path = PathElement[] | readonly PathElement[] export declare type PathElement = PropertyName | Index | KeyedPathElement export declare type PropertyName = string export declare type Result<E, V> = [E, V] export declare type SafePath<S extends string> = StripError<StringToPath<S>> export declare type Split< S extends string, Char extends string, IncludeSeparator extends boolean = false, > = S extends `${infer First}${Char}${infer Remainder}` ? [First, `${IncludeSeparator extends true ? Char : ''}${Remainder}`] : [S] export declare type SplitAll< S extends string, Char extends string, > = S extends `${infer First}${Char}${infer Remainder}` ? [First, ...SplitAll<Remainder, Char>] : [S] export declare function startsWith(parentPath: Path, path: Path): boolean export declare function stringify(pathArray: Path): string export declare type StringToPath<S extends string> = Unwrap< ParseAllProps<SplitAll<Trim<S>, '.'>> > export declare type StripError< S extends StringToPath<string> | ParseError<string>, > = S extends ParseError<string> ? never : S export declare type ToArray<R extends Result<any, any>> = R extends [ infer E, infer V, ] ? E extends null ? V extends any[] ? R : Ok<[R[1]]> : R : R export declare type ToNumber<T extends string> = T extends `${infer N extends number}` ? N : never export declare type Trim< S extends string, Char extends string = ' ', > = TrimRight<TrimLeft<S, Char>, Char> export declare type TrimLeft< Str extends string, Char extends string = ' ', > = string extends Str ? Str : Str extends `${Char}${infer Trimmed}` ? TrimLeft<Trimmed, Char> : Str export declare type TrimRight< Str extends string, Char extends string = ' ', > = string extends Str ? Str : Str extends `${infer Trimmed}${Char}` ? TrimRight<Trimmed, Char> : Str export declare type Try<R extends Result<any, any>, Handled> = R[1] extends null ? Handled : R export declare type Unwrap<R extends Result<any, any>> = R extends [ infer E, infer V, ] ? E extends null ? V : E : never export {}