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
306 lines
12 KiB
Plaintext
306 lines
12 KiB
Plaintext
import { MissingEditorProp } from '../../../errors/index.js';
|
|
import { fieldAffectsData, tabHasName } from '../../config/types.js';
|
|
import { getFieldPaths } from '../../getFieldPaths.js';
|
|
import { traverseFields } from './traverseFields.js';
|
|
// This function is responsible for the following actions, in order:
|
|
// - Execute field hooks
|
|
export const promise = async ({ blockData, collection, context, data, doc, field, fieldIndex, global, operation, parentIndexPath, parentIsLocalized, parentPath, parentSchemaPath, previousDoc, previousSiblingDoc, req, siblingData, siblingDoc, siblingFields })=>{
|
|
const { indexPath, path, schemaPath } = getFieldPaths({
|
|
field,
|
|
index: fieldIndex,
|
|
parentIndexPath,
|
|
parentPath,
|
|
parentSchemaPath
|
|
});
|
|
const pathSegments = path ? path.split('.') : [];
|
|
const schemaPathSegments = schemaPath ? schemaPath.split('.') : [];
|
|
const indexPathSegments = indexPath ? indexPath.split('-').filter(Boolean)?.map(Number) : [];
|
|
const getNestedValue = (data, path)=>path.reduce((acc, key)=>acc && acc[key] !== undefined ? acc[key] : undefined, data);
|
|
const previousValData = previousSiblingDoc && Object.keys(previousSiblingDoc).length > 0 ? previousSiblingDoc : previousDoc;
|
|
if (fieldAffectsData(field)) {
|
|
// Execute hooks
|
|
if ('hooks' in field && field.hooks?.afterChange) {
|
|
for (const hook of field.hooks.afterChange){
|
|
const hookedValue = await hook({
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data,
|
|
field,
|
|
global,
|
|
indexPath: indexPathSegments,
|
|
operation,
|
|
originalDoc: doc,
|
|
path: pathSegments,
|
|
previousDoc,
|
|
previousSiblingDoc,
|
|
previousValue: getNestedValue(previousValData, pathSegments) ?? previousValData?.[field.name],
|
|
req,
|
|
schemaPath: schemaPathSegments,
|
|
siblingData,
|
|
siblingFields: siblingFields,
|
|
value: getNestedValue(siblingDoc, pathSegments) ?? siblingDoc?.[field.name]
|
|
});
|
|
if (hookedValue !== undefined) {
|
|
siblingDoc[field.name] = hookedValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Traverse subfields
|
|
switch(field.type){
|
|
case 'array':
|
|
{
|
|
const rows = siblingDoc[field.name];
|
|
if (Array.isArray(rows)) {
|
|
const promises = [];
|
|
rows.forEach((row, rowIndex)=>{
|
|
promises.push(traverseFields({
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data,
|
|
doc,
|
|
fields: field.fields,
|
|
global,
|
|
operation,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path + '.' + rowIndex,
|
|
parentSchemaPath: schemaPath,
|
|
previousDoc,
|
|
previousSiblingDoc: previousDoc?.[field.name]?.[rowIndex] || {},
|
|
req,
|
|
siblingData: siblingData?.[field.name]?.[rowIndex] || {},
|
|
siblingDoc: row ? {
|
|
...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) {
|
|
promises.push(traverseFields({
|
|
blockData: siblingData?.[field.name]?.[rowIndex],
|
|
collection,
|
|
context,
|
|
data,
|
|
doc,
|
|
fields: block.fields,
|
|
global,
|
|
operation,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path + '.' + rowIndex,
|
|
parentSchemaPath: schemaPath + '.' + block.slug,
|
|
previousDoc,
|
|
previousSiblingDoc: previousValData?.[field.name]?.[rowIndex] || {},
|
|
req,
|
|
siblingData: siblingData?.[field.name]?.[rowIndex] || {},
|
|
siblingDoc: row ? {
|
|
...row
|
|
} : {}
|
|
}));
|
|
}
|
|
});
|
|
await Promise.all(promises);
|
|
}
|
|
break;
|
|
}
|
|
case 'collapsible':
|
|
case 'row':
|
|
{
|
|
await traverseFields({
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data,
|
|
doc,
|
|
fields: field.fields,
|
|
global,
|
|
operation,
|
|
parentIndexPath: indexPath,
|
|
parentIsLocalized,
|
|
parentPath,
|
|
parentSchemaPath: schemaPath,
|
|
previousDoc,
|
|
previousSiblingDoc: {
|
|
...previousSiblingDoc
|
|
},
|
|
req,
|
|
siblingData: siblingData || {},
|
|
siblingDoc: {
|
|
...siblingDoc
|
|
}
|
|
});
|
|
break;
|
|
}
|
|
case 'group':
|
|
{
|
|
if (fieldAffectsData(field)) {
|
|
await traverseFields({
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data,
|
|
doc,
|
|
fields: field.fields,
|
|
global,
|
|
operation,
|
|
parentIndexPath: '',
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: path,
|
|
parentSchemaPath: schemaPath,
|
|
previousDoc,
|
|
previousSiblingDoc: previousDoc?.[field.name] || {},
|
|
req,
|
|
siblingData: siblingData?.[field.name] || {},
|
|
siblingDoc: siblingDoc?.[field.name] || {}
|
|
});
|
|
} else {
|
|
await traverseFields({
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data,
|
|
doc,
|
|
fields: field.fields,
|
|
global,
|
|
operation,
|
|
parentIndexPath: indexPath,
|
|
parentIsLocalized,
|
|
parentPath,
|
|
parentSchemaPath: schemaPath,
|
|
previousDoc,
|
|
previousSiblingDoc: {
|
|
...previousSiblingDoc
|
|
},
|
|
req,
|
|
siblingData: siblingData || {},
|
|
siblingDoc: {
|
|
...siblingDoc
|
|
}
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
case 'richText':
|
|
{
|
|
if (!field?.editor) {
|
|
throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
|
|
;
|
|
}
|
|
if (typeof field.editor === 'function') {
|
|
throw new Error('Attempted to access unsanitized rich text editor.');
|
|
}
|
|
const editor = field.editor;
|
|
if (editor?.hooks?.afterChange?.length) {
|
|
for (const hook of editor.hooks.afterChange){
|
|
const hookedValue = await hook({
|
|
collection,
|
|
context,
|
|
data,
|
|
field,
|
|
global,
|
|
indexPath: indexPathSegments,
|
|
operation,
|
|
originalDoc: doc,
|
|
parentIsLocalized,
|
|
path: pathSegments,
|
|
previousDoc,
|
|
previousSiblingDoc,
|
|
previousValue: getNestedValue(previousValData, pathSegments) ?? previousValData?.[field.name],
|
|
req,
|
|
schemaPath: schemaPathSegments,
|
|
siblingData,
|
|
value: siblingDoc?.[field.name]
|
|
});
|
|
if (hookedValue !== undefined) {
|
|
siblingDoc[field.name] = hookedValue;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 'tab':
|
|
{
|
|
let tabSiblingData = siblingData;
|
|
let tabSiblingDoc = siblingDoc;
|
|
let tabPreviousSiblingDoc = {
|
|
...previousDoc
|
|
};
|
|
const isNamedTab = tabHasName(field);
|
|
if (isNamedTab) {
|
|
tabSiblingData = siblingData?.[field.name] ?? {};
|
|
tabSiblingDoc = siblingDoc?.[field.name] ?? {};
|
|
tabPreviousSiblingDoc = previousSiblingDoc?.[field.name] ?? {};
|
|
}
|
|
await traverseFields({
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data,
|
|
doc,
|
|
fields: field.fields,
|
|
global,
|
|
operation,
|
|
parentIndexPath: isNamedTab ? '' : indexPath,
|
|
parentIsLocalized: parentIsLocalized || field.localized,
|
|
parentPath: isNamedTab ? path : parentPath,
|
|
parentSchemaPath: schemaPath,
|
|
previousDoc,
|
|
previousSiblingDoc: tabPreviousSiblingDoc,
|
|
req,
|
|
siblingData: tabSiblingData,
|
|
siblingDoc: tabSiblingDoc
|
|
});
|
|
break;
|
|
}
|
|
case 'tabs':
|
|
{
|
|
await traverseFields({
|
|
blockData,
|
|
collection,
|
|
context,
|
|
data,
|
|
doc,
|
|
fields: field.tabs.map((tab)=>({
|
|
...tab,
|
|
type: 'tab'
|
|
})),
|
|
global,
|
|
operation,
|
|
parentIndexPath: indexPath,
|
|
parentIsLocalized,
|
|
parentPath: path,
|
|
parentSchemaPath: schemaPath,
|
|
previousDoc,
|
|
previousSiblingDoc: {
|
|
...previousSiblingDoc
|
|
},
|
|
req,
|
|
siblingData: siblingData || {},
|
|
siblingDoc: {
|
|
...siblingDoc
|
|
}
|
|
});
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
//# sourceMappingURL=promise.js.map |