import {KeyedSegment} from '@sanity/types'
import {MultipleMutationResult} from '@sanity/client'
import {Mutation as Mutation_2} from '@sanity/client'
import {Path} from '@sanity/types'
import {SanityClient} from '@sanity/client'
import {SanityDocument as SanityDocument_2} from '@sanity/types'

declare const ALLOWED_PROPERTIES: readonly [
  'fetch',
  'clone',
  'config',
  'withConfig',
  'getDocument',
  'getDocuments',
  'users',
  'projects',
]

declare type AllowedMethods = (typeof ALLOWED_PROPERTIES)[number]

declare type AnyArray<T = any> = T[] | readonly T[]

/**
 * @public
 *
 * Represents an operation that can be applied to values of all types
 */
export declare type AnyOp = SetOp<unknown> | SetIfMissingOp<unknown> | UnsetOp

/**
 * API configuration for the migration runner
 * @internal
 * @hidden
 */
export declare interface APIConfig {
  projectId: string
  apiVersion: `vX` | `v${number}-${number}-${number}`
  token: string
  dataset: string
  apiHost?: string
}

/**
 * Creates an `insert` operation that appends the provided items.
 * @param items - The items to append.
 * @returns An `insert` operation for adding a value to the end of an array.
 * {@link https://www.sanity.io/docs/http-patches#Cw4vhD88}
 *
 * @example
 * ```ts
 * const appendFoo = append('foo')
 * const appendObject = append({name: 'foo'})
 * const appendObjects = append([{name: 'foo'}, [{name: 'bar'}]])
 * ```
 */
export declare function append<const Items extends AnyArray<unknown>>(
  items: Items | ArrayElement<Items>,
): InsertOp<NormalizeReadOnlyArray<Items>, 'after', -1>

declare type ArrayElement<A> = A extends readonly (infer T)[] ? T : never

/**
 * @public
 *
 * Represents ann operation that can be applied to an array
 */
export declare type ArrayOp =
  | InsertOp<AnyArray, RelativePosition, IndexedSegment | KeyedSegment>
  | ReplaceOp<AnyArray, IndexedSegment | KeyedSegment>
  | TruncateOp

export declare type AsyncIterableMigration = (
  documents: () => AsyncIterableIterator<SanityDocument_2>,
  context: MigrationContext,
) => AsyncGenerator<Mutation | Transaction | (Mutation | Transaction)[]>

/**
 * Creates a {@link NodePatch} at a specific path.
 * @param path - The path where the operation should be applied.
 * @param operation - The operation to be applied.
 * @returns The node patch.
 */
export declare function at<O extends Operation>(
  path: Path | string,
  operation: O,
): NodePatch<Path, O>

export declare function collectMigrationMutations(
  migration: Migration,
  documents: () => AsyncIterableIterator<SanityDocument_2>,
  context: MigrationContext,
): AsyncGenerator<Transaction | Mutation | (Transaction | Mutation)[], any, any>

/**
 * Creates a new document.
 * @param document - The document to be created.
 * @returns The mutation to create the document.
 */
export declare function create<Doc extends Optional<SanityDocument, '_id'>>(
  document: Doc,
): CreateMutation<Doc>

/**
 * Creates a document if it does not exist.
 * @param document - The document to be created.
 * @returns The mutation operation to create the document if it does not exist.
 */
export declare function createIfNotExists<Doc extends SanityDocument>(
  document: Doc,
): CreateIfNotExistsMutation<Doc>

/**
 * @public
 *
 * Represents a mutation that can create a new document in the Sanity Content Lake if its ID does not exist.
 */
export declare type CreateIfNotExistsMutation<Doc extends SanityDocument> = {
  type: 'createIfNotExists'
  document: Doc
}

/**
 * @public
 *
 * Represents a mutation that creates a new document in the Sanity Content Lake. This mutation will fail if the ID already exist.
 */
export declare type CreateMutation<Doc extends Optional<SanityDocument, '_id'>> = {
  type: 'create'
  document: Doc
}

/**
 * Creates or replaces a document.
 * @param document - The document to be created or replaced.
 * @returns The mutation operation to create or replace the document.
 */
export declare function createOrReplace<Doc extends SanityDocument>(
  document: Doc,
): CreateOrReplaceMutation<Doc>

/**
 * @public
 *
 * Represents a mutation that can create or replace a document in the Sanity Content Lake given its ID.
 */
export declare type CreateOrReplaceMutation<Doc extends SanityDocument> = {
  type: 'createOrReplace'
  document: Doc
}

/**
 * Creates a `dec` (decrement) operation with the provided amount.
 * @param amount - The amount to decrement by.
 * @returns A `dec` operation.
 * {@link https://www.sanity.io/docs/http-patches#vIT8WWQo}
 *
 * @example
 * ```ts
 * const decBy1 = dec()
 * const decBy10 = dec(10)
 * ```
 */
export declare const dec: <const N extends number = 1>(amount?: N) => DecOp<N>

export declare function decodeText(
  it: AsyncIterableIterator<Uint8Array>,
): AsyncGenerator<string, void, unknown>

/**
 * @public
 *
 * Represents a decrement-operation that can be applied to a number
 */
export declare type DecOp<Amount extends number> = {
  type: 'dec'
  amount: Amount
}

export declare const DEFAULT_MUTATION_CONCURRENCY = 6

/**
 * @public
 *
 * Helper function for defining a Sanity content migration. This function does not do anything on its own;
 * it exists to check that your schema definition is correct, and help autocompletion in your IDE.
 *
 * {@link https://www.sanity.io/docs/schema-and-content-migrations#af2be129ccd6}

 * @example Basic usage
 *
 * ```ts
 * export default defineMigration({
 *  title: 'Make sure all strings with “acme” is uppercased to “ACME”',
 *  migrate: {
 *    string(node, path, context) {
 *      if (node === "acme") {
 *        return set(node.toUpperCase())
 *      }
 *    },
 *  },
 * })
 * ```
 * @param migration - The migration definition
 *
 * See {@link Migration}
 */
export declare function defineMigration<T extends Migration>(migration: T): T

/**
 * Alias for delete
 */
export declare const del: typeof delete_

export declare function delay<T>(
  it: AsyncIterableIterator<T>,
  ms: number,
): AsyncGenerator<Awaited<T>, void, unknown>

/**
 * Deletes a document.
 * @param id - The id of the document to be deleted.
 * @returns The mutation operation to delete the document.
 */
export declare function delete_(id: string): DeleteMutation

/**
 * @public
 *
 * Represents a mutation that can delete a document in the Sanity Content Lake.
 */
export declare type DeleteMutation = {
  type: 'delete'
  id: string
}

/**
 * Creates a `diffMatchPatch` operation with the provided value.
 * @param value - The value for the diff match patch operation.
 * @returns A `diffMatchPatch` operation.
 * {@link https://www.sanity.io/docs/http-patches#aTbJhlAJ}
 * @public
 */
export declare const diffMatchPatch: (value: string) => DiffMatchPatchOp

/**
 * @public
 *
 * Represents a diff-match-patch operation that can be applied to a string
 * {@link https://www.npmjs.com/package/@sanity/diff-match-patch}
 */
export declare type DiffMatchPatchOp = {
  type: 'diffMatchPatch'
  value: string
}

/**
 * @public
 *
 * Possible return values from a migration helper that runs on a document as a whole
 * Currently, this is only applies to {@link NodeMigration.document}
 */
export declare type DocumentMigrationReturnValue =
  | Mutation
  | Mutation[]
  | NodePatch
  | NodePatch[]
  | Mutation_2
  | Mutation_2[]

export declare function dryRun(
  config: MigrationRunnerOptions,
  migration: Migration,
): AsyncGenerator<Transaction | Mutation | (Transaction | Mutation)[], void, any>

/**
 * API configuration for exports
 * @internal
 * @hidden
 */
export declare interface ExportAPIConfig extends APIConfig {
  documentTypes?: string[]
}

declare interface FetchOptions {
  url: string | URL
  init: RequestInit
}

export declare function filter<T>(
  it: AsyncIterableIterator<T>,
  predicate: (value: T) => boolean | Promise<boolean>,
): AsyncGenerator<Awaited<T>, void, unknown>

export declare function fromDocuments(
  documents: SanityDocument_2[],
): Generator<SanityDocument_2, void, unknown>

export declare function fromExportArchive(
  path: string,
): AsyncGenerator<Uint8Array<ArrayBufferLike>, void, unknown>

export declare function fromExportEndpoint(
  options: ExportAPIConfig,
): Promise<ReadableStream<Uint8Array<ArrayBufferLike>>>

/**
 * Creates an `inc` (increment) operation with the provided amount.
 * @param amount - The amount to increment by.
 * @returns An incrementation operation for numeric values
 * {@link https://www.sanity.io/docs/http-patches#vIT8WWQo}
 *
 * @example
 * ```ts
 * const incBy1 = inc()
 * const incBy5 = inc(5)
 * ```
 */
export declare const inc: <const N extends number = 1>(amount?: N) => IncOp<N>

/**
 * @public
 *
 * Represents an increment-operation that can be applied to a number
 */
export declare type IncOp<Amount extends number> = {
  type: 'inc'
  amount: Amount
}

/**
 * @public
 *
 * Represents an indexed segment in a document.
 */
export declare type IndexedSegment = number

/**
 * Creates an `insert` operation with the provided items, position, and reference item.
 * @param items - The items to insert.
 * @param position - The position to insert at.
 * @param indexOrReferenceItem - The index or reference item to insert before or after.
 * @returns An `insert` operation for adding values to arrays
 * {@link https://www.sanity.io/docs/http-patches#febxf6Fk}
 *
 * @example
 * ```ts
 * const prependFoo = insert(['foo'], 'before', 0)
 * const appendFooAndBar = insert(['foo', 'bar'], 'after', someArray.length -1)
 * const insertObjAfterXYZ = insert({name: 'foo'}, 'after', {_key: 'xyz'}])
 * ```
 */
export declare function insert<
  const Items extends AnyArray<unknown>,
  const Pos extends RelativePosition,
  const ReferenceItem extends IndexedSegment | KeyedSegment,
>(
  items: Items | ArrayElement<Items>,
  position: Pos,
  indexOrReferenceItem: ReferenceItem,
): InsertOp<NormalizeReadOnlyArray<Items>, Pos, ReferenceItem>

/**
 * Creates an `insert` operation that inserts the provided items after the provided index or reference item.
 * @param items - The items to insert.
 * @param indexOrReferenceItem - The index or reference item to insert after.
 * @returns An `insert` operation after the provided index or reference item.
 * {@link https://www.sanity.io/docs/http-patches#0SQmPlb6}
 *
 * @example
 * ```ts
 * const insertFooAfterIndex3 = insertAfter('foo', 3)
 * const insertObjectAfterKey = insertAfter({name: 'foo'}, {_key: 'xyz'}]
 * ```
 */
export declare const insertAfter: <
  const Items extends AnyArray<unknown>,
  const ReferenceItem extends IndexedSegment | KeyedSegment,
>(
  items: Items | ArrayElement<Items>,
  indexOrReferenceItem: ReferenceItem,
) => InsertOp<NormalizeReadOnlyArray<Items>, 'after', ReferenceItem>

/**
 * Creates an `insert` operation that inserts the provided items before the provided index or reference item.
 * @param items - The items to insert.
 * @param indexOrReferenceItem - The index or reference item to insert before.
 * @returns An `insert` operation before the provided index or reference item.
 * {@link https://www.sanity.io/docs/http-patches#0SQmPlb6}
 * @public
 *
 * @example
 * ```ts
 * const insertFooBeforeIndex3 = insertBefore('foo', 3)
 * const insertObjectBeforeKey = insertBefore({name: 'foo'}, {_key: 'xyz'}]
 * ```
 */
export declare function insertBefore<
  const Items extends AnyArray<unknown>,
  const ReferenceItem extends IndexedSegment | KeyedSegment,
>(
  items: Items | ArrayElement<Items>,
  indexOrReferenceItem: ReferenceItem,
): InsertOp<NormalizeReadOnlyArray<Items>, 'before', ReferenceItem>

/**
 * @public
 *
 * Represents an insert-operation that can be applied to an array
 */
export declare type InsertOp<
  Items extends AnyArray,
  Pos extends RelativePosition,
  ReferenceItem extends IndexedSegment | KeyedSegment,
> = {
  type: 'insert'
  referenceItem: ReferenceItem
  position: Pos
  items: Items
}

export declare type JsonArray = JsonValue[] | readonly JsonValue[]

export declare type JsonObject = {
  [Key in string]: JsonValue
} & {
  [Key in string]?: JsonValue | undefined
}

export declare interface JSONOptions<Type> {
  parse?: JSONParser<Type>
}

export declare type JSONParser<Type> = (line: string) => Type

export declare type JsonPrimitive = string | number | boolean | null

export declare type JsonValue = JsonPrimitive | JsonObject | JsonArray

export {KeyedSegment}

export declare function map<T, U>(
  it: AsyncIterableIterator<T>,
  project: (value: T) => U,
): AsyncIterableIterator<U>

export declare const MAX_MUTATION_CONCURRENCY = 10

/**
 * @public
 *
 * Interface for `Migration['migrate']`. Either a NodeMigration or an AsyncIterableMigration
 * {@link NodeMigration}
 * {@link AsyncIterableMigration}
 */
export declare type MigrateDefinition = NodeMigration | AsyncIterableMigration

/**
 * @public
 *
 * Main interface for a content migration definition
 * {@link https://www.sanity.io/docs/schema-and-content-migrations#af2be129ccd6}
 */
export declare interface Migration<Def extends MigrateDefinition = MigrateDefinition> {
  /**
   * A reader-friendly description of what the content migration does
   */
  title: string
  /**
   * An array of document types to run the content migration on. If you don’t define this, the migration type will target all document types.
   * Note: This reflects the document types your migration will be based on, not necessarily the documents you will modify.
   */
  documentTypes?: string[]
  /**
   * A simple GROQ-filter (doesn’t support joins) for documents you want to run the content migration on.
   * Note: instead of adding `_type == 'yourType'` to the filter, it's better to add its `_type` to `documentTypes`.
   * Note: `documentTypes` and `filter` are combined with AND. This means a document will only be included in the
   * migration if its `_type` matches any of the provided `documentTypes` AND it also matches the `filter` (if provided).
   */
  filter?: string
  /**
   * An object of named helper functions corresponding to the primary schema type of the content you want to migrate.
   * You can also run these functions as async and return the migration instructions as promises if you need to fetch data from elsewhere.
   * If you want more control, `migrate` can also be an async iterable function that yields mutations or transactions.
   * {@link NodeMigration}
   * {@link AsyncIterableMigration}
   *
   */
  migrate: Def
}

/**
 * @public
 *
 * Migration context. This will be passed to both async iterable migrations and node migration helper functions
 */
export declare interface MigrationContext {
  client: RestrictedClient
  filtered: {
    getDocument<T extends SanityDocument_2>(id: string): Promise<T | undefined>
    getDocuments<T extends SanityDocument_2>(ids: string[]): Promise<T[]>
  }
  dryRun: boolean
}

/**
 * Migration progress, only used internally (for now)
 * @internal
 * @hidden
 */
export declare type MigrationProgress = {
  documents: number
  mutations: number
  pending: number
  queuedBatches: number
  currentTransactions: (Transaction | Mutation)[]
  completedTransactions: MultipleMutationResult[]
  done?: boolean
}

export declare interface MigrationRunnerConfig {
  api: APIConfig
  concurrency?: number
  onProgress?: (event: MigrationProgress) => void
}

declare interface MigrationRunnerOptions {
  api: APIConfig
  exportPath?: string
}

/**
 * @public
 *
 * Represents a mutation that can be applied to a document in the Sanity Content Lake.
 */
export declare type Mutation<Doc extends SanityDocument = any> =
  | CreateMutation<Doc>
  | CreateIfNotExistsMutation<Doc>
  | CreateOrReplaceMutation<Doc>
  | DeleteMutation
  | PatchMutation

/**
 * @public
 *
 * Node migration helper functions. As the migration is processing a document, it will visit each node in the document, depth-first, call the appropriate helper function for the node type and collect any mutations returned from it.
 */
export declare interface NodeMigration {
  /**
   * Helper function for migrating a document as a whole
   * @param doc - The document currently being processed
   * @param context - The {@link MigrationContext} instance
   */
  document?: <Doc extends SanityDocument_2>(
    doc: Doc,
    context: MigrationContext,
  ) =>
    | void
    | DocumentMigrationReturnValue
    | Transaction
    | Promise<DocumentMigrationReturnValue | Transaction>
  /**
   * Helper function that will be called for each node in each document included in the migration
   * @param node - The node currently being visited
   * @param path - The path to the node within the document. See {@link Path}
   * @param context - The {@link MigrationContext} instance
   */
  node?: <Node extends JsonValue>(
    node: Node,
    path: Path,
    context: MigrationContext,
  ) => void | NodeMigrationReturnValue | Promise<void | NodeMigrationReturnValue>
  /**
   * Helper function that will be called for each object in each document included in the migration
   * @param object - The object value currently being visited
   * @param path - The path to the node within the document. See {@link Path}
   * @param context - The {@link MigrationContext} instance
   */
  object?: <Node extends JsonObject>(
    node: Node,
    path: Path,
    context: MigrationContext,
  ) => void | NodeMigrationReturnValue | Promise<void | NodeMigrationReturnValue>
  /**
   * Helper function that will be called for each array in each document included in the migration
   * @param object - The object value currently being visited
   * @param path - The path to the node within the document. See {@link Path}
   * @param context - The {@link MigrationContext} instance
   */
  array?: <Node extends JsonArray>(
    node: Node,
    path: Path,
    context: MigrationContext,
  ) => void | NodeMigrationReturnValue | Promise<void | NodeMigrationReturnValue>
  /**
   * Helper function that will be called for each string in each document included in the migration
   * @param string - The string value currently being visited
   * @param path - The path to the node within the document. See {@link Path}
   * @param context - The {@link MigrationContext} instance
   */
  string?: <Node extends string>(
    node: Node,
    path: Path,
    context: MigrationContext,
  ) => void | NodeMigrationReturnValue | Promise<void | NodeMigrationReturnValue>
  /**
   * Helper function that will be called for each number in each document included in the migration
   * @param string - The string value currently being visited
   * @param path - The path to the node within the document. See {@link Path}
   * @param context - The {@link MigrationContext} instance
   */
  number?: <Node extends number>(
    node: Node,
    path: Path,
    context: MigrationContext,
  ) => void | NodeMigrationReturnValue | Promise<void | NodeMigrationReturnValue>
  /**
   * Helper function that will be called for each boolean value in each document included in the migration
   * @param string - The string value currently being visited
   * @param path - The path to the node within the document. See {@link Path}
   * @param context - The {@link MigrationContext} instance
   */
  boolean?: <Node extends boolean>(
    node: Node,
    path: Path,
    context: MigrationContext,
  ) => void | NodeMigrationReturnValue | Promise<void | NodeMigrationReturnValue>
  /**
   * Helper function that will be called for each `null` value in each document included in the migration
   * @param string - The string value currently being visited
   * @param path - The path to the node within the document. See {@link Path}
   * @param context - The {@link MigrationContext} instance
   */
  null?: <Node extends null>(
    node: Node,
    path: Path,
    context: MigrationContext,
  ) => void | NodeMigrationReturnValue | Promise<void | NodeMigrationReturnValue>
}

/**
 * @public
 *
 * Possible return values from a migration helper that runs on nodes within a document
 */
export declare type NodeMigrationReturnValue =
  | DocumentMigrationReturnValue
  | Operation
  | Operation[]

/**
 * @public
 *
 * A NodePatch represents a single operation that can be applied at a node at a specific path in a Sanity document.
 */
export declare type NodePatch<P extends Path = Path, O extends Operation = Operation> = {
  path: P
  op: O
}

/**
 * @public
 *
 * A list of {@link NodePatch} objects.
 */
export declare type NodePatchList =
  | [NodePatch, ...NodePatch[]]
  | NodePatch[]
  | readonly NodePatch[]
  | readonly [NodePatch, ...NodePatch[]]

declare type NormalizeReadOnlyArray<T> = T extends readonly [infer NP, ...infer Rest]
  ? [NP, ...Rest]
  : T extends readonly (infer NP)[]
    ? NP[]
    : T

/**
 * @public
 *
 * Represents an operation that can be applied to a number
 */
export declare type NumberOp = IncOp<number> | DecOp<number>

/**
 * @public
 *
 * Represents an operation that can be applied to values of all types
 */
export declare type Operation = PrimitiveOp | ArrayOp

declare type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>

export declare function parse<Type>(
  it: AsyncIterableIterator<string>,
  options?: JSONOptions<Type>,
): AsyncIterableIterator<Type>

export declare function parseJSON<Type>(
  it: AsyncIterableIterator<string>,
  {parse}?: JSONOptions<Type>,
): AsyncIterableIterator<Type>

/**
 * Applies a patch to a document.
 * @param id - The ID of the document to be patched.
 * @param patches - The patches to be applied.
 * @param options - Optional patch options.
 * @returns The mutation to patch the document.
 */
export declare function patch<P extends NodePatchList | NodePatch>(
  id: string,
  patches: P,
  options?: PatchOptions,
): PatchMutation<NormalizeReadOnlyArray<Tuplify<P>>>

/**
 * @public
 *
 * Represents a patch mutation that can change a value for a document in the Sanity Content Lake.
 */
export declare type PatchMutation<Patches extends NodePatchList = NodePatchList> = {
  type: 'patch'
  id: string
  patches: Patches
  options?: PatchOptions
}

/**
 * @public
 *
 * Options for a patch operation.
 */
export declare type PatchOptions = {
  /**
   * {@link https://www.sanity.io/docs/http-mutations#26600a871378}
   */
  ifRevision?: string
}

export {Path}

/**
 * Creates an `insert` operation that prepends the provided items.
 * @param items - The items to prepend.
 * @returns An `insert` operation for adding a value to the start of an array.
 * {@link https://www.sanity.io/docs/http-patches#refAUsf0}
 *
 * @example
 * ```ts
 * const prependFoo = prepend('foo')
 * const prependObject = prepend({name: 'foo'})
 * const prependObjects = prepend([{name: 'foo'}, [{name: 'bar'}]])
 * ```
 */
export declare function prepend<const Items extends AnyArray<unknown>>(
  items: Items | ArrayElement<Items>,
): InsertOp<NormalizeReadOnlyArray<Items>, 'before', 0>

/**
 * @public
 *
 * Represents an operation that can be applied to any primitive value
 */
export declare type PrimitiveOp = AnyOp | StringOp | NumberOp

/**
 * @public
 *
 * Represents a relative position in a document.
 */
export declare type RelativePosition = 'before' | 'after'

/**
 * Creates a `replace` operation with the provided items and reference item.
 * @param items - The items to replace.
 * @param referenceItem - The reference item to replace.
 * @returns A ReplaceOp operation.
 * @remarks This will be converted to an `insert`/`replace` patch when submitted to the API
 * {@link https://www.sanity.io/docs/http-patches#GnVSwcPa}
 *
 * @example
 * ```ts
 * const replaceItem3WithFoo = replace('foo', 3)
 * const replaceItem3WithFooAndBar = replace(['foo', 'bar'], 3)
 * const replaceObject = replace({name: 'bar'}, {_key: 'xyz'})
 * ```
 */
export declare function replace<
  Items extends any[],
  ReferenceItem extends IndexedSegment | KeyedSegment,
>(items: Items | ArrayElement<Items>, referenceItem: ReferenceItem): ReplaceOp<Items, ReferenceItem>

/**
 * @public
 *
 * Represents a replace-operation that can be applied to an array
 */
export declare type ReplaceOp<
  Items extends AnyArray,
  ReferenceItem extends IndexedSegment | KeyedSegment,
> = {
  type: 'replace'
  referenceItem: ReferenceItem
  items: Items
}

declare type RestrictedClient = Pick<SanityClient, AllowedMethods>

export declare function run(config: MigrationRunnerConfig, migration: Migration): Promise<void>

/**
 * Safe JSON parser that is able to handle lines interrupted by an error object.
 *
 * This may occur when streaming NDJSON from the Export HTTP API.
 *
 * @internal
 * @see {@link https://github.com/sanity-io/sanity/pull/1787 | Initial pull request}
 */
export declare const safeJsonParser: (line: string) => SanityDocument_2

/**
 * @public
 *
 * A Sanity Content Lake document
 */
export declare type SanityDocument = {
  _id?: string
  _type: string
  _createdAt?: string
  _updatedAt?: string
  _rev?: string
}

/**
 * Creates a `set` operation with the provided value.
 * @param value - The value to set.
 * @returns A `set` operation.
 * {@link https://www.sanity.io/docs/http-patches#6TPENSW3}
 *
 * @example
 * ```ts
 * const setFoo = set('foo')
 * const setEmptyArray = set([])
 * ```
 */
export declare const set: <const T>(value: T) => SetOp<T>

/**
 * Creates a `setIfMissing` operation with the provided value.
 * @param value - The value to set if missing.
 * @returns A `setIfMissing` operation.
 * {@link https://www.sanity.io/docs/http-patches#A80781bT}
 * @example
 * ```ts
 * const setFooIfMissing = setIfMissing('foo')
 * const setEmptyArrayIfMissing = setIfMissing([])
 * ```
 */
export declare const setIfMissing: <const T>(value: T) => SetIfMissingOp<T>

/**
 * @public
 *
 * Represents a setIfMissing operation that can be applied to any value
 */
export declare type SetIfMissingOp<T> = {
  type: 'setIfMissing'
  value: T
}

/**
 * @public
 *
 * Represents a set-operation that can be applied to any value
 */
export declare type SetOp<T> = {
  type: 'set'
  value: T
}

export declare function split(
  it: AsyncIterableIterator<string>,
  delimiter: string,
): AsyncIterableIterator<string>

export declare function stringify(
  iterable: AsyncIterableIterator<unknown>,
): AsyncGenerator<string, void, unknown>

export declare function stringifyJSON(
  it: AsyncIterableIterator<unknown>,
): AsyncGenerator<string, void, unknown>

/**
 * @public
 *
 * Represents an operation that can be applied to a string
 */
export declare type StringOp = DiffMatchPatchOp

export declare function take<T>(
  it: AsyncIterableIterator<T>,
  count: number,
): AsyncGenerator<Awaited<T>, void, unknown>

export declare function toArray<T>(it: AsyncIterableIterator<T>): Promise<T[]>

export declare function toFetchOptionsIterable(
  apiConfig: APIConfig,
  mutations: AsyncIterableIterator<TransactionPayload>,
): AsyncGenerator<FetchOptions, void, unknown>

export declare interface Transaction {
  type: 'transaction'
  id?: string
  mutations: Mutation[]
}

/**
 * @public
 *
 * Wraps a set of mutations in a transaction.
 * Note: use with caution. Transactions cannot be optimized and will be submitted one-by-one, which means they will make
 * your migration run slower and produce more API requests.
 * @param transactionId - The transaction ID. This is optional and should usually be omitted, as it will be auto-generated by the server if not provided.
 * @param mutations - The mutations to include in the transaction.
 *
 * {@link https://www.sanity.io/docs/http-mutations#afccc1b9ef78}
 */
export declare function transaction(transactionId: string, mutations: Mutation[]): Transaction

export declare function transaction(mutations: Mutation[]): Transaction

declare interface TransactionPayload {
  transactionId?: string
  mutations: Mutation_2[]
}

/**
 * Creates a `truncate` operation that will remove all items after `startIndex` until the end of the array or the provided `endIndex`.
 * @param startIndex - The start index for the truncate operation.
 * @param endIndex - The end index for the truncate operation.
 * @returns A `truncate` operation.
 * @remarks - This will be converted to an `unset` patch when submitted to the API
 * {@link https://www.sanity.io/docs/http-patches#xRtBjp8o}
 *
 * @example
 * ```ts
 * const clearArray = truncate(0)
 * const removeItems = truncate(3, 5) // Removes items at index 3, 4, and 5
 * const truncate200 = truncate(200) // Removes all items after index 200
 * ```
 */
export declare function truncate(startIndex: number, endIndex?: number): TruncateOp

/**
 * @public
 *
 * Represents a truncate-operation that can be applied to an array
 */
export declare type TruncateOp = {
  type: 'truncate'
  startIndex: number
  endIndex?: number
}

declare type Tuplify<T> = T extends readonly [infer NP, ...infer Rest]
  ? [NP, ...Rest]
  : T extends readonly (infer NP)[]
    ? NP[]
    : [T]

/**
 * Creates an `unset` operation.
 * @returns An `unset` operation.
 * {@link https://www.sanity.io/docs/http-patches#xRtBjp8o}
 *
 * @example
 * ```ts
 * const unsetAnyValue = unset()
 * ```
 */
export declare const unset: () => UnsetOp

/**
 * @public
 *
 * Represents an unset operation that can be applied to any value
 */
export declare type UnsetOp = {
  type: 'unset'
}

export {}
