/* eslint-disable @typescript-eslint/ban-types */ import { Path, Block, Reference, ReferenceSchemaType as BaseReferenceSchemaType, ArraySchemaType as BaseArraySchemaType, BaseSchemaType as BaseGenericSchemaType, BlockSchemaType as BaseBlockSchemaType, BooleanSchemaType as BaseBooleanSchemaType, NumberSchemaType as BaseNumberSchemaType, ObjectSchemaType as BaseObjectSchemaType, StringSchemaType as BaseStringSchemaType, ObjectFieldType, ConditionalProperty, } from '@sanity/types' import {ComponentType} from 'react' import { // Base diffs ArrayDiff as AgnosticArrayDiff, BooleanDiff as AgnosticBooleanDiff, NullDiff as AgnosticNullDiff, NumberDiff as AgnosticNumberDiff, ObjectDiff as AgnosticObjectDiff, StringDiff as AgnosticStringDiff, TypeChangeDiff as AgnosticTypeChangeDiff, // Diff internals ItemDiff as AgnosticItemDiff, StringSegmentChanged as AgnosticStringSegmentChanged, StringSegmentUnchanged as AgnosticStringSegmentUnchanged, } from '@sanity/diff' import {FieldValueError} from './validation' /** * History timeline / chunking */ export type ChunkType = | 'initial' | 'create' | 'editDraft' | 'delete' | 'publish' | 'unpublish' | 'discardDraft' | 'editLive' export type Chunk = { index: number id: string type: ChunkType start: number end: number startTimestamp: string endTimestamp: string authors: Set draftState: 'present' | 'missing' | 'unknown' publishedState: 'present' | 'missing' | 'unknown' } /** * Annotation connected to a change */ export type AnnotationDetails = { chunk: Chunk timestamp: string author: string } export type Annotation = AnnotationDetails | null /** * Diff types with annotation type set automatically */ export type ArrayDiff = AgnosticArrayDiff export type BooleanDiff = AgnosticBooleanDiff export type NullDiff = AgnosticNullDiff export type NumberDiff = AgnosticNumberDiff export type ObjectDiff> = AgnosticObjectDiff export type StringDiff = AgnosticStringDiff export type ReferenceDiff = ObjectDiff export type TypeChangeDiff = AgnosticTypeChangeDiff export type Diff> = | ArrayDiff | BooleanDiff | NullDiff | NumberDiff | ObjectDiff | StringDiff | TypeChangeDiff export type StringDiffSegment = StringSegmentChanged | StringSegmentUnchanged export type StringSegmentChanged = AgnosticStringSegmentChanged export type StringSegmentUnchanged = AgnosticStringSegmentUnchanged export type ItemDiff = AgnosticItemDiff /** * Diff extensions for presentational concerns */ export interface ArrayItemMetadata { fromType?: SchemaType toType?: SchemaType } /** * Diff components */ export type DiffComponent = ComponentType> export type DiffComponentOptions = { component: DiffComponent showHeader?: boolean } export type DiffProps = { diff: T schemaType: T extends ObjectDiff ? ObjectSchemaType : T extends ArrayDiff ? ArraySchemaType : T extends BooleanDiff ? BooleanSchemaType : T extends StringDiff ? StringSchemaType : T extends NumberDiff ? NumberSchemaType : SchemaType } /** * Resolvers */ export type DiffComponentResolver = (options: { schemaType: SchemaType parentSchemaType?: ArraySchemaType | ObjectSchemaType }) => React.ComponentType | DiffComponentOptions | undefined /** * Schema */ // Note: INCOMPLETE, but good enough for diffs export interface BaseSchemaType extends BaseGenericSchemaType { diffComponent?: DiffComponent | DiffComponentOptions } export interface StringSchemaType extends BaseStringSchemaType { diffComponent?: DiffComponent | DiffComponentOptions } export interface NumberSchemaType extends BaseNumberSchemaType { diffComponent?: DiffComponent | DiffComponentOptions } export interface BooleanSchemaType extends BaseBooleanSchemaType { diffComponent?: DiffComponent | DiffComponentOptions } export interface ArraySchemaType extends BaseArraySchemaType { diffComponent?: DiffComponent> | DiffComponentOptions> } export interface BlockSchemaType extends BaseBlockSchemaType { diffComponent?: DiffComponent>> | DiffComponentOptions>> } export interface ObjectSchemaType> extends BaseObjectSchemaType { diffComponent?: DiffComponent> | DiffComponentOptions> } export interface ReferenceSchemaType extends BaseReferenceSchemaType { diffComponent?: DiffComponent> | DiffComponentOptions> } export type SchemaType> = | ArraySchemaType | BooleanSchemaType | NumberSchemaType | ObjectSchemaType | StringSchemaType /** * "Changes" (presentation-oriented grouping of diffs) */ export interface GroupChangeNode { type: 'group' changes: ChangeNode[] key: string path: Path titlePath: ChangeTitlePath schemaType?: SchemaType readOnly?: ConditionalProperty hidden?: ConditionalProperty fieldsetName?: string } export interface FieldChangeNode { type: 'field' diff: Diff itemDiff?: ItemDiff parentDiff?: ObjectDiff | ArrayDiff key: string path: Path error?: FieldValueError titlePath: ChangeTitlePath schemaType: ObjectFieldType showHeader: boolean showIndex: boolean diffComponent?: DiffComponent parentSchema?: ArraySchemaType | ObjectSchemaType readOnly?: ConditionalProperty hidden?: ConditionalProperty } export type ChangeNode = GroupChangeNode | FieldChangeNode export interface FromToIndex { hasMoved: boolean fromIndex?: number toIndex?: number annotation?: Annotation } export type ChangeTitlePath = (string | FromToIndex)[] /** * Document operations API + patches * @todo remove - should be imported from somewhere else */ export type InsertPatch = | {before: string; items: unknown[]} | {after: string; items: unknown[]} | {replace: string; items: unknown[]} export interface PatchOperations { set?: {[key: string]: unknown} setIfMissing?: {[key: string]: unknown} merge?: {[key: string]: unknown} diffMatchPatch?: {[key: string]: unknown} unset?: string[] inc?: {[key: string]: number} dec?: {[key: string]: number} insert?: InsertPatch ifRevisionID?: string } export interface OperationsAPI { patch: { execute: (patches: PatchOperations[]) => void } } /** * From sanity-diff-patch */ export interface SetDiffPatch { op: 'set' path: Path value: unknown } export interface UnsetDiffPatch { op: 'unset' path: Path } export interface InsertDiffPatch { op: 'insert' after: Path items: unknown[] } export type DiffPatch = SetDiffPatch | UnsetDiffPatch | InsertDiffPatch