payload
Version:
Node, React, Headless CMS and Application Framework built on Next.js
373 lines (372 loc) • 14.8 kB
JavaScript
// @ts-strict-ignore
/* eslint-disable perfectionist/sort-switch-case */ // Keep perfectionist/sort-switch-case disabled - it incorrectly messes up the ordering of the switch cases, causing it to break
import { getFromImportMap } from '../../bin/generateImportMap/utilities/getFromImportMap.js';
import { MissingEditorProp } from '../../errors/MissingEditorProp.js';
import { fieldAffectsData } from '../../fields/config/types.js';
import { flattenTopLevelFields } from '../../index.js';
const serverOnlyFieldProperties = [
'hooks',
'access',
'validate',
'defaultValue',
'filterOptions',
'editor',
'custom',
'typescriptSchema',
'dbName',
'enumName',
'graphQL'
];
const serverOnlyFieldAdminProperties = [
'condition',
'components'
];
export const createClientBlocks = ({ blocks, defaultIDType, i18n, importMap })=>{
const clientBlocks = [];
for(let i = 0; i < blocks.length; i++){
const block = blocks[i];
if (typeof block === 'string') {
// Do not process blocks that are just strings - they are processed once in the client config
clientBlocks.push(block);
continue;
}
const clientBlock = {
slug: block.slug,
fields: []
};
if (block.imageAltText) {
clientBlock.imageAltText = block.imageAltText;
}
if (block.imageURL) {
clientBlock.imageURL = block.imageURL;
}
if (block.admin?.custom || block.admin?.group) {
clientBlock.admin = {};
if (block.admin.custom) {
clientBlock.admin.custom = block.admin.custom;
}
if (block.admin.group) {
clientBlock.admin.group = block.admin.group;
}
}
if (block?.admin?.jsx) {
const jsxResolved = getFromImportMap({
importMap,
PayloadComponent: block.admin.jsx,
schemaPath: ''
});
clientBlock.jsx = jsxResolved;
}
if (block?.admin?.disableBlockName) {
// Check for existing admin object, this way we don't have to spread it in
if (clientBlock.admin) {
clientBlock.admin.disableBlockName = block.admin.disableBlockName;
} else {
clientBlock.admin = {
disableBlockName: block.admin.disableBlockName
};
}
}
if (block.labels) {
clientBlock.labels = {};
if (block.labels.singular) {
if (typeof block.labels.singular === 'function') {
clientBlock.labels.singular = block.labels.singular({
i18n,
t: i18n.t
});
} else {
clientBlock.labels.singular = block.labels.singular;
}
if (typeof block.labels.plural === 'function') {
clientBlock.labels.plural = block.labels.plural({
i18n,
t: i18n.t
});
} else {
clientBlock.labels.plural = block.labels.plural;
}
}
}
clientBlock.fields = createClientFields({
defaultIDType,
fields: block.fields,
i18n,
importMap
});
clientBlocks.push(clientBlock);
}
return clientBlocks;
};
export const createClientField = ({ defaultIDType, field: incomingField, i18n, importMap })=>{
const clientField = {};
for(const key in incomingField){
if (serverOnlyFieldProperties.includes(key)) {
continue;
}
switch(key){
case 'admin':
if (!incomingField.admin) {
break;
}
clientField.admin = {};
for(const adminKey in incomingField.admin){
if (serverOnlyFieldAdminProperties.includes(adminKey)) {
continue;
}
switch(adminKey){
case 'description':
if ('description' in incomingField.admin) {
if (typeof incomingField.admin?.description !== 'function') {
;
clientField.admin.description = incomingField.admin.description;
}
}
break;
default:
clientField.admin[adminKey] = incomingField.admin[adminKey];
}
}
break;
case 'blocks':
case 'fields':
case 'tabs':
break;
case 'label':
//@ts-expect-error - would need to type narrow
if (typeof incomingField.label === 'function') {
//@ts-expect-error - would need to type narrow
clientField.label = incomingField.label({
i18n,
t: i18n.t
});
} else {
//@ts-expect-error - would need to type narrow
clientField.label = incomingField.label;
}
break;
default:
clientField[key] = incomingField[key];
}
}
switch(incomingField.type){
case 'array':
{
if (incomingField.labels) {
const field = clientField;
field.labels = {};
if (incomingField.labels.singular) {
if (typeof incomingField.labels.singular === 'function') {
field.labels.singular = incomingField.labels.singular({
i18n,
t: i18n.t
});
} else {
field.labels.singular = incomingField.labels.singular;
}
if (typeof incomingField.labels.plural === 'function') {
field.labels.plural = incomingField.labels.plural({
i18n,
t: i18n.t
});
} else {
field.labels.plural = incomingField.labels.plural;
}
}
}
}
// falls through
case 'collapsible':
case 'group':
case 'row':
{
const field = clientField;
if (!field.fields) {
field.fields = [];
}
field.fields = createClientFields({
defaultIDType,
disableAddingID: incomingField.type !== 'array',
fields: incomingField.fields,
i18n,
importMap
});
break;
}
case 'blocks':
{
const field = clientField;
if (incomingField.labels) {
field.labels = {};
if (incomingField.labels.singular) {
if (typeof incomingField.labels.singular === 'function') {
field.labels.singular = incomingField.labels.singular({
i18n,
t: i18n.t
});
} else {
field.labels.singular = incomingField.labels.singular;
}
if (typeof incomingField.labels.plural === 'function') {
field.labels.plural = incomingField.labels.plural({
i18n,
t: i18n.t
});
} else {
field.labels.plural = incomingField.labels.plural;
}
}
}
if (incomingField.blockReferences?.length) {
field.blockReferences = createClientBlocks({
blocks: incomingField.blockReferences,
defaultIDType,
i18n,
importMap
});
}
if (incomingField.blocks?.length) {
field.blocks = createClientBlocks({
blocks: incomingField.blocks,
defaultIDType,
i18n,
importMap
});
}
break;
}
case 'join':
{
const field = clientField;
field.targetField = {
relationTo: field.targetField?.relationTo
};
break;
}
case 'radio':
// falls through
case 'select':
{
const field = clientField;
if (incomingField.options?.length) {
for(let i = 0; i < incomingField.options.length; i++){
const option = incomingField.options[i];
if (typeof option === 'object' && typeof option.label === 'function') {
if (!field.options) {
field.options = [];
}
field.options[i] = {
label: option.label({
i18n,
t: i18n.t
}),
value: option.value
};
}
}
}
break;
}
case 'richText':
{
if (!incomingField?.editor) {
throw new MissingEditorProp(incomingField) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
;
}
if (typeof incomingField?.editor === 'function') {
throw new Error('Attempted to access unsanitized rich text editor.');
}
break;
}
case 'tabs':
{
const field = clientField;
if (incomingField.tabs?.length) {
field.tabs = [];
for(let i = 0; i < incomingField.tabs.length; i++){
const tab = incomingField.tabs[i];
const clientTab = {};
for(const key in tab){
if (serverOnlyFieldProperties.includes(key)) {
continue;
}
const tabProp = tab[key];
if (key === 'fields') {
clientTab.fields = createClientFields({
defaultIDType,
disableAddingID: true,
fields: tab.fields,
i18n,
importMap
});
} else if ((key === 'label' || key === 'description') && typeof tabProp === 'function') {
clientTab[key] = tabProp({
t: i18n.t
});
} else if (key === 'admin') {
clientTab.admin = {};
for(const adminKey in tab.admin){
if (serverOnlyFieldAdminProperties.includes(adminKey)) {
continue;
}
switch(adminKey){
case 'description':
if ('description' in tab.admin) {
if (typeof tab.admin?.description === 'function') {
clientTab.admin.description = tab.admin.description({
i18n,
t: i18n.t
});
} else {
clientTab.admin.description = tab.admin.description;
}
}
break;
default:
clientField.admin[adminKey] = tab.admin[adminKey];
}
}
} else {
clientTab[key] = tabProp;
}
}
field.tabs[i] = clientTab;
}
}
break;
}
default:
break;
}
return clientField;
};
export const createClientFields = ({ defaultIDType, disableAddingID, fields, i18n, importMap })=>{
const clientFields = [];
for(let i = 0; i < fields.length; i++){
const field = fields[i];
const clientField = createClientField({
defaultIDType,
field,
i18n,
importMap
});
clientFields.push(clientField);
}
const hasID = flattenTopLevelFields(fields).some((f)=>fieldAffectsData(f) && f.name === 'id');
if (!disableAddingID && !hasID) {
clientFields.push({
name: 'id',
type: defaultIDType,
admin: {
description: 'The unique identifier for this document',
disableBulkEdit: true,
disabled: true,
hidden: true
},
hidden: true,
label: 'ID'
});
}
return clientFields;
};
//# sourceMappingURL=client.js.map