{"version":3,"sources":["../../../src/fields/config/sanitizeJoinField.ts"],"sourcesContent":["import type { SanitizedJoin, SanitizedJoins } from '../../collections/config/types.js'\nimport type { Config } from '../../config/types.js'\nimport type { FlattenedJoinField, JoinField } from './types.js'\n\nimport { APIError } from '../../errors/index.js'\n\n/**\n * Info about an orderable join field, collected during sanitization\n * and processed after all collections are sanitized.\n */\nexport type OrderableJoinInfo = {\n  /** The `on` path of the join field */\n  joinFieldOn: string\n  /** The name of the order field to add (e.g., `_posts_myJoin_order`) */\n  orderFieldName: string\n  /** The collection that will receive the order field */\n  targetCollectionSlug: string\n}\nimport { InvalidFieldJoin } from '../../errors/InvalidFieldJoin.js'\nimport { flattenAllFields } from '../../utilities/flattenAllFields.js'\nimport { getFieldByPath } from '../../utilities/getFieldByPath.js'\n\nexport const sanitizeJoinField = ({\n  config,\n  field,\n  joinPath,\n  joins,\n  orderableJoins,\n  parentIsLocalized,\n  polymorphicJoins,\n  validateOnly,\n}: {\n  config: Config\n  field: FlattenedJoinField | JoinField\n  joinPath?: string\n  joins?: SanitizedJoins\n  /** Tracker for orderable join fields - populated during sanitization */\n  orderableJoins?: OrderableJoinInfo[]\n  parentIsLocalized: boolean\n  polymorphicJoins?: SanitizedJoin[]\n  validateOnly?: boolean\n}) => {\n  // the `joins` arg is not passed for globals or when recursing on fields that do not allow a join field\n  if (typeof joins === 'undefined') {\n    throw new APIError('Join fields cannot be added to arrays, blocks or globals.')\n  }\n  if (typeof field.maxDepth === 'undefined') {\n    field.maxDepth = 1\n  }\n  const join: SanitizedJoin = {\n    field,\n    joinPath: `${joinPath ? joinPath + '.' : ''}${field.name}`,\n    parentIsLocalized,\n    // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n    targetField: undefined,\n  }\n\n  // Orderable joins must target a single collection\n  if (field.orderable && Array.isArray(field.collection)) {\n    throw new APIError('Orderable joins must target a single collection')\n  }\n\n  if (Array.isArray(field.collection)) {\n    for (const collection of field.collection) {\n      const sanitizedField = {\n        ...field,\n        collection,\n      } as FlattenedJoinField\n\n      sanitizeJoinField({\n        config,\n        field: sanitizedField,\n        joinPath,\n        joins,\n        parentIsLocalized,\n        polymorphicJoins,\n        validateOnly: true,\n      })\n    }\n\n    if (Array.isArray(polymorphicJoins)) {\n      polymorphicJoins.push(join)\n    }\n\n    return\n  }\n\n  const joinCollection = config.collections?.find(\n    (collection) => collection.slug === field.collection,\n  )\n  if (!joinCollection) {\n    throw new InvalidFieldJoin(field)\n  }\n\n  const relationshipField = getFieldByPath({\n    fields: flattenAllFields({ cache: true, fields: joinCollection.fields }),\n    path: field.on,\n  })\n\n  if (\n    !relationshipField ||\n    (relationshipField.field.type !== 'relationship' && relationshipField.field.type !== 'upload')\n  ) {\n    throw new InvalidFieldJoin(join.field)\n  }\n\n  if (relationshipField.pathHasLocalized) {\n    join.getForeignPath = ({ locale }) => {\n      return relationshipField.localizedPath.replace('<locale>', locale!)\n    }\n  }\n\n  if (!relationshipField.field.index && !relationshipField.field.unique) {\n    relationshipField.field.index = true\n  }\n\n  if (validateOnly) {\n    return\n  }\n\n  // Track orderable joins for post-sanitization processing\n  if (field.orderable && orderableJoins) {\n    const prefix = joinPath ? joinPath.replace(/\\./g, '_') + '_' : ''\n    const orderFieldName = `_${field.collection}_${prefix}${field.name}_order`\n\n    // Set defaultSort on the join field\n    field.defaultSort = field.defaultSort ?? orderFieldName\n\n    orderableJoins.push({\n      joinFieldOn: field.on,\n      orderFieldName,\n      targetCollectionSlug: field.collection,\n    })\n  }\n\n  join.targetField = relationshipField.field\n\n  // override the join field localized property to use whatever the relationship field has\n  // or if it's nested to a localized array / blocks / tabs / group\n  field.localized = relationshipField.field.localized\n  // override the join field hasMany property to use whatever the relationship field has\n  field.hasMany = relationshipField.field.hasMany\n\n  // @ts-expect-error converting JoinField to FlattenedJoinField to track targetField\n  field.targetField = join.targetField\n\n  if (!joins[field.collection]) {\n    joins[field.collection] = [join]\n  } else {\n    joins[field.collection]?.push(join)\n  }\n}\n"],"names":["APIError","InvalidFieldJoin","flattenAllFields","getFieldByPath","sanitizeJoinField","config","field","joinPath","joins","orderableJoins","parentIsLocalized","polymorphicJoins","validateOnly","maxDepth","join","name","targetField","undefined","orderable","Array","isArray","collection","sanitizedField","push","joinCollection","collections","find","slug","relationshipField","fields","cache","path","on","type","pathHasLocalized","getForeignPath","locale","localizedPath","replace","index","unique","prefix","orderFieldName","defaultSort","joinFieldOn","targetCollectionSlug","localized","hasMany"],"mappings":"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"}