@roxxel/payload-multilang 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +16 -3
  2. package/dist/components/LanguageListToolbar.js +4 -3
  3. package/dist/components/LanguageListToolbar.js.map +1 -1
  4. package/dist/components/LanguageMetabox.js +18 -17
  5. package/dist/components/LanguageMetabox.js.map +1 -1
  6. package/dist/components/TranslationActionsClient.js +16 -14
  7. package/dist/components/TranslationActionsClient.js.map +1 -1
  8. package/dist/components/TranslationColumnCell.js +4 -1
  9. package/dist/components/TranslationColumnCell.js.map +1 -1
  10. package/dist/components/TranslationColumnCellClient.js +16 -7
  11. package/dist/components/TranslationColumnCellClient.js.map +1 -1
  12. package/dist/components/TranslationsTab.js +9 -8
  13. package/dist/components/TranslationsTab.js.map +1 -1
  14. package/dist/constants.d.ts +1 -1
  15. package/dist/constants.js +1 -1
  16. package/dist/constants.js.map +1 -1
  17. package/dist/endpoints/translations.js +4 -6
  18. package/dist/endpoints/translations.js.map +1 -1
  19. package/dist/hooks/translatedCollection.d.ts +2 -1
  20. package/dist/hooks/translatedCollection.js +122 -15
  21. package/dist/hooks/translatedCollection.js.map +1 -1
  22. package/dist/hooks/translatedGlobal.js +5 -1
  23. package/dist/hooks/translatedGlobal.js.map +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +22 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/lib/config.js +2 -10
  28. package/dist/lib/config.js.map +1 -1
  29. package/dist/lib/data.d.ts +1 -2
  30. package/dist/lib/data.js +32 -4
  31. package/dist/lib/data.js.map +1 -1
  32. package/dist/translations.d.ts +72 -0
  33. package/dist/translations.js +72 -0
  34. package/dist/translations.js.map +1 -0
  35. package/dist/types.d.ts +0 -19
  36. package/dist/types.js.map +1 -1
  37. package/docs/configuration.md +43 -9
  38. package/docs/usage.md +10 -34
  39. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/translatedCollection.ts"],"sourcesContent":["import type {\n CollectionAfterChangeHook,\n CollectionBeforeChangeHook,\n CollectionConfig,\n Field,\n Where,\n} from 'payload'\n\nimport { randomUUID } from 'crypto'\n\nimport type { ResolvedMultilangCollection } from '../types.js'\n\nimport { MULTILANG_SKIP_HOOK } from '../constants.js'\nimport { asDocument, getID, getStringValue } from '../lib/data.js'\n\nconst hasSkipContext = (context?: Record<string, unknown>): boolean =>\n context?.[MULTILANG_SKIP_HOOK] === true\n\nconst valuesAreEqual = (left: unknown, right: unknown): boolean => {\n if (left === right) {\n return true\n }\n\n return JSON.stringify(left) === JSON.stringify(right)\n}\n\nconst isConfiguredLanguage = (\n collection: ResolvedMultilangCollection,\n language: string | undefined,\n): boolean =>\n Boolean(\n language &&\n collection.languages.some((configuredLanguage) => configuredLanguage.code === language),\n )\n\ntype CollectionEditViews = NonNullable<\n NonNullable<NonNullable<CollectionConfig['admin']>['components']>['views']\n>['edit']\n\nconst getDuplicateLanguageIDs = async ({\n collection,\n excludeID,\n group,\n language,\n req,\n}: {\n collection: ResolvedMultilangCollection\n excludeID?: number | string\n group: string\n language: string\n req: Parameters<CollectionBeforeChangeHook>[0]['req']\n}): Promise<Array<number | string>> => {\n const and: Where[] = [\n {\n [collection.fieldNames.group]: {\n equals: group,\n },\n },\n {\n [collection.fieldNames.language]: {\n equals: language,\n },\n },\n ]\n\n if (excludeID) {\n and.push({\n id: {\n not_equals: excludeID,\n },\n })\n }\n\n const result = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 200,\n overrideAccess: true,\n req,\n where: {\n and,\n },\n })\n\n return result.docs\n .map((doc) => getID(asDocument(doc).id))\n .filter((id): id is number | string => id !== undefined)\n}\n\nexport const createTranslatedCollectionBeforeChangeHook =\n ({ collection }: { collection: ResolvedMultilangCollection }): CollectionBeforeChangeHook =>\n async ({ context, data, operation, originalDoc, req }) => {\n if (hasSkipContext(context)) {\n return data\n }\n\n const nextData = asDocument(data)\n const original = asDocument(originalDoc)\n const { group: groupField, language: languageField } = collection.fieldNames\n const originalLanguage = getStringValue(original[languageField])\n const originalLanguageIsConfigured = isConfiguredLanguage(collection, originalLanguage)\n const incomingLanguage = getStringValue(nextData[languageField])\n\n if (operation === 'update' && originalLanguage && !originalLanguageIsConfigured) {\n if (\n !incomingLanguage ||\n incomingLanguage === originalLanguage ||\n !isConfiguredLanguage(collection, incomingLanguage)\n ) {\n nextData[languageField] = ''\n }\n } else if (!incomingLanguage) {\n nextData[languageField] =\n operation === 'create'\n ? collection.defaultLanguage.code\n : originalLanguageIsConfigured\n ? originalLanguage\n : ''\n }\n\n const language = getStringValue(nextData[languageField])\n\n if (\n operation === 'update' &&\n originalLanguage &&\n originalLanguageIsConfigured &&\n language !== originalLanguage\n ) {\n throw new Error('Document language cannot be changed after creation.')\n }\n\n if (language && !isConfiguredLanguage(collection, language)) {\n throw new Error(`Language \"${language}\" is not configured for ${collection.slug}.`)\n }\n\n if (!getStringValue(nextData[groupField])) {\n const fallbackGroup = getStringValue(original[groupField])\n nextData[groupField] = fallbackGroup || randomUUID()\n }\n\n const group = getStringValue(nextData[groupField])\n\n if (language && group) {\n const currentID = operation === 'update' ? getID(original.id) : undefined\n const duplicateIDs = await getDuplicateLanguageIDs({\n collection,\n excludeID: currentID,\n group,\n language,\n req,\n })\n\n if (duplicateIDs.length > 0) {\n throw new Error(\n `A ${collection.slug} translation already exists for language \"${language}\" in this translation group.`,\n )\n }\n }\n\n return nextData\n }\n\nexport const createSynchronizedFieldsAfterChangeHook =\n ({ collection }: { collection: ResolvedMultilangCollection }): CollectionAfterChangeHook =>\n async ({ context, doc, operation, previousDoc, req }) => {\n if (\n hasSkipContext(context) ||\n operation !== 'update' ||\n collection.synchronizedFields.length === 0\n ) {\n return doc\n }\n\n const nextDoc = asDocument(doc)\n const previous = asDocument(previousDoc)\n const group = getStringValue(nextDoc[collection.fieldNames.group])\n const currentID = getID(nextDoc.id)\n\n if (!group || !currentID) {\n return doc\n }\n\n const synchronizedData = collection.synchronizedFields.reduce<Record<string, unknown>>(\n (acc, fieldName) => {\n if (fieldName in nextDoc && !valuesAreEqual(nextDoc[fieldName], previous[fieldName])) {\n acc[fieldName] = nextDoc[fieldName]\n }\n\n return acc\n },\n {},\n )\n\n if (Object.keys(synchronizedData).length === 0) {\n return doc\n }\n\n const translations = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 200,\n overrideAccess: true,\n req,\n where: {\n and: [\n {\n [collection.fieldNames.group]: {\n equals: group,\n },\n },\n {\n id: {\n not_equals: currentID,\n },\n },\n ],\n },\n })\n\n await Promise.all(\n translations.docs\n .map((translation) => getID(asDocument(translation).id))\n .filter((id): id is number | string => id !== undefined)\n .map((id) =>\n req.payload.update({\n id,\n collection: collection.slug,\n context: {\n [MULTILANG_SKIP_HOOK]: true,\n },\n data: synchronizedData,\n overrideAccess: true,\n req,\n }),\n ),\n )\n\n return doc\n }\n\nexport const createHiddenFields = ({\n collection,\n}: {\n collection: ResolvedMultilangCollection\n}): Field[] => [\n {\n name: collection.fieldNames.language,\n type: 'text',\n admin: {\n disableListColumn: true,\n hidden: true,\n },\n index: true,\n label: 'Language',\n },\n {\n name: collection.fieldNames.group,\n type: 'text',\n admin: {\n disableListColumn: true,\n hidden: true,\n },\n index: true,\n label: 'Translations',\n },\n {\n name: collection.fieldNames.meta,\n type: 'json',\n admin: {\n disableListColumn: true,\n hidden: true,\n },\n },\n {\n name: 'multilangLanguageMetabox',\n type: 'ui',\n admin: {\n components: {\n Field: '@roxxel/payload-multilang/client#LanguageMetabox',\n },\n position: 'sidebar',\n },\n },\n]\n\nexport const getLanguageColumnName = (): string => 'payloadMultilangTranslations'\n\nexport const createLanguageColumnFields = ({\n collection,\n}: {\n collection: ResolvedMultilangCollection\n}): Field[] => {\n const label = collection.languages\n .map((language) => language.flagLabel || language.code.toUpperCase())\n .join(' ')\n\n return [\n {\n name: getLanguageColumnName(),\n type: 'ui',\n admin: {\n components: {\n Cell: '@roxxel/payload-multilang/rsc#TranslationColumnCell',\n },\n disableListColumn: false,\n width: '132px',\n },\n label: label || 'Translations',\n },\n ]\n}\n\nexport const translatedCollectionMeta = ({\n collection,\n}: {\n collection: ResolvedMultilangCollection\n}) => ({\n defaultLanguage: collection.defaultLanguage,\n fieldNames: collection.fieldNames,\n languages: collection.languages,\n})\n\nconst getDefaultColumns = ({\n collection,\n existingDefaultColumns,\n languageColumnName,\n}: {\n collection: ResolvedMultilangCollection\n existingDefaultColumns: string[]\n languageColumnName: string\n}): string[] => {\n const hiddenMultilangColumns = new Set([\n collection.fieldNames.group,\n collection.fieldNames.language,\n collection.fieldNames.meta,\n languageColumnName,\n ])\n const visibleExistingColumns = existingDefaultColumns.filter(\n (column) => !hiddenMultilangColumns.has(column),\n )\n\n return [...visibleExistingColumns, languageColumnName]\n}\n\nexport const withTranslatedCollection = ({\n collection,\n config,\n}: {\n collection: ResolvedMultilangCollection\n config: CollectionConfig\n}): CollectionConfig => {\n const existingDefaultColumns = config.admin?.defaultColumns || []\n const languageColumnName = getLanguageColumnName()\n const existingEditViews =\n (config.admin?.components?.views?.edit as Record<string, unknown> | undefined) || {}\n const defaultColumns = getDefaultColumns({\n collection,\n existingDefaultColumns,\n languageColumnName,\n })\n\n return {\n ...config,\n admin: {\n ...config.admin,\n components: {\n ...config.admin?.components,\n beforeList: [\n ...(config.admin?.components?.beforeList || []),\n '@roxxel/payload-multilang/client#LanguageListToolbar',\n ],\n beforeListTable: config.admin?.components?.beforeListTable,\n views: {\n ...config.admin?.components?.views,\n edit: {\n ...existingEditViews,\n translations: {\n Component: '@roxxel/payload-multilang/rsc#TranslationsTab',\n path: '/translations',\n tab: {\n label: 'Translations',\n order: 80,\n },\n },\n } as CollectionEditViews,\n },\n },\n custom: {\n ...config.admin?.custom,\n payloadMultilang: translatedCollectionMeta({\n collection,\n }),\n },\n defaultColumns,\n },\n endpoints: [...(config.endpoints || [])],\n fields: [\n ...(config.fields || []),\n ...createHiddenFields({ collection }),\n ...createLanguageColumnFields({ collection }),\n ],\n hooks: {\n ...config.hooks,\n afterChange: [\n createSynchronizedFieldsAfterChangeHook({\n collection,\n }),\n ...(config.hooks?.afterChange || []),\n ],\n beforeChange: [\n createTranslatedCollectionBeforeChangeHook({\n collection,\n }),\n ...(config.hooks?.beforeChange || []),\n ],\n },\n }\n}\n"],"names":["randomUUID","MULTILANG_SKIP_HOOK","asDocument","getID","getStringValue","hasSkipContext","context","valuesAreEqual","left","right","JSON","stringify","isConfiguredLanguage","collection","language","Boolean","languages","some","configuredLanguage","code","getDuplicateLanguageIDs","excludeID","group","req","and","fieldNames","equals","push","id","not_equals","result","payload","find","slug","depth","limit","overrideAccess","where","docs","map","doc","filter","undefined","createTranslatedCollectionBeforeChangeHook","data","operation","originalDoc","nextData","original","groupField","languageField","originalLanguage","originalLanguageIsConfigured","incomingLanguage","defaultLanguage","Error","fallbackGroup","currentID","duplicateIDs","length","createSynchronizedFieldsAfterChangeHook","previousDoc","synchronizedFields","nextDoc","previous","synchronizedData","reduce","acc","fieldName","Object","keys","translations","Promise","all","translation","update","createHiddenFields","name","type","admin","disableListColumn","hidden","index","label","meta","components","Field","position","getLanguageColumnName","createLanguageColumnFields","flagLabel","toUpperCase","join","Cell","width","translatedCollectionMeta","getDefaultColumns","existingDefaultColumns","languageColumnName","hiddenMultilangColumns","Set","visibleExistingColumns","column","has","withTranslatedCollection","config","defaultColumns","existingEditViews","views","edit","beforeList","beforeListTable","Component","path","tab","order","custom","payloadMultilang","endpoints","fields","hooks","afterChange","beforeChange"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/hooks/translatedCollection.ts"],"sourcesContent":["import type {\n CollectionAfterChangeHook,\n CollectionBeforeChangeHook,\n CollectionConfig,\n Field,\n Where,\n} from 'payload'\n\nimport { randomUUID } from 'crypto'\n\nimport type { ResolvedMultilangCollection } from '../types.js'\n\nimport { MULTILANG_SKIP_HOOK } from '../constants.js'\nimport { asDocument, getID, getStringValue } from '../lib/data.js'\n\nconst LANGUAGE_LABEL = {\n en: 'Language',\n uk: 'Мова',\n}\n\nconst TRANSLATIONS_LABEL = {\n en: 'Translations',\n uk: 'Переклади',\n}\n\ntype FieldAffectingData = { name: string } & Field\ntype SynchronizedField = {\n name: string\n strategy: 'shell' | 'value'\n type: 'array' | 'blocks' | Field['type']\n}\n\nconst hasSkipContext = (context?: Record<string, unknown>): boolean =>\n context?.[MULTILANG_SKIP_HOOK] === true\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst toArray = (value: unknown): Record<string, unknown>[] =>\n Array.isArray(value) ? value.filter(isObject) : []\n\nconst valuesAreEqual = (left: unknown, right: unknown): boolean => {\n if (left === right) {\n return true\n }\n\n return JSON.stringify(left) === JSON.stringify(right)\n}\n\nconst fieldAffectsData = (field: Field): field is FieldAffectingData =>\n 'name' in field && typeof field.name === 'string' && field.type !== 'ui'\n\nconst fieldSynchronizes = (field: Field): boolean => {\n const custom = isObject(field.custom) ? field.custom : {}\n const multilang = isObject(custom.multilang) ? custom.multilang : {}\n\n return multilang.synchronize === true\n}\n\nconst getSynchronizedFields = (fields: Field[] = []): SynchronizedField[] =>\n fields.flatMap((field) => {\n if (!fieldAffectsData(field) || !fieldSynchronizes(field)) {\n return []\n }\n\n return [\n {\n name: field.name,\n type: field.type,\n strategy: field.type === 'array' || field.type === 'blocks' ? 'shell' : 'value',\n },\n ]\n })\n\nconst getRowKey = (row: Record<string, unknown>, index: number): string => {\n const id = getID(row.id)\n\n return id === undefined ? `index:${index}` : `id:${String(id)}`\n}\n\nconst getShellSignature = (value: unknown, field: SynchronizedField): string =>\n JSON.stringify(\n toArray(value).map((row, index) => ({\n blockName: field.type === 'blocks' ? getStringValue(row.blockName) : undefined,\n blockType: field.type === 'blocks' ? getStringValue(row.blockType) : undefined,\n key: getRowKey(row, index),\n })),\n )\n\nconst shellChanged = (\n field: SynchronizedField,\n nextDoc: Record<string, unknown>,\n previous: Record<string, unknown>,\n): boolean => {\n if (!(field.name in nextDoc)) {\n return false\n }\n\n return (\n getShellSignature(nextDoc[field.name], field) !==\n getShellSignature(previous[field.name], field)\n )\n}\n\nconst createShellRow = (\n sourceRow: Record<string, unknown>,\n targetRow: Record<string, unknown> | undefined,\n field: SynchronizedField,\n): Record<string, unknown> => {\n const row = targetRow ? { ...targetRow } : {}\n\n if (field.type === 'blocks' && 'blockType' in sourceRow) {\n row.blockType = sourceRow.blockType\n }\n\n if (field.type === 'blocks') {\n if ('blockName' in sourceRow) {\n row.blockName = sourceRow.blockName\n } else {\n delete row.blockName\n }\n }\n\n return row\n}\n\nconst synchronizeShellValue = ({\n field,\n previousSourceValue,\n sourceValue,\n targetValue,\n}: {\n field: SynchronizedField\n previousSourceValue: unknown\n sourceValue: unknown\n targetValue: unknown\n}): unknown[] => {\n const targetRows = toArray(targetValue)\n const previousSourceIndexesByKey = new Map(\n toArray(previousSourceValue).map((row, index) => [getRowKey(row, index), index] as const),\n )\n\n return toArray(sourceValue).map((sourceRow, index) => {\n const previousIndex = previousSourceIndexesByKey.get(getRowKey(sourceRow, index))\n\n return createShellRow(\n sourceRow,\n previousIndex === undefined ? undefined : targetRows[previousIndex],\n field,\n )\n })\n}\n\nconst getSynchronizedDataForTranslation = ({\n fields,\n nextDoc,\n previous,\n translation,\n}: {\n fields: SynchronizedField[]\n nextDoc: Record<string, unknown>\n previous: Record<string, unknown>\n translation: Record<string, unknown>\n}): Record<string, unknown> =>\n fields.reduce<Record<string, unknown>>((acc, field) => {\n if (field.strategy === 'value') {\n acc[field.name] = nextDoc[field.name]\n\n return acc\n }\n\n const value = synchronizeShellValue({\n field,\n previousSourceValue: previous[field.name],\n sourceValue: nextDoc[field.name],\n targetValue: translation[field.name],\n })\n\n if (!valuesAreEqual(value, translation[field.name])) {\n acc[field.name] = value\n }\n\n return acc\n }, {})\n\nconst isConfiguredLanguage = (\n collection: ResolvedMultilangCollection,\n language: string | undefined,\n): boolean =>\n Boolean(\n language &&\n collection.languages.some((configuredLanguage) => configuredLanguage.code === language),\n )\n\ntype CollectionEditViews = NonNullable<\n NonNullable<NonNullable<CollectionConfig['admin']>['components']>['views']\n>['edit']\n\nconst getDuplicateLanguageIDs = async ({\n collection,\n excludeID,\n group,\n language,\n req,\n}: {\n collection: ResolvedMultilangCollection\n excludeID?: number | string\n group: string\n language: string\n req: Parameters<CollectionBeforeChangeHook>[0]['req']\n}): Promise<Array<number | string>> => {\n const and: Where[] = [\n {\n [collection.fieldNames.group]: {\n equals: group,\n },\n },\n {\n [collection.fieldNames.language]: {\n equals: language,\n },\n },\n ]\n\n if (excludeID) {\n and.push({\n id: {\n not_equals: excludeID,\n },\n })\n }\n\n const result = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 200,\n overrideAccess: true,\n req,\n where: {\n and,\n },\n })\n\n return result.docs\n .map((doc) => getID(asDocument(doc).id))\n .filter((id): id is number | string => id !== undefined)\n}\n\nexport const createTranslatedCollectionBeforeChangeHook =\n ({ collection }: { collection: ResolvedMultilangCollection }): CollectionBeforeChangeHook =>\n async ({ context, data, operation, originalDoc, req }) => {\n if (hasSkipContext(context)) {\n return data\n }\n\n const nextData = asDocument(data)\n const original = asDocument(originalDoc)\n const { group: groupField, language: languageField } = collection.fieldNames\n const originalLanguage = getStringValue(original[languageField])\n const originalLanguageIsConfigured = isConfiguredLanguage(collection, originalLanguage)\n const incomingLanguage = getStringValue(nextData[languageField])\n\n if (operation === 'update' && originalLanguage && !originalLanguageIsConfigured) {\n if (\n !incomingLanguage ||\n incomingLanguage === originalLanguage ||\n !isConfiguredLanguage(collection, incomingLanguage)\n ) {\n nextData[languageField] = ''\n }\n } else if (!incomingLanguage) {\n nextData[languageField] =\n operation === 'create'\n ? collection.defaultLanguage.code\n : originalLanguageIsConfigured\n ? originalLanguage\n : ''\n }\n\n const language = getStringValue(nextData[languageField])\n\n if (\n operation === 'update' &&\n originalLanguage &&\n originalLanguageIsConfigured &&\n language !== originalLanguage\n ) {\n throw new Error('Document language cannot be changed after creation.')\n }\n\n if (language && !isConfiguredLanguage(collection, language)) {\n throw new Error(`Language \"${language}\" is not configured for ${collection.slug}.`)\n }\n\n if (!getStringValue(nextData[groupField])) {\n const fallbackGroup = getStringValue(original[groupField])\n nextData[groupField] = fallbackGroup || randomUUID()\n }\n\n const group = getStringValue(nextData[groupField])\n\n if (language && group) {\n const currentID = operation === 'update' ? getID(original.id) : undefined\n const duplicateIDs = await getDuplicateLanguageIDs({\n collection,\n excludeID: currentID,\n group,\n language,\n req,\n })\n\n if (duplicateIDs.length > 0) {\n throw new Error(\n `A ${collection.slug} translation already exists for language \"${language}\" in this translation group.`,\n )\n }\n }\n\n return nextData\n }\n\nexport const createSynchronizedFieldsAfterChangeHook =\n ({\n collection,\n fields,\n }: {\n collection: ResolvedMultilangCollection\n fields?: Field[]\n }): CollectionAfterChangeHook =>\n async ({ context, doc, operation, previousDoc, req }) => {\n const synchronizedFields = getSynchronizedFields(fields)\n\n if (hasSkipContext(context) || operation !== 'update' || synchronizedFields.length === 0) {\n return doc\n }\n\n const nextDoc = asDocument(doc)\n const previous = asDocument(previousDoc)\n const group = getStringValue(nextDoc[collection.fieldNames.group])\n const currentID = getID(nextDoc.id)\n\n if (!group || !currentID) {\n return doc\n }\n\n const changedFields = synchronizedFields.filter((field) => {\n if (field.strategy === 'shell') {\n return shellChanged(field, nextDoc, previous)\n }\n\n return field.name in nextDoc && !valuesAreEqual(nextDoc[field.name], previous[field.name])\n })\n\n if (changedFields.length === 0) {\n return doc\n }\n\n const translations = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 200,\n overrideAccess: true,\n req,\n where: {\n and: [\n {\n [collection.fieldNames.group]: {\n equals: group,\n },\n },\n {\n id: {\n not_equals: currentID,\n },\n },\n ],\n },\n })\n\n await Promise.all(\n translations.docs\n .map((translation) => {\n const translationDoc = asDocument(translation)\n const id = getID(translationDoc.id)\n\n if (id === undefined) {\n return undefined\n }\n\n const synchronizedData = getSynchronizedDataForTranslation({\n fields: changedFields,\n nextDoc,\n previous,\n translation: translationDoc,\n })\n\n if (Object.keys(synchronizedData).length === 0) {\n return undefined\n }\n\n return {\n id,\n data: synchronizedData,\n }\n })\n .filter(\n (update): update is { data: Record<string, unknown>; id: number | string } =>\n update !== undefined,\n )\n .map(({ id, data }) =>\n req.payload.update({\n id,\n collection: collection.slug,\n context: {\n [MULTILANG_SKIP_HOOK]: true,\n },\n data,\n overrideAccess: true,\n req,\n }),\n ),\n )\n\n return doc\n }\n\nexport const createHiddenFields = ({\n collection,\n}: {\n collection: ResolvedMultilangCollection\n}): Field[] => [\n {\n name: collection.fieldNames.language,\n type: 'text',\n admin: {\n disableListColumn: true,\n hidden: true,\n },\n index: true,\n label: LANGUAGE_LABEL,\n },\n {\n name: collection.fieldNames.group,\n type: 'text',\n admin: {\n disableListColumn: true,\n hidden: true,\n },\n index: true,\n label: TRANSLATIONS_LABEL,\n },\n {\n name: collection.fieldNames.meta,\n type: 'json',\n admin: {\n disableListColumn: true,\n hidden: true,\n },\n },\n {\n name: 'multilangLanguageMetabox',\n type: 'ui',\n admin: {\n components: {\n Field: '@roxxel/payload-multilang/client#LanguageMetabox',\n },\n position: 'sidebar',\n },\n },\n]\n\nexport const getLanguageColumnName = (): string => 'payloadMultilangTranslations'\n\nexport const createLanguageColumnFields = ({\n collection,\n}: {\n collection: ResolvedMultilangCollection\n}): Field[] => {\n const label = collection.languages\n .map((language) => language.flagLabel || language.code.toUpperCase())\n .join(' ')\n\n return [\n {\n name: getLanguageColumnName(),\n type: 'ui',\n admin: {\n components: {\n Cell: '@roxxel/payload-multilang/rsc#TranslationColumnCell',\n },\n disableListColumn: false,\n width: '132px',\n },\n label: label || TRANSLATIONS_LABEL,\n },\n ]\n}\n\nexport const translatedCollectionMeta = ({\n collection,\n}: {\n collection: ResolvedMultilangCollection\n}) => ({\n defaultLanguage: collection.defaultLanguage,\n fieldNames: collection.fieldNames,\n languages: collection.languages,\n})\n\nconst getDefaultColumns = ({\n collection,\n existingDefaultColumns,\n languageColumnName,\n}: {\n collection: ResolvedMultilangCollection\n existingDefaultColumns: string[]\n languageColumnName: string\n}): string[] => {\n const hiddenMultilangColumns = new Set([\n collection.fieldNames.group,\n collection.fieldNames.language,\n collection.fieldNames.meta,\n languageColumnName,\n ])\n const visibleExistingColumns = existingDefaultColumns.filter(\n (column) => !hiddenMultilangColumns.has(column),\n )\n\n return [...visibleExistingColumns, languageColumnName]\n}\n\nexport const withTranslatedCollection = ({\n collection,\n config,\n}: {\n collection: ResolvedMultilangCollection\n config: CollectionConfig\n}): CollectionConfig => {\n const existingDefaultColumns = config.admin?.defaultColumns || []\n const languageColumnName = getLanguageColumnName()\n const existingEditViews =\n (config.admin?.components?.views?.edit as Record<string, unknown> | undefined) || {}\n const defaultColumns = getDefaultColumns({\n collection,\n existingDefaultColumns,\n languageColumnName,\n })\n\n return {\n ...config,\n admin: {\n ...config.admin,\n components: {\n ...config.admin?.components,\n beforeList: [\n ...(config.admin?.components?.beforeList || []),\n '@roxxel/payload-multilang/client#LanguageListToolbar',\n ],\n beforeListTable: config.admin?.components?.beforeListTable,\n views: {\n ...config.admin?.components?.views,\n edit: {\n ...existingEditViews,\n translations: {\n Component: '@roxxel/payload-multilang/rsc#TranslationsTab',\n path: '/translations',\n tab: {\n label: ({ t }) => t('payloadMultilang:translations'),\n order: 80,\n },\n },\n } as CollectionEditViews,\n },\n },\n custom: {\n ...config.admin?.custom,\n payloadMultilang: translatedCollectionMeta({\n collection,\n }),\n },\n defaultColumns,\n },\n endpoints: [...(config.endpoints || [])],\n fields: [\n ...(config.fields || []),\n ...createHiddenFields({ collection }),\n ...createLanguageColumnFields({ collection }),\n ],\n hooks: {\n ...config.hooks,\n afterChange: [\n createSynchronizedFieldsAfterChangeHook({\n collection,\n fields: config.fields,\n }),\n ...(config.hooks?.afterChange || []),\n ],\n beforeChange: [\n createTranslatedCollectionBeforeChangeHook({\n collection,\n }),\n ...(config.hooks?.beforeChange || []),\n ],\n },\n }\n}\n"],"names":["randomUUID","MULTILANG_SKIP_HOOK","asDocument","getID","getStringValue","LANGUAGE_LABEL","en","uk","TRANSLATIONS_LABEL","hasSkipContext","context","isObject","value","Array","isArray","toArray","filter","valuesAreEqual","left","right","JSON","stringify","fieldAffectsData","field","name","type","fieldSynchronizes","custom","multilang","synchronize","getSynchronizedFields","fields","flatMap","strategy","getRowKey","row","index","id","undefined","String","getShellSignature","map","blockName","blockType","key","shellChanged","nextDoc","previous","createShellRow","sourceRow","targetRow","synchronizeShellValue","previousSourceValue","sourceValue","targetValue","targetRows","previousSourceIndexesByKey","Map","previousIndex","get","getSynchronizedDataForTranslation","translation","reduce","acc","isConfiguredLanguage","collection","language","Boolean","languages","some","configuredLanguage","code","getDuplicateLanguageIDs","excludeID","group","req","and","fieldNames","equals","push","not_equals","result","payload","find","slug","depth","limit","overrideAccess","where","docs","doc","createTranslatedCollectionBeforeChangeHook","data","operation","originalDoc","nextData","original","groupField","languageField","originalLanguage","originalLanguageIsConfigured","incomingLanguage","defaultLanguage","Error","fallbackGroup","currentID","duplicateIDs","length","createSynchronizedFieldsAfterChangeHook","previousDoc","synchronizedFields","changedFields","translations","Promise","all","translationDoc","synchronizedData","Object","keys","update","createHiddenFields","admin","disableListColumn","hidden","label","meta","components","Field","position","getLanguageColumnName","createLanguageColumnFields","flagLabel","toUpperCase","join","Cell","width","translatedCollectionMeta","getDefaultColumns","existingDefaultColumns","languageColumnName","hiddenMultilangColumns","Set","visibleExistingColumns","column","has","withTranslatedCollection","config","defaultColumns","existingEditViews","views","edit","beforeList","beforeListTable","Component","path","tab","t","order","payloadMultilang","endpoints","hooks","afterChange","beforeChange"],"mappings":"AAQA,SAASA,UAAU,QAAQ,SAAQ;AAInC,SAASC,mBAAmB,QAAQ,kBAAiB;AACrD,SAASC,UAAU,EAAEC,KAAK,EAAEC,cAAc,QAAQ,iBAAgB;AAElE,MAAMC,iBAAiB;IACrBC,IAAI;IACJC,IAAI;AACN;AAEA,MAAMC,qBAAqB;IACzBF,IAAI;IACJC,IAAI;AACN;AASA,MAAME,iBAAiB,CAACC,UACtBA,SAAS,CAACT,oBAAoB,KAAK;AAErC,MAAMU,WAAW,CAACC,QAChB,OAAOA,UAAU,YAAYA,UAAU,QAAQ,CAACC,MAAMC,OAAO,CAACF;AAEhE,MAAMG,UAAU,CAACH,QACfC,MAAMC,OAAO,CAACF,SAASA,MAAMI,MAAM,CAACL,YAAY,EAAE;AAEpD,MAAMM,iBAAiB,CAACC,MAAeC;IACrC,IAAID,SAASC,OAAO;QAClB,OAAO;IACT;IAEA,OAAOC,KAAKC,SAAS,CAACH,UAAUE,KAAKC,SAAS,CAACF;AACjD;AAEA,MAAMG,mBAAmB,CAACC,QACxB,UAAUA,SAAS,OAAOA,MAAMC,IAAI,KAAK,YAAYD,MAAME,IAAI,KAAK;AAEtE,MAAMC,oBAAoB,CAACH;IACzB,MAAMI,SAAShB,SAASY,MAAMI,MAAM,IAAIJ,MAAMI,MAAM,GAAG,CAAC;IACxD,MAAMC,YAAYjB,SAASgB,OAAOC,SAAS,IAAID,OAAOC,SAAS,GAAG,CAAC;IAEnE,OAAOA,UAAUC,WAAW,KAAK;AACnC;AAEA,MAAMC,wBAAwB,CAACC,SAAkB,EAAE,GACjDA,OAAOC,OAAO,CAAC,CAACT;QACd,IAAI,CAACD,iBAAiBC,UAAU,CAACG,kBAAkBH,QAAQ;YACzD,OAAO,EAAE;QACX;QAEA,OAAO;YACL;gBACEC,MAAMD,MAAMC,IAAI;gBAChBC,MAAMF,MAAME,IAAI;gBAChBQ,UAAUV,MAAME,IAAI,KAAK,WAAWF,MAAME,IAAI,KAAK,WAAW,UAAU;YAC1E;SACD;IACH;AAEF,MAAMS,YAAY,CAACC,KAA8BC;IAC/C,MAAMC,KAAKlC,MAAMgC,IAAIE,EAAE;IAEvB,OAAOA,OAAOC,YAAY,CAAC,MAAM,EAAEF,OAAO,GAAG,CAAC,GAAG,EAAEG,OAAOF,KAAK;AACjE;AAEA,MAAMG,oBAAoB,CAAC5B,OAAgBW,QACzCH,KAAKC,SAAS,CACZN,QAAQH,OAAO6B,GAAG,CAAC,CAACN,KAAKC,QAAW,CAAA;YAClCM,WAAWnB,MAAME,IAAI,KAAK,WAAWrB,eAAe+B,IAAIO,SAAS,IAAIJ;YACrEK,WAAWpB,MAAME,IAAI,KAAK,WAAWrB,eAAe+B,IAAIQ,SAAS,IAAIL;YACrEM,KAAKV,UAAUC,KAAKC;QACtB,CAAA;AAGJ,MAAMS,eAAe,CACnBtB,OACAuB,SACAC;IAEA,IAAI,CAAExB,CAAAA,MAAMC,IAAI,IAAIsB,OAAM,GAAI;QAC5B,OAAO;IACT;IAEA,OACEN,kBAAkBM,OAAO,CAACvB,MAAMC,IAAI,CAAC,EAAED,WACvCiB,kBAAkBO,QAAQ,CAACxB,MAAMC,IAAI,CAAC,EAAED;AAE5C;AAEA,MAAMyB,iBAAiB,CACrBC,WACAC,WACA3B;IAEA,MAAMY,MAAMe,YAAY;QAAE,GAAGA,SAAS;IAAC,IAAI,CAAC;IAE5C,IAAI3B,MAAME,IAAI,KAAK,YAAY,eAAewB,WAAW;QACvDd,IAAIQ,SAAS,GAAGM,UAAUN,SAAS;IACrC;IAEA,IAAIpB,MAAME,IAAI,KAAK,UAAU;QAC3B,IAAI,eAAewB,WAAW;YAC5Bd,IAAIO,SAAS,GAAGO,UAAUP,SAAS;QACrC,OAAO;YACL,OAAOP,IAAIO,SAAS;QACtB;IACF;IAEA,OAAOP;AACT;AAEA,MAAMgB,wBAAwB,CAAC,EAC7B5B,KAAK,EACL6B,mBAAmB,EACnBC,WAAW,EACXC,WAAW,EAMZ;IACC,MAAMC,aAAaxC,QAAQuC;IAC3B,MAAME,6BAA6B,IAAIC,IACrC1C,QAAQqC,qBAAqBX,GAAG,CAAC,CAACN,KAAKC,QAAU;YAACF,UAAUC,KAAKC;YAAQA;SAAM;IAGjF,OAAOrB,QAAQsC,aAAaZ,GAAG,CAAC,CAACQ,WAAWb;QAC1C,MAAMsB,gBAAgBF,2BAA2BG,GAAG,CAACzB,UAAUe,WAAWb;QAE1E,OAAOY,eACLC,WACAS,kBAAkBpB,YAAYA,YAAYiB,UAAU,CAACG,cAAc,EACnEnC;IAEJ;AACF;AAEA,MAAMqC,oCAAoC,CAAC,EACzC7B,MAAM,EACNe,OAAO,EACPC,QAAQ,EACRc,WAAW,EAMZ,GACC9B,OAAO+B,MAAM,CAA0B,CAACC,KAAKxC;QAC3C,IAAIA,MAAMU,QAAQ,KAAK,SAAS;YAC9B8B,GAAG,CAACxC,MAAMC,IAAI,CAAC,GAAGsB,OAAO,CAACvB,MAAMC,IAAI,CAAC;YAErC,OAAOuC;QACT;QAEA,MAAMnD,QAAQuC,sBAAsB;YAClC5B;YACA6B,qBAAqBL,QAAQ,CAACxB,MAAMC,IAAI,CAAC;YACzC6B,aAAaP,OAAO,CAACvB,MAAMC,IAAI,CAAC;YAChC8B,aAAaO,WAAW,CAACtC,MAAMC,IAAI,CAAC;QACtC;QAEA,IAAI,CAACP,eAAeL,OAAOiD,WAAW,CAACtC,MAAMC,IAAI,CAAC,GAAG;YACnDuC,GAAG,CAACxC,MAAMC,IAAI,CAAC,GAAGZ;QACpB;QAEA,OAAOmD;IACT,GAAG,CAAC;AAEN,MAAMC,uBAAuB,CAC3BC,YACAC,WAEAC,QACED,YACAD,WAAWG,SAAS,CAACC,IAAI,CAAC,CAACC,qBAAuBA,mBAAmBC,IAAI,KAAKL;AAOlF,MAAMM,0BAA0B,OAAO,EACrCP,UAAU,EACVQ,SAAS,EACTC,KAAK,EACLR,QAAQ,EACRS,GAAG,EAOJ;IACC,MAAMC,MAAe;QACnB;YACE,CAACX,WAAWY,UAAU,CAACH,KAAK,CAAC,EAAE;gBAC7BI,QAAQJ;YACV;QACF;QACA;YACE,CAACT,WAAWY,UAAU,CAACX,QAAQ,CAAC,EAAE;gBAChCY,QAAQZ;YACV;QACF;KACD;IAED,IAAIO,WAAW;QACbG,IAAIG,IAAI,CAAC;YACP1C,IAAI;gBACF2C,YAAYP;YACd;QACF;IACF;IAEA,MAAMQ,SAAS,MAAMN,IAAIO,OAAO,CAACC,IAAI,CAAC;QACpClB,YAAYA,WAAWmB,IAAI;QAC3BC,OAAO;QACPC,OAAO;QACPC,gBAAgB;QAChBZ;QACAa,OAAO;YACLZ;QACF;IACF;IAEA,OAAOK,OAAOQ,IAAI,CACfhD,GAAG,CAAC,CAACiD,MAAQvF,MAAMD,WAAWwF,KAAKrD,EAAE,GACrCrB,MAAM,CAAC,CAACqB,KAA8BA,OAAOC;AAClD;AAEA,OAAO,MAAMqD,6CACX,CAAC,EAAE1B,UAAU,EAA+C,GAC5D,OAAO,EAAEvD,OAAO,EAAEkF,IAAI,EAAEC,SAAS,EAAEC,WAAW,EAAEnB,GAAG,EAAE;QACnD,IAAIlE,eAAeC,UAAU;YAC3B,OAAOkF;QACT;QAEA,MAAMG,WAAW7F,WAAW0F;QAC5B,MAAMI,WAAW9F,WAAW4F;QAC5B,MAAM,EAAEpB,OAAOuB,UAAU,EAAE/B,UAAUgC,aAAa,EAAE,GAAGjC,WAAWY,UAAU;QAC5E,MAAMsB,mBAAmB/F,eAAe4F,QAAQ,CAACE,cAAc;QAC/D,MAAME,+BAA+BpC,qBAAqBC,YAAYkC;QACtE,MAAME,mBAAmBjG,eAAe2F,QAAQ,CAACG,cAAc;QAE/D,IAAIL,cAAc,YAAYM,oBAAoB,CAACC,8BAA8B;YAC/E,IACE,CAACC,oBACDA,qBAAqBF,oBACrB,CAACnC,qBAAqBC,YAAYoC,mBAClC;gBACAN,QAAQ,CAACG,cAAc,GAAG;YAC5B;QACF,OAAO,IAAI,CAACG,kBAAkB;YAC5BN,QAAQ,CAACG,cAAc,GACrBL,cAAc,WACV5B,WAAWqC,eAAe,CAAC/B,IAAI,GAC/B6B,+BACED,mBACA;QACV;QAEA,MAAMjC,WAAW9D,eAAe2F,QAAQ,CAACG,cAAc;QAEvD,IACEL,cAAc,YACdM,oBACAC,gCACAlC,aAAaiC,kBACb;YACA,MAAM,IAAII,MAAM;QAClB;QAEA,IAAIrC,YAAY,CAACF,qBAAqBC,YAAYC,WAAW;YAC3D,MAAM,IAAIqC,MAAM,CAAC,UAAU,EAAErC,SAAS,wBAAwB,EAAED,WAAWmB,IAAI,CAAC,CAAC,CAAC;QACpF;QAEA,IAAI,CAAChF,eAAe2F,QAAQ,CAACE,WAAW,GAAG;YACzC,MAAMO,gBAAgBpG,eAAe4F,QAAQ,CAACC,WAAW;YACzDF,QAAQ,CAACE,WAAW,GAAGO,iBAAiBxG;QAC1C;QAEA,MAAM0E,QAAQtE,eAAe2F,QAAQ,CAACE,WAAW;QAEjD,IAAI/B,YAAYQ,OAAO;YACrB,MAAM+B,YAAYZ,cAAc,WAAW1F,MAAM6F,SAAS3D,EAAE,IAAIC;YAChE,MAAMoE,eAAe,MAAMlC,wBAAwB;gBACjDP;gBACAQ,WAAWgC;gBACX/B;gBACAR;gBACAS;YACF;YAEA,IAAI+B,aAAaC,MAAM,GAAG,GAAG;gBAC3B,MAAM,IAAIJ,MACR,CAAC,EAAE,EAAEtC,WAAWmB,IAAI,CAAC,0CAA0C,EAAElB,SAAS,4BAA4B,CAAC;YAE3G;QACF;QAEA,OAAO6B;IACT,EAAC;AAEH,OAAO,MAAMa,0CACX,CAAC,EACC3C,UAAU,EACVlC,MAAM,EAIP,GACD,OAAO,EAAErB,OAAO,EAAEgF,GAAG,EAAEG,SAAS,EAAEgB,WAAW,EAAElC,GAAG,EAAE;QAClD,MAAMmC,qBAAqBhF,sBAAsBC;QAEjD,IAAItB,eAAeC,YAAYmF,cAAc,YAAYiB,mBAAmBH,MAAM,KAAK,GAAG;YACxF,OAAOjB;QACT;QAEA,MAAM5C,UAAU5C,WAAWwF;QAC3B,MAAM3C,WAAW7C,WAAW2G;QAC5B,MAAMnC,QAAQtE,eAAe0C,OAAO,CAACmB,WAAWY,UAAU,CAACH,KAAK,CAAC;QACjE,MAAM+B,YAAYtG,MAAM2C,QAAQT,EAAE;QAElC,IAAI,CAACqC,SAAS,CAAC+B,WAAW;YACxB,OAAOf;QACT;QAEA,MAAMqB,gBAAgBD,mBAAmB9F,MAAM,CAAC,CAACO;YAC/C,IAAIA,MAAMU,QAAQ,KAAK,SAAS;gBAC9B,OAAOY,aAAatB,OAAOuB,SAASC;YACtC;YAEA,OAAOxB,MAAMC,IAAI,IAAIsB,WAAW,CAAC7B,eAAe6B,OAAO,CAACvB,MAAMC,IAAI,CAAC,EAAEuB,QAAQ,CAACxB,MAAMC,IAAI,CAAC;QAC3F;QAEA,IAAIuF,cAAcJ,MAAM,KAAK,GAAG;YAC9B,OAAOjB;QACT;QAEA,MAAMsB,eAAe,MAAMrC,IAAIO,OAAO,CAACC,IAAI,CAAC;YAC1ClB,YAAYA,WAAWmB,IAAI;YAC3BC,OAAO;YACPC,OAAO;YACPC,gBAAgB;YAChBZ;YACAa,OAAO;gBACLZ,KAAK;oBACH;wBACE,CAACX,WAAWY,UAAU,CAACH,KAAK,CAAC,EAAE;4BAC7BI,QAAQJ;wBACV;oBACF;oBACA;wBACErC,IAAI;4BACF2C,YAAYyB;wBACd;oBACF;iBACD;YACH;QACF;QAEA,MAAMQ,QAAQC,GAAG,CACfF,aAAavB,IAAI,CACdhD,GAAG,CAAC,CAACoB;YACJ,MAAMsD,iBAAiBjH,WAAW2D;YAClC,MAAMxB,KAAKlC,MAAMgH,eAAe9E,EAAE;YAElC,IAAIA,OAAOC,WAAW;gBACpB,OAAOA;YACT;YAEA,MAAM8E,mBAAmBxD,kCAAkC;gBACzD7B,QAAQgF;gBACRjE;gBACAC;gBACAc,aAAasD;YACf;YAEA,IAAIE,OAAOC,IAAI,CAACF,kBAAkBT,MAAM,KAAK,GAAG;gBAC9C,OAAOrE;YACT;YAEA,OAAO;gBACLD;gBACAuD,MAAMwB;YACR;QACF,GACCpG,MAAM,CACL,CAACuG,SACCA,WAAWjF,WAEdG,GAAG,CAAC,CAAC,EAAEJ,EAAE,EAAEuD,IAAI,EAAE,GAChBjB,IAAIO,OAAO,CAACqC,MAAM,CAAC;gBACjBlF;gBACA4B,YAAYA,WAAWmB,IAAI;gBAC3B1E,SAAS;oBACP,CAACT,oBAAoB,EAAE;gBACzB;gBACA2F;gBACAL,gBAAgB;gBAChBZ;YACF;QAIN,OAAOe;IACT,EAAC;AAEH,OAAO,MAAM8B,qBAAqB,CAAC,EACjCvD,UAAU,EAGX,GAAc;QACb;YACEzC,MAAMyC,WAAWY,UAAU,CAACX,QAAQ;YACpCzC,MAAM;YACNgG,OAAO;gBACLC,mBAAmB;gBACnBC,QAAQ;YACV;YACAvF,OAAO;YACPwF,OAAOvH;QACT;QACA;YACEmB,MAAMyC,WAAWY,UAAU,CAACH,KAAK;YACjCjD,MAAM;YACNgG,OAAO;gBACLC,mBAAmB;gBACnBC,QAAQ;YACV;YACAvF,OAAO;YACPwF,OAAOpH;QACT;QACA;YACEgB,MAAMyC,WAAWY,UAAU,CAACgD,IAAI;YAChCpG,MAAM;YACNgG,OAAO;gBACLC,mBAAmB;gBACnBC,QAAQ;YACV;QACF;QACA;YACEnG,MAAM;YACNC,MAAM;YACNgG,OAAO;gBACLK,YAAY;oBACVC,OAAO;gBACT;gBACAC,UAAU;YACZ;QACF;KACD,CAAA;AAED,OAAO,MAAMC,wBAAwB,IAAc,+BAA8B;AAEjF,OAAO,MAAMC,6BAA6B,CAAC,EACzCjE,UAAU,EAGX;IACC,MAAM2D,QAAQ3D,WAAWG,SAAS,CAC/B3B,GAAG,CAAC,CAACyB,WAAaA,SAASiE,SAAS,IAAIjE,SAASK,IAAI,CAAC6D,WAAW,IACjEC,IAAI,CAAC;IAER,OAAO;QACL;YACE7G,MAAMyG;YACNxG,MAAM;YACNgG,OAAO;gBACLK,YAAY;oBACVQ,MAAM;gBACR;gBACAZ,mBAAmB;gBACnBa,OAAO;YACT;YACAX,OAAOA,SAASpH;QAClB;KACD;AACH,EAAC;AAED,OAAO,MAAMgI,2BAA2B,CAAC,EACvCvE,UAAU,EAGX,GAAM,CAAA;QACLqC,iBAAiBrC,WAAWqC,eAAe;QAC3CzB,YAAYZ,WAAWY,UAAU;QACjCT,WAAWH,WAAWG,SAAS;IACjC,CAAA,EAAE;AAEF,MAAMqE,oBAAoB,CAAC,EACzBxE,UAAU,EACVyE,sBAAsB,EACtBC,kBAAkB,EAKnB;IACC,MAAMC,yBAAyB,IAAIC,IAAI;QACrC5E,WAAWY,UAAU,CAACH,KAAK;QAC3BT,WAAWY,UAAU,CAACX,QAAQ;QAC9BD,WAAWY,UAAU,CAACgD,IAAI;QAC1Bc;KACD;IACD,MAAMG,yBAAyBJ,uBAAuB1H,MAAM,CAC1D,CAAC+H,SAAW,CAACH,uBAAuBI,GAAG,CAACD;IAG1C,OAAO;WAAID;QAAwBH;KAAmB;AACxD;AAEA,OAAO,MAAMM,2BAA2B,CAAC,EACvChF,UAAU,EACViF,MAAM,EAIP;IACC,MAAMR,yBAAyBQ,OAAOzB,KAAK,EAAE0B,kBAAkB,EAAE;IACjE,MAAMR,qBAAqBV;IAC3B,MAAMmB,oBACJ,AAACF,OAAOzB,KAAK,EAAEK,YAAYuB,OAAOC,QAAgD,CAAC;IACrF,MAAMH,iBAAiBV,kBAAkB;QACvCxE;QACAyE;QACAC;IACF;IAEA,OAAO;QACL,GAAGO,MAAM;QACTzB,OAAO;YACL,GAAGyB,OAAOzB,KAAK;YACfK,YAAY;gBACV,GAAGoB,OAAOzB,KAAK,EAAEK,UAAU;gBAC3ByB,YAAY;uBACNL,OAAOzB,KAAK,EAAEK,YAAYyB,cAAc,EAAE;oBAC9C;iBACD;gBACDC,iBAAiBN,OAAOzB,KAAK,EAAEK,YAAY0B;gBAC3CH,OAAO;oBACL,GAAGH,OAAOzB,KAAK,EAAEK,YAAYuB,KAAK;oBAClCC,MAAM;wBACJ,GAAGF,iBAAiB;wBACpBpC,cAAc;4BACZyC,WAAW;4BACXC,MAAM;4BACNC,KAAK;gCACH/B,OAAO,CAAC,EAAEgC,CAAC,EAAE,GAAKA,EAAE;gCACpBC,OAAO;4BACT;wBACF;oBACF;gBACF;YACF;YACAlI,QAAQ;gBACN,GAAGuH,OAAOzB,KAAK,EAAE9F,MAAM;gBACvBmI,kBAAkBtB,yBAAyB;oBACzCvE;gBACF;YACF;YACAkF;QACF;QACAY,WAAW;eAAKb,OAAOa,SAAS,IAAI,EAAE;SAAE;QACxChI,QAAQ;eACFmH,OAAOnH,MAAM,IAAI,EAAE;eACpByF,mBAAmB;gBAAEvD;YAAW;eAChCiE,2BAA2B;gBAAEjE;YAAW;SAC5C;QACD+F,OAAO;YACL,GAAGd,OAAOc,KAAK;YACfC,aAAa;gBACXrD,wCAAwC;oBACtC3C;oBACAlC,QAAQmH,OAAOnH,MAAM;gBACvB;mBACImH,OAAOc,KAAK,EAAEC,eAAe,EAAE;aACpC;YACDC,cAAc;gBACZvE,2CAA2C;oBACzC1B;gBACF;mBACIiF,OAAOc,KAAK,EAAEE,gBAAgB,EAAE;aACrC;QACH;IACF;AACF,EAAC"}
@@ -1,3 +1,7 @@
1
+ const LOCALIZED_CONTENT_LABEL = {
2
+ en: 'Localized content',
3
+ uk: 'Локалізований вміст'
4
+ };
1
5
  const withOptionalRequired = (field, required)=>{
2
6
  if (required || !('required' in field)) {
3
7
  return field;
@@ -42,7 +46,7 @@ export const translatedGlobalMeta = ({ global })=>({
42
46
  });
43
47
  export const createGlobalLanguageTabsField = ({ config, global })=>({
44
48
  type: 'tabs',
45
- label: global.label,
49
+ label: global.label === 'Localized content' ? LOCALIZED_CONTENT_LABEL : global.label,
46
50
  tabs: global.languages.map((language)=>({
47
51
  name: language.code,
48
52
  fields: config.fields.map((field)=>cloneField(field, language.code === global.defaultLanguage.code)),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/translatedGlobal.ts"],"sourcesContent":["import type { Field, GlobalConfig, Tab } from 'payload'\n\nimport type { ResolvedMultilangGlobal } from '../types.js'\n\nconst withOptionalRequired = (field: Field, required: boolean): Field => {\n if (required || !('required' in field)) {\n return field\n }\n\n return {\n ...field,\n required: false,\n } as Field\n}\n\nconst cloneField = (field: Field, required: boolean): Field => {\n if (field.type === 'tabs') {\n return withOptionalRequired(\n {\n ...field,\n tabs: field.tabs.map((tab) => ({\n ...tab,\n fields: tab.fields.map((tabField) => cloneField(tabField, required)),\n })),\n },\n required,\n )\n }\n\n if ('fields' in field && Array.isArray(field.fields)) {\n return withOptionalRequired(\n {\n ...field,\n fields: field.fields.map((childField) => cloneField(childField, required)),\n },\n required,\n )\n }\n\n if (field.type === 'blocks') {\n return withOptionalRequired(\n {\n ...field,\n blocks: field.blocks.map((block) => ({\n ...block,\n fields: block.fields.map((blockField) => cloneField(blockField, required)),\n })),\n },\n required,\n )\n }\n\n return withOptionalRequired(\n {\n ...field,\n },\n required,\n )\n}\n\nexport const translatedGlobalMeta = ({\n global,\n}: {\n global: ResolvedMultilangGlobal\n}) => ({\n defaultLanguage: global.defaultLanguage,\n languages: global.languages,\n})\n\nexport const createGlobalLanguageTabsField = ({\n config,\n global,\n}: {\n config: GlobalConfig\n global: ResolvedMultilangGlobal\n}): Field => ({\n type: 'tabs',\n label: global.label,\n tabs: global.languages.map(\n (language): Tab => ({\n name: language.code,\n fields: config.fields.map((field) =>\n cloneField(field, language.code === global.defaultLanguage.code),\n ),\n label: language.flagLabel ? `${language.flagLabel} ${language.name}` : language.name,\n }),\n ),\n})\n\nexport const withTranslatedGlobal = ({\n config,\n global,\n}: {\n config: GlobalConfig\n global: ResolvedMultilangGlobal\n}): GlobalConfig => ({\n ...config,\n admin: {\n ...config.admin,\n custom: {\n ...config.admin?.custom,\n payloadMultilang: translatedGlobalMeta({\n global,\n }),\n },\n },\n fields: [\n createGlobalLanguageTabsField({\n config,\n global,\n }),\n ],\n})\n"],"names":["withOptionalRequired","field","required","cloneField","type","tabs","map","tab","fields","tabField","Array","isArray","childField","blocks","block","blockField","translatedGlobalMeta","global","defaultLanguage","languages","createGlobalLanguageTabsField","config","label","language","name","code","flagLabel","withTranslatedGlobal","admin","custom","payloadMultilang"],"mappings":"AAIA,MAAMA,uBAAuB,CAACC,OAAcC;IAC1C,IAAIA,YAAY,CAAE,CAAA,cAAcD,KAAI,GAAI;QACtC,OAAOA;IACT;IAEA,OAAO;QACL,GAAGA,KAAK;QACRC,UAAU;IACZ;AACF;AAEA,MAAMC,aAAa,CAACF,OAAcC;IAChC,IAAID,MAAMG,IAAI,KAAK,QAAQ;QACzB,OAAOJ,qBACL;YACE,GAAGC,KAAK;YACRI,MAAMJ,MAAMI,IAAI,CAACC,GAAG,CAAC,CAACC,MAAS,CAAA;oBAC7B,GAAGA,GAAG;oBACNC,QAAQD,IAAIC,MAAM,CAACF,GAAG,CAAC,CAACG,WAAaN,WAAWM,UAAUP;gBAC5D,CAAA;QACF,GACAA;IAEJ;IAEA,IAAI,YAAYD,SAASS,MAAMC,OAAO,CAACV,MAAMO,MAAM,GAAG;QACpD,OAAOR,qBACL;YACE,GAAGC,KAAK;YACRO,QAAQP,MAAMO,MAAM,CAACF,GAAG,CAAC,CAACM,aAAeT,WAAWS,YAAYV;QAClE,GACAA;IAEJ;IAEA,IAAID,MAAMG,IAAI,KAAK,UAAU;QAC3B,OAAOJ,qBACL;YACE,GAAGC,KAAK;YACRY,QAAQZ,MAAMY,MAAM,CAACP,GAAG,CAAC,CAACQ,QAAW,CAAA;oBACnC,GAAGA,KAAK;oBACRN,QAAQM,MAAMN,MAAM,CAACF,GAAG,CAAC,CAACS,aAAeZ,WAAWY,YAAYb;gBAClE,CAAA;QACF,GACAA;IAEJ;IAEA,OAAOF,qBACL;QACE,GAAGC,KAAK;IACV,GACAC;AAEJ;AAEA,OAAO,MAAMc,uBAAuB,CAAC,EACnCC,MAAM,EAGP,GAAM,CAAA;QACLC,iBAAiBD,OAAOC,eAAe;QACvCC,WAAWF,OAAOE,SAAS;IAC7B,CAAA,EAAE;AAEF,OAAO,MAAMC,gCAAgC,CAAC,EAC5CC,MAAM,EACNJ,MAAM,EAIP,GAAa,CAAA;QACZb,MAAM;QACNkB,OAAOL,OAAOK,KAAK;QACnBjB,MAAMY,OAAOE,SAAS,CAACb,GAAG,CACxB,CAACiB,WAAmB,CAAA;gBAClBC,MAAMD,SAASE,IAAI;gBACnBjB,QAAQa,OAAOb,MAAM,CAACF,GAAG,CAAC,CAACL,QACzBE,WAAWF,OAAOsB,SAASE,IAAI,KAAKR,OAAOC,eAAe,CAACO,IAAI;gBAEjEH,OAAOC,SAASG,SAAS,GAAG,GAAGH,SAASG,SAAS,CAAC,CAAC,EAAEH,SAASC,IAAI,EAAE,GAAGD,SAASC,IAAI;YACtF,CAAA;IAEJ,CAAA,EAAE;AAEF,OAAO,MAAMG,uBAAuB,CAAC,EACnCN,MAAM,EACNJ,MAAM,EAIP,GAAoB,CAAA;QACnB,GAAGI,MAAM;QACTO,OAAO;YACL,GAAGP,OAAOO,KAAK;YACfC,QAAQ;gBACN,GAAGR,OAAOO,KAAK,EAAEC,MAAM;gBACvBC,kBAAkBd,qBAAqB;oBACrCC;gBACF;YACF;QACF;QACAT,QAAQ;YACNY,8BAA8B;gBAC5BC;gBACAJ;YACF;SACD;IACH,CAAA,EAAE"}
1
+ {"version":3,"sources":["../../src/hooks/translatedGlobal.ts"],"sourcesContent":["import type { Field, GlobalConfig, Tab } from 'payload'\n\nimport type { ResolvedMultilangGlobal } from '../types.js'\n\nconst LOCALIZED_CONTENT_LABEL = {\n en: 'Localized content',\n uk: 'Локалізований вміст',\n}\n\nconst withOptionalRequired = (field: Field, required: boolean): Field => {\n if (required || !('required' in field)) {\n return field\n }\n\n return {\n ...field,\n required: false,\n } as Field\n}\n\nconst cloneField = (field: Field, required: boolean): Field => {\n if (field.type === 'tabs') {\n return withOptionalRequired(\n {\n ...field,\n tabs: field.tabs.map((tab) => ({\n ...tab,\n fields: tab.fields.map((tabField) => cloneField(tabField, required)),\n })),\n },\n required,\n )\n }\n\n if ('fields' in field && Array.isArray(field.fields)) {\n return withOptionalRequired(\n {\n ...field,\n fields: field.fields.map((childField) => cloneField(childField, required)),\n },\n required,\n )\n }\n\n if (field.type === 'blocks') {\n return withOptionalRequired(\n {\n ...field,\n blocks: field.blocks.map((block) => ({\n ...block,\n fields: block.fields.map((blockField) => cloneField(blockField, required)),\n })),\n },\n required,\n )\n }\n\n return withOptionalRequired(\n {\n ...field,\n },\n required,\n )\n}\n\nexport const translatedGlobalMeta = ({\n global,\n}: {\n global: ResolvedMultilangGlobal\n}) => ({\n defaultLanguage: global.defaultLanguage,\n languages: global.languages,\n})\n\nexport const createGlobalLanguageTabsField = ({\n config,\n global,\n}: {\n config: GlobalConfig\n global: ResolvedMultilangGlobal\n}): Field => ({\n type: 'tabs',\n label:\n global.label === 'Localized content'\n ? LOCALIZED_CONTENT_LABEL\n : global.label,\n tabs: global.languages.map(\n (language): Tab => ({\n name: language.code,\n fields: config.fields.map((field) =>\n cloneField(field, language.code === global.defaultLanguage.code),\n ),\n label: language.flagLabel ? `${language.flagLabel} ${language.name}` : language.name,\n }),\n ),\n})\n\nexport const withTranslatedGlobal = ({\n config,\n global,\n}: {\n config: GlobalConfig\n global: ResolvedMultilangGlobal\n}): GlobalConfig => ({\n ...config,\n admin: {\n ...config.admin,\n custom: {\n ...config.admin?.custom,\n payloadMultilang: translatedGlobalMeta({\n global,\n }),\n },\n },\n fields: [\n createGlobalLanguageTabsField({\n config,\n global,\n }),\n ],\n})\n"],"names":["LOCALIZED_CONTENT_LABEL","en","uk","withOptionalRequired","field","required","cloneField","type","tabs","map","tab","fields","tabField","Array","isArray","childField","blocks","block","blockField","translatedGlobalMeta","global","defaultLanguage","languages","createGlobalLanguageTabsField","config","label","language","name","code","flagLabel","withTranslatedGlobal","admin","custom","payloadMultilang"],"mappings":"AAIA,MAAMA,0BAA0B;IAC9BC,IAAI;IACJC,IAAI;AACN;AAEA,MAAMC,uBAAuB,CAACC,OAAcC;IAC1C,IAAIA,YAAY,CAAE,CAAA,cAAcD,KAAI,GAAI;QACtC,OAAOA;IACT;IAEA,OAAO;QACL,GAAGA,KAAK;QACRC,UAAU;IACZ;AACF;AAEA,MAAMC,aAAa,CAACF,OAAcC;IAChC,IAAID,MAAMG,IAAI,KAAK,QAAQ;QACzB,OAAOJ,qBACL;YACE,GAAGC,KAAK;YACRI,MAAMJ,MAAMI,IAAI,CAACC,GAAG,CAAC,CAACC,MAAS,CAAA;oBAC7B,GAAGA,GAAG;oBACNC,QAAQD,IAAIC,MAAM,CAACF,GAAG,CAAC,CAACG,WAAaN,WAAWM,UAAUP;gBAC5D,CAAA;QACF,GACAA;IAEJ;IAEA,IAAI,YAAYD,SAASS,MAAMC,OAAO,CAACV,MAAMO,MAAM,GAAG;QACpD,OAAOR,qBACL;YACE,GAAGC,KAAK;YACRO,QAAQP,MAAMO,MAAM,CAACF,GAAG,CAAC,CAACM,aAAeT,WAAWS,YAAYV;QAClE,GACAA;IAEJ;IAEA,IAAID,MAAMG,IAAI,KAAK,UAAU;QAC3B,OAAOJ,qBACL;YACE,GAAGC,KAAK;YACRY,QAAQZ,MAAMY,MAAM,CAACP,GAAG,CAAC,CAACQ,QAAW,CAAA;oBACnC,GAAGA,KAAK;oBACRN,QAAQM,MAAMN,MAAM,CAACF,GAAG,CAAC,CAACS,aAAeZ,WAAWY,YAAYb;gBAClE,CAAA;QACF,GACAA;IAEJ;IAEA,OAAOF,qBACL;QACE,GAAGC,KAAK;IACV,GACAC;AAEJ;AAEA,OAAO,MAAMc,uBAAuB,CAAC,EACnCC,MAAM,EAGP,GAAM,CAAA;QACLC,iBAAiBD,OAAOC,eAAe;QACvCC,WAAWF,OAAOE,SAAS;IAC7B,CAAA,EAAE;AAEF,OAAO,MAAMC,gCAAgC,CAAC,EAC5CC,MAAM,EACNJ,MAAM,EAIP,GAAa,CAAA;QACZb,MAAM;QACNkB,OACEL,OAAOK,KAAK,KAAK,sBACbzB,0BACAoB,OAAOK,KAAK;QAClBjB,MAAMY,OAAOE,SAAS,CAACb,GAAG,CACxB,CAACiB,WAAmB,CAAA;gBAClBC,MAAMD,SAASE,IAAI;gBACnBjB,QAAQa,OAAOb,MAAM,CAACF,GAAG,CAAC,CAACL,QACzBE,WAAWF,OAAOsB,SAASE,IAAI,KAAKR,OAAOC,eAAe,CAACO,IAAI;gBAEjEH,OAAOC,SAASG,SAAS,GAAG,GAAGH,SAASG,SAAS,CAAC,CAAC,EAAEH,SAASC,IAAI,EAAE,GAAGD,SAASC,IAAI;YACtF,CAAA;IAEJ,CAAA,EAAE;AAEF,OAAO,MAAMG,uBAAuB,CAAC,EACnCN,MAAM,EACNJ,MAAM,EAIP,GAAoB,CAAA;QACnB,GAAGI,MAAM;QACTO,OAAO;YACL,GAAGP,OAAOO,KAAK;YACfC,QAAQ;gBACN,GAAGR,OAAOO,KAAK,EAAEC,MAAM;gBACvBC,kBAAkBd,qBAAqB;oBACrCC;gBACF;YACF;QACF;QACAT,QAAQ;YACNY,8BAA8B;gBAC5BC;gBACAJ;YACF;SACD;IACH,CAAA,EAAE"}
package/dist/index.d.ts CHANGED
@@ -3,5 +3,6 @@ import type { PayloadMultilangConfig } from './types.js';
3
3
  export { DEFAULT_FIELD_NAMES, MULTILANG_GROUP_FIELD, MULTILANG_LANGUAGE_FIELD, MULTILANG_META_FIELD, } from './constants.js';
4
4
  export { createMultilangHelpers, findGlobalByLanguageWithPayload, getDocumentTranslationsWithPayload, getDocumentTranslationWithPayload, getGroupTranslationsWithPayload, getMultilangDocumentLanguage, localizedSlugQuery, updateGlobalByLanguageWithPayload, withLanguage, } from './lib/data.js';
5
5
  export type { FindGlobalByLanguageArgs, GetDocumentTranslationArgs, GetDocumentTranslationsArgs, LocalizedSlugQuery, LocalizedSlugQueryArgs, LocalizedSlugQueryStatus, MultilangDocumentLanguageArgs, MultilangHelpers, PayloadFactory, UpdateGlobalByLanguageArgs, } from './lib/data.js';
6
+ export { type PayloadMultilangTranslationKey, payloadMultilangTranslations, type PayloadMultilangTranslations, } from './translations.js';
6
7
  export type { MultilangCollectionOptions, MultilangFieldNames, MultilangGlobalOptions, MultilangLanguage, PayloadMultilangConfig, ResolvedMultilangGlobal, TranslationMap, TranslationState, } from './types.js';
7
8
  export declare const payloadMultilang: (pluginOptions?: PayloadMultilangConfig) => Plugin;
package/dist/index.js CHANGED
@@ -2,8 +2,28 @@ import { createTranslationEndpoints } from './endpoints/translations.js';
2
2
  import { withTranslatedCollection } from './hooks/translatedCollection.js';
3
3
  import { withTranslatedGlobal } from './hooks/translatedGlobal.js';
4
4
  import { getCollectionConfig, getGlobalConfig, sanitizePluginConfig } from './lib/config.js';
5
+ import { payloadMultilangTranslations } from './translations.js';
5
6
  export { DEFAULT_FIELD_NAMES, MULTILANG_GROUP_FIELD, MULTILANG_LANGUAGE_FIELD, MULTILANG_META_FIELD } from './constants.js';
6
7
  export { createMultilangHelpers, findGlobalByLanguageWithPayload, getDocumentTranslationsWithPayload, getDocumentTranslationWithPayload, getGroupTranslationsWithPayload, getMultilangDocumentLanguage, localizedSlugQuery, updateGlobalByLanguageWithPayload, withLanguage } from './lib/data.js';
8
+ export { payloadMultilangTranslations } from './translations.js';
9
+ const isRecord = (value)=>Boolean(value) && typeof value === 'object' && !Array.isArray(value);
10
+ const mergeTranslations = (base, override)=>{
11
+ const output = {
12
+ ...base
13
+ };
14
+ Object.entries(override).forEach(([key, value])=>{
15
+ const existing = output[key];
16
+ output[key] = isRecord(existing) && isRecord(value) ? mergeTranslations(existing, value) : value;
17
+ });
18
+ return output;
19
+ };
20
+ const withPluginTranslations = (config)=>({
21
+ ...config,
22
+ i18n: {
23
+ ...config.i18n,
24
+ translations: mergeTranslations(payloadMultilangTranslations, config.i18n?.translations || {})
25
+ }
26
+ });
7
27
  export const payloadMultilang = (pluginOptions = {
8
28
  languages: []
9
29
  })=>(config)=>{
@@ -46,7 +66,7 @@ export const payloadMultilang = (pluginOptions = {
46
66
  global: translatedGlobal
47
67
  });
48
68
  });
49
- return {
69
+ return withPluginTranslations({
50
70
  ...config,
51
71
  admin: {
52
72
  ...config.admin,
@@ -61,7 +81,7 @@ export const payloadMultilang = (pluginOptions = {
61
81
  },
62
82
  collections,
63
83
  globals
64
- };
84
+ });
65
85
  };
66
86
 
67
87
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config, GlobalConfig, Plugin } from 'payload'\n\nimport type { PayloadMultilangConfig } from './types.js'\n\nimport { createTranslationEndpoints } from './endpoints/translations.js'\nimport { withTranslatedCollection } from './hooks/translatedCollection.js'\nimport { withTranslatedGlobal } from './hooks/translatedGlobal.js'\nimport {\n getCollectionConfig,\n getGlobalConfig,\n sanitizePluginConfig,\n} from './lib/config.js'\n\nexport {\n DEFAULT_FIELD_NAMES,\n MULTILANG_GROUP_FIELD,\n MULTILANG_LANGUAGE_FIELD,\n MULTILANG_META_FIELD,\n} from './constants.js'\n\nexport {\n createMultilangHelpers,\n findGlobalByLanguageWithPayload,\n getDocumentTranslationsWithPayload,\n getDocumentTranslationWithPayload,\n getGroupTranslationsWithPayload,\n getMultilangDocumentLanguage,\n localizedSlugQuery,\n updateGlobalByLanguageWithPayload,\n withLanguage,\n} from './lib/data.js'\n\nexport type {\n FindGlobalByLanguageArgs,\n GetDocumentTranslationArgs,\n GetDocumentTranslationsArgs,\n LocalizedSlugQuery,\n LocalizedSlugQueryArgs,\n LocalizedSlugQueryStatus,\n MultilangDocumentLanguageArgs,\n MultilangHelpers,\n PayloadFactory,\n UpdateGlobalByLanguageArgs,\n} from './lib/data.js'\n\nexport type {\n MultilangCollectionOptions,\n MultilangFieldNames,\n MultilangGlobalOptions,\n MultilangLanguage,\n PayloadMultilangConfig,\n ResolvedMultilangGlobal,\n TranslationMap,\n TranslationState,\n} from './types.js'\n\nexport const payloadMultilang =\n (pluginOptions: PayloadMultilangConfig = { languages: [] }): Plugin =>\n (config: Config): Config => {\n if (pluginOptions.disabled) {\n return config\n }\n\n if (config.localization) {\n throw new Error(\n 'payload-multilang uses per-language documents and cannot run with Payload built-in localization enabled. Set localization: false and do not use localized: true fields for this plugin model.',\n )\n }\n\n const pluginConfig = sanitizePluginConfig(pluginOptions)\n\n const incomingCollections = config.collections || []\n const collections = incomingCollections.map(\n (collection): CollectionConfig => {\n const translatedCollection = getCollectionConfig(\n pluginConfig.collections,\n collection.slug,\n )\n\n if (!translatedCollection) {\n return collection\n }\n\n const translated = withTranslatedCollection({\n collection: translatedCollection,\n config: collection,\n })\n\n return {\n ...translated,\n endpoints: [\n ...(translated.endpoints || []),\n ...createTranslationEndpoints({\n collection: translatedCollection,\n collectionConfig: collection,\n }),\n ],\n }\n },\n )\n\n const incomingGlobals = config.globals || []\n const globals = incomingGlobals.map((globalConfig): GlobalConfig => {\n const translatedGlobal = getGlobalConfig(\n pluginConfig.globals,\n globalConfig.slug,\n )\n\n if (!translatedGlobal) {\n return globalConfig\n }\n\n return withTranslatedGlobal({\n config: globalConfig,\n global: translatedGlobal,\n })\n })\n\n return {\n ...config,\n admin: {\n ...config.admin,\n custom: {\n ...config.admin?.custom,\n payloadMultilang: {\n ...((config.admin?.custom as\n | { payloadMultilang?: Record<string, unknown> }\n | undefined)?.payloadMultilang || {}),\n defaultLanguage: pluginConfig.defaultLanguage,\n languages: pluginConfig.languages,\n },\n },\n },\n collections,\n globals,\n }\n }\n"],"names":["createTranslationEndpoints","withTranslatedCollection","withTranslatedGlobal","getCollectionConfig","getGlobalConfig","sanitizePluginConfig","DEFAULT_FIELD_NAMES","MULTILANG_GROUP_FIELD","MULTILANG_LANGUAGE_FIELD","MULTILANG_META_FIELD","createMultilangHelpers","findGlobalByLanguageWithPayload","getDocumentTranslationsWithPayload","getDocumentTranslationWithPayload","getGroupTranslationsWithPayload","getMultilangDocumentLanguage","localizedSlugQuery","updateGlobalByLanguageWithPayload","withLanguage","payloadMultilang","pluginOptions","languages","config","disabled","localization","Error","pluginConfig","incomingCollections","collections","map","collection","translatedCollection","slug","translated","endpoints","collectionConfig","incomingGlobals","globals","globalConfig","translatedGlobal","global","admin","custom","defaultLanguage"],"mappings":"AAIA,SAASA,0BAA0B,QAAQ,8BAA6B;AACxE,SAASC,wBAAwB,QAAQ,kCAAiC;AAC1E,SAASC,oBAAoB,QAAQ,8BAA6B;AAClE,SACEC,mBAAmB,EACnBC,eAAe,EACfC,oBAAoB,QACf,kBAAiB;AAExB,SACEC,mBAAmB,EACnBC,qBAAqB,EACrBC,wBAAwB,EACxBC,oBAAoB,QACf,iBAAgB;AAEvB,SACEC,sBAAsB,EACtBC,+BAA+B,EAC/BC,kCAAkC,EAClCC,iCAAiC,EACjCC,+BAA+B,EAC/BC,4BAA4B,EAC5BC,kBAAkB,EAClBC,iCAAiC,EACjCC,YAAY,QACP,gBAAe;AA0BtB,OAAO,MAAMC,mBACX,CAACC,gBAAwC;IAAEC,WAAW,EAAE;AAAC,CAAC,GAC1D,CAACC;QACC,IAAIF,cAAcG,QAAQ,EAAE;YAC1B,OAAOD;QACT;QAEA,IAAIA,OAAOE,YAAY,EAAE;YACvB,MAAM,IAAIC,MACR;QAEJ;QAEA,MAAMC,eAAerB,qBAAqBe;QAE1C,MAAMO,sBAAsBL,OAAOM,WAAW,IAAI,EAAE;QACpD,MAAMA,cAAcD,oBAAoBE,GAAG,CACzC,CAACC;YACC,MAAMC,uBAAuB5B,oBAC3BuB,aAAaE,WAAW,EACxBE,WAAWE,IAAI;YAGjB,IAAI,CAACD,sBAAsB;gBACzB,OAAOD;YACT;YAEA,MAAMG,aAAahC,yBAAyB;gBAC1C6B,YAAYC;gBACZT,QAAQQ;YACV;YAEA,OAAO;gBACL,GAAGG,UAAU;gBACbC,WAAW;uBACLD,WAAWC,SAAS,IAAI,EAAE;uBAC3BlC,2BAA2B;wBAC5B8B,YAAYC;wBACZI,kBAAkBL;oBACpB;iBACD;YACH;QACF;QAGF,MAAMM,kBAAkBd,OAAOe,OAAO,IAAI,EAAE;QAC5C,MAAMA,UAAUD,gBAAgBP,GAAG,CAAC,CAACS;YACnC,MAAMC,mBAAmBnC,gBACvBsB,aAAaW,OAAO,EACpBC,aAAaN,IAAI;YAGnB,IAAI,CAACO,kBAAkB;gBACrB,OAAOD;YACT;YAEA,OAAOpC,qBAAqB;gBAC1BoB,QAAQgB;gBACRE,QAAQD;YACV;QACF;QAEA,OAAO;YACL,GAAGjB,MAAM;YACTmB,OAAO;gBACL,GAAGnB,OAAOmB,KAAK;gBACfC,QAAQ;oBACN,GAAGpB,OAAOmB,KAAK,EAAEC,MAAM;oBACvBvB,kBAAkB;wBAChB,GAAI,AAACG,OAAOmB,KAAK,EAAEC,QAEHvB,oBAAoB,CAAC,CAAC;wBACtCwB,iBAAiBjB,aAAaiB,eAAe;wBAC7CtB,WAAWK,aAAaL,SAAS;oBACnC;gBACF;YACF;YACAO;YACAS;QACF;IACF,EAAC"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionConfig, Config, GlobalConfig, Plugin } from 'payload'\n\nimport type { PayloadMultilangConfig } from './types.js'\n\nimport { createTranslationEndpoints } from './endpoints/translations.js'\nimport { withTranslatedCollection } from './hooks/translatedCollection.js'\nimport { withTranslatedGlobal } from './hooks/translatedGlobal.js'\nimport {\n getCollectionConfig,\n getGlobalConfig,\n sanitizePluginConfig,\n} from './lib/config.js'\nimport { payloadMultilangTranslations } from './translations.js'\n\nexport {\n DEFAULT_FIELD_NAMES,\n MULTILANG_GROUP_FIELD,\n MULTILANG_LANGUAGE_FIELD,\n MULTILANG_META_FIELD,\n} from './constants.js'\n\nexport {\n createMultilangHelpers,\n findGlobalByLanguageWithPayload,\n getDocumentTranslationsWithPayload,\n getDocumentTranslationWithPayload,\n getGroupTranslationsWithPayload,\n getMultilangDocumentLanguage,\n localizedSlugQuery,\n updateGlobalByLanguageWithPayload,\n withLanguage,\n} from './lib/data.js'\n\nexport type {\n FindGlobalByLanguageArgs,\n GetDocumentTranslationArgs,\n GetDocumentTranslationsArgs,\n LocalizedSlugQuery,\n LocalizedSlugQueryArgs,\n LocalizedSlugQueryStatus,\n MultilangDocumentLanguageArgs,\n MultilangHelpers,\n PayloadFactory,\n UpdateGlobalByLanguageArgs,\n} from './lib/data.js'\n\nexport {\n type PayloadMultilangTranslationKey,\n payloadMultilangTranslations,\n type PayloadMultilangTranslations,\n} from './translations.js'\n\nexport type {\n MultilangCollectionOptions,\n MultilangFieldNames,\n MultilangGlobalOptions,\n MultilangLanguage,\n PayloadMultilangConfig,\n ResolvedMultilangGlobal,\n TranslationMap,\n TranslationState,\n} from './types.js'\n\ntype TranslationRecord = Record<string, unknown>\n\nconst isRecord = (value: unknown): value is TranslationRecord =>\n Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n\nconst mergeTranslations = (\n base: TranslationRecord,\n override: TranslationRecord,\n): TranslationRecord => {\n const output: TranslationRecord = { ...base }\n\n Object.entries(override).forEach(([key, value]) => {\n const existing = output[key]\n\n output[key] =\n isRecord(existing) && isRecord(value)\n ? mergeTranslations(existing, value)\n : value\n })\n\n return output\n}\n\nconst withPluginTranslations = (config: Config): Config => ({\n ...config,\n i18n: {\n ...config.i18n,\n translations: mergeTranslations(\n payloadMultilangTranslations,\n (config.i18n?.translations || {}) as TranslationRecord,\n ) as NonNullable<Config['i18n']>['translations'],\n },\n})\n\nexport const payloadMultilang =\n (pluginOptions: PayloadMultilangConfig = { languages: [] }): Plugin =>\n (config: Config): Config => {\n if (pluginOptions.disabled) {\n return config\n }\n\n if (config.localization) {\n throw new Error(\n 'payload-multilang uses per-language documents and cannot run with Payload built-in localization enabled. Set localization: false and do not use localized: true fields for this plugin model.',\n )\n }\n\n const pluginConfig = sanitizePluginConfig(pluginOptions)\n\n const incomingCollections = config.collections || []\n const collections = incomingCollections.map(\n (collection): CollectionConfig => {\n const translatedCollection = getCollectionConfig(\n pluginConfig.collections,\n collection.slug,\n )\n\n if (!translatedCollection) {\n return collection\n }\n\n const translated = withTranslatedCollection({\n collection: translatedCollection,\n config: collection,\n })\n\n return {\n ...translated,\n endpoints: [\n ...(translated.endpoints || []),\n ...createTranslationEndpoints({\n collection: translatedCollection,\n collectionConfig: collection,\n }),\n ],\n }\n },\n )\n\n const incomingGlobals = config.globals || []\n const globals = incomingGlobals.map((globalConfig): GlobalConfig => {\n const translatedGlobal = getGlobalConfig(\n pluginConfig.globals,\n globalConfig.slug,\n )\n\n if (!translatedGlobal) {\n return globalConfig\n }\n\n return withTranslatedGlobal({\n config: globalConfig,\n global: translatedGlobal,\n })\n })\n\n return withPluginTranslations({\n ...config,\n admin: {\n ...config.admin,\n custom: {\n ...config.admin?.custom,\n payloadMultilang: {\n ...((config.admin?.custom as\n | { payloadMultilang?: Record<string, unknown> }\n | undefined)?.payloadMultilang || {}),\n defaultLanguage: pluginConfig.defaultLanguage,\n languages: pluginConfig.languages,\n },\n },\n },\n collections,\n globals,\n })\n }\n"],"names":["createTranslationEndpoints","withTranslatedCollection","withTranslatedGlobal","getCollectionConfig","getGlobalConfig","sanitizePluginConfig","payloadMultilangTranslations","DEFAULT_FIELD_NAMES","MULTILANG_GROUP_FIELD","MULTILANG_LANGUAGE_FIELD","MULTILANG_META_FIELD","createMultilangHelpers","findGlobalByLanguageWithPayload","getDocumentTranslationsWithPayload","getDocumentTranslationWithPayload","getGroupTranslationsWithPayload","getMultilangDocumentLanguage","localizedSlugQuery","updateGlobalByLanguageWithPayload","withLanguage","isRecord","value","Boolean","Array","isArray","mergeTranslations","base","override","output","Object","entries","forEach","key","existing","withPluginTranslations","config","i18n","translations","payloadMultilang","pluginOptions","languages","disabled","localization","Error","pluginConfig","incomingCollections","collections","map","collection","translatedCollection","slug","translated","endpoints","collectionConfig","incomingGlobals","globals","globalConfig","translatedGlobal","global","admin","custom","defaultLanguage"],"mappings":"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"}
@@ -1,10 +1,9 @@
1
- import { DEFAULT_DUPLICATE_EXCLUDE_FIELDS, DEFAULT_FIELD_NAMES, DEFAULT_GLOBAL_TABS_LABEL } from '../constants.js';
1
+ import { DEFAULT_FIELD_NAMES, DEFAULT_GLOBAL_TABS_LABEL } from '../constants.js';
2
2
  export const resolveFieldNames = (pluginFieldNames, collectionFieldNames)=>({
3
3
  ...DEFAULT_FIELD_NAMES,
4
4
  ...pluginFieldNames || {},
5
5
  ...collectionFieldNames || {}
6
6
  });
7
- const uniqueStrings = (...values)=>Array.from(new Set(values.flatMap((value)=>(value || []).map((field)=>field.trim()).filter(Boolean))));
8
7
  export const sanitizePluginConfig = (pluginOptions)=>{
9
8
  const languages = normalizeConfiguredLanguages(pluginOptions.languages || []);
10
9
  const defaultLanguage = languages.find((language)=>language.isDefault);
@@ -20,15 +19,8 @@ export const sanitizePluginConfig = (pluginOptions)=>{
20
19
  {
21
20
  slug,
22
21
  defaultLanguage,
23
- duplicate: collectionOptions.duplicate ?? true,
24
- duplicateExcludeFields: [
25
- ...DEFAULT_DUPLICATE_EXCLUDE_FIELDS,
26
- ...pluginOptions.duplicateExcludeFields || [],
27
- ...collectionOptions.duplicateExcludeFields || []
28
- ],
29
22
  fieldNames: resolveFieldNames(pluginOptions.fieldNames, collectionOptions.fields),
30
- languages,
31
- synchronizedFields: uniqueStrings(collectionOptions.synchronizedFields)
23
+ languages
32
24
  }
33
25
  ];
34
26
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/config.ts"],"sourcesContent":["import type {\n MultilangCollectionOptions,\n MultilangFieldNames,\n MultilangGlobalOptions,\n MultilangLanguage,\n PayloadMultilangConfig,\n ResolvedMultilangCollection,\n ResolvedMultilangGlobal,\n} from '../types.js'\n\nimport {\n DEFAULT_DUPLICATE_EXCLUDE_FIELDS,\n DEFAULT_FIELD_NAMES,\n DEFAULT_GLOBAL_TABS_LABEL,\n} from '../constants.js'\n\nexport type SanitizedPluginConfig = {\n collections: ResolvedMultilangCollection[]\n defaultLanguage: MultilangLanguage\n disabled: boolean\n globals: ResolvedMultilangGlobal[]\n languages: MultilangLanguage[]\n raw: PayloadMultilangConfig\n}\n\nexport const resolveFieldNames = (\n pluginFieldNames?: Partial<MultilangFieldNames>,\n collectionFieldNames?: Partial<MultilangFieldNames>,\n): MultilangFieldNames => ({\n ...DEFAULT_FIELD_NAMES,\n ...(pluginFieldNames || {}),\n ...(collectionFieldNames || {}),\n})\n\nconst uniqueStrings = (...values: Array<string[] | undefined>): string[] =>\n Array.from(\n new Set(\n values.flatMap((value) =>\n (value || []).map((field) => field.trim()).filter(Boolean),\n ),\n ),\n )\n\nexport const sanitizePluginConfig = (\n pluginOptions: PayloadMultilangConfig,\n): SanitizedPluginConfig => {\n const languages = normalizeConfiguredLanguages(pluginOptions.languages || [])\n const defaultLanguage = languages.find((language) => language.isDefault)\n\n if (!defaultLanguage) {\n throw new Error('payload-multilang requires one active default language.')\n }\n\n const collections = Object.entries(pluginOptions.collections || {}).flatMap(\n ([slug, value]) => {\n if (!value) {\n return []\n }\n\n const collectionOptions: MultilangCollectionOptions =\n value === true ? {} : value\n\n return [\n {\n slug,\n defaultLanguage,\n duplicate: collectionOptions.duplicate ?? true,\n duplicateExcludeFields: [\n ...DEFAULT_DUPLICATE_EXCLUDE_FIELDS,\n ...(pluginOptions.duplicateExcludeFields || []),\n ...(collectionOptions.duplicateExcludeFields || []),\n ],\n fieldNames: resolveFieldNames(\n pluginOptions.fieldNames,\n collectionOptions.fields,\n ),\n languages,\n synchronizedFields: uniqueStrings(collectionOptions.synchronizedFields),\n },\n ]\n },\n )\n\n const globals = Object.entries(pluginOptions.globals || {}).flatMap(\n ([slug, value]) => {\n if (!value) {\n return []\n }\n\n const globalOptions: MultilangGlobalOptions = value === true ? {} : value\n\n return [\n {\n slug,\n defaultLanguage,\n label: globalOptions.label?.trim() || DEFAULT_GLOBAL_TABS_LABEL,\n languages,\n },\n ]\n },\n )\n\n return {\n collections,\n defaultLanguage,\n disabled: Boolean(pluginOptions.disabled),\n globals,\n languages,\n raw: pluginOptions,\n }\n}\n\nexport const getCollectionConfig = (\n collections: ResolvedMultilangCollection[],\n slug: string,\n): ResolvedMultilangCollection | undefined =>\n collections.find((collection) => collection.slug === slug)\n\nexport const getGlobalConfig = (\n globals: ResolvedMultilangGlobal[],\n slug: string,\n): ResolvedMultilangGlobal | undefined =>\n globals.find((global) => global.slug === slug)\n\nexport const normalizeConfiguredLanguages = (\n languages: MultilangLanguage[],\n): MultilangLanguage[] => {\n const seen = new Set<string>()\n const normalized = languages.map((language, index): MultilangLanguage => {\n const code = language.code.trim().toLowerCase()\n\n if (!code) {\n throw new Error(`payload-multilang language at index ${index} is missing a code.`)\n }\n\n if (seen.has(code)) {\n throw new Error(`payload-multilang language code \"${code}\" is duplicated.`)\n }\n\n seen.add(code)\n\n return {\n id: language.id,\n name: language.name?.trim() || code,\n active: language.active !== false,\n code,\n direction: language.direction === 'rtl' ? 'rtl' : 'ltr',\n flagLabel: language.flagLabel?.trim(),\n isDefault: language.isDefault === true,\n locale: language.locale?.trim(),\n order: typeof language.order === 'number' ? language.order : 0,\n }\n })\n\n const activeDefaults = normalized.filter(\n (language) => language.active !== false && language.isDefault,\n )\n\n if (activeDefaults.length !== 1) {\n throw new Error('payload-multilang requires exactly one active default language.')\n }\n\n return normalized.sort((a, b) => {\n const order = (a.order || 0) - (b.order || 0)\n\n if (order !== 0) {\n return order\n }\n\n return a.code.localeCompare(b.code)\n })\n}\n"],"names":["DEFAULT_DUPLICATE_EXCLUDE_FIELDS","DEFAULT_FIELD_NAMES","DEFAULT_GLOBAL_TABS_LABEL","resolveFieldNames","pluginFieldNames","collectionFieldNames","uniqueStrings","values","Array","from","Set","flatMap","value","map","field","trim","filter","Boolean","sanitizePluginConfig","pluginOptions","languages","normalizeConfiguredLanguages","defaultLanguage","find","language","isDefault","Error","collections","Object","entries","slug","collectionOptions","duplicate","duplicateExcludeFields","fieldNames","fields","synchronizedFields","globals","globalOptions","label","disabled","raw","getCollectionConfig","collection","getGlobalConfig","global","seen","normalized","index","code","toLowerCase","has","add","id","name","active","direction","flagLabel","locale","order","activeDefaults","length","sort","a","b","localeCompare"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/config.ts"],"sourcesContent":["import type {\n MultilangCollectionOptions,\n MultilangFieldNames,\n MultilangGlobalOptions,\n MultilangLanguage,\n PayloadMultilangConfig,\n ResolvedMultilangCollection,\n ResolvedMultilangGlobal,\n} from '../types.js'\n\nimport { DEFAULT_FIELD_NAMES, DEFAULT_GLOBAL_TABS_LABEL } from '../constants.js'\n\nexport type SanitizedPluginConfig = {\n collections: ResolvedMultilangCollection[]\n defaultLanguage: MultilangLanguage\n disabled: boolean\n globals: ResolvedMultilangGlobal[]\n languages: MultilangLanguage[]\n raw: PayloadMultilangConfig\n}\n\nexport const resolveFieldNames = (\n pluginFieldNames?: Partial<MultilangFieldNames>,\n collectionFieldNames?: Partial<MultilangFieldNames>,\n): MultilangFieldNames => ({\n ...DEFAULT_FIELD_NAMES,\n ...(pluginFieldNames || {}),\n ...(collectionFieldNames || {}),\n})\n\nexport const sanitizePluginConfig = (\n pluginOptions: PayloadMultilangConfig,\n): SanitizedPluginConfig => {\n const languages = normalizeConfiguredLanguages(pluginOptions.languages || [])\n const defaultLanguage = languages.find((language) => language.isDefault)\n\n if (!defaultLanguage) {\n throw new Error('payload-multilang requires one active default language.')\n }\n\n const collections = Object.entries(pluginOptions.collections || {}).flatMap(\n ([slug, value]) => {\n if (!value) {\n return []\n }\n\n const collectionOptions: MultilangCollectionOptions =\n value === true ? {} : value\n\n return [\n {\n slug,\n defaultLanguage,\n fieldNames: resolveFieldNames(\n pluginOptions.fieldNames,\n collectionOptions.fields,\n ),\n languages,\n },\n ]\n },\n )\n\n const globals = Object.entries(pluginOptions.globals || {}).flatMap(\n ([slug, value]) => {\n if (!value) {\n return []\n }\n\n const globalOptions: MultilangGlobalOptions = value === true ? {} : value\n\n return [\n {\n slug,\n defaultLanguage,\n label: globalOptions.label?.trim() || DEFAULT_GLOBAL_TABS_LABEL,\n languages,\n },\n ]\n },\n )\n\n return {\n collections,\n defaultLanguage,\n disabled: Boolean(pluginOptions.disabled),\n globals,\n languages,\n raw: pluginOptions,\n }\n}\n\nexport const getCollectionConfig = (\n collections: ResolvedMultilangCollection[],\n slug: string,\n): ResolvedMultilangCollection | undefined =>\n collections.find((collection) => collection.slug === slug)\n\nexport const getGlobalConfig = (\n globals: ResolvedMultilangGlobal[],\n slug: string,\n): ResolvedMultilangGlobal | undefined =>\n globals.find((global) => global.slug === slug)\n\nexport const normalizeConfiguredLanguages = (\n languages: MultilangLanguage[],\n): MultilangLanguage[] => {\n const seen = new Set<string>()\n const normalized = languages.map((language, index): MultilangLanguage => {\n const code = language.code.trim().toLowerCase()\n\n if (!code) {\n throw new Error(`payload-multilang language at index ${index} is missing a code.`)\n }\n\n if (seen.has(code)) {\n throw new Error(`payload-multilang language code \"${code}\" is duplicated.`)\n }\n\n seen.add(code)\n\n return {\n id: language.id,\n name: language.name?.trim() || code,\n active: language.active !== false,\n code,\n direction: language.direction === 'rtl' ? 'rtl' : 'ltr',\n flagLabel: language.flagLabel?.trim(),\n isDefault: language.isDefault === true,\n locale: language.locale?.trim(),\n order: typeof language.order === 'number' ? language.order : 0,\n }\n })\n\n const activeDefaults = normalized.filter(\n (language) => language.active !== false && language.isDefault,\n )\n\n if (activeDefaults.length !== 1) {\n throw new Error('payload-multilang requires exactly one active default language.')\n }\n\n return normalized.sort((a, b) => {\n const order = (a.order || 0) - (b.order || 0)\n\n if (order !== 0) {\n return order\n }\n\n return a.code.localeCompare(b.code)\n })\n}\n"],"names":["DEFAULT_FIELD_NAMES","DEFAULT_GLOBAL_TABS_LABEL","resolveFieldNames","pluginFieldNames","collectionFieldNames","sanitizePluginConfig","pluginOptions","languages","normalizeConfiguredLanguages","defaultLanguage","find","language","isDefault","Error","collections","Object","entries","flatMap","slug","value","collectionOptions","fieldNames","fields","globals","globalOptions","label","trim","disabled","Boolean","raw","getCollectionConfig","collection","getGlobalConfig","global","seen","Set","normalized","map","index","code","toLowerCase","has","add","id","name","active","direction","flagLabel","locale","order","activeDefaults","filter","length","sort","a","b","localeCompare"],"mappings":"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"}
@@ -104,10 +104,9 @@ export declare const updateGlobalByLanguageWithPayload: <TDoc extends DocumentDa
104
104
  req?: PayloadRequest;
105
105
  slug: GlobalSlug;
106
106
  }) => Promise<TDoc>;
107
- export declare const duplicateDocumentData: ({ collection, doc, duplicateExcludeFields, fieldNames, targetLanguage, }: {
107
+ export declare const duplicateDocumentData: ({ collection, doc, fieldNames, targetLanguage, }: {
108
108
  collection: CollectionConfig;
109
109
  doc: DocumentData;
110
- duplicateExcludeFields: string[];
111
110
  fieldNames: MultilangFieldNames;
112
111
  targetLanguage: string;
113
112
  }) => DocumentData;
package/dist/lib/data.js CHANGED
@@ -1,4 +1,4 @@
1
- import { DEFAULT_FIELD_NAMES } from '../constants.js';
1
+ import { DEFAULT_FIELD_NAMES, SYSTEM_DUPLICATION_EXCLUDED_FIELDS } from '../constants.js';
2
2
  export const asDocument = (value)=>value && typeof value === 'object' ? value : {};
3
3
  export const getStringValue = (value)=>typeof value === 'string' && value.length > 0 ? value : undefined;
4
4
  export const getID = (value)=>typeof value === 'number' || typeof value === 'string' ? value : undefined;
@@ -278,12 +278,40 @@ export const updateGlobalByLanguageWithPayload = async ({ slug, data, depth, lan
278
278
  });
279
279
  };
280
280
  const fieldAffectsData = (field)=>'name' in field && typeof field.name === 'string' && field.type !== 'ui';
281
- export const duplicateDocumentData = ({ collection, doc, duplicateExcludeFields, fieldNames, targetLanguage })=>{
281
+ const duplicateFieldValue = (field, value)=>{
282
+ if (field.type === 'array' && Array.isArray(value)) {
283
+ return value.map((row)=>duplicateRowValue(asDocument(row), field.fields));
284
+ }
285
+ if (field.type === 'blocks' && Array.isArray(value)) {
286
+ return value.map((row)=>{
287
+ const rowData = asDocument(row);
288
+ const block = field.blocks.find((candidate)=>candidate.slug === getStringValue(rowData.blockType));
289
+ return duplicateRowValue(rowData, block?.fields || []);
290
+ });
291
+ }
292
+ return value;
293
+ };
294
+ const duplicateRowValue = (row, fields)=>{
295
+ const data = Object.entries(row).reduce((acc, [key, value])=>{
296
+ if (key !== 'id') {
297
+ acc[key] = value;
298
+ }
299
+ return acc;
300
+ }, {});
301
+ for (const field of fields){
302
+ if (!fieldAffectsData(field) || !(field.name in data)) {
303
+ continue;
304
+ }
305
+ data[field.name] = duplicateFieldValue(field, data[field.name]);
306
+ }
307
+ return data;
308
+ };
309
+ export const duplicateDocumentData = ({ collection, doc, fieldNames, targetLanguage })=>{
282
310
  const excluded = new Set([
283
311
  fieldNames.group,
284
312
  fieldNames.language,
285
313
  fieldNames.meta,
286
- ...duplicateExcludeFields
314
+ ...SYSTEM_DUPLICATION_EXCLUDED_FIELDS
287
315
  ]);
288
316
  const data = {};
289
317
  for (const field of collection.fields || []){
@@ -293,7 +321,7 @@ export const duplicateDocumentData = ({ collection, doc, duplicateExcludeFields,
293
321
  if (!(field.name in doc)) {
294
322
  continue;
295
323
  }
296
- data[field.name] = doc[field.name];
324
+ data[field.name] = duplicateFieldValue(field, doc[field.name]);
297
325
  }
298
326
  if (typeof data.slug === 'string' && data.slug.length > 0) {
299
327
  data.slug = `${data.slug}-${targetLanguage}`;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/data.ts"],"sourcesContent":["import type {\n CollectionConfig,\n CollectionSlug,\n Config,\n Field,\n GlobalSlug,\n Payload,\n PayloadRequest,\n Where,\n} from 'payload'\n\nimport type {\n MultilangFieldNames,\n MultilangLanguage,\n TranslationState,\n WithLanguageArgs,\n} from '../types.js'\n\nimport { DEFAULT_FIELD_NAMES } from '../constants.js'\n\nexport type DocumentData = {\n id?: number | string\n} & Record<string, unknown>\n\nexport const asDocument = (value: unknown): DocumentData =>\n value && typeof value === 'object' ? (value as DocumentData) : {}\n\nexport const getStringValue = (value: unknown): string | undefined =>\n typeof value === 'string' && value.length > 0 ? value : undefined\n\nexport const getID = (value: unknown): number | string | undefined =>\n typeof value === 'number' || typeof value === 'string' ? value : undefined\n\nexport const normalizeLanguage = (doc: unknown): MultilangLanguage => {\n const data = asDocument(doc)\n const code = getStringValue(data.code)?.trim().toLowerCase() || ''\n\n return {\n id: getID(data.id),\n name: getStringValue(data.name)?.trim() || code,\n active: data.active !== false,\n code,\n direction: data.direction === 'rtl' ? 'rtl' : 'ltr',\n flagLabel: getStringValue(data.flagLabel),\n isDefault: data.isDefault === true,\n locale: getStringValue(data.locale),\n order: typeof data.order === 'number' ? data.order : 0,\n }\n}\n\ntype ConfigWithMultilang = Pick<Config, 'admin'> | Pick<Payload['config'], 'admin'>\n\nexport const getLanguagesFromCustom = (custom: unknown): MultilangLanguage[] => {\n const payloadMultilang = asDocument(asDocument(custom).payloadMultilang)\n const languages = payloadMultilang.languages\n\n if (!Array.isArray(languages)) {\n return []\n }\n\n return languages.map(normalizeLanguage).filter((language) => language.code)\n}\n\n/**\n * Returns the languages configured for payload-multilang.\n */\nexport const getLanguages = ({\n config,\n languages,\n payload,\n}: {\n config?: ConfigWithMultilang\n languages?: MultilangLanguage[]\n payload?: Payload\n} = {}): MultilangLanguage[] => {\n if (languages) {\n return languages.map(normalizeLanguage).filter((language) => language.code)\n }\n\n if (payload) {\n return getLanguagesFromCustom(payload.config.admin?.custom)\n }\n\n if (config) {\n return getLanguagesFromCustom(config.admin?.custom)\n }\n\n throw new Error(\n 'getLanguages requires languages, config, or payload. Use createMultilangHelpers({ getPayload }) for app-level convenience.',\n )\n}\n\nexport const getDefaultLanguage = ({\n config,\n languages,\n payload,\n}: {\n config?: ConfigWithMultilang\n languages?: MultilangLanguage[]\n payload?: Payload\n}): MultilangLanguage | undefined => {\n const configuredLanguages = getLanguages({ config, languages, payload })\n\n return configuredLanguages.find((language) => language.isDefault) || configuredLanguages[0]\n}\n\n/**\n * Adds a language constraint to a Payload `where` query.\n *\n * Use this when querying an enabled collection directly and you only want documents for one\n * payload-multilang language.\n */\nexport const withLanguage = ({\n fieldName = DEFAULT_FIELD_NAMES.language,\n language,\n where,\n}: WithLanguageArgs): Where => {\n const languageWhere: Where = {\n [fieldName]: {\n equals: language,\n },\n }\n\n if (!where) {\n return languageWhere\n }\n\n return {\n and: [where, languageWhere],\n }\n}\n\nexport type MultilangDocumentLanguageArgs = {\n data?: unknown\n doc?: unknown\n fallback?: string\n fieldName?: string\n}\n\n/**\n * Resolves a document's payload-multilang language from draft/form data first, then persisted doc data.\n *\n * Useful in Payload admin preview and livePreview URL builders where unsaved form data may already\n * contain the selected language.\n */\nexport const getMultilangDocumentLanguage = ({\n data,\n doc,\n fallback,\n fieldName = DEFAULT_FIELD_NAMES.language,\n}: MultilangDocumentLanguageArgs): string | undefined =>\n getStringValue(asDocument(data)[fieldName]) ||\n getStringValue(asDocument(doc)[fieldName]) ||\n fallback\n\nexport type LocalizedSlugQueryStatus = 'any' | 'draft' | 'published'\n\nexport type LocalizedSlugQueryArgs = {\n fieldName?: string\n language: string\n slug: string\n slugFieldName?: string\n status?: LocalizedSlugQueryStatus\n where?: Where\n}\n\nexport type LocalizedSlugQuery = {\n draft?: boolean\n where: Where\n}\n\n/**\n * Builds the common Payload Local API query for per-language documents addressed by slug.\n */\nexport const localizedSlugQuery = ({\n slug,\n fieldName = DEFAULT_FIELD_NAMES.language,\n language,\n slugFieldName = 'slug',\n status = 'published',\n where,\n}: LocalizedSlugQueryArgs): LocalizedSlugQuery => {\n const constraints: Where[] = [\n {\n [slugFieldName]: {\n equals: slug,\n },\n },\n {\n [fieldName]: {\n equals: language,\n },\n },\n ]\n\n if (where) {\n constraints.unshift(where)\n }\n\n if (status !== 'any') {\n constraints.push({\n _status: {\n equals: status,\n },\n })\n }\n\n return {\n ...(status === 'draft' ? { draft: true } : {}),\n where:\n constraints.length === 1\n ? constraints[0]\n : {\n and: constraints,\n },\n }\n}\n\nexport const getDocumentTranslationsWithPayload = async <TDoc extends DocumentData = DocumentData>({\n id,\n collection,\n fieldNames = DEFAULT_FIELD_NAMES,\n overrideAccess = true,\n payload,\n req,\n}: {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n id: number | string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n}): Promise<TranslationState<TDoc>> => {\n const source = asDocument(\n await payload.findByID({\n id,\n collection,\n depth: 0,\n overrideAccess,\n req,\n }),\n ) as TDoc\n\n const group = getStringValue(source[fieldNames.group])\n const language = getStringValue(source[fieldNames.language])\n\n if (!group) {\n return {\n language,\n source,\n translations: language ? { [language]: source } : {},\n }\n }\n\n const result = await payload.find({\n collection,\n depth: 0,\n limit: 200,\n overrideAccess,\n req,\n where: {\n [fieldNames.group]: {\n equals: group,\n },\n },\n })\n\n const translations = result.docs.reduce<TranslationState<TDoc>['translations']>((acc, doc) => {\n const translation = asDocument(doc) as TDoc\n const code = getStringValue(translation[fieldNames.language])\n\n if (code) {\n acc[code] = translation\n }\n\n return acc\n }, {})\n\n return {\n group,\n language,\n source,\n translations,\n }\n}\n\nexport const getGroupTranslationsWithPayload = async <TDoc extends DocumentData = DocumentData>({\n collection,\n fieldNames = DEFAULT_FIELD_NAMES,\n group,\n overrideAccess = true,\n payload,\n req,\n}: {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n group: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n}): Promise<TranslationState<TDoc>> => {\n const result = await payload.find({\n collection,\n depth: 0,\n limit: 200,\n overrideAccess,\n req,\n where: {\n [fieldNames.group]: {\n equals: group,\n },\n },\n })\n\n const translations = result.docs.reduce<TranslationState<TDoc>['translations']>((acc, doc) => {\n const translation = asDocument(doc) as TDoc\n const code = getStringValue(translation[fieldNames.language])\n\n if (code) {\n acc[code] = translation\n }\n\n return acc\n }, {})\n\n return {\n group,\n translations,\n }\n}\n\n/**\n * Returns the source document and every document in the same translation group, keyed by language.\n */\nexport const getDocumentTranslationWithPayload = async <TDoc extends DocumentData = DocumentData>({\n id,\n collection,\n fieldNames,\n language,\n overrideAccess = true,\n payload,\n req,\n}: {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n id: number | string\n language: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n}): Promise<TDoc | undefined> => {\n const state = await getDocumentTranslationsWithPayload<TDoc>({\n id,\n collection,\n fieldNames,\n overrideAccess,\n payload,\n req,\n })\n\n return state.translations[language]\n}\n\nconst GLOBAL_SYSTEM_FIELDS = new Set(['_status', 'createdAt', 'globalType', 'id', 'updatedAt'])\n\nconst getGlobalPayloadMultilangCustom = ({\n slug,\n payload,\n}: {\n payload: Payload\n slug: GlobalSlug\n}): {\n defaultLanguage?: MultilangLanguage\n languages?: MultilangLanguage[]\n} => {\n const global = payload.config.globals.find((item) => item.slug === slug)\n const payloadMultilang = asDocument(asDocument(global?.admin?.custom).payloadMultilang)\n\n return payloadMultilang as {\n defaultLanguage?: MultilangLanguage\n languages?: MultilangLanguage[]\n }\n}\n\nconst validateGlobalLanguage = ({\n slug,\n language,\n payload,\n}: {\n language: string\n payload: Payload\n slug: GlobalSlug\n}): void => {\n const languages = getGlobalPayloadMultilangCustom({ slug, payload }).languages\n\n if (!Array.isArray(languages) || languages.length === 0) {\n return\n }\n\n if (!languages.some((candidate) => candidate.code === language)) {\n throw new Error(`Language \"${language}\" is not configured for ${slug}.`)\n }\n}\n\nconst getGlobalLanguageTab = <TDoc extends DocumentData = DocumentData>({\n doc,\n language,\n}: {\n doc: DocumentData\n language: string\n}): TDoc => {\n const languageData = asDocument(doc[language])\n const systemData = Object.entries(doc).reduce<DocumentData>((acc, [key, value]) => {\n if (GLOBAL_SYSTEM_FIELDS.has(key)) {\n acc[key] = value\n }\n\n return acc\n }, {})\n\n return {\n ...systemData,\n ...languageData,\n } as TDoc\n}\n\nexport const findGlobalByLanguageWithPayload = async <TDoc extends DocumentData = DocumentData>({\n slug,\n depth,\n language,\n overrideAccess = true,\n payload,\n req,\n}: {\n depth?: number\n language: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n slug: GlobalSlug\n}): Promise<TDoc> => {\n validateGlobalLanguage({ slug, language, payload })\n\n const doc = asDocument(\n await payload.findGlobal({\n slug,\n depth,\n overrideAccess,\n req,\n } as never),\n )\n\n return getGlobalLanguageTab<TDoc>({\n doc,\n language,\n })\n}\n\nexport const updateGlobalByLanguageWithPayload = async <TDoc extends DocumentData = DocumentData>({\n slug,\n data,\n depth,\n language,\n overrideAccess = true,\n payload,\n req,\n}: {\n data: Record<string, unknown>\n depth?: number\n language: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n slug: GlobalSlug\n}): Promise<TDoc> => {\n validateGlobalLanguage({ slug, language, payload })\n\n const currentDoc = asDocument(\n await payload.findGlobal({\n slug,\n depth: 0,\n overrideAccess,\n req,\n } as never),\n )\n const currentLanguageData = asDocument(currentDoc[language])\n\n const doc = asDocument(\n await payload.updateGlobal({\n slug,\n data: {\n [language]: {\n ...currentLanguageData,\n ...data,\n },\n },\n depth,\n overrideAccess,\n req,\n } as never),\n )\n\n return getGlobalLanguageTab<TDoc>({\n doc,\n language,\n })\n}\n\nconst fieldAffectsData = (field: Field): field is { name: string } & Field =>\n 'name' in field && typeof field.name === 'string' && field.type !== 'ui'\n\nexport const duplicateDocumentData = ({\n collection,\n doc,\n duplicateExcludeFields,\n fieldNames,\n targetLanguage,\n}: {\n collection: CollectionConfig\n doc: DocumentData\n duplicateExcludeFields: string[]\n fieldNames: MultilangFieldNames\n targetLanguage: string\n}): DocumentData => {\n const excluded = new Set([\n fieldNames.group,\n fieldNames.language,\n fieldNames.meta,\n ...duplicateExcludeFields,\n ])\n\n const data: DocumentData = {}\n\n for (const field of collection.fields || []) {\n if (!fieldAffectsData(field) || excluded.has(field.name)) {\n continue\n }\n\n if (!(field.name in doc)) {\n continue\n }\n\n data[field.name] = doc[field.name]\n }\n\n if (typeof data.slug === 'string' && data.slug.length > 0) {\n data.slug = `${data.slug}-${targetLanguage}`\n }\n\n return data\n}\n\nexport type PayloadFactory = () => Payload | Promise<Payload>\n\nexport type GetDocumentTranslationsArgs = {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n id: number | string\n overrideAccess?: boolean\n req?: PayloadRequest\n}\n\nexport type GetDocumentTranslationArgs = {\n language: string\n} & GetDocumentTranslationsArgs\n\nexport type FindGlobalByLanguageArgs = {\n depth?: number\n language: string\n overrideAccess?: boolean\n req?: PayloadRequest\n slug: GlobalSlug\n}\n\nexport type UpdateGlobalByLanguageArgs = {\n data: Record<string, unknown>\n} & FindGlobalByLanguageArgs\n\nexport type MultilangHelpers = {\n findGlobalByLanguage: <TDoc extends DocumentData = DocumentData>(\n args: FindGlobalByLanguageArgs,\n ) => Promise<TDoc>\n getDocumentTranslation: <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationArgs,\n ) => Promise<TDoc | undefined>\n getDocumentTranslations: <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationsArgs,\n ) => Promise<TranslationState<TDoc>>\n getLanguages: () => Promise<MultilangLanguage[]>\n updateGlobalByLanguage: <TDoc extends DocumentData = DocumentData>(\n args: UpdateGlobalByLanguageArgs,\n ) => Promise<TDoc>\n}\n\nexport const createMultilangHelpers = ({\n getPayload,\n}: {\n getPayload: PayloadFactory\n}): MultilangHelpers => {\n const resolvePayload = async () => getPayload()\n\n return {\n findGlobalByLanguage: async <TDoc extends DocumentData = DocumentData>({\n slug,\n depth,\n language,\n overrideAccess,\n req,\n }: FindGlobalByLanguageArgs): Promise<TDoc> =>\n findGlobalByLanguageWithPayload<TDoc>({\n slug,\n depth,\n language,\n overrideAccess,\n payload: await resolvePayload(),\n req,\n }),\n\n getDocumentTranslation: async <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationArgs,\n ): Promise<TDoc | undefined> =>\n getDocumentTranslationWithPayload<TDoc>({\n ...args,\n payload: await resolvePayload(),\n }),\n\n getDocumentTranslations: async <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationsArgs,\n ): Promise<TranslationState<TDoc>> =>\n getDocumentTranslationsWithPayload<TDoc>({\n ...args,\n payload: await resolvePayload(),\n }),\n\n getLanguages: async (): Promise<MultilangLanguage[]> =>\n getLanguages({ payload: await resolvePayload() }),\n\n updateGlobalByLanguage: async <TDoc extends DocumentData = DocumentData>({\n slug,\n data,\n depth,\n language,\n overrideAccess,\n req,\n }: UpdateGlobalByLanguageArgs): Promise<TDoc> =>\n updateGlobalByLanguageWithPayload<TDoc>({\n slug,\n data,\n depth,\n language,\n overrideAccess,\n payload: await resolvePayload(),\n req,\n }),\n }\n}\n"],"names":["DEFAULT_FIELD_NAMES","asDocument","value","getStringValue","length","undefined","getID","normalizeLanguage","doc","data","code","trim","toLowerCase","id","name","active","direction","flagLabel","isDefault","locale","order","getLanguagesFromCustom","custom","payloadMultilang","languages","Array","isArray","map","filter","language","getLanguages","config","payload","admin","Error","getDefaultLanguage","configuredLanguages","find","withLanguage","fieldName","where","languageWhere","equals","and","getMultilangDocumentLanguage","fallback","localizedSlugQuery","slug","slugFieldName","status","constraints","unshift","push","_status","draft","getDocumentTranslationsWithPayload","collection","fieldNames","overrideAccess","req","source","findByID","depth","group","translations","result","limit","docs","reduce","acc","translation","getGroupTranslationsWithPayload","getDocumentTranslationWithPayload","state","GLOBAL_SYSTEM_FIELDS","Set","getGlobalPayloadMultilangCustom","global","globals","item","validateGlobalLanguage","some","candidate","getGlobalLanguageTab","languageData","systemData","Object","entries","key","has","findGlobalByLanguageWithPayload","findGlobal","updateGlobalByLanguageWithPayload","currentDoc","currentLanguageData","updateGlobal","fieldAffectsData","field","type","duplicateDocumentData","duplicateExcludeFields","targetLanguage","excluded","meta","fields","createMultilangHelpers","getPayload","resolvePayload","findGlobalByLanguage","getDocumentTranslation","args","getDocumentTranslations","updateGlobalByLanguage"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/lib/data.ts"],"sourcesContent":["import type {\n CollectionConfig,\n CollectionSlug,\n Config,\n Field,\n GlobalSlug,\n Payload,\n PayloadRequest,\n Where,\n} from 'payload'\n\nimport type {\n MultilangFieldNames,\n MultilangLanguage,\n TranslationState,\n WithLanguageArgs,\n} from '../types.js'\n\nimport { DEFAULT_FIELD_NAMES, SYSTEM_DUPLICATION_EXCLUDED_FIELDS } from '../constants.js'\n\nexport type DocumentData = {\n id?: number | string\n} & Record<string, unknown>\n\nexport const asDocument = (value: unknown): DocumentData =>\n value && typeof value === 'object' ? (value as DocumentData) : {}\n\nexport const getStringValue = (value: unknown): string | undefined =>\n typeof value === 'string' && value.length > 0 ? value : undefined\n\nexport const getID = (value: unknown): number | string | undefined =>\n typeof value === 'number' || typeof value === 'string' ? value : undefined\n\nexport const normalizeLanguage = (doc: unknown): MultilangLanguage => {\n const data = asDocument(doc)\n const code = getStringValue(data.code)?.trim().toLowerCase() || ''\n\n return {\n id: getID(data.id),\n name: getStringValue(data.name)?.trim() || code,\n active: data.active !== false,\n code,\n direction: data.direction === 'rtl' ? 'rtl' : 'ltr',\n flagLabel: getStringValue(data.flagLabel),\n isDefault: data.isDefault === true,\n locale: getStringValue(data.locale),\n order: typeof data.order === 'number' ? data.order : 0,\n }\n}\n\ntype ConfigWithMultilang = Pick<Config, 'admin'> | Pick<Payload['config'], 'admin'>\n\nexport const getLanguagesFromCustom = (custom: unknown): MultilangLanguage[] => {\n const payloadMultilang = asDocument(asDocument(custom).payloadMultilang)\n const languages = payloadMultilang.languages\n\n if (!Array.isArray(languages)) {\n return []\n }\n\n return languages.map(normalizeLanguage).filter((language) => language.code)\n}\n\n/**\n * Returns the languages configured for payload-multilang.\n */\nexport const getLanguages = ({\n config,\n languages,\n payload,\n}: {\n config?: ConfigWithMultilang\n languages?: MultilangLanguage[]\n payload?: Payload\n} = {}): MultilangLanguage[] => {\n if (languages) {\n return languages.map(normalizeLanguage).filter((language) => language.code)\n }\n\n if (payload) {\n return getLanguagesFromCustom(payload.config.admin?.custom)\n }\n\n if (config) {\n return getLanguagesFromCustom(config.admin?.custom)\n }\n\n throw new Error(\n 'getLanguages requires languages, config, or payload. Use createMultilangHelpers({ getPayload }) for app-level convenience.',\n )\n}\n\nexport const getDefaultLanguage = ({\n config,\n languages,\n payload,\n}: {\n config?: ConfigWithMultilang\n languages?: MultilangLanguage[]\n payload?: Payload\n}): MultilangLanguage | undefined => {\n const configuredLanguages = getLanguages({ config, languages, payload })\n\n return configuredLanguages.find((language) => language.isDefault) || configuredLanguages[0]\n}\n\n/**\n * Adds a language constraint to a Payload `where` query.\n *\n * Use this when querying an enabled collection directly and you only want documents for one\n * payload-multilang language.\n */\nexport const withLanguage = ({\n fieldName = DEFAULT_FIELD_NAMES.language,\n language,\n where,\n}: WithLanguageArgs): Where => {\n const languageWhere: Where = {\n [fieldName]: {\n equals: language,\n },\n }\n\n if (!where) {\n return languageWhere\n }\n\n return {\n and: [where, languageWhere],\n }\n}\n\nexport type MultilangDocumentLanguageArgs = {\n data?: unknown\n doc?: unknown\n fallback?: string\n fieldName?: string\n}\n\n/**\n * Resolves a document's payload-multilang language from draft/form data first, then persisted doc data.\n *\n * Useful in Payload admin preview and livePreview URL builders where unsaved form data may already\n * contain the selected language.\n */\nexport const getMultilangDocumentLanguage = ({\n data,\n doc,\n fallback,\n fieldName = DEFAULT_FIELD_NAMES.language,\n}: MultilangDocumentLanguageArgs): string | undefined =>\n getStringValue(asDocument(data)[fieldName]) ||\n getStringValue(asDocument(doc)[fieldName]) ||\n fallback\n\nexport type LocalizedSlugQueryStatus = 'any' | 'draft' | 'published'\n\nexport type LocalizedSlugQueryArgs = {\n fieldName?: string\n language: string\n slug: string\n slugFieldName?: string\n status?: LocalizedSlugQueryStatus\n where?: Where\n}\n\nexport type LocalizedSlugQuery = {\n draft?: boolean\n where: Where\n}\n\n/**\n * Builds the common Payload Local API query for per-language documents addressed by slug.\n */\nexport const localizedSlugQuery = ({\n slug,\n fieldName = DEFAULT_FIELD_NAMES.language,\n language,\n slugFieldName = 'slug',\n status = 'published',\n where,\n}: LocalizedSlugQueryArgs): LocalizedSlugQuery => {\n const constraints: Where[] = [\n {\n [slugFieldName]: {\n equals: slug,\n },\n },\n {\n [fieldName]: {\n equals: language,\n },\n },\n ]\n\n if (where) {\n constraints.unshift(where)\n }\n\n if (status !== 'any') {\n constraints.push({\n _status: {\n equals: status,\n },\n })\n }\n\n return {\n ...(status === 'draft' ? { draft: true } : {}),\n where:\n constraints.length === 1\n ? constraints[0]\n : {\n and: constraints,\n },\n }\n}\n\nexport const getDocumentTranslationsWithPayload = async <TDoc extends DocumentData = DocumentData>({\n id,\n collection,\n fieldNames = DEFAULT_FIELD_NAMES,\n overrideAccess = true,\n payload,\n req,\n}: {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n id: number | string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n}): Promise<TranslationState<TDoc>> => {\n const source = asDocument(\n await payload.findByID({\n id,\n collection,\n depth: 0,\n overrideAccess,\n req,\n }),\n ) as TDoc\n\n const group = getStringValue(source[fieldNames.group])\n const language = getStringValue(source[fieldNames.language])\n\n if (!group) {\n return {\n language,\n source,\n translations: language ? { [language]: source } : {},\n }\n }\n\n const result = await payload.find({\n collection,\n depth: 0,\n limit: 200,\n overrideAccess,\n req,\n where: {\n [fieldNames.group]: {\n equals: group,\n },\n },\n })\n\n const translations = result.docs.reduce<TranslationState<TDoc>['translations']>((acc, doc) => {\n const translation = asDocument(doc) as TDoc\n const code = getStringValue(translation[fieldNames.language])\n\n if (code) {\n acc[code] = translation\n }\n\n return acc\n }, {})\n\n return {\n group,\n language,\n source,\n translations,\n }\n}\n\nexport const getGroupTranslationsWithPayload = async <TDoc extends DocumentData = DocumentData>({\n collection,\n fieldNames = DEFAULT_FIELD_NAMES,\n group,\n overrideAccess = true,\n payload,\n req,\n}: {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n group: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n}): Promise<TranslationState<TDoc>> => {\n const result = await payload.find({\n collection,\n depth: 0,\n limit: 200,\n overrideAccess,\n req,\n where: {\n [fieldNames.group]: {\n equals: group,\n },\n },\n })\n\n const translations = result.docs.reduce<TranslationState<TDoc>['translations']>((acc, doc) => {\n const translation = asDocument(doc) as TDoc\n const code = getStringValue(translation[fieldNames.language])\n\n if (code) {\n acc[code] = translation\n }\n\n return acc\n }, {})\n\n return {\n group,\n translations,\n }\n}\n\n/**\n * Returns the source document and every document in the same translation group, keyed by language.\n */\nexport const getDocumentTranslationWithPayload = async <TDoc extends DocumentData = DocumentData>({\n id,\n collection,\n fieldNames,\n language,\n overrideAccess = true,\n payload,\n req,\n}: {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n id: number | string\n language: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n}): Promise<TDoc | undefined> => {\n const state = await getDocumentTranslationsWithPayload<TDoc>({\n id,\n collection,\n fieldNames,\n overrideAccess,\n payload,\n req,\n })\n\n return state.translations[language]\n}\n\nconst GLOBAL_SYSTEM_FIELDS = new Set(['_status', 'createdAt', 'globalType', 'id', 'updatedAt'])\n\nconst getGlobalPayloadMultilangCustom = ({\n slug,\n payload,\n}: {\n payload: Payload\n slug: GlobalSlug\n}): {\n defaultLanguage?: MultilangLanguage\n languages?: MultilangLanguage[]\n} => {\n const global = payload.config.globals.find((item) => item.slug === slug)\n const payloadMultilang = asDocument(asDocument(global?.admin?.custom).payloadMultilang)\n\n return payloadMultilang as {\n defaultLanguage?: MultilangLanguage\n languages?: MultilangLanguage[]\n }\n}\n\nconst validateGlobalLanguage = ({\n slug,\n language,\n payload,\n}: {\n language: string\n payload: Payload\n slug: GlobalSlug\n}): void => {\n const languages = getGlobalPayloadMultilangCustom({ slug, payload }).languages\n\n if (!Array.isArray(languages) || languages.length === 0) {\n return\n }\n\n if (!languages.some((candidate) => candidate.code === language)) {\n throw new Error(`Language \"${language}\" is not configured for ${slug}.`)\n }\n}\n\nconst getGlobalLanguageTab = <TDoc extends DocumentData = DocumentData>({\n doc,\n language,\n}: {\n doc: DocumentData\n language: string\n}): TDoc => {\n const languageData = asDocument(doc[language])\n const systemData = Object.entries(doc).reduce<DocumentData>((acc, [key, value]) => {\n if (GLOBAL_SYSTEM_FIELDS.has(key)) {\n acc[key] = value\n }\n\n return acc\n }, {})\n\n return {\n ...systemData,\n ...languageData,\n } as TDoc\n}\n\nexport const findGlobalByLanguageWithPayload = async <TDoc extends DocumentData = DocumentData>({\n slug,\n depth,\n language,\n overrideAccess = true,\n payload,\n req,\n}: {\n depth?: number\n language: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n slug: GlobalSlug\n}): Promise<TDoc> => {\n validateGlobalLanguage({ slug, language, payload })\n\n const doc = asDocument(\n await payload.findGlobal({\n slug,\n depth,\n overrideAccess,\n req,\n } as never),\n )\n\n return getGlobalLanguageTab<TDoc>({\n doc,\n language,\n })\n}\n\nexport const updateGlobalByLanguageWithPayload = async <TDoc extends DocumentData = DocumentData>({\n slug,\n data,\n depth,\n language,\n overrideAccess = true,\n payload,\n req,\n}: {\n data: Record<string, unknown>\n depth?: number\n language: string\n overrideAccess?: boolean\n payload: Payload\n req?: PayloadRequest\n slug: GlobalSlug\n}): Promise<TDoc> => {\n validateGlobalLanguage({ slug, language, payload })\n\n const currentDoc = asDocument(\n await payload.findGlobal({\n slug,\n depth: 0,\n overrideAccess,\n req,\n } as never),\n )\n const currentLanguageData = asDocument(currentDoc[language])\n\n const doc = asDocument(\n await payload.updateGlobal({\n slug,\n data: {\n [language]: {\n ...currentLanguageData,\n ...data,\n },\n },\n depth,\n overrideAccess,\n req,\n } as never),\n )\n\n return getGlobalLanguageTab<TDoc>({\n doc,\n language,\n })\n}\n\nconst fieldAffectsData = (field: Field): field is { name: string } & Field =>\n 'name' in field && typeof field.name === 'string' && field.type !== 'ui'\n\nconst duplicateFieldValue = (field: Field, value: unknown): unknown => {\n if (field.type === 'array' && Array.isArray(value)) {\n return value.map((row) =>\n duplicateRowValue(asDocument(row), field.fields),\n )\n }\n\n if (field.type === 'blocks' && Array.isArray(value)) {\n return value.map((row) => {\n const rowData = asDocument(row)\n const block = field.blocks.find(\n (candidate) => candidate.slug === getStringValue(rowData.blockType),\n )\n\n return duplicateRowValue(rowData, block?.fields || [])\n })\n }\n\n return value\n}\n\nconst duplicateRowValue = (\n row: Record<string, unknown>,\n fields: Field[],\n): Record<string, unknown> => {\n const data = Object.entries(row).reduce<Record<string, unknown>>(\n (acc, [key, value]) => {\n if (key !== 'id') {\n acc[key] = value\n }\n\n return acc\n },\n {},\n )\n\n for (const field of fields) {\n if (!fieldAffectsData(field) || !(field.name in data)) {\n continue\n }\n\n data[field.name] = duplicateFieldValue(field, data[field.name])\n }\n\n return data\n}\n\nexport const duplicateDocumentData = ({\n collection,\n doc,\n fieldNames,\n targetLanguage,\n}: {\n collection: CollectionConfig\n doc: DocumentData\n fieldNames: MultilangFieldNames\n targetLanguage: string\n}): DocumentData => {\n const excluded = new Set([\n fieldNames.group,\n fieldNames.language,\n fieldNames.meta,\n ...SYSTEM_DUPLICATION_EXCLUDED_FIELDS,\n ])\n\n const data: DocumentData = {}\n\n for (const field of collection.fields || []) {\n if (!fieldAffectsData(field) || excluded.has(field.name)) {\n continue\n }\n\n if (!(field.name in doc)) {\n continue\n }\n\n data[field.name] = duplicateFieldValue(field, doc[field.name])\n }\n\n if (typeof data.slug === 'string' && data.slug.length > 0) {\n data.slug = `${data.slug}-${targetLanguage}`\n }\n\n return data\n}\n\nexport type PayloadFactory = () => Payload | Promise<Payload>\n\nexport type GetDocumentTranslationsArgs = {\n collection: CollectionSlug\n fieldNames?: MultilangFieldNames\n id: number | string\n overrideAccess?: boolean\n req?: PayloadRequest\n}\n\nexport type GetDocumentTranslationArgs = {\n language: string\n} & GetDocumentTranslationsArgs\n\nexport type FindGlobalByLanguageArgs = {\n depth?: number\n language: string\n overrideAccess?: boolean\n req?: PayloadRequest\n slug: GlobalSlug\n}\n\nexport type UpdateGlobalByLanguageArgs = {\n data: Record<string, unknown>\n} & FindGlobalByLanguageArgs\n\nexport type MultilangHelpers = {\n findGlobalByLanguage: <TDoc extends DocumentData = DocumentData>(\n args: FindGlobalByLanguageArgs,\n ) => Promise<TDoc>\n getDocumentTranslation: <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationArgs,\n ) => Promise<TDoc | undefined>\n getDocumentTranslations: <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationsArgs,\n ) => Promise<TranslationState<TDoc>>\n getLanguages: () => Promise<MultilangLanguage[]>\n updateGlobalByLanguage: <TDoc extends DocumentData = DocumentData>(\n args: UpdateGlobalByLanguageArgs,\n ) => Promise<TDoc>\n}\n\nexport const createMultilangHelpers = ({\n getPayload,\n}: {\n getPayload: PayloadFactory\n}): MultilangHelpers => {\n const resolvePayload = async () => getPayload()\n\n return {\n findGlobalByLanguage: async <TDoc extends DocumentData = DocumentData>({\n slug,\n depth,\n language,\n overrideAccess,\n req,\n }: FindGlobalByLanguageArgs): Promise<TDoc> =>\n findGlobalByLanguageWithPayload<TDoc>({\n slug,\n depth,\n language,\n overrideAccess,\n payload: await resolvePayload(),\n req,\n }),\n\n getDocumentTranslation: async <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationArgs,\n ): Promise<TDoc | undefined> =>\n getDocumentTranslationWithPayload<TDoc>({\n ...args,\n payload: await resolvePayload(),\n }),\n\n getDocumentTranslations: async <TDoc extends DocumentData = DocumentData>(\n args: GetDocumentTranslationsArgs,\n ): Promise<TranslationState<TDoc>> =>\n getDocumentTranslationsWithPayload<TDoc>({\n ...args,\n payload: await resolvePayload(),\n }),\n\n getLanguages: async (): Promise<MultilangLanguage[]> =>\n getLanguages({ payload: await resolvePayload() }),\n\n updateGlobalByLanguage: async <TDoc extends DocumentData = DocumentData>({\n slug,\n data,\n depth,\n language,\n overrideAccess,\n req,\n }: UpdateGlobalByLanguageArgs): Promise<TDoc> =>\n updateGlobalByLanguageWithPayload<TDoc>({\n slug,\n data,\n depth,\n language,\n overrideAccess,\n payload: await resolvePayload(),\n req,\n }),\n }\n}\n"],"names":["DEFAULT_FIELD_NAMES","SYSTEM_DUPLICATION_EXCLUDED_FIELDS","asDocument","value","getStringValue","length","undefined","getID","normalizeLanguage","doc","data","code","trim","toLowerCase","id","name","active","direction","flagLabel","isDefault","locale","order","getLanguagesFromCustom","custom","payloadMultilang","languages","Array","isArray","map","filter","language","getLanguages","config","payload","admin","Error","getDefaultLanguage","configuredLanguages","find","withLanguage","fieldName","where","languageWhere","equals","and","getMultilangDocumentLanguage","fallback","localizedSlugQuery","slug","slugFieldName","status","constraints","unshift","push","_status","draft","getDocumentTranslationsWithPayload","collection","fieldNames","overrideAccess","req","source","findByID","depth","group","translations","result","limit","docs","reduce","acc","translation","getGroupTranslationsWithPayload","getDocumentTranslationWithPayload","state","GLOBAL_SYSTEM_FIELDS","Set","getGlobalPayloadMultilangCustom","global","globals","item","validateGlobalLanguage","some","candidate","getGlobalLanguageTab","languageData","systemData","Object","entries","key","has","findGlobalByLanguageWithPayload","findGlobal","updateGlobalByLanguageWithPayload","currentDoc","currentLanguageData","updateGlobal","fieldAffectsData","field","type","duplicateFieldValue","row","duplicateRowValue","fields","rowData","block","blocks","blockType","duplicateDocumentData","targetLanguage","excluded","meta","createMultilangHelpers","getPayload","resolvePayload","findGlobalByLanguage","getDocumentTranslation","args","getDocumentTranslations","updateGlobalByLanguage"],"mappings":"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"}