Files
klz-cables.com/.pnpm-store/v10/files/fa/c94202f0d76b4392d63e897e97aa5e6b59b91c5ab9965b760c29391a70a7f1a9549c2112256e32c9423468e4fc4374535d4fa9478ce4e8f724a66b7ba4b563
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

226 lines
7.6 KiB
Plaintext

import ObjectIdImport from 'bson-objectid';
import { canAccessAdmin, traverseFields } from 'payload';
import { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from 'payload/shared';
const ObjectId = 'default' in ObjectIdImport ? ObjectIdImport.default : ObjectIdImport;
function iterateFields(fields, fromLocaleData, toLocaleData, req, parentIsLocalized) {
fields.map(field => {
if (fieldAffectsData(field)) {
switch (field.type) {
case 'array':
// if the field has no value, take the source value
if (field.name in toLocaleData &&
// only replace if the target value is null or undefined
[null, undefined].includes(toLocaleData[field.name]) && field.name in fromLocaleData) {
toLocaleData[field.name] = fromLocaleData[field.name];
break;
}
// if the field has a value - loop over the data from target
if (field.name in toLocaleData) {
toLocaleData[field.name].map((item, index) => {
if (fromLocaleData[field.name]?.[index]) {
// Generate new IDs if the field is localized to prevent errors with relational DBs.
if (fieldShouldBeLocalized({
field,
parentIsLocalized
})) {
toLocaleData[field.name][index].id = new ObjectId().toHexString();
}
iterateFields(field.fields, fromLocaleData[field.name][index], item, req, parentIsLocalized || field.localized);
}
});
}
break;
case 'blocks':
// if the field has no value, take the source value
if (field.name in toLocaleData && (
// only replace if the target value is null, undefined, or empty array
[null, undefined].includes(toLocaleData[field.name]) || Array.isArray(toLocaleData[field.name]) && toLocaleData[field.name].length === 0) && field.name in fromLocaleData) {
toLocaleData[field.name] = fromLocaleData[field.name];
break;
}
// if the field has a value - loop over the data from target
if (field.name in toLocaleData) {
toLocaleData[field.name].map((blockData, index) => {
const block = req.payload.blocks[blockData.blockType] ?? (field.blockReferences ?? field.blocks).find(block => typeof block !== 'string' && block.slug === blockData.blockType);
// Generate new IDs if the field is localized to prevent errors with relational DBs.
if (fieldShouldBeLocalized({
field,
parentIsLocalized
})) {
toLocaleData[field.name][index].id = new ObjectId().toHexString();
}
if (block?.fields?.length) {
iterateFields(block?.fields, fromLocaleData[field.name][index], blockData, req, parentIsLocalized || field.localized);
}
});
}
break;
case 'checkbox':
case 'code':
case 'date':
case 'email':
case 'json':
case 'number':
case 'point':
case 'radio':
case 'relationship':
case 'richText':
case 'select':
case 'text':
case 'textarea':
case 'upload':
if (field.name in toLocaleData &&
// only replace if the target value is null or undefined
[null, undefined].includes(toLocaleData[field.name]) && field.name in fromLocaleData) {
toLocaleData[field.name] = fromLocaleData[field.name];
}
break;
case 'group':
{
if (fieldAffectsData(field) && field.name in toLocaleData && fromLocaleData?.[field.name] !== undefined) {
iterateFields(field.fields, fromLocaleData[field.name], toLocaleData[field.name], req, parentIsLocalized || field.localized);
} else {
iterateFields(field.fields, fromLocaleData, toLocaleData, req, parentIsLocalized);
}
break;
}
}
} else {
switch (field.type) {
case 'collapsible':
case 'row':
iterateFields(field.fields, fromLocaleData, toLocaleData, req, parentIsLocalized);
break;
case 'tabs':
field.tabs.map(tab => {
if (tabHasName(tab)) {
if (tab.name in toLocaleData && fromLocaleData?.[tab.name] !== undefined) {
iterateFields(tab.fields, fromLocaleData[tab.name], toLocaleData[tab.name], req, parentIsLocalized);
}
} else {
iterateFields(tab.fields, fromLocaleData, toLocaleData, req, parentIsLocalized);
}
});
break;
}
}
});
}
function mergeData(fromLocaleData, toLocaleData, fields, req, parentIsLocalized) {
iterateFields(fields, fromLocaleData, toLocaleData, req, parentIsLocalized);
return toLocaleData;
}
/**
* We don't have to recursively remove all ids,
* just the ones from the fields inside a localized array or block.
*/
function removeIdIfParentIsLocalized(data, fields) {
traverseFields({
callback: ({
parentIsLocalized,
ref
}) => {
if (parentIsLocalized) {
delete ref.id;
}
},
fields,
fillEmpty: false,
ref: data
});
return data;
}
export const copyDataFromLocaleHandler = async args => {
const {
req
} = args;
try {
return await copyDataFromLocale(args);
} catch (err) {
req.payload.logger.error({
err,
msg: `There was an error copying data from "${args.fromLocale}" to "${args.toLocale}"`
});
// Re-throw the error so it can be caught by the client
throw err;
}
};
export const copyDataFromLocale = async args => {
const {
collectionSlug,
docID,
fromLocale,
globalSlug,
overrideData = false,
req: {
payload,
payload: {
collections,
globals
},
user
},
req,
toLocale
} = args;
await canAccessAdmin({
req
});
const [fromLocaleData, toLocaleData] = await Promise.allSettled([globalSlug ? payload.findGlobal({
slug: globalSlug,
depth: 0,
locale: fromLocale,
overrideAccess: false,
user
}) : payload.findByID({
id: docID,
collection: collectionSlug,
depth: 0,
joins: false,
locale: fromLocale,
overrideAccess: false,
user
}), globalSlug ? payload.findGlobal({
slug: globalSlug,
depth: 0,
locale: toLocale,
overrideAccess: false,
user
}) : payload.findByID({
id: docID,
collection: collectionSlug,
depth: 0,
joins: false,
locale: toLocale,
overrideAccess: false,
user
})]);
if (fromLocaleData.status === 'rejected') {
throw new Error(`Error fetching data from locale "${fromLocale}"`);
}
if (toLocaleData.status === 'rejected') {
throw new Error(`Error fetching data from locale "${toLocale}"`);
}
const fields = globalSlug ? globals[globalSlug].config.fields : collections[collectionSlug].config.fields;
const fromLocaleDataWithoutID = fromLocaleData.value;
const toLocaleDataWithoutID = toLocaleData.value;
const dataWithID = overrideData ? fromLocaleDataWithoutID : mergeData(fromLocaleDataWithoutID, toLocaleDataWithoutID, fields, req, false);
const data = removeIdIfParentIsLocalized(dataWithID, fields);
return globalSlug ? await payload.updateGlobal({
slug: globalSlug,
data,
locale: toLocale,
overrideAccess: false,
req,
user
}) : await payload.update({
id: docID,
collection: collectionSlug,
data,
locale: toLocale,
overrideAccess: false,
req,
user
});
};
//# sourceMappingURL=copyDataFromLocale.js.map