{"version":3,"file":"index.cjs","sources":["../src/paths.ts","../src/diffError.ts","../src/validate.ts","../src/diffPatch.ts"],"sourcesContent":["import type {KeyedSanityObject} from './diffPatch.js'\n\nconst IS_DOTTABLE_RE = /^[A-Za-z_][A-Za-z0-9_]*$/\n\n/**\n * A segment of a path\n *\n * @public\n */\nexport type PathSegment =\n  | string // Property\n  | number // Array index\n  | {_key: string} // Array `_key` lookup\n  | [number | '', number | ''] // From/to array index\n\n/**\n * An array of path segments representing a path in a document\n *\n * @public\n */\nexport type Path = PathSegment[]\n\n/**\n * Converts an array path to a string path\n *\n * @param path - The array path to convert\n * @returns A stringified path\n * @internal\n */\nexport function pathToString(path: Path): string {\n  return path.reduce((target: string, segment: PathSegment, i: number) => {\n    if (Array.isArray(segment)) {\n      return `${target}[${segment.join(':')}]`\n    }\n\n    if (isKeyedObject(segment)) {\n      return `${target}[_key==\"${segment._key}\"]`\n    }\n\n    if (typeof segment === 'number') {\n      return `${target}[${segment}]`\n    }\n\n    if (typeof segment === 'string' && !IS_DOTTABLE_RE.test(segment)) {\n      return `${target}['${segment}']`\n    }\n\n    if (typeof segment === 'string') {\n      const separator = i === 0 ? '' : '.'\n      return `${target}${separator}${segment}`\n    }\n\n    throw new Error(`Unsupported path segment \"${segment}\"`)\n  }, '')\n}\n\nfunction isKeyedObject(obj: any): obj is KeyedSanityObject {\n  return typeof obj === 'object' && typeof obj._key === 'string'\n}\n","import {type Path, pathToString} from './paths.js'\n\n/**\n * Represents an error that occurred during a diff process.\n * Contains `path`, `value` and `serializedPath` properties,\n * which is helpful for debugging and showing friendly messages.\n *\n * @public\n */\nexport class DiffError extends Error {\n  public path: Path\n  public value: unknown\n  public serializedPath: string\n\n  constructor(message: string, path: Path, value?: unknown) {\n    const serializedPath = pathToString(path)\n    super(`${message} (at '${serializedPath}')`)\n\n    this.path = path\n    this.serializedPath = serializedPath\n    this.value = value\n  }\n}\n","import {DiffError} from './diffError.js'\nimport type {Path} from './paths.js'\n\nconst idPattern = /^[a-z0-9][a-z0-9_.-]+$/i\nconst propPattern = /^[a-zA-Z_][a-zA-Z0-9_-]*$/\nconst propStartPattern = /^[a-z_]/i\n\n/**\n * Validate the given document/subtree for Sanity compatibility\n *\n * @param item - The document or subtree to validate\n * @param path - The path to the current item, for error reporting\n * @returns True if valid, throws otherwise\n * @internal\n */\nexport function validateDocument(item: unknown, path: Path = []): boolean {\n  if (Array.isArray(item)) {\n    return item.every((child, i) => {\n      if (Array.isArray(child)) {\n        throw new DiffError('Multi-dimensional arrays not supported', path.concat(i))\n      }\n\n      return validateDocument(child, path.concat(i))\n    })\n  }\n\n  if (typeof item === 'object' && item !== null) {\n    const obj = item as {[key: string]: any}\n    return Object.keys(obj).every(\n      (key) =>\n        validateProperty(key, obj[key], path) && validateDocument(obj[key], path.concat(key)),\n    )\n  }\n\n  return true\n}\n\n/**\n * Validate a property for Sanity compatibility\n *\n * @param property - The property to valide\n * @param value - The value of the property\n * @param path - The path of the property, for error reporting\n * @returns The property name, if valid\n * @internal\n */\nexport function validateProperty(property: string, value: unknown, path: Path): string {\n  if (!propStartPattern.test(property)) {\n    throw new DiffError('Keys must start with a letter (a-z)', path.concat(property), value)\n  }\n\n  if (!propPattern.test(property)) {\n    throw new DiffError(\n      'Keys can only contain letters, numbers and underscores',\n      path.concat(property),\n      value,\n    )\n  }\n\n  if (property === '_key' || property === '_ref' || property === '_type') {\n    if (typeof value !== 'string') {\n      throw new DiffError('Keys must be strings', path.concat(property), value)\n    }\n\n    if (!idPattern.test(value)) {\n      throw new DiffError('Invalid key - use less exotic characters', path.concat(property), value)\n    }\n  }\n\n  return property\n}\n","import {cleanupEfficiency, makeDiff, makePatches, stringifyPatches} from '@sanity/diff-match-patch'\nimport {DiffError} from './diffError.js'\nimport {type Path, pathToString} from './paths.js'\nimport {validateProperty} from './validate.js'\nimport {\n  type Patch,\n  type SetPatch,\n  type UnsetPatch,\n  type InsertAfterPatch,\n  type DiffMatchPatch,\n  type SanityInsertPatch,\n  type SanityPatch,\n  type SanitySetPatch,\n  type SanityUnsetPatch,\n  type SanityDiffMatchPatch,\n  type SanityPatchMutation,\n} from './patches.js'\n\nconst ignoredKeys = ['_id', '_type', '_createdAt', '_updatedAt', '_rev']\n\ntype PrimitiveValue = string | number | boolean | null | undefined\n\n/**\n * An object (record) that has a `_key` property\n *\n * @internal\n */\nexport interface KeyedSanityObject {\n  [key: string]: unknown\n  _key: string\n}\n\n/**\n * An object (record) that _may_ have a `_key` property\n *\n * @internal\n */\nexport type SanityObject = KeyedSanityObject | Partial<KeyedSanityObject>\n\n/**\n * Represents a partial Sanity document (eg a \"stub\").\n *\n * @public\n */\nexport interface DocumentStub {\n  _id?: string\n  _type?: string\n  _rev?: string\n  _createdAt?: string\n  _updatedAt?: string\n  [key: string]: unknown\n}\n\n/**\n * Options for the diff-match-patch algorithm.\n *\n * @public\n */\nexport interface DiffMatchPatchOptions {\n  /**\n   * Whether or not to use diff-match-patch at all\n   *\n   * @defaultValue `true`\n   */\n  enabled: boolean\n\n  /**\n   * Threshold at which to start using diff-match-patch instead of a regular `set` patch.\n   *\n   * @defaultValue `30`\n   */\n  lengthThresholdAbsolute: number\n\n  /**\n   * Only use generated diff-match-patch if the patch length is less than or equal to\n   * (targetString * relative). Example: A 100 character target with a relative factor\n   * of 1.2 will allow a 120 character diff-match-patch. If larger than this number,\n   * it will fall back to a regular `set` patch.\n   *\n   * @defaultValue `1.2`\n   */\n  lengthThresholdRelative: number\n}\n\n/**\n * Options for the patch generator\n *\n * @public\n */\nexport interface PatchOptions {\n  /**\n   * Document ID to apply the patch to.\n   *\n   * @defaultValue `undefined` - tries to extract `_id` from passed document\n   */\n  id?: string\n\n  /**\n   * Base path to apply the patch to - useful if diffing sub-branches of a document.\n   *\n   * @defaultValue `[]` - eg root of the document\n   */\n  basePath?: Path\n\n  /**\n   * Only apply the patch if the document revision matches this value.\n   * If the property is the boolean value `true`, it will attempt to extract\n   * the revision from the document `_rev` property.\n   *\n   * @defaultValue `undefined` (do not apply revision check)\n   */\n  ifRevisionID?: string | true\n\n  /**\n   * Whether or not to hide warnings during the diff process.\n   *\n   * @defaultValue `false`\n   */\n  hideWarnings?: boolean\n\n  /**\n   * Options for the diff-match-patch algorithm.\n   */\n  diffMatchPatch?: Partial<DiffMatchPatchOptions>\n}\n\n/**\n * Options for diff generation, where all DMP properties are required\n *\n * @public\n */\nexport type DiffOptions = PatchOptions & {diffMatchPatch: Required<DiffMatchPatchOptions>}\n\nconst defaultOptions = {\n  hideWarnings: false,\n  diffMatchPatch: {\n    enabled: true,\n\n    // Only use diff-match-patch if target string is longer than this threshold\n    lengthThresholdAbsolute: 30,\n\n    // Only use generated diff-match-patch if the patch length is less than or equal to\n    // (targetString * relative). Example: A 100 character target with a relative factor\n    // of 1.2 will allow a 120 character diff-match-patch. If larger than this number,\n    // it will fall back to a regular `set` patch.\n    lengthThresholdRelative: 1.2,\n  },\n} satisfies DiffOptions\n\n/**\n * Merges the default options with the passed in options.\n *\n * @param options - Options to merge with the defaults\n * @returns Merged options\n */\nfunction mergeOptions(options: PatchOptions): DiffOptions {\n  return {\n    ...defaultOptions,\n    ...options,\n    diffMatchPatch: {...defaultOptions.diffMatchPatch, ...(options.diffMatchPatch || {})},\n  }\n}\n\n/**\n * Generates an array of mutations for Sanity, based on the differences between\n * the two passed documents/trees.\n *\n * @param itemA - The first document/tree to compare\n * @param itemB - The second document/tree to compare\n * @param opts - Options for the diff generation\n * @returns Array of mutations\n * @public\n */\nexport function diffPatch(\n  itemA: DocumentStub,\n  itemB: DocumentStub,\n  opts?: PatchOptions,\n): SanityPatchMutation[] {\n  const options = mergeOptions(opts || {})\n  const id = options.id || (itemA._id === itemB._id && itemA._id)\n  const revisionLocked = options.ifRevisionID\n  const ifRevisionID = typeof revisionLocked === 'boolean' ? itemA._rev : revisionLocked\n  const basePath = options.basePath || []\n  if (!id) {\n    throw new Error(\n      '_id on itemA and itemB not present or differs, specify document id the mutations should be applied to',\n    )\n  }\n\n  if (revisionLocked === true && !ifRevisionID) {\n    throw new Error(\n      '`ifRevisionID` is set to `true`, but no `_rev` was passed in item A. Either explicitly set `ifRevisionID` to a revision, or pass `_rev` as part of item A.',\n    )\n  }\n\n  if (basePath.length === 0 && itemA._type !== itemB._type) {\n    throw new Error(`_type is immutable and cannot be changed (${itemA._type} => ${itemB._type})`)\n  }\n\n  const operations = diffItem(itemA, itemB, options, basePath, [])\n  return serializePatches(operations, {id, ifRevisionID: revisionLocked ? ifRevisionID : undefined})\n}\n\n/**\n * Diffs two items and returns an array of patches.\n * Note that this is different from `diffPatch`, which generates _mutations_.\n *\n * @param itemA - The first item to compare\n * @param itemB - The second item to compare\n * @param opts - Options for the diff generation\n * @param path - Path to the current item\n * @param patches - Array of patches to append the results to. Note that this is MUTATED.\n * @returns Array of patches\n * @public\n */\nexport function diffItem(\n  itemA: unknown,\n  itemB: unknown,\n  opts: DiffOptions = defaultOptions,\n  path: Path = [],\n  patches: Patch[] = [],\n): Patch[] {\n  if (itemA === itemB) {\n    return patches\n  }\n\n  const aType = Array.isArray(itemA) ? 'array' : typeof itemA\n  const bType = Array.isArray(itemB) ? 'array' : typeof itemB\n\n  const aIsUndefined = aType === 'undefined'\n  const bIsUndefined = bType === 'undefined'\n\n  if (aIsUndefined && !bIsUndefined) {\n    patches.push({op: 'set', path, value: itemB})\n    return patches\n  }\n\n  if (!aIsUndefined && bIsUndefined) {\n    patches.push({op: 'unset', path})\n    return patches\n  }\n\n  const options = mergeOptions(opts)\n  const dataType = aIsUndefined ? bType : aType\n  const isContainer = dataType === 'object' || dataType === 'array'\n  if (!isContainer) {\n    return diffPrimitive(itemA as PrimitiveValue, itemB as PrimitiveValue, options, path, patches)\n  }\n\n  if (aType !== bType) {\n    // Array => Object / Object => Array\n    patches.push({op: 'set', path, value: itemB})\n    return patches\n  }\n\n  return dataType === 'array'\n    ? diffArray(itemA as unknown[], itemB as unknown[], options, path, patches)\n    : diffObject(itemA as object, itemB as object, options, path, patches)\n}\n\nfunction diffObject(\n  itemA: SanityObject,\n  itemB: SanityObject,\n  options: DiffOptions,\n  path: Path,\n  patches: Patch[],\n) {\n  const atRoot = path.length === 0\n  const aKeys = Object.keys(itemA)\n    .filter(atRoot ? isNotIgnoredKey : yes)\n    .map((key) => validateProperty(key, itemA[key], path))\n\n  const aKeysLength = aKeys.length\n  const bKeys = Object.keys(itemB)\n    .filter(atRoot ? isNotIgnoredKey : yes)\n    .map((key) => validateProperty(key, itemB[key], path))\n\n  const bKeysLength = bKeys.length\n\n  // Check for deleted items\n  for (let i = 0; i < aKeysLength; i++) {\n    const key = aKeys[i]\n    if (!(key in itemB)) {\n      patches.push({op: 'unset', path: path.concat(key)})\n    }\n  }\n\n  // Check for changed items\n  for (let i = 0; i < bKeysLength; i++) {\n    const key = bKeys[i]\n    diffItem(itemA[key], itemB[key], options, path.concat([key]), patches)\n  }\n\n  return patches\n}\n\nfunction diffArray(\n  itemA: unknown[],\n  itemB: unknown[],\n  options: DiffOptions,\n  path: Path,\n  patches: Patch[],\n) {\n  // Check for new items\n  if (itemB.length > itemA.length) {\n    patches.push({\n      op: 'insert',\n      after: path.concat([-1]),\n      items: itemB.slice(itemA.length).map((item, i) => nullifyUndefined(item, path, i, options)),\n    })\n  }\n\n  // Check for deleted items\n  if (itemB.length < itemA.length) {\n    const isSingle = itemA.length - itemB.length === 1\n    const unsetItems = itemA.slice(itemB.length)\n\n    // If we're revision locked, we can safely unset ranges (eg 5:<end-of-array>).\n    // Also, if we don't have unique array keys, we can't use any better approach\n    // than array indexes. If we _do_ have unique array keys, we'll want to unset\n    // by key, as this is safer in a realtime, collaborative setting\n    if (isRevisionLocked(options) || !isUniquelyKeyed(unsetItems)) {\n      patches.push({\n        op: 'unset',\n        path: path.concat([isSingle ? itemB.length : [itemB.length, '']]),\n      })\n    } else {\n      patches.push(\n        ...unsetItems.map(\n          (item): UnsetPatch => ({op: 'unset', path: path.concat({_key: item._key})}),\n        ),\n      )\n    }\n  }\n\n  // Check for illegal array contents\n  for (let i = 0; i < itemB.length; i++) {\n    if (Array.isArray(itemB[i])) {\n      throw new DiffError('Multi-dimensional arrays not supported', path.concat(i), itemB[i])\n    }\n  }\n\n  const overlapping = Math.min(itemA.length, itemB.length)\n  const segmentA = itemA.slice(0, overlapping)\n  const segmentB = itemB.slice(0, overlapping)\n\n  return isUniquelyKeyed(segmentA) && isUniquelyKeyed(segmentB)\n    ? diffArrayByKey(segmentA, segmentB, options, path, patches)\n    : diffArrayByIndex(segmentA, segmentB, options, path, patches)\n}\n\nfunction diffArrayByIndex(\n  itemA: unknown[],\n  itemB: unknown[],\n  options: DiffOptions,\n  path: Path,\n  patches: Patch[],\n) {\n  for (let i = 0; i < itemA.length; i++) {\n    diffItem(\n      itemA[i],\n      nullifyUndefined(itemB[i], path, i, options),\n      options,\n      path.concat(i),\n      patches,\n    )\n  }\n\n  return patches\n}\n\nfunction diffArrayByKey(\n  itemA: KeyedSanityObject[],\n  itemB: KeyedSanityObject[],\n  options: DiffOptions,\n  path: Path,\n  patches: Patch[],\n) {\n  const keyedA = indexByKey(itemA)\n  const keyedB = indexByKey(itemB)\n\n  // There's a bunch of hard/semi-hard problems related to using keys\n  // Unless we have the exact same order, just use indexes for now\n  if (!arrayIsEqual(keyedA.keys, keyedB.keys)) {\n    return diffArrayByIndex(itemA, itemB, options, path, patches)\n  }\n\n  for (let i = 0; i < keyedB.keys.length; i++) {\n    const key = keyedB.keys[i]\n    const valueA = keyedA.index[key]\n    const valueB = nullifyUndefined(keyedB.index[key], path, i, options)\n    diffItem(valueA, valueB, options, path.concat({_key: key}), patches)\n  }\n\n  return patches\n}\n\nfunction getDiffMatchPatch(\n  itemA: PrimitiveValue,\n  itemB: PrimitiveValue,\n  options: DiffOptions,\n  path: Path,\n): DiffMatchPatch | undefined {\n  const {enabled, lengthThresholdRelative, lengthThresholdAbsolute} = options.diffMatchPatch\n  const segment = path[path.length - 1]\n  if (\n    !enabled ||\n    // Don't use for anything but strings\n    typeof itemA !== 'string' ||\n    typeof itemB !== 'string' ||\n    // Don't use for `_key`, `_ref` etc\n    (typeof segment === 'string' && segment[0] === '_') ||\n    // Don't use on short strings\n    itemB.length < lengthThresholdAbsolute\n  ) {\n    return undefined\n  }\n\n  let strPatch = ''\n  try {\n    const patch = makeDiff(itemA, itemB)\n    const diff = cleanupEfficiency(patch)\n    strPatch = stringifyPatches(makePatches(diff))\n  } catch (err) {\n    // Fall back to using regular set patch\n    return undefined\n  }\n\n  // Don't use patch if it's longer than allowed relative threshold.\n  // Allow a 120 character patch for a 100 character string,\n  // but don't allow a 800 character patch for a 500 character value.\n  return strPatch.length > itemB.length * lengthThresholdRelative\n    ? undefined\n    : {op: 'diffMatchPatch', path, value: strPatch}\n}\n\nfunction diffPrimitive(\n  itemA: PrimitiveValue,\n  itemB: PrimitiveValue,\n  options: DiffOptions,\n  path: Path,\n  patches: Patch[],\n): Patch[] {\n  const dmp = getDiffMatchPatch(itemA, itemB, options, path)\n\n  patches.push(\n    dmp || {\n      op: 'set',\n      path,\n      value: itemB,\n    },\n  )\n\n  return patches\n}\n\nfunction isNotIgnoredKey(key: string) {\n  return ignoredKeys.indexOf(key) === -1\n}\n\nfunction serializePatches(\n  patches: Patch[],\n  options: {id: string; ifRevisionID?: string},\n): SanityPatchMutation[] {\n  if (patches.length === 0) {\n    return []\n  }\n\n  const {id, ifRevisionID} = options\n  const set = patches.filter((patch): patch is SetPatch => patch.op === 'set')\n  const unset = patches.filter((patch): patch is UnsetPatch => patch.op === 'unset')\n  const insert = patches.filter((patch): patch is InsertAfterPatch => patch.op === 'insert')\n  const dmp = patches.filter((patch): patch is DiffMatchPatch => patch.op === 'diffMatchPatch')\n\n  const withSet =\n    set.length > 0 &&\n    set.reduce(\n      (patch: SanitySetPatch, item: SetPatch) => {\n        const path = pathToString(item.path)\n        patch.set[path] = item.value\n        return patch\n      },\n      {id, set: {}},\n    )\n\n  const withUnset =\n    unset.length > 0 &&\n    unset.reduce(\n      (patch: SanityUnsetPatch, item: UnsetPatch) => {\n        const path = pathToString(item.path)\n        patch.unset.push(path)\n        return patch\n      },\n      {id, unset: []},\n    )\n\n  const withInsert = insert.reduce((acc: SanityInsertPatch[], item: InsertAfterPatch) => {\n    const after = pathToString(item.after)\n    return acc.concat({id, insert: {after, items: item.items}})\n  }, [])\n\n  const withDmp =\n    dmp.length > 0 &&\n    dmp.reduce(\n      (patch: SanityDiffMatchPatch, item: DiffMatchPatch) => {\n        const path = pathToString(item.path)\n        patch.diffMatchPatch[path] = item.value\n        return patch\n      },\n      {id, diffMatchPatch: {}},\n    )\n\n  const patchSet: SanityPatch[] = [withUnset, withSet, withDmp, ...withInsert].filter(\n    (item): item is SanityPatch => item !== false,\n  )\n\n  return patchSet.map((patch, i) => ({\n    patch: ifRevisionID && i === 0 ? {...patch, ifRevisionID} : patch,\n  }))\n}\n\nfunction isUniquelyKeyed(arr: unknown[]): arr is KeyedSanityObject[] {\n  const keys = []\n\n  for (let i = 0; i < arr.length; i++) {\n    const key = getKey(arr[i])\n    if (!key || keys.indexOf(key) !== -1) {\n      return false\n    }\n\n    keys.push(key)\n  }\n\n  return true\n}\n\nfunction getKey(obj: unknown) {\n  return typeof obj === 'object' && obj !== null && (obj as KeyedSanityObject)._key\n}\n\nfunction indexByKey(arr: KeyedSanityObject[]) {\n  return arr.reduce(\n    (acc, item) => {\n      acc.keys.push(item._key)\n      acc.index[item._key] = item\n      return acc\n    },\n    {keys: [] as string[], index: {} as {[key: string]: KeyedSanityObject}},\n  )\n}\n\nfunction arrayIsEqual(itemA: unknown[], itemB: unknown[]) {\n  return itemA.length === itemB.length && itemA.every((item, i) => itemB[i] === item)\n}\n\nfunction nullifyUndefined(item: unknown, path: Path, index: number, options: PatchOptions) {\n  if (typeof item !== 'undefined') {\n    return item\n  }\n\n  if (!options.hideWarnings) {\n    const serializedPath = pathToString(path.concat(index))\n    console.warn(`undefined value in array converted to null (at '${serializedPath}')`)\n  }\n\n  return null\n}\n\nfunction isRevisionLocked(options: PatchOptions): boolean {\n  return Boolean(options.ifRevisionID)\n}\n\nfunction yes(_: unknown) {\n  return true\n}\n"],"names":["makeDiff","cleanupEfficiency","stringifyPatches","makePatches"],"mappings":"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"}