UNPKG

@bjoerge/mutiny

Version:

Tiny toolkit for working with Sanity mutations in JavaScript & TypeScript

1,159 lines (1,005 loc) 27.4 kB
export declare type AnyArray<T = any> = T[] | readonly T[] export declare type AnyEmptyArray = [] | readonly [] export declare type AnyOp = SetOp<unknown> | SetIfMissingOp<unknown> | UnsetOp export declare function append<const Items extends AnyArray<unknown>>( items: Items | ArrayElement<Items>, ): InsertOp<NormalizeReadOnlyArray<Items>, 'after', -1> export declare type ArrayElement<A> = A extends readonly (infer T)[] ? T : never export declare type ArrayOp = | InsertOp<AnyArray, RelativePosition, Index | KeyedPathElement> | UpsertOp<AnyArray, RelativePosition, Index | KeyedPathElement> | ReplaceOp<AnyArray, Index | KeyedPathElement> | TruncateOp export declare type Arrify<T> = (T extends (infer E)[] ? E : T)[] export declare const assign: < const T extends { [x: string]: unknown }, >( value: T, ) => AssignOp<T> declare type AssignMutation = [ 'patch', 'assign', Id, CompactPath, [object], RevisionLock?, ] export declare type AssignOp<T extends object = object> = { type: 'assign' value: T } export declare function at<const P extends Path, O extends Operation>( path: P, operation: O, ): NodePatch<NormalizeReadOnlyArray<P>, O> export declare function at<const P extends string, O extends Operation>( path: P, operation: O, ): NodePatch<SafePath<P>, O> export declare function autoKeys<Item>(generateKey: (item: Item) => string): { insert: <Pos extends RelativePosition, Ref extends number | KeyedPathElement>( position: Pos, referenceItem: Ref, items: Item[], ) => InsertOp<Item[], Pos, Ref> upsert: < Pos_1 extends RelativePosition, ReferenceItem extends number | KeyedPathElement, >( items: Item[], position: Pos_1, referenceItem: ReferenceItem, ) => UpsertOp<Item[], Pos_1, ReferenceItem> replace: < Pos_2 extends RelativePosition, ReferenceItem_1 extends number | KeyedPathElement, >( items: Item[], position: Pos_2, referenceItem: ReferenceItem_1, ) => ReplaceOp<Item[], ReferenceItem_1> insertBefore: <Ref_1 extends number | KeyedPathElement>( ref: Ref_1, items: Item[], ) => InsertOp<Item[], 'before', Ref_1> prepend: (items: Item[]) => InsertOp<Item[], 'before', 0> insertAfter: <Ref_2 extends number | KeyedPathElement>( ref: Ref_2, items: Item[], ) => InsertOp<Item[], 'after', Ref_2> append: (items: Item[]) => InsertOp<Item[], 'after', -1> } export declare type ByIndex<P extends number, T extends AnyArray> = T[P] declare namespace CompactEncoder { export { decode, encode, Id, RevisionLock, CompactPath, ItemRef, DeleteMutation_2 as DeleteMutation, CreateMutation_2 as CreateMutation, CreateIfNotExistsMutation_2 as CreateIfNotExistsMutation, CreateOrReplaceMutation_2 as CreateOrReplaceMutation, UnsetMutation, InsertMutation, UpsertMutation, TruncateMutation, IncMutation, DecMutation, AssignMutation, UnassignMutation, ReplaceMutation, SetMutation, SetIfMissingMutation, DiffMatchPatchMutation, CompactPatchMutation, CompactMutation, } } export {CompactEncoder} declare namespace CompactFormatter { export {format, ItemRef_2 as ItemRef} } export {CompactFormatter} declare type CompactMutation<Doc> = | DeleteMutation_2 | CreateMutation_2<Doc> | CreateIfNotExistsMutation_2<Doc> | CreateOrReplaceMutation_2<Doc> | CompactPatchMutation declare type CompactPatchMutation = | UnsetMutation | InsertMutation | UpsertMutation | TruncateMutation | IncMutation | DecMutation | SetMutation | SetIfMissingMutation | DiffMatchPatchMutation | AssignMutation | UnassignMutation | ReplaceMutation declare type CompactPath = string 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 function create<Doc extends Optional<SanityDocumentBase, '_id'>>( document: Doc, ): CreateMutation<Doc> export declare function createIfNotExists<Doc extends SanityDocumentBase>( document: Doc, ): CreateIfNotExistsMutation<Doc> export declare type CreateIfNotExistsMutation<Doc extends SanityDocumentBase> = { type: 'createIfNotExists' document: Doc } declare type CreateIfNotExistsMutation_2<Doc> = ['createIfNotExists', Doc] export declare type CreateMutation< Doc extends Optional<SanityDocumentBase, '_id'>, > = { type: 'create' document: Doc } declare type CreateMutation_2<Doc> = ['create', Doc] export declare function createOrReplace<Doc extends SanityDocumentBase>( document: Doc, ): CreateOrReplaceMutation<Doc> export declare type CreateOrReplaceMutation<Doc extends SanityDocumentBase> = { type: 'createOrReplace' document: Doc } declare type CreateOrReplaceMutation_2<Doc> = ['createOrReplace', Doc] export declare const dec: <const N extends number = 1>(amount?: N) => DecOp<N> declare type DecMutation = [ 'patch', 'dec', Id, CompactPath, [number], RevisionLock?, ] declare function decode<Doc extends SanityDocumentBase>( mutations: CompactMutation<Doc>[], ): Mutation[] declare function decode_2<Doc extends SanityDocumentBase>( encodedMutation: SanityMutation<Doc>, ): Mutation declare function decodeAll<Doc extends SanityDocumentBase>( sanityMutations: SanityMutation<Doc>[], ): Mutation[] export declare type DecOp<Amount extends number> = { type: 'dec' amount: Amount } export declare const del: typeof delete_ export declare function delete_(id: string): DeleteMutation export declare type DeleteMutation = { type: 'delete' id: string } declare type DeleteMutation_2 = ['delete', Id] export declare const destroy: typeof delete_ export declare const diffMatchPatch: (value: string) => DiffMatchPatchOp declare type DiffMatchPatchMutation = [ 'patch', 'diffMatchPatch', Id, CompactPath, [string], RevisionLock?, ] export declare type DiffMatchPatchOp = { type: 'diffMatchPatch' value: string } 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 declare function encode<Doc extends SanityDocumentBase>( mutations: Mutation[], ): CompactMutation<Doc>[] declare function encode_2(mutation: Mutation): | { patch: | { unset: string[] insert?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { insert: { [x: string]: string | readonly any[] items: AnyArray replace?: undefined } unset?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { diffMatchPatch: { [x: string]: string } unset?: undefined insert?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { inc: { [x: string]: number } unset?: undefined insert?: undefined diffMatchPatch?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { dec: { [x: string]: number } unset?: undefined insert?: undefined diffMatchPatch?: undefined inc?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { unset?: undefined insert?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { unset: string[] insert: { [x: string]: string | readonly any[] items: AnyArray replace?: undefined } diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { set: { [k: string]: never } unset?: undefined insert?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined ifRevisionID?: string | undefined id: string } | { insert: { replace: string items: AnyArray } unset?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } }[] | { [x: string]: any delete?: undefined } | { delete: { id: string } } declare function encodeAll(mutations: Mutation[]): any[] declare function encodeMutation(mutation: Mutation): | { patch: | { unset: string[] insert?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { insert: { [x: string]: string | readonly any[] items: AnyArray replace?: undefined } unset?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { diffMatchPatch: { [x: string]: string } unset?: undefined insert?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { inc: { [x: string]: number } unset?: undefined insert?: undefined diffMatchPatch?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { dec: { [x: string]: number } unset?: undefined insert?: undefined diffMatchPatch?: undefined inc?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { unset?: undefined insert?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { unset: string[] insert: { [x: string]: string | readonly any[] items: AnyArray replace?: undefined } diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } | { set: { [k: string]: never } unset?: undefined insert?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined ifRevisionID?: string | undefined id: string } | { insert: { replace: string items: AnyArray } unset?: undefined diffMatchPatch?: undefined inc?: undefined dec?: undefined set?: undefined ifRevisionID?: string | undefined id: string } }[] | { [x: string]: any delete?: undefined } | { delete: { id: string } } declare function encodeTransaction(transaction: Transaction): { transactionId: string | undefined mutations: any[] } 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 declare function format<Doc extends SanityDocumentBase>( mutations: Mutation[], ): string declare type Id = string export declare const inc: <const N extends number = 1>(amount?: N) => IncOp<N> declare type IncMutation = [ 'patch', 'inc', Id, CompactPath, [number], RevisionLock?, ] export declare type IncOp<Amount extends number> = { type: 'inc' amount: Amount } export declare type Index = number declare type Insert = { before?: string after?: string replace?: string items: any[] } export declare function insert< const Items extends AnyArray<unknown>, const Pos extends RelativePosition, const ReferenceItem extends Index | KeyedPathElement, >( items: Items | ArrayElement<Items>, position: Pos, indexOrReferenceItem: ReferenceItem, ): InsertOp<NormalizeReadOnlyArray<Items>, Pos, ReferenceItem> export declare const insertAfter: < const Items extends AnyArray<unknown>, const ReferenceItem extends number | KeyedPathElement, >( items: Items | ArrayElement<Items>, indexOrReferenceItem: ReferenceItem, ) => InsertOp<NormalizeReadOnlyArray<Items>, 'after', ReferenceItem> export declare function insertBefore< const Items extends AnyArray<unknown>, const ReferenceItem extends Index | KeyedPathElement, >( items: Items | ArrayElement<Items>, indexOrReferenceItem: ReferenceItem, ): InsertOp<NormalizeReadOnlyArray<Items>, 'before', ReferenceItem> declare type InsertMutation = [ 'patch', 'insert', Id, CompactPath, [RelativePosition, ItemRef, AnyArray], RevisionLock?, ] export declare type InsertOp< Items extends AnyArray, Pos extends RelativePosition, ReferenceItem extends Index | KeyedPathElement, > = { type: 'insert' referenceItem: ReferenceItem position: Pos items: Items } declare type ItemRef = string | number declare type ItemRef_2 = string | number 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 type Mutation<Doc extends SanityDocumentBase = any> = | CreateMutation<Doc> | CreateIfNotExistsMutation<Doc> | CreateOrReplaceMutation<Doc> | DeleteMutation | PatchMutation export declare type NodePatch< P extends Path = Path, O extends Operation = Operation, > = { path: P op: O } export declare type NodePatchList = | [NodePatch, ...NodePatch[]] | NodePatch[] | readonly NodePatch[] | readonly [NodePatch, ...NodePatch[]] export declare type NormalizeReadOnlyArray<T> = T extends readonly [ infer NP, ...infer Rest, ] ? [NP, ...Rest] : T extends readonly (infer NP)[] ? NP[] : T export declare type NumberOp = IncOp<number> | DecOp<number> export declare type ObjectOp = AssignOp | UnassignOp 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 type Operation = PrimitiveOp | ArrayOp | ObjectOp export declare type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>> 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 function patch<P extends NodePatchList | NodePatch>( id: string, patches: P, options?: PatchOptions, ): PatchMutation<NormalizeReadOnlyArray<Tuplify<P>>> export declare type PatchMutation< Patches extends NodePatchList = NodePatchList, > = { type: 'patch' id: string patches: Patches options?: PatchOptions } export declare type PatchOptions = { ifRevision?: string } export declare type Path = PathElement[] | readonly PathElement[] export declare type PathElement = PropertyName | Index | KeyedPathElement export declare function prepend<const Items extends AnyArray<unknown>>( items: Items | ArrayElement<Items>, ): InsertOp<NormalizeReadOnlyArray<Items>, 'before', 0> export declare type PrimitiveOp = AnyOp | StringOp | NumberOp export declare type PropertyName = string export declare type RelativePosition = 'before' | 'after' export declare function replace< Items extends any[], ReferenceItem extends Index | KeyedPathElement, >( items: Items | ArrayElement<Items>, referenceItem: ReferenceItem, ): ReplaceOp<Items, ReferenceItem> declare type ReplaceMutation = [ 'patch', 'replace', Id, CompactPath, [ItemRef, AnyArray], RevisionLock?, ] export declare type ReplaceOp< Items extends AnyArray, ReferenceItem extends Index | KeyedPathElement, > = { type: 'replace' referenceItem: ReferenceItem items: Items } export declare type Result<E, V> = [E, V] declare type RevisionLock = string export declare type SafePath<S extends string> = StripError<StringToPath<S>> declare type SanityCreateIfNotExistsMutation<Doc extends SanityDocumentBase> = { createIfNotExists: Doc } declare type SanityCreateMutation<Doc extends SanityDocumentBase> = { create: Doc } declare type SanityCreateOrReplaceMutation<Doc extends SanityDocumentBase> = { createOrReplace: Doc } declare type SanityDecPatch = { id: string dec: { [path: string]: number } } declare type SanityDeleteMutation = { delete: { id: string } } declare type SanityDiffMatchPatch = { id: string diffMatchPatch: { [path: string]: string } } export declare type SanityDocumentBase = { _id?: string _type: string _createdAt?: string _updatedAt?: string _rev?: string } declare namespace SanityEncoder { export { decodeAll, decode_2 as decode, Mutation, SanityDocumentBase, SanityDiffMatchPatch, SanitySetPatch, Insert, SanityInsertPatch, SanityUnsetPatch, SanityIncPatch, SanityDecPatch, SanitySetIfMissingPatch, SanityPatch, SanityCreateIfNotExistsMutation, SanityCreateOrReplaceMutation, SanityCreateMutation, SanityDeleteMutation, SanityPatchMutation, SanityMutation, encode_2 as encode, encodeAll, encodeTransaction, encodeMutation, } } export {SanityEncoder} declare type SanityIncPatch = { id: string inc: { [path: string]: number } } declare type SanityInsertPatch = { id: string insert: Insert } declare type SanityMutation< Doc extends SanityDocumentBase = SanityDocumentBase, > = | SanityCreateMutation<Doc> | SanityCreateIfNotExistsMutation<Doc> | SanityCreateOrReplaceMutation<Doc> | SanityDeleteMutation | SanityPatchMutation declare type SanityPatch = | SanitySetPatch | SanityUnsetPatch | SanityInsertPatch | SanitySetIfMissingPatch | SanityDiffMatchPatch | SanityIncPatch | SanityDecPatch declare type SanityPatchMutation = { patch: | SanitySetPatch | SanitySetIfMissingPatch | SanityDiffMatchPatch | SanityInsertPatch | SanityUnsetPatch } declare type SanitySetIfMissingPatch = { id: string setIfMissing: { [path: string]: any } } declare type SanitySetPatch = { id: string set: { [path: string]: any } } declare type SanityUnsetPatch = { id: string unset: string[] } export declare const set: <const T>(value: T) => SetOp<T> export declare const setIfMissing: <const T>(value: T) => SetIfMissingOp<T> declare type SetIfMissingMutation = [ 'patch', 'setIfMissing', Id, CompactPath, [unknown], RevisionLock?, ] export declare type SetIfMissingOp<T> = { type: 'setIfMissing' value: T } declare type SetMutation = ['patch', 'set', Id, CompactPath, any, RevisionLock?] export declare type SetOp<T> = { type: 'set' value: T } 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 type StringOp = DiffMatchPatchOp 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 interface Transaction { id?: string mutations: Mutation[] } 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 function truncate( startIndex: number, endIndex?: number, ): TruncateOp declare type TruncateMutation = [ 'patch', 'truncate', Id, CompactPath, [startIndex: number, endIndex: number | undefined], RevisionLock?, ] export declare type TruncateOp = { type: 'truncate' startIndex: number endIndex?: number } export declare type Try<R extends Result<any, any>, Handled> = R[1] extends null ? Handled : R export declare type Tuplify<T> = T extends readonly [infer NP, ...infer Rest] ? [NP, ...Rest] : T extends readonly (infer NP)[] ? NP[] : [T] export declare const unassign: <const K extends readonly string[]>( keys: K, ) => UnassignOp<K> declare type UnassignMutation = [ 'patch', 'assign', Id, CompactPath, [string[]], RevisionLock?, ] export declare type UnassignOp< K extends readonly string[] = readonly string[], > = { type: 'unassign' keys: K } export declare const unset: () => UnsetOp declare type UnsetMutation = [ 'patch', 'unset', Id, CompactPath, [], RevisionLock?, ] export declare type UnsetOp = { type: 'unset' } export declare type Unwrap<R extends Result<any, any>> = R extends [ infer E, infer V, ] ? E extends null ? V : E : never export declare function upsert< const Items extends AnyArray<unknown>, const Pos extends RelativePosition, const ReferenceItem extends Index | KeyedPathElement, >( items: Items | ArrayElement<Items>, position: Pos, referenceItem: ReferenceItem, ): UpsertOp<Items, Pos, ReferenceItem> declare type UpsertMutation = [ 'patch', 'upsert', Id, CompactPath, [RelativePosition, ItemRef, AnyArray], RevisionLock?, ] export declare type UpsertOp< Items extends AnyArray, Pos extends RelativePosition, ReferenceItem extends Index | KeyedPathElement, > = { type: 'upsert' items: Items referenceItem: ReferenceItem position: Pos } export {}