179 lines
5.0 KiB
JavaScript
179 lines
5.0 KiB
JavaScript
const validationPromise = require('./validationPromise');
|
|
const accessPromise = require('./accessPromise');
|
|
const hookPromise = require('./hookPromise');
|
|
|
|
const traverseFields = (args) => {
|
|
const {
|
|
fields,
|
|
data = {},
|
|
originalDoc = {},
|
|
path,
|
|
reduceLocales,
|
|
locale,
|
|
fallbackLocale,
|
|
accessPromises,
|
|
operation,
|
|
overrideAccess,
|
|
req,
|
|
id,
|
|
relationshipPopulations,
|
|
depth,
|
|
currentDepth,
|
|
hook,
|
|
hookPromises,
|
|
fullOriginalDoc,
|
|
fullData,
|
|
performFieldOperations,
|
|
validationPromises,
|
|
errors,
|
|
payload,
|
|
populate,
|
|
} = args;
|
|
|
|
fields.forEach((field) => {
|
|
const dataCopy = data;
|
|
|
|
if (reduceLocales && field.name && field.localized && locale !== 'all' && typeof data[field.name] === 'object') {
|
|
let localizedValue = data[field.name][locale];
|
|
if (typeof localizedValue === 'undefined' && fallbackLocale) localizedValue = data[field.name][fallbackLocale];
|
|
if (typeof localizedValue === 'undefined') localizedValue = null;
|
|
dataCopy[field.name] = localizedValue;
|
|
}
|
|
|
|
if (operation === 'read' && field.hidden && typeof data[field.name] !== 'undefined') {
|
|
delete data[field.name];
|
|
}
|
|
|
|
if (field.type === 'upload') {
|
|
if (data[field.name] === '') dataCopy[field.name] = null;
|
|
}
|
|
|
|
if (field.type === 'checkbox') {
|
|
if (data[field.name] === 'true') dataCopy[field.name] = true;
|
|
if (data[field.name] === 'false') dataCopy[field.name] = false;
|
|
if (data[field.name] === '') dataCopy[field.name] = false;
|
|
}
|
|
|
|
// If richText content comes through as a string, parse it into JSON
|
|
|
|
if (field.type === 'richText' && typeof data[field.name] === 'string') {
|
|
dataCopy[field.name] = JSON.parse(data[field.name]);
|
|
}
|
|
|
|
accessPromises.push(accessPromise({
|
|
populate,
|
|
data,
|
|
originalDoc,
|
|
field,
|
|
operation,
|
|
overrideAccess,
|
|
req,
|
|
id,
|
|
relationshipPopulations,
|
|
hook,
|
|
}));
|
|
|
|
hookPromises.push(hookPromise({
|
|
data,
|
|
field,
|
|
hook,
|
|
performFieldOperations,
|
|
req,
|
|
operation,
|
|
fullOriginalDoc,
|
|
fullData,
|
|
payload,
|
|
}));
|
|
|
|
if (field.fields) {
|
|
if (field.name === undefined) {
|
|
traverseFields({
|
|
...args,
|
|
fields: field.fields,
|
|
});
|
|
} else if (field.type === 'array') {
|
|
if (Array.isArray(data[field.name])) {
|
|
data[field.name].forEach((rowData, i) => {
|
|
const originalDocRow = originalDoc && originalDoc[field.name] && originalDoc[field.name][i];
|
|
traverseFields({
|
|
...args,
|
|
fields: field.fields,
|
|
data: rowData,
|
|
originalDoc: originalDocRow || undefined,
|
|
path: `${path}${field.name}.${i}.`,
|
|
});
|
|
});
|
|
}
|
|
} else {
|
|
traverseFields({
|
|
...args,
|
|
fields: field.fields,
|
|
data: data[field.name],
|
|
originalDoc: originalDoc[field.name],
|
|
path: `${path}${field.name}.`,
|
|
});
|
|
}
|
|
}
|
|
|
|
if (field.type === 'blocks') {
|
|
if (Array.isArray(data[field.name])) {
|
|
data[field.name].forEach((rowData, i) => {
|
|
const block = field.blocks.find((blockType) => blockType.slug === rowData.blockType);
|
|
const originalDocRow = originalDoc && originalDoc[field.name] && originalDoc[field.name][i];
|
|
|
|
if (block) {
|
|
traverseFields({
|
|
...args,
|
|
fields: block.fields,
|
|
data: rowData,
|
|
originalDoc: originalDocRow || undefined,
|
|
path: `${path}${field.name}.${i}.`,
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if ((operation === 'create' || operation === 'update') && field.name) {
|
|
const updatedData = data;
|
|
|
|
if (data[field.name] === undefined && originalDoc[field.name] === undefined && field.defaultValue) {
|
|
updatedData[field.name] = field.defaultValue;
|
|
}
|
|
|
|
if (field.type === 'array' || field.type === 'blocks') {
|
|
const hasRowsOfNewData = Array.isArray(data[field.name]);
|
|
const newRowCount = hasRowsOfNewData ? data[field.name].length : 0;
|
|
|
|
// Handle cases of arrays being intentionally set to 0
|
|
if (data[field.name] === '0' || data[field.name] === 0 || data[field.name] === null) {
|
|
updatedData[field.name] = [];
|
|
}
|
|
|
|
const hasRowsOfExistingData = Array.isArray(originalDoc[field.name]);
|
|
const existingRowCount = hasRowsOfExistingData ? originalDoc[field.name].length : 0;
|
|
|
|
validationPromises.push(() => validationPromise({
|
|
errors,
|
|
hook,
|
|
newData: { [field.name]: newRowCount },
|
|
existingData: { [field.name]: existingRowCount },
|
|
field,
|
|
path,
|
|
}));
|
|
} else {
|
|
validationPromises.push(() => validationPromise({
|
|
errors,
|
|
hook,
|
|
newData: data,
|
|
existingData: originalDoc,
|
|
field,
|
|
path,
|
|
}));
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
module.exports = traverseFields;
|