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
362 lines
16 KiB
Plaintext
362 lines
16 KiB
Plaintext
import { fieldAffectsData, fieldShouldBeLocalized } from '../../config/types.js';
|
|
import { getFieldPaths } from '../../getFieldPaths.js';
|
|
import { traverseFields } from './traverseFields.js';
|
|
export const promise = async ({ id, blockData, collection, context, doc, field, fieldIndex, overrideAccess, parentIndexPath, parentIsLocalized, parentPath, parentSchemaPath, req, siblingDoc, siblingFields })=>{
|
|
const { indexPath, path, schemaPath } = getFieldPaths({
|
|
field,
|
|
index: fieldIndex,
|
|
parentIndexPath,
|
|
parentPath,
|
|
parentSchemaPath
|
|
});
|
|
const { localization } = req.payload.config;
|
|
const pathSegments = path ? path.split('.') : [];
|
|
const schemaPathSegments = schemaPath ? schemaPath.split('.') : [];
|
|
const indexPathSegments = indexPath ? indexPath.split('-').filter(Boolean)?.map(Number) : [];
|
|
if (fieldAffectsData(field)) {
|
|
let fieldData = siblingDoc?.[field.name];
|
|
const fieldIsLocalized = localization && fieldShouldBeLocalized({
|
|
field,
|
|
parentIsLocalized
|
|
});
|
|
// Run field beforeDuplicate hooks.
|
|
// These hooks are responsible for resetting the `id` field values of array and block rows. See `baseIDField`.
|
|
if (Array.isArray('hooks' in field && field.hooks?.beforeDuplicate)) {
|
|
if (fieldIsLocalized) {
|
|
const localeData = {};
|
|
for (const locale of localization.localeCodes){
|
|
const beforeDuplicateArgs = {
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data: doc,
|
|
field,
|
|
global: undefined,
|
|
indexPath: indexPathSegments,
|
|
path: pathSegments,
|
|
previousSiblingDoc: siblingDoc,
|
|
previousValue: siblingDoc[field.name]?.[locale],
|
|
req,
|
|
schemaPath: schemaPathSegments,
|
|
siblingData: siblingDoc,
|
|
siblingDocWithLocales: siblingDoc,
|
|
siblingFields: siblingFields,
|
|
value: siblingDoc[field.name]?.[locale]
|
|
};
|
|
let hookResult;
|
|
if ('hooks' in field && field.hooks?.beforeDuplicate) {
|
|
for (const hook of field.hooks.beforeDuplicate){
|
|
hookResult = await hook(beforeDuplicateArgs);
|
|
}
|
|
}
|
|
if (typeof hookResult !== 'undefined') {
|
|
localeData[locale] = hookResult;
|
|
}
|
|
}
|
|
siblingDoc[field.name] = localeData;
|
|
} else {
|
|
const beforeDuplicateArgs = {
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data: doc,
|
|
field,
|
|
global: undefined,
|
|
indexPath: indexPathSegments,
|
|
path: pathSegments,
|
|
previousSiblingDoc: siblingDoc,
|
|
previousValue: siblingDoc[field.name],
|
|
req,
|
|
schemaPath: schemaPathSegments,
|
|
siblingData: siblingDoc,
|
|
siblingDocWithLocales: siblingDoc,
|
|
siblingFields: siblingFields,
|
|
value: siblingDoc[field.name]
|
|
};
|
|
let hookResult;
|
|
if ('hooks' in field && field.hooks?.beforeDuplicate) {
|
|
for (const hook of field.hooks.beforeDuplicate){
|
|
hookResult = await hook(beforeDuplicateArgs);
|
|
}
|
|
}
|
|
if (typeof hookResult !== 'undefined') {
|
|
siblingDoc[field.name] = hookResult;
|
|
}
|
|
}
|
|
}
|
|
// First, for any localized fields, we will loop over locales
|
|
// and if locale data is present, traverse the sub fields.
|
|
// There are only a few different fields where this is possible.
|
|
if (fieldIsLocalized) {
|
|
if (typeof fieldData !== 'object' || fieldData === null) {
|
|
siblingDoc[field.name] = {};
|
|
fieldData = siblingDoc[field.name];
|
|
}
|
|
const promises = [];
|
|
localization.localeCodes.forEach((locale)=>{
|
|
if (fieldData[locale]) {
|
|
switch(field.type){
|
|
case 'array':
|
|
{
|
|
const rows = fieldData[locale];
|
|
if (Array.isArray(rows)) {
|
|
const promises = [];
|
|
rows.forEach((row, rowIndex)=>{
|
|
promises.push(traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: field.fields,
|
|
overrideAccess,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path + '.' + rowIndex,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc: row
|
|
}));
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
case 'blocks':
|
|
{
|
|
const rows = fieldData[locale];
|
|
if (Array.isArray(rows)) {
|
|
const promises = [];
|
|
rows.forEach((row, rowIndex)=>{
|
|
const blockTypeToMatch = row.blockType;
|
|
const block = req.payload.blocks[blockTypeToMatch] ?? (field.blockReferences ?? field.blocks).find((curBlock)=>typeof curBlock !== 'string' && curBlock.slug === blockTypeToMatch);
|
|
promises.push(traverseFields({
|
|
id,
|
|
blockData: row,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: block.fields,
|
|
overrideAccess,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path + '.' + rowIndex,
|
|
parentSchemaPath: schemaPath + '.' + block.slug,
|
|
req,
|
|
siblingDoc: row
|
|
}));
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
case 'group':
|
|
case 'tab':
|
|
{
|
|
promises.push(traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: field.fields,
|
|
overrideAccess,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc: fieldData[locale]
|
|
}));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
await Promise.all(promises);
|
|
} else {
|
|
// If the field is not localized, but it affects data,
|
|
// we need to further traverse its children
|
|
// so the child fields can run beforeDuplicate hooks
|
|
switch(field.type){
|
|
case 'array':
|
|
{
|
|
const rows = siblingDoc[field.name];
|
|
if (Array.isArray(rows)) {
|
|
const promises = [];
|
|
rows.forEach((row, rowIndex)=>{
|
|
promises.push(traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: field.fields,
|
|
overrideAccess,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path + '.' + rowIndex,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc: row
|
|
}));
|
|
});
|
|
await Promise.all(promises);
|
|
}
|
|
break;
|
|
}
|
|
case 'blocks':
|
|
{
|
|
const rows = siblingDoc[field.name];
|
|
if (Array.isArray(rows)) {
|
|
const promises = [];
|
|
rows.forEach((row, rowIndex)=>{
|
|
const blockTypeToMatch = row.blockType;
|
|
const block = req.payload.blocks[blockTypeToMatch] ?? (field.blockReferences ?? field.blocks).find((curBlock)=>typeof curBlock !== 'string' && curBlock.slug === blockTypeToMatch);
|
|
if (block) {
|
|
;
|
|
row.blockType = blockTypeToMatch;
|
|
promises.push(traverseFields({
|
|
id,
|
|
blockData: row,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: block.fields,
|
|
overrideAccess,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path + '.' + rowIndex,
|
|
parentSchemaPath: schemaPath + '.' + block.slug,
|
|
req,
|
|
siblingDoc: row
|
|
}));
|
|
}
|
|
});
|
|
await Promise.all(promises);
|
|
}
|
|
break;
|
|
}
|
|
case 'group':
|
|
{
|
|
if (typeof siblingDoc[field.name] !== 'object') {
|
|
siblingDoc[field.name] = {};
|
|
}
|
|
const groupDoc = siblingDoc[field.name];
|
|
await traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: field.fields,
|
|
overrideAccess,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc: groupDoc
|
|
});
|
|
break;
|
|
}
|
|
case 'tab':
|
|
{
|
|
if (typeof siblingDoc[field.name] !== 'object') {
|
|
siblingDoc[field.name] = {};
|
|
}
|
|
const tabDoc = siblingDoc[field.name];
|
|
await traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: field.fields,
|
|
overrideAccess,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc: tabDoc
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Finally, we traverse fields which do not affect data here - collapsibles, rows, unnamed groups
|
|
switch(field.type){
|
|
case 'collapsible':
|
|
case 'group':
|
|
case 'row':
|
|
{
|
|
await traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: field.fields,
|
|
overrideAccess,
|
|
parentIndexPath: indexPath,
|
|
parentIsLocalized,
|
|
parentPath,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc
|
|
});
|
|
break;
|
|
}
|
|
// Unnamed Tab
|
|
// @ts-expect-error `fieldAffectsData` inferred return type doesn't account for TabAsField
|
|
case 'tab':
|
|
{
|
|
await traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
// @ts-expect-error `fieldAffectsData` inferred return type doesn't account for TabAsField
|
|
fields: field.fields,
|
|
overrideAccess,
|
|
parentIndexPath: indexPath,
|
|
parentIsLocalized,
|
|
parentPath,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc
|
|
});
|
|
break;
|
|
}
|
|
case 'tabs':
|
|
{
|
|
await traverseFields({
|
|
id,
|
|
blockData,
|
|
collection,
|
|
context,
|
|
doc,
|
|
fields: field.tabs.map((tab)=>({
|
|
...tab,
|
|
type: 'tab'
|
|
})),
|
|
overrideAccess,
|
|
parentIndexPath: indexPath,
|
|
parentIsLocalized,
|
|
parentPath: path,
|
|
parentSchemaPath: schemaPath,
|
|
req,
|
|
siblingDoc
|
|
});
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//# sourceMappingURL=promise.js.map |