{"version":3,"sources":["../../src/database/getLocalizedPaths.ts"],"sourcesContent":["import type { PathToQuery } from './queryValidation/types.js'\n\nimport {\n  type Field,\n  fieldShouldBeLocalized,\n  type FlattenedBlock,\n  type FlattenedField,\n} from '../fields/config/types.js'\nimport { APIError, type Payload, type SanitizedCollectionConfig } from '../index.js'\nimport { SAFE_FIELD_PATH_REGEX } from '../types/constants.js'\n\nexport function getLocalizedPaths({\n  collectionSlug,\n  fields,\n  globalSlug,\n  incomingPath,\n  locale,\n  overrideAccess = false,\n  parentIsLocalized,\n  payload,\n}: {\n  collectionSlug?: string\n  fields: FlattenedField[]\n  globalSlug?: string\n  incomingPath: string\n  locale?: string\n  overrideAccess?: boolean\n  /**\n   * @todo make required in v4.0. Usually, you'd wanna pass this through\n   */\n  parentIsLocalized?: boolean\n  payload: Payload\n}): PathToQuery[] {\n  const pathSegments = incomingPath.split('.')\n  const localizationConfig = payload.config.localization\n\n  let paths: PathToQuery[] = [\n    {\n      collectionSlug,\n      complete: false,\n      // @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve\n      field: undefined,\n      fields,\n      globalSlug,\n      invalid: false,\n      parentIsLocalized: parentIsLocalized!,\n      path: '',\n    },\n  ]\n\n  for (let i = 0; i < pathSegments.length; i += 1) {\n    const segment = pathSegments[i]\n\n    const lastIncompletePath = paths.find(({ complete }) => !complete)\n\n    if (lastIncompletePath) {\n      const { path } = lastIncompletePath\n      let currentPath = path ? `${path}.${segment}` : segment\n\n      let fieldsToSearch: FlattenedField[]\n      let _parentIsLocalized = parentIsLocalized\n\n      let matchedField!: FlattenedField\n\n      if (lastIncompletePath?.field?.type === 'blocks') {\n        if (segment === 'blockType') {\n          matchedField = {\n            name: 'blockType',\n            type: 'text',\n          }\n        } else {\n          for (const _block of lastIncompletePath.field.blockReferences ??\n            lastIncompletePath.field.blocks) {\n            let block: FlattenedBlock\n            if (typeof _block === 'string') {\n              block = payload.blocks[_block]!\n            } else {\n              block = _block\n            }\n\n            matchedField = block.flattenedFields.find((field) => field.name === segment)!\n            if (matchedField) {\n              break\n            }\n          }\n        }\n      } else {\n        if (lastIncompletePath?.field && 'flattenedFields' in lastIncompletePath.field) {\n          fieldsToSearch = lastIncompletePath.field.flattenedFields\n        } else {\n          fieldsToSearch = lastIncompletePath.fields!\n        }\n        _parentIsLocalized = parentIsLocalized || lastIncompletePath.field?.localized\n\n        matchedField = fieldsToSearch.find((field) => field.name === segment)!\n      }\n\n      lastIncompletePath.field = matchedField!\n\n      if (currentPath === 'globalType' && globalSlug) {\n        lastIncompletePath.path = currentPath\n        lastIncompletePath.complete = true\n        lastIncompletePath.field = {\n          name: 'globalType',\n          type: 'text',\n        }\n\n        return paths\n      }\n\n      if (currentPath === 'relationTo') {\n        lastIncompletePath.path = currentPath\n        lastIncompletePath.complete = true\n        lastIncompletePath.field = {\n          name: 'relationTo',\n          type: 'select',\n          options: Object.keys(payload.collections),\n        }\n\n        return paths\n      }\n\n      if (!matchedField && currentPath === 'id' && i === pathSegments.length - 1) {\n        lastIncompletePath.path = currentPath\n        const idField: Field = {\n          name: 'id',\n          type: payload.db.defaultIDType as 'text',\n        }\n        lastIncompletePath.field = idField\n        lastIncompletePath.complete = true\n        return paths\n      }\n\n      if (matchedField) {\n        if ('hidden' in matchedField && matchedField.hidden && !overrideAccess) {\n          lastIncompletePath.invalid = true\n        }\n\n        const nextSegment = pathSegments[i + 1]!\n        const currentFieldIsLocalized = fieldShouldBeLocalized({\n          field: matchedField,\n          parentIsLocalized: _parentIsLocalized!,\n        })\n\n        const nextSegmentIsLocale =\n          localizationConfig &&\n          localizationConfig.localeCodes.includes(nextSegment) &&\n          currentFieldIsLocalized\n\n        if (nextSegmentIsLocale) {\n          // Skip the next iteration, because it's a locale\n          i += 1\n          currentPath = `${currentPath}.${nextSegment}`\n        } else if (localizationConfig && currentFieldIsLocalized) {\n          currentPath = `${currentPath}.${locale}`\n        }\n\n        switch (matchedField.type) {\n          case 'join':\n          case 'relationship':\n          case 'upload': {\n            // If this is a polymorphic relation,\n            // We only support querying directly (no nested querying)\n            if (matchedField.type !== 'join' && typeof matchedField.relationTo !== 'string') {\n              lastIncompletePath.path = pathSegments.join('.')\n              if (![matchedField.name, 'relationTo', 'value'].includes(pathSegments.at(-1)!)) {\n                lastIncompletePath.invalid = true\n              } else {\n                lastIncompletePath.complete = true\n              }\n            } else {\n              lastIncompletePath.complete = true\n              lastIncompletePath.path = currentPath!\n\n              const nestedPathToQuery = pathSegments\n                .slice(nextSegmentIsLocale ? i + 2 : i + 1)\n                .join('.')\n\n              if (nestedPathToQuery) {\n                let relatedCollection: SanitizedCollectionConfig\n                if (matchedField.type === 'join') {\n                  if (Array.isArray(matchedField.collection)) {\n                    throw new APIError('Not supported')\n                  }\n\n                  relatedCollection = payload.collections[matchedField.collection]!.config\n                } else {\n                  relatedCollection = payload.collections[matchedField.relationTo as string]!.config\n                }\n\n                const remainingPaths = getLocalizedPaths({\n                  collectionSlug: relatedCollection.slug,\n                  fields: relatedCollection.flattenedFields,\n                  globalSlug,\n                  incomingPath: nestedPathToQuery,\n                  locale,\n                  parentIsLocalized: false,\n                  payload,\n                })\n\n                paths = [...paths, ...remainingPaths]\n              }\n\n              return paths\n            }\n\n            break\n          }\n          case 'json':\n          case 'richText': {\n            const upcomingSegments = pathSegments.slice(i + 1).join('.')\n            pathSegments.forEach((path) => {\n              if (!SAFE_FIELD_PATH_REGEX.test(path)) {\n                lastIncompletePath.invalid = true\n              }\n            })\n            lastIncompletePath.complete = true\n            lastIncompletePath.path = upcomingSegments\n              ? `${currentPath}.${upcomingSegments}`\n              : currentPath!\n            return paths\n          }\n\n          default: {\n            if (i + 1 === pathSegments.length) {\n              lastIncompletePath.complete = true\n            }\n            lastIncompletePath.path = currentPath!\n          }\n        }\n      } else {\n        lastIncompletePath.invalid = true\n        lastIncompletePath.path = currentPath!\n        return paths\n      }\n    }\n  }\n\n  return paths\n}\n"],"names":["fieldShouldBeLocalized","APIError","SAFE_FIELD_PATH_REGEX","getLocalizedPaths","collectionSlug","fields","globalSlug","incomingPath","locale","overrideAccess","parentIsLocalized","payload","pathSegments","split","localizationConfig","config","localization","paths","complete","field","undefined","invalid","path","i","length","segment","lastIncompletePath","find","currentPath","fieldsToSearch","_parentIsLocalized","matchedField","type","name","_block","blockReferences","blocks","block","flattenedFields","localized","options","Object","keys","collections","idField","db","defaultIDType","hidden","nextSegment","currentFieldIsLocalized","nextSegmentIsLocale","localeCodes","includes","relationTo","join","at","nestedPathToQuery","slice","relatedCollection","Array","isArray","collection","remainingPaths","slug","upcomingSegments","forEach","test"],"mappings":"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"}