UNPKG

payload

Version:

Node, React, Headless CMS and Application Framework built on Next.js

277 lines (276 loc) • 11.2 kB
// @ts-strict-ignore import { MissingEditorProp } from '../../../errors/index.js'; import { fieldAffectsData, tabHasName } from '../../config/types.js'; import { getFieldPathsModified as 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) : []; if (fieldAffectsData(field)) { // Execute hooks if (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: previousDoc[field.name], req, schemaPath: schemaPathSegments, siblingData, siblingFields, value: 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: previousDoc?.[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': { 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] }); 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: previousDoc[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 = siblingDoc; const isNamedTab = tabHasName(field); if (isNamedTab) { tabSiblingData = siblingData[field.name] ?? {}; tabSiblingDoc = siblingDoc[field.name] ?? {}; tabPreviousSiblingDoc = previousDoc[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