payload 3.78.0-internal-debug.f663370 → 3.78.0-internal.5219978
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.
- package/dist/admin/forms/Form.d.ts +6 -0
- package/dist/admin/forms/Form.d.ts.map +1 -1
- package/dist/admin/forms/Form.js.map +1 -1
- package/dist/admin/views/dashboard.d.ts +19 -4
- package/dist/admin/views/dashboard.d.ts.map +1 -1
- package/dist/admin/views/dashboard.js.map +1 -1
- package/dist/admin/views/list.d.ts +2 -0
- package/dist/admin/views/list.d.ts.map +1 -1
- package/dist/admin/views/list.js.map +1 -1
- package/dist/bin/generateImportMap/iterateConfig.d.ts.map +1 -1
- package/dist/bin/generateImportMap/iterateConfig.js +10 -0
- package/dist/bin/generateImportMap/iterateConfig.js.map +1 -1
- package/dist/bin/migrate.js +1 -1
- package/dist/bin/migrate.js.map +1 -1
- package/dist/collections/config/types.d.ts +0 -1
- package/dist/collections/config/types.d.ts.map +1 -1
- package/dist/collections/config/types.js.map +1 -1
- package/dist/collections/operations/update.d.ts.map +1 -1
- package/dist/collections/operations/update.js +2 -0
- package/dist/collections/operations/update.js.map +1 -1
- package/dist/collections/operations/updateByID.d.ts.map +1 -1
- package/dist/collections/operations/updateByID.js +2 -0
- package/dist/collections/operations/updateByID.js.map +1 -1
- package/dist/config/client.d.ts +4 -2
- package/dist/config/client.d.ts.map +1 -1
- package/dist/config/client.js +10 -2
- package/dist/config/client.js.map +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +13 -0
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +14 -5
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/createDatabaseAdapter.d.ts +1 -1
- package/dist/database/createDatabaseAdapter.d.ts.map +1 -1
- package/dist/database/createDatabaseAdapter.js +3 -2
- package/dist/database/createDatabaseAdapter.js.map +1 -1
- package/dist/database/migrations/createMigration.js +2 -2
- package/dist/database/migrations/createMigration.js.map +1 -1
- package/dist/database/migrations/readMigrationFiles.d.ts.map +1 -1
- package/dist/database/migrations/readMigrationFiles.js +6 -5
- package/dist/database/migrations/readMigrationFiles.js.map +1 -1
- package/dist/database/queryValidation/validateQueryPaths.d.ts.map +1 -1
- package/dist/database/queryValidation/validateQueryPaths.js +4 -0
- package/dist/database/queryValidation/validateQueryPaths.js.map +1 -1
- package/dist/database/types.d.ts +1 -4
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/exports/shared.d.ts +1 -0
- package/dist/exports/shared.d.ts.map +1 -1
- package/dist/exports/shared.js +1 -0
- package/dist/exports/shared.js.map +1 -1
- package/dist/index.bundled.d.ts +62 -16
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/uploads/endpoints/getFileFromURL.d.ts.map +1 -1
- package/dist/uploads/endpoints/getFileFromURL.js +4 -1
- package/dist/uploads/endpoints/getFileFromURL.js.map +1 -1
- package/dist/uploads/generateFileData.js +1 -1
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/utilities/configToJSONSchema.d.ts.map +1 -1
- package/dist/utilities/configToJSONSchema.js +105 -6
- package/dist/utilities/configToJSONSchema.js.map +1 -1
- package/dist/utilities/configToJSONSchema.spec.js +36 -4
- package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
- package/dist/utilities/mergeLocalizedData.d.ts.map +1 -1
- package/dist/utilities/mergeLocalizedData.js +44 -15
- package/dist/utilities/mergeLocalizedData.js.map +1 -1
- package/dist/utilities/mergeLocalizedData.spec.js +161 -0
- package/dist/utilities/mergeLocalizedData.spec.js.map +1 -1
- package/dist/utilities/sanitizeFilename.d.ts +6 -0
- package/dist/utilities/sanitizeFilename.d.ts.map +1 -0
- package/dist/utilities/sanitizeFilename.js +22 -0
- package/dist/utilities/sanitizeFilename.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/mergeLocalizedData.ts"],"sourcesContent":["import type { Block, Field, FlattenedBlock } from '../fields/config/types.js'\nimport type { SanitizedConfig } from '../index.js'\nimport type { JsonObject } from '../types/index.js'\n\nimport { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/config/types.js'\n\ntype MergeDataToSelectedLocalesArgs = {\n configBlockReferences: SanitizedConfig['blocks']\n dataWithLocales: JsonObject\n docWithLocales: JsonObject\n fields: Field[]\n parentIsLocalized?: boolean\n selectedLocales: string[]\n}\n\n/**\n * Merges data from dataWithLocales onto docWithLocales for specified locales.\n * For localized fields, merges only the specified locales while preserving others.\n * For non-localized fields, keeps existing values from docWithLocales unchanged.\n * Returns a new object without mutating the original.\n */\nexport function mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields,\n parentIsLocalized = false,\n selectedLocales,\n}: MergeDataToSelectedLocalesArgs): JsonObject {\n if (!docWithLocales || typeof docWithLocales !== 'object') {\n return dataWithLocales || docWithLocales\n }\n\n const result: JsonObject = { ...docWithLocales }\n\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n // If the parent is localized, all children are inherently \"localized\"\n if (parentIsLocalized && dataWithLocales[field.name]) {\n result[field.name] = dataWithLocales[field.name]\n continue\n }\n\n const fieldIsLocalized = fieldShouldBeLocalized({ field, parentIsLocalized })\n\n switch (field.type) {\n case 'array': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedArray: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedArray[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedArray\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized array - still process children for any localized fields\n result[field.name] = newValue.map((newItem: JsonObject, index: number) => {\n const existingItem = existingValue?.[index] || {}\n\n return mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newItem,\n docWithLocales: existingItem,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n })\n }\n }\n break\n }\n\n case 'blocks': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized blocks - still process children for any localized fields\n result[field.name] = newValue.map((newBlockData: JsonObject, index: number) => {\n let block: Block | FlattenedBlock | undefined\n if (configBlockReferences && field.blockReferences) {\n for (const blockOrReference of field.blockReferences) {\n if (typeof blockOrReference === 'string') {\n block = configBlockReferences.find((b) => b.slug === newBlockData.blockType)\n } else {\n block = blockOrReference\n }\n }\n } else if (field.blocks) {\n block = field.blocks.find((b) => b.slug === newBlockData.blockType)\n }\n\n if (block) {\n const blockData =\n Array.isArray(existingValue) && existingValue[index]\n ? (existingValue[index] as JsonObject)\n : {}\n\n return mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newBlockData,\n docWithLocales: blockData,\n fields: block?.fields || [],\n parentIsLocalized,\n selectedLocales,\n })\n }\n\n return newBlockData\n })\n }\n }\n break\n }\n\n case 'group': {\n if (fieldAffectsData(field) && field.name) {\n // Named groups create a nested data structure\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const groupData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n groupData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = groupData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized group - still process children for any localized fields\n result[field.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue,\n docWithLocales: existingValue || {},\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n } else {\n // Unnamed groups pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales: result, // Use current result to avoid re-processing already-handled fields\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, merged)\n }\n break\n }\n\n default: {\n // For all other data-affecting fields (text, number, select, etc.)\n if (fieldIsLocalized) {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name] || {}\n\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...existingValue }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n merged[locale] = newValue[locale]\n }\n }\n\n result[field.name] = merged\n } else if (parentIsLocalized) {\n // Child of localized parent - replace with new value\n result[field.name] = newValue\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n }\n } else if (parentIsLocalized) {\n result[field.name] = dataWithLocales[field.name]\n } else {\n result[field.name] =\n field.name in dataWithLocales\n ? dataWithLocales[field.name]\n : docWithLocales[field.name]\n }\n break\n }\n }\n } else {\n // Layout-only fields that don't affect data structure\n switch (field.type) {\n case 'collapsible':\n case 'row': {\n // These pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales: result, // Use current result to avoid re-processing already-handled fields\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, merged)\n break\n }\n\n case 'tabs': {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n // Named tabs create a nested data structure and can be localized\n const tabIsLocalized = fieldShouldBeLocalized({ field: tab, parentIsLocalized })\n\n if (tab.name in dataWithLocales) {\n const newValue = dataWithLocales[tab.name]\n const existingValue = docWithLocales[tab.name]\n\n if (tabIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n merged[locale] = newValue[locale]\n }\n }\n\n result[tab.name] = merged\n } else {\n // Preserve existing value if new value is not a valid object\n result[tab.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized tab - still process children for any localized fields\n result[tab.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue as JsonObject,\n docWithLocales: existingValue || {},\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n } else {\n // Unnamed tabs pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales: result, // Use current result to avoid re-processing already-handled fields\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n Object.assign(result, merged)\n }\n }\n break\n }\n }\n }\n }\n\n return result\n}\n"],"names":["fieldAffectsData","fieldShouldBeLocalized","tabHasName","mergeLocalizedData","configBlockReferences","dataWithLocales","docWithLocales","fields","parentIsLocalized","selectedLocales","result","field","name","fieldIsLocalized","type","newValue","existingValue","Array","isArray","updatedArray","locale","map","newItem","index","existingItem","updatedData","newBlockData","block","blockReferences","blockOrReference","find","b","slug","blockType","blocks","blockData","groupData","merged","Object","assign","tab","tabs","tabIsLocalized"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/mergeLocalizedData.ts"],"sourcesContent":["import type { Block, Field, FlattenedBlock } from '../fields/config/types.js'\nimport type { SanitizedConfig } from '../index.js'\nimport type { JsonObject } from '../types/index.js'\n\nimport { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../fields/config/types.js'\n\n/**\n * Collects field names at the current data level, recursing through pass-through fields\n * (row, collapsible, unnamed group, unnamed tab) but stopping at named fields.\n */\nfunction collectFlattenedFieldNames(fields: Field[]): Set<string> {\n const names = new Set<string>()\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n names.add(field.name)\n } else if ('fields' in field && Array.isArray(field.fields)) {\n // Pass-through fields (row, collapsible, unnamed group)\n for (const name of collectFlattenedFieldNames(field.fields)) {\n names.add(name)\n }\n } else if (field.type === 'tabs') {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n names.add(tab.name)\n } else {\n for (const name of collectFlattenedFieldNames(tab.fields)) {\n names.add(name)\n }\n }\n }\n }\n }\n return names\n}\n\ntype MergeDataToSelectedLocalesArgs = {\n configBlockReferences: SanitizedConfig['blocks']\n dataWithLocales: JsonObject\n docWithLocales: JsonObject\n fields: Field[]\n parentIsLocalized?: boolean\n selectedLocales: string[]\n}\n\n/**\n * Merges data from dataWithLocales onto docWithLocales for specified locales.\n * For localized fields, merges only the specified locales while preserving others.\n * For non-localized fields, keeps existing values from docWithLocales unchanged.\n * Returns a new object without mutating the original.\n */\nexport function mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields,\n parentIsLocalized = false,\n selectedLocales,\n}: MergeDataToSelectedLocalesArgs): JsonObject {\n if (!docWithLocales || typeof docWithLocales !== 'object') {\n return dataWithLocales || docWithLocales\n }\n\n const result: JsonObject = { ...docWithLocales }\n\n for (const field of fields) {\n if (fieldAffectsData(field)) {\n // If the parent is localized, all children are inherently \"localized\"\n if (parentIsLocalized && dataWithLocales[field.name]) {\n result[field.name] = dataWithLocales[field.name]\n continue\n }\n\n const fieldIsLocalized = fieldShouldBeLocalized({ field, parentIsLocalized })\n\n switch (field.type) {\n case 'array': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedArray: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedArray[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedArray\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized array - still process children for any localized fields\n result[field.name] = newValue.map((newItem: JsonObject, index: number) => {\n const existingItem = existingValue?.[index] || {}\n\n return mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newItem,\n docWithLocales: existingItem,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n })\n }\n }\n break\n }\n\n case 'blocks': {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const updatedData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n updatedData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = updatedData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (Array.isArray(newValue)) {\n // Non-localized blocks - still process children for any localized fields\n result[field.name] = newValue.map((newBlockData: JsonObject, index: number) => {\n let block: Block | FlattenedBlock | undefined\n if (configBlockReferences && field.blockReferences) {\n for (const blockOrReference of field.blockReferences) {\n if (typeof blockOrReference === 'string') {\n block = configBlockReferences.find((b) => b.slug === newBlockData.blockType)\n } else {\n block = blockOrReference\n }\n }\n } else if (field.blocks) {\n block = field.blocks.find((b) => b.slug === newBlockData.blockType)\n }\n\n if (block) {\n const blockData =\n Array.isArray(existingValue) && existingValue[index]\n ? (existingValue[index] as JsonObject)\n : {}\n\n return mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newBlockData,\n docWithLocales: blockData,\n fields: block?.fields || [],\n parentIsLocalized,\n selectedLocales,\n })\n }\n\n return newBlockData\n })\n }\n }\n break\n }\n\n case 'group': {\n if (fieldAffectsData(field) && field.name) {\n // Named groups create a nested data structure\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name]\n\n if (fieldIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const groupData: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n groupData[locale] = newValue[locale]\n }\n }\n\n result[field.name] = groupData\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized group - still process children for any localized fields\n result[field.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue,\n docWithLocales: existingValue || {},\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n }\n break\n }\n\n default: {\n // For all other data-affecting fields (text, number, select, etc.)\n if (fieldIsLocalized) {\n if (field.name in dataWithLocales) {\n const newValue = dataWithLocales[field.name]\n const existingValue = docWithLocales[field.name] || {}\n\n // If localized, handle locale keys\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...existingValue }\n\n for (const locale of selectedLocales) {\n if (locale in newValue) {\n merged[locale] = newValue[locale]\n }\n }\n\n result[field.name] = merged\n } else if (parentIsLocalized) {\n // Child of localized parent - replace with new value\n result[field.name] = newValue\n } else {\n // Preserve existing value if new value is not a valid object\n result[field.name] = existingValue\n }\n }\n } else if (parentIsLocalized) {\n result[field.name] = dataWithLocales[field.name]\n } else {\n result[field.name] =\n field.name in dataWithLocales\n ? dataWithLocales[field.name]\n : docWithLocales[field.name]\n }\n break\n }\n }\n } else {\n // Layout-only fields that don't affect data structure\n switch (field.type) {\n case 'collapsible':\n case 'group':\n case 'row': {\n // These pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields: field.fields,\n parentIsLocalized,\n selectedLocales,\n })\n // Only copy fields that belong to this layout field to avoid overwriting already-processed fields\n const fieldNames = collectFlattenedFieldNames(field.fields)\n for (const name of fieldNames) {\n if (name in merged) {\n result[name] = merged[name]\n }\n }\n break\n }\n\n case 'tabs': {\n for (const tab of field.tabs) {\n if (tabHasName(tab)) {\n // Named tabs create a nested data structure and can be localized\n const tabIsLocalized = fieldShouldBeLocalized({ field: tab, parentIsLocalized })\n\n if (tab.name in dataWithLocales) {\n const newValue = dataWithLocales[tab.name]\n const existingValue = docWithLocales[tab.name]\n\n if (tabIsLocalized) {\n if (newValue && typeof newValue === 'object' && !Array.isArray(newValue)) {\n const merged: Record<string, unknown> = { ...(existingValue || {}) }\n\n for (const locale of selectedLocales) {\n if (locale in newValue && typeof newValue[locale] === 'object') {\n merged[locale] = newValue[locale]\n }\n }\n\n result[tab.name] = merged\n } else {\n // Preserve existing value if new value is not a valid object\n result[tab.name] = existingValue\n }\n } else if (typeof newValue === 'object' && !Array.isArray(newValue)) {\n // Non-localized tab - still process children for any localized fields\n result[tab.name] = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales: newValue as JsonObject,\n docWithLocales: existingValue || {},\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n }\n }\n } else {\n // Unnamed tabs pass through the same data level\n const merged = mergeLocalizedData({\n configBlockReferences,\n dataWithLocales,\n docWithLocales,\n fields: tab.fields,\n parentIsLocalized,\n selectedLocales,\n })\n // Only copy fields that belong to this tab to avoid overwriting already-processed fields\n const tabFieldNames = collectFlattenedFieldNames(tab.fields)\n for (const name of tabFieldNames) {\n if (name in merged) {\n result[name] = merged[name]\n }\n }\n }\n }\n break\n }\n }\n }\n }\n\n return result\n}\n"],"names":["fieldAffectsData","fieldShouldBeLocalized","tabHasName","collectFlattenedFieldNames","fields","names","Set","field","add","name","Array","isArray","type","tab","tabs","mergeLocalizedData","configBlockReferences","dataWithLocales","docWithLocales","parentIsLocalized","selectedLocales","result","fieldIsLocalized","newValue","existingValue","updatedArray","locale","map","newItem","index","existingItem","updatedData","newBlockData","block","blockReferences","blockOrReference","find","b","slug","blockType","blocks","blockData","groupData","merged","fieldNames","tabIsLocalized","tabFieldNames"],"mappings":"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"}
|
|
@@ -778,6 +778,167 @@ describe('mergeLocalizedData', ()=>{
|
|
|
778
778
|
es: 'Spanish Description'
|
|
779
779
|
});
|
|
780
780
|
});
|
|
781
|
+
it('should not lose other locale data when processing unnamed groups', ()=>{
|
|
782
|
+
// https://github.com/payloadcms/payload/issues/15642
|
|
783
|
+
const fields = [
|
|
784
|
+
{
|
|
785
|
+
name: 'textFieldRoot',
|
|
786
|
+
type: 'text'
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
name: 'textFieldRootLocalized',
|
|
790
|
+
type: 'text',
|
|
791
|
+
localized: true
|
|
792
|
+
},
|
|
793
|
+
// Unnamed group - fields at same data level as root
|
|
794
|
+
{
|
|
795
|
+
type: 'group',
|
|
796
|
+
fields: [
|
|
797
|
+
{
|
|
798
|
+
name: 'textFieldNested',
|
|
799
|
+
type: 'text'
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
name: 'textFieldNestedLocalized',
|
|
803
|
+
type: 'text',
|
|
804
|
+
localized: true
|
|
805
|
+
}
|
|
806
|
+
]
|
|
807
|
+
}
|
|
808
|
+
];
|
|
809
|
+
// Document already has English data published
|
|
810
|
+
const docWithLocales = {
|
|
811
|
+
textFieldRoot: 'Root Value',
|
|
812
|
+
textFieldRootLocalized: {
|
|
813
|
+
en: 'English Root Localized',
|
|
814
|
+
es: 'Spanish Root Localized'
|
|
815
|
+
},
|
|
816
|
+
textFieldNested: 'Nested Value',
|
|
817
|
+
textFieldNestedLocalized: {
|
|
818
|
+
en: 'English Nested Localized',
|
|
819
|
+
es: 'Spanish Nested Localized'
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
// Publishing only English locale with updated data
|
|
823
|
+
const dataWithLocales = {
|
|
824
|
+
textFieldRoot: 'Updated Root Value',
|
|
825
|
+
textFieldRootLocalized: {
|
|
826
|
+
en: 'Updated English Root Localized'
|
|
827
|
+
},
|
|
828
|
+
textFieldNested: 'Updated Nested Value',
|
|
829
|
+
textFieldNestedLocalized: {
|
|
830
|
+
en: 'Updated English Nested Localized'
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
const result = mergeLocalizedData({
|
|
834
|
+
configBlockReferences: [],
|
|
835
|
+
dataWithLocales,
|
|
836
|
+
docWithLocales,
|
|
837
|
+
fields,
|
|
838
|
+
selectedLocales: [
|
|
839
|
+
'en'
|
|
840
|
+
]
|
|
841
|
+
});
|
|
842
|
+
// Root non-localized field should be updated
|
|
843
|
+
expect(result.textFieldRoot).toBe('Updated Root Value');
|
|
844
|
+
// Root localized field should merge: update en, preserve es
|
|
845
|
+
expect(result.textFieldRootLocalized).toEqual({
|
|
846
|
+
en: 'Updated English Root Localized',
|
|
847
|
+
es: 'Spanish Root Localized'
|
|
848
|
+
});
|
|
849
|
+
// Nested non-localized field should be updated
|
|
850
|
+
expect(result.textFieldNested).toBe('Updated Nested Value');
|
|
851
|
+
// Nested localized field should merge: update en, preserve es
|
|
852
|
+
// This is the bug - es data is lost
|
|
853
|
+
expect(result.textFieldNestedLocalized).toEqual({
|
|
854
|
+
en: 'Updated English Nested Localized',
|
|
855
|
+
es: 'Spanish Nested Localized'
|
|
856
|
+
});
|
|
857
|
+
});
|
|
858
|
+
it('should not lose other locale data when processing row fields', ()=>{
|
|
859
|
+
const fields = [
|
|
860
|
+
{
|
|
861
|
+
type: 'row',
|
|
862
|
+
fields: [
|
|
863
|
+
{
|
|
864
|
+
name: 'rowFieldLocalized',
|
|
865
|
+
type: 'text',
|
|
866
|
+
localized: true
|
|
867
|
+
}
|
|
868
|
+
]
|
|
869
|
+
}
|
|
870
|
+
];
|
|
871
|
+
const docWithLocales = {
|
|
872
|
+
rowFieldLocalized: {
|
|
873
|
+
en: 'English Value',
|
|
874
|
+
es: 'Spanish Value'
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
const dataWithLocales = {
|
|
878
|
+
rowFieldLocalized: {
|
|
879
|
+
en: 'Updated English Value'
|
|
880
|
+
}
|
|
881
|
+
};
|
|
882
|
+
const result = mergeLocalizedData({
|
|
883
|
+
configBlockReferences: [],
|
|
884
|
+
dataWithLocales,
|
|
885
|
+
docWithLocales,
|
|
886
|
+
fields,
|
|
887
|
+
selectedLocales: [
|
|
888
|
+
'en'
|
|
889
|
+
]
|
|
890
|
+
});
|
|
891
|
+
expect(result.rowFieldLocalized).toEqual({
|
|
892
|
+
en: 'Updated English Value',
|
|
893
|
+
es: 'Spanish Value'
|
|
894
|
+
});
|
|
895
|
+
});
|
|
896
|
+
it('should preserve other locale data when updating through unnamed tabs', ()=>{
|
|
897
|
+
const fields = [
|
|
898
|
+
{
|
|
899
|
+
type: 'tabs',
|
|
900
|
+
tabs: [
|
|
901
|
+
{
|
|
902
|
+
label: 'Tab 1',
|
|
903
|
+
fields: [
|
|
904
|
+
{
|
|
905
|
+
name: 'tabFieldLocalized',
|
|
906
|
+
type: 'text',
|
|
907
|
+
localized: true
|
|
908
|
+
}
|
|
909
|
+
]
|
|
910
|
+
}
|
|
911
|
+
]
|
|
912
|
+
}
|
|
913
|
+
];
|
|
914
|
+
// Document has both en and es data
|
|
915
|
+
const docWithLocales = {
|
|
916
|
+
tabFieldLocalized: {
|
|
917
|
+
en: 'English Value',
|
|
918
|
+
es: 'Spanish Value'
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
// Only updating en
|
|
922
|
+
const dataWithLocales = {
|
|
923
|
+
tabFieldLocalized: {
|
|
924
|
+
en: 'Updated English Value'
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
const result = mergeLocalizedData({
|
|
928
|
+
configBlockReferences: [],
|
|
929
|
+
dataWithLocales,
|
|
930
|
+
docWithLocales,
|
|
931
|
+
fields,
|
|
932
|
+
selectedLocales: [
|
|
933
|
+
'en'
|
|
934
|
+
]
|
|
935
|
+
});
|
|
936
|
+
// es should be preserved
|
|
937
|
+
expect(result.tabFieldLocalized).toEqual({
|
|
938
|
+
en: 'Updated English Value',
|
|
939
|
+
es: 'Spanish Value'
|
|
940
|
+
});
|
|
941
|
+
});
|
|
781
942
|
});
|
|
782
943
|
});
|
|
783
944
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utilities/mergeLocalizedData.spec.ts"],"sourcesContent":["import type { Field } from '../fields/config/types.js'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { mergeLocalizedData } from './mergeLocalizedData.js'\n\ndescribe('mergeLocalizedData', () => {\n const selectedLocales = ['en']\n const configBlockReferences = []\n\n describe('simple fields', () => {\n it('should merge localized field values for selected locales', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'English Title',\n es: 'Spanish Title',\n de: 'German Title',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'Updated English Title',\n es: 'Updated Spanish Title',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.title).toEqual({\n en: 'Updated English Title',\n es: 'Spanish Title',\n de: 'German Title',\n })\n })\n\n it('should keep doc value for non-localized fields', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: false,\n },\n ]\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales: {\n title: 'New Title',\n },\n docWithLocales: {\n title: 'Old Title',\n },\n fields,\n selectedLocales,\n })\n\n expect(result.title).toBe('New Title')\n\n const missingData = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales: {},\n docWithLocales: {\n title: 'Old Title',\n },\n fields,\n selectedLocales,\n })\n\n expect(missingData.title).toBe('Old Title')\n\n const updatedData = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales: {\n title: 'Updated Title',\n },\n docWithLocales: {},\n fields,\n selectedLocales,\n })\n\n expect(updatedData.title).toBe('Updated Title')\n })\n })\n\n describe('groups', () => {\n it('should merge localized group with locale keys at top level', () => {\n const fields: Field[] = [\n {\n name: 'meta',\n type: 'group',\n localized: true,\n fields: [\n {\n name: 'title',\n type: 'text',\n },\n {\n name: 'description',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n meta: {\n en: {\n title: 'EN Title',\n description: 'EN Desc',\n },\n es: {\n title: 'ES Title',\n description: 'ES Desc',\n },\n },\n }\n\n const dataWithLocales = {\n meta: {\n en: {\n title: 'Updated EN Title',\n description: 'Updated EN Desc',\n },\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.meta).toEqual({\n en: {\n title: 'Updated EN Title',\n description: 'Updated EN Desc',\n },\n es: {\n title: 'ES Title',\n description: 'ES Desc',\n },\n })\n })\n\n it('should handle non-localized group with localized children', () => {\n const fields: Field[] = [\n {\n name: 'meta',\n type: 'group',\n localized: false,\n fields: [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n {\n name: 'version',\n type: 'number',\n localized: false,\n },\n ],\n },\n ]\n\n const docWithLocales = {\n meta: {\n title: {\n en: 'EN Title',\n es: 'ES Title',\n },\n version: 1,\n },\n }\n\n const dataWithLocales = {\n meta: {\n title: {\n en: 'Updated EN Title',\n },\n version: 2,\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.meta).toEqual({\n title: {\n en: 'Updated EN Title',\n es: 'ES Title',\n },\n version: 2,\n })\n })\n })\n\n describe('arrays', () => {\n it('should merge localized array with locale keys at top level', () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n localized: true,\n fields: [\n {\n name: 'name',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n items: {\n en: [{ name: 'EN Item 1' }, { name: 'EN Item 2' }],\n es: [{ name: 'ES Item 1' }],\n },\n }\n\n const dataWithLocales = {\n items: {\n en: [{ name: 'Updated EN Item 1' }, { name: 'Updated EN Item 2' }],\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.items).toEqual({\n en: [{ name: 'Updated EN Item 1' }, { name: 'Updated EN Item 2' }],\n es: [{ name: 'ES Item 1' }],\n })\n })\n\n it('should handle non-localized array with localized children', () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n localized: false,\n fields: [\n {\n name: 'name',\n type: 'text',\n localized: true,\n },\n ],\n },\n ]\n\n const docWithLocales = {\n items: [\n {\n name: {\n en: 'EN Item 1',\n es: 'ES Item 1',\n },\n },\n {\n name: {\n en: 'EN Item 2',\n es: 'ES Item 2',\n },\n },\n ],\n }\n\n const dataWithLocales = {\n items: [\n {\n name: {\n en: 'Updated EN Item 1',\n },\n },\n {\n name: {\n en: 'Updated EN Item 2',\n },\n },\n ],\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.items).toEqual([\n {\n name: {\n en: 'Updated EN Item 1',\n es: 'ES Item 1',\n },\n },\n {\n name: {\n en: 'Updated EN Item 2',\n es: 'ES Item 2',\n },\n },\n ])\n })\n })\n\n describe('blocks', () => {\n it('should merge localized blocks with locale keys at top level', () => {\n const fields: Field[] = [\n {\n name: 'content',\n type: 'blocks',\n localized: true,\n blocks: [\n {\n slug: 'text',\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n content: {\n en: [{ blockType: 'text', text: 'EN Text' }],\n es: [{ blockType: 'text', text: 'ES Text' }],\n },\n }\n\n const dataWithLocales = {\n content: {\n en: [{ blockType: 'text', text: 'Updated EN Text' }],\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.content).toEqual({\n en: [{ blockType: 'text', text: 'Updated EN Text' }],\n es: [{ blockType: 'text', text: 'ES Text' }],\n })\n })\n\n it('should handle blocks with nested arrays', () => {\n const fields: Field[] = [\n {\n name: 'content',\n type: 'blocks',\n localized: true,\n blocks: [\n {\n slug: 'nested',\n fields: [\n {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'name',\n type: 'text',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n content: {\n en: [\n {\n blockType: 'nested',\n items: [{ name: 'EN Item 1' }],\n },\n ],\n es: [\n {\n blockType: 'nested',\n items: [{ name: 'ES Item 1' }],\n },\n ],\n },\n }\n\n const dataWithLocales = {\n content: {\n en: [\n {\n blockType: 'nested',\n items: [{ name: 'Updated EN Item 1' }],\n },\n ],\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.content).toEqual({\n en: [\n {\n blockType: 'nested',\n items: [{ name: 'Updated EN Item 1' }],\n },\n ],\n es: [\n {\n blockType: 'nested',\n items: [{ name: 'ES Item 1' }],\n },\n ],\n })\n })\n })\n\n describe('tabs', () => {\n it('should merge localized named tabs with locale keys at top level', () => {\n const fields: Field[] = [\n {\n type: 'tabs',\n tabs: [\n {\n name: 'meta',\n localized: true,\n fields: [\n {\n name: 'title',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n meta: {\n en: {\n title: 'EN Title',\n },\n es: {\n title: 'ES Title',\n },\n },\n }\n\n const dataWithLocales = {\n meta: {\n en: {\n title: 'Updated EN Title',\n },\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.meta).toEqual({\n en: {\n title: 'Updated EN Title',\n },\n es: {\n title: 'ES Title',\n },\n })\n })\n\n it('should handle unnamed tabs with localized fields', () => {\n const fields: Field[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'tab1',\n fields: [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'EN Title',\n es: 'ES Title',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'Updated EN Title',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.title).toEqual({\n en: 'Updated EN Title',\n es: 'ES Title',\n })\n })\n })\n\n describe('deeply nested structures', () => {\n it('should handle multiple levels of nesting with locale keys only at topmost localized field', () => {\n const fields: Field[] = [\n {\n name: 'outer',\n type: 'group',\n localized: true,\n fields: [\n {\n name: 'inner',\n type: 'group',\n localized: false,\n fields: [\n {\n name: 'items',\n type: 'array',\n localized: false,\n fields: [\n {\n name: 'text',\n type: 'text',\n localized: false,\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n outer: {\n en: {\n inner: {\n items: [{ text: 'EN Item 1' }],\n },\n },\n es: {\n inner: {\n items: [{ text: 'ES Item 1' }],\n },\n },\n },\n }\n\n const dataWithLocales = {\n outer: {\n en: {\n inner: {\n items: [{ text: 'Updated EN Item 1' }],\n },\n },\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.outer).toEqual({\n en: {\n inner: {\n items: [{ text: 'Updated EN Item 1' }],\n },\n },\n es: {\n inner: {\n items: [{ text: 'ES Item 1' }],\n },\n },\n })\n })\n })\n\n describe('multiple selected locales', () => {\n it('should merge multiple locales when selected', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'EN Title',\n es: 'ES Title',\n de: 'DE Title',\n fr: 'FR Title',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'Updated EN Title',\n es: 'Updated ES Title',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales: ['en', 'es'],\n })\n\n expect(result.title).toEqual({\n en: 'Updated EN Title',\n es: 'Updated ES Title',\n de: 'DE Title',\n fr: 'FR Title',\n })\n })\n })\n\n describe('pass through fields, rows, collapsibles, unnamed tabs, unnamed groups', () => {\n it('should not lose merged locale data when processing unnamed tabs', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Other Fields',\n fields: [\n {\n name: 'description',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'English Title',\n },\n description: {\n en: 'English Description',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'English Title',\n es: 'Spanish Title',\n },\n description: {\n en: 'English Description',\n es: 'Spanish Description',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales: ['es'],\n })\n\n expect(result.title).toEqual({\n en: 'English Title',\n es: 'Spanish Title',\n })\n\n expect(result.description).toEqual({\n en: 'English Description',\n es: 'Spanish Description',\n })\n })\n })\n})\n"],"names":["describe","expect","it","mergeLocalizedData","selectedLocales","configBlockReferences","fields","name","type","localized","docWithLocales","title","en","es","de","dataWithLocales","result","toEqual","toBe","missingData","updatedData","meta","description","version","items","blocks","slug","content","blockType","text","tabs","label","outer","inner","fr"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/mergeLocalizedData.spec.ts"],"sourcesContent":["import type { Field } from '../fields/config/types.js'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { mergeLocalizedData } from './mergeLocalizedData.js'\n\ndescribe('mergeLocalizedData', () => {\n const selectedLocales = ['en']\n const configBlockReferences = []\n\n describe('simple fields', () => {\n it('should merge localized field values for selected locales', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'English Title',\n es: 'Spanish Title',\n de: 'German Title',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'Updated English Title',\n es: 'Updated Spanish Title',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.title).toEqual({\n en: 'Updated English Title',\n es: 'Spanish Title',\n de: 'German Title',\n })\n })\n\n it('should keep doc value for non-localized fields', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: false,\n },\n ]\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales: {\n title: 'New Title',\n },\n docWithLocales: {\n title: 'Old Title',\n },\n fields,\n selectedLocales,\n })\n\n expect(result.title).toBe('New Title')\n\n const missingData = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales: {},\n docWithLocales: {\n title: 'Old Title',\n },\n fields,\n selectedLocales,\n })\n\n expect(missingData.title).toBe('Old Title')\n\n const updatedData = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales: {\n title: 'Updated Title',\n },\n docWithLocales: {},\n fields,\n selectedLocales,\n })\n\n expect(updatedData.title).toBe('Updated Title')\n })\n })\n\n describe('groups', () => {\n it('should merge localized group with locale keys at top level', () => {\n const fields: Field[] = [\n {\n name: 'meta',\n type: 'group',\n localized: true,\n fields: [\n {\n name: 'title',\n type: 'text',\n },\n {\n name: 'description',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n meta: {\n en: {\n title: 'EN Title',\n description: 'EN Desc',\n },\n es: {\n title: 'ES Title',\n description: 'ES Desc',\n },\n },\n }\n\n const dataWithLocales = {\n meta: {\n en: {\n title: 'Updated EN Title',\n description: 'Updated EN Desc',\n },\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.meta).toEqual({\n en: {\n title: 'Updated EN Title',\n description: 'Updated EN Desc',\n },\n es: {\n title: 'ES Title',\n description: 'ES Desc',\n },\n })\n })\n\n it('should handle non-localized group with localized children', () => {\n const fields: Field[] = [\n {\n name: 'meta',\n type: 'group',\n localized: false,\n fields: [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n {\n name: 'version',\n type: 'number',\n localized: false,\n },\n ],\n },\n ]\n\n const docWithLocales = {\n meta: {\n title: {\n en: 'EN Title',\n es: 'ES Title',\n },\n version: 1,\n },\n }\n\n const dataWithLocales = {\n meta: {\n title: {\n en: 'Updated EN Title',\n },\n version: 2,\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.meta).toEqual({\n title: {\n en: 'Updated EN Title',\n es: 'ES Title',\n },\n version: 2,\n })\n })\n })\n\n describe('arrays', () => {\n it('should merge localized array with locale keys at top level', () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n localized: true,\n fields: [\n {\n name: 'name',\n type: 'text',\n },\n ],\n },\n ]\n\n const docWithLocales = {\n items: {\n en: [{ name: 'EN Item 1' }, { name: 'EN Item 2' }],\n es: [{ name: 'ES Item 1' }],\n },\n }\n\n const dataWithLocales = {\n items: {\n en: [{ name: 'Updated EN Item 1' }, { name: 'Updated EN Item 2' }],\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.items).toEqual({\n en: [{ name: 'Updated EN Item 1' }, { name: 'Updated EN Item 2' }],\n es: [{ name: 'ES Item 1' }],\n })\n })\n\n it('should handle non-localized array with localized children', () => {\n const fields: Field[] = [\n {\n name: 'items',\n type: 'array',\n localized: false,\n fields: [\n {\n name: 'name',\n type: 'text',\n localized: true,\n },\n ],\n },\n ]\n\n const docWithLocales = {\n items: [\n {\n name: {\n en: 'EN Item 1',\n es: 'ES Item 1',\n },\n },\n {\n name: {\n en: 'EN Item 2',\n es: 'ES Item 2',\n },\n },\n ],\n }\n\n const dataWithLocales = {\n items: [\n {\n name: {\n en: 'Updated EN Item 1',\n },\n },\n {\n name: {\n en: 'Updated EN Item 2',\n },\n },\n ],\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.items).toEqual([\n {\n name: {\n en: 'Updated EN Item 1',\n es: 'ES Item 1',\n },\n },\n {\n name: {\n en: 'Updated EN Item 2',\n es: 'ES Item 2',\n },\n },\n ])\n })\n })\n\n describe('blocks', () => {\n it('should merge localized blocks with locale keys at top level', () => {\n const fields: Field[] = [\n {\n name: 'content',\n type: 'blocks',\n localized: true,\n blocks: [\n {\n slug: 'text',\n fields: [\n {\n name: 'text',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n content: {\n en: [{ blockType: 'text', text: 'EN Text' }],\n es: [{ blockType: 'text', text: 'ES Text' }],\n },\n }\n\n const dataWithLocales = {\n content: {\n en: [{ blockType: 'text', text: 'Updated EN Text' }],\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.content).toEqual({\n en: [{ blockType: 'text', text: 'Updated EN Text' }],\n es: [{ blockType: 'text', text: 'ES Text' }],\n })\n })\n\n it('should handle blocks with nested arrays', () => {\n const fields: Field[] = [\n {\n name: 'content',\n type: 'blocks',\n localized: true,\n blocks: [\n {\n slug: 'nested',\n fields: [\n {\n name: 'items',\n type: 'array',\n fields: [\n {\n name: 'name',\n type: 'text',\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n content: {\n en: [\n {\n blockType: 'nested',\n items: [{ name: 'EN Item 1' }],\n },\n ],\n es: [\n {\n blockType: 'nested',\n items: [{ name: 'ES Item 1' }],\n },\n ],\n },\n }\n\n const dataWithLocales = {\n content: {\n en: [\n {\n blockType: 'nested',\n items: [{ name: 'Updated EN Item 1' }],\n },\n ],\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.content).toEqual({\n en: [\n {\n blockType: 'nested',\n items: [{ name: 'Updated EN Item 1' }],\n },\n ],\n es: [\n {\n blockType: 'nested',\n items: [{ name: 'ES Item 1' }],\n },\n ],\n })\n })\n })\n\n describe('tabs', () => {\n it('should merge localized named tabs with locale keys at top level', () => {\n const fields: Field[] = [\n {\n type: 'tabs',\n tabs: [\n {\n name: 'meta',\n localized: true,\n fields: [\n {\n name: 'title',\n type: 'text',\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n meta: {\n en: {\n title: 'EN Title',\n },\n es: {\n title: 'ES Title',\n },\n },\n }\n\n const dataWithLocales = {\n meta: {\n en: {\n title: 'Updated EN Title',\n },\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.meta).toEqual({\n en: {\n title: 'Updated EN Title',\n },\n es: {\n title: 'ES Title',\n },\n })\n })\n\n it('should handle unnamed tabs with localized fields', () => {\n const fields: Field[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'tab1',\n fields: [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'EN Title',\n es: 'ES Title',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'Updated EN Title',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.title).toEqual({\n en: 'Updated EN Title',\n es: 'ES Title',\n })\n })\n })\n\n describe('deeply nested structures', () => {\n it('should handle multiple levels of nesting with locale keys only at topmost localized field', () => {\n const fields: Field[] = [\n {\n name: 'outer',\n type: 'group',\n localized: true,\n fields: [\n {\n name: 'inner',\n type: 'group',\n localized: false,\n fields: [\n {\n name: 'items',\n type: 'array',\n localized: false,\n fields: [\n {\n name: 'text',\n type: 'text',\n localized: false,\n },\n ],\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n outer: {\n en: {\n inner: {\n items: [{ text: 'EN Item 1' }],\n },\n },\n es: {\n inner: {\n items: [{ text: 'ES Item 1' }],\n },\n },\n },\n }\n\n const dataWithLocales = {\n outer: {\n en: {\n inner: {\n items: [{ text: 'Updated EN Item 1' }],\n },\n },\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales,\n })\n\n expect(result.outer).toEqual({\n en: {\n inner: {\n items: [{ text: 'Updated EN Item 1' }],\n },\n },\n es: {\n inner: {\n items: [{ text: 'ES Item 1' }],\n },\n },\n })\n })\n })\n\n describe('multiple selected locales', () => {\n it('should merge multiple locales when selected', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'EN Title',\n es: 'ES Title',\n de: 'DE Title',\n fr: 'FR Title',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'Updated EN Title',\n es: 'Updated ES Title',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales: ['en', 'es'],\n })\n\n expect(result.title).toEqual({\n en: 'Updated EN Title',\n es: 'Updated ES Title',\n de: 'DE Title',\n fr: 'FR Title',\n })\n })\n })\n\n describe('pass through fields, rows, collapsibles, unnamed tabs, unnamed groups', () => {\n it('should not lose merged locale data when processing unnamed tabs', () => {\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n localized: true,\n },\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Other Fields',\n fields: [\n {\n name: 'description',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n const docWithLocales = {\n title: {\n en: 'English Title',\n },\n description: {\n en: 'English Description',\n },\n }\n\n const dataWithLocales = {\n title: {\n en: 'English Title',\n es: 'Spanish Title',\n },\n description: {\n en: 'English Description',\n es: 'Spanish Description',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales: ['es'],\n })\n\n expect(result.title).toEqual({\n en: 'English Title',\n es: 'Spanish Title',\n })\n\n expect(result.description).toEqual({\n en: 'English Description',\n es: 'Spanish Description',\n })\n })\n\n it('should not lose other locale data when processing unnamed groups', () => {\n // https://github.com/payloadcms/payload/issues/15642\n const fields: Field[] = [\n {\n name: 'textFieldRoot',\n type: 'text',\n },\n {\n name: 'textFieldRootLocalized',\n type: 'text',\n localized: true,\n },\n // Unnamed group - fields at same data level as root\n {\n type: 'group',\n fields: [\n {\n name: 'textFieldNested',\n type: 'text',\n },\n {\n name: 'textFieldNestedLocalized',\n type: 'text',\n localized: true,\n },\n ],\n },\n ]\n\n // Document already has English data published\n const docWithLocales = {\n textFieldRoot: 'Root Value',\n textFieldRootLocalized: {\n en: 'English Root Localized',\n es: 'Spanish Root Localized',\n },\n textFieldNested: 'Nested Value',\n textFieldNestedLocalized: {\n en: 'English Nested Localized',\n es: 'Spanish Nested Localized',\n },\n }\n\n // Publishing only English locale with updated data\n const dataWithLocales = {\n textFieldRoot: 'Updated Root Value',\n textFieldRootLocalized: {\n en: 'Updated English Root Localized',\n },\n textFieldNested: 'Updated Nested Value',\n textFieldNestedLocalized: {\n en: 'Updated English Nested Localized',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales: ['en'],\n })\n\n // Root non-localized field should be updated\n expect(result.textFieldRoot).toBe('Updated Root Value')\n\n // Root localized field should merge: update en, preserve es\n expect(result.textFieldRootLocalized).toEqual({\n en: 'Updated English Root Localized',\n es: 'Spanish Root Localized',\n })\n\n // Nested non-localized field should be updated\n expect(result.textFieldNested).toBe('Updated Nested Value')\n\n // Nested localized field should merge: update en, preserve es\n // This is the bug - es data is lost\n expect(result.textFieldNestedLocalized).toEqual({\n en: 'Updated English Nested Localized',\n es: 'Spanish Nested Localized',\n })\n })\n\n it('should not lose other locale data when processing row fields', () => {\n const fields: Field[] = [\n {\n type: 'row',\n fields: [\n {\n name: 'rowFieldLocalized',\n type: 'text',\n localized: true,\n },\n ],\n },\n ]\n\n const docWithLocales = {\n rowFieldLocalized: {\n en: 'English Value',\n es: 'Spanish Value',\n },\n }\n\n const dataWithLocales = {\n rowFieldLocalized: {\n en: 'Updated English Value',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales: ['en'],\n })\n\n expect(result.rowFieldLocalized).toEqual({\n en: 'Updated English Value',\n es: 'Spanish Value',\n })\n })\n\n it('should preserve other locale data when updating through unnamed tabs', () => {\n const fields: Field[] = [\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Tab 1',\n fields: [\n {\n name: 'tabFieldLocalized',\n type: 'text',\n localized: true,\n },\n ],\n },\n ],\n },\n ]\n\n // Document has both en and es data\n const docWithLocales = {\n tabFieldLocalized: {\n en: 'English Value',\n es: 'Spanish Value',\n },\n }\n\n // Only updating en\n const dataWithLocales = {\n tabFieldLocalized: {\n en: 'Updated English Value',\n },\n }\n\n const result = mergeLocalizedData({\n configBlockReferences: [],\n dataWithLocales,\n docWithLocales,\n fields,\n selectedLocales: ['en'],\n })\n\n // es should be preserved\n expect(result.tabFieldLocalized).toEqual({\n en: 'Updated English Value',\n es: 'Spanish Value',\n })\n })\n })\n})\n"],"names":["describe","expect","it","mergeLocalizedData","selectedLocales","configBlockReferences","fields","name","type","localized","docWithLocales","title","en","es","de","dataWithLocales","result","toEqual","toBe","missingData","updatedData","meta","description","version","items","blocks","slug","content","blockType","text","tabs","label","outer","inner","fr","textFieldRoot","textFieldRootLocalized","textFieldNested","textFieldNestedLocalized","rowFieldLocalized","tabFieldLocalized"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizeFilename.d.ts","sourceRoot":"","sources":["../../src/utilities/sanitizeFilename.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoBzD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { APIError } from '../errors/APIError.js';
|
|
2
|
+
/**
|
|
3
|
+
* Strips directory components and control characters from a filename,
|
|
4
|
+
* leaving only the base filename.
|
|
5
|
+
*/ export function sanitizeFilename(filename) {
|
|
6
|
+
let sanitized = filename.replace(/\\/g, '/');
|
|
7
|
+
const lastSlash = sanitized.lastIndexOf('/');
|
|
8
|
+
if (lastSlash !== -1) {
|
|
9
|
+
sanitized = sanitized.slice(lastSlash + 1);
|
|
10
|
+
}
|
|
11
|
+
if (sanitized === '.' || sanitized === '..') {
|
|
12
|
+
sanitized = '';
|
|
13
|
+
}
|
|
14
|
+
// eslint-disable-next-line no-control-regex
|
|
15
|
+
sanitized = sanitized.replace(/[\x00-\x1f\x80-\x9f]/g, '');
|
|
16
|
+
if (!sanitized) {
|
|
17
|
+
throw new APIError('Invalid filename', 400);
|
|
18
|
+
}
|
|
19
|
+
return sanitized;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=sanitizeFilename.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/sanitizeFilename.ts"],"sourcesContent":["import { APIError } from '../errors/APIError.js'\n\n/**\n * Strips directory components and control characters from a filename,\n * leaving only the base filename.\n */\nexport function sanitizeFilename(filename: string): string {\n let sanitized = filename.replace(/\\\\/g, '/')\n\n const lastSlash = sanitized.lastIndexOf('/')\n if (lastSlash !== -1) {\n sanitized = sanitized.slice(lastSlash + 1)\n }\n\n if (sanitized === '.' || sanitized === '..') {\n sanitized = ''\n }\n\n // eslint-disable-next-line no-control-regex\n sanitized = sanitized.replace(/[\\x00-\\x1f\\x80-\\x9f]/g, '')\n\n if (!sanitized) {\n throw new APIError('Invalid filename', 400)\n }\n\n return sanitized\n}\n"],"names":["APIError","sanitizeFilename","filename","sanitized","replace","lastSlash","lastIndexOf","slice"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,wBAAuB;AAEhD;;;CAGC,GACD,OAAO,SAASC,iBAAiBC,QAAgB;IAC/C,IAAIC,YAAYD,SAASE,OAAO,CAAC,OAAO;IAExC,MAAMC,YAAYF,UAAUG,WAAW,CAAC;IACxC,IAAID,cAAc,CAAC,GAAG;QACpBF,YAAYA,UAAUI,KAAK,CAACF,YAAY;IAC1C;IAEA,IAAIF,cAAc,OAAOA,cAAc,MAAM;QAC3CA,YAAY;IACd;IAEA,4CAA4C;IAC5CA,YAAYA,UAAUC,OAAO,CAAC,yBAAyB;IAEvD,IAAI,CAACD,WAAW;QACd,MAAM,IAAIH,SAAS,oBAAoB;IACzC;IAEA,OAAOG;AACT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload",
|
|
3
|
-
"version": "3.78.0-internal
|
|
3
|
+
"version": "3.78.0-internal.5219978",
|
|
4
4
|
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"admin panel",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"undici": "7.18.2",
|
|
116
116
|
"uuid": "10.0.0",
|
|
117
117
|
"ws": "^8.16.0",
|
|
118
|
-
"@payloadcms/translations": "3.78.0-internal
|
|
118
|
+
"@payloadcms/translations": "3.78.0-internal.5219978"
|
|
119
119
|
},
|
|
120
120
|
"devDependencies": {
|
|
121
121
|
"@hyrious/esbuild-plugin-commonjs": "0.2.6",
|