Files
payload/src/fields/performFieldOperations.ts
2020-11-23 13:55:39 -05:00

96 lines
2.4 KiB
TypeScript

import { ValidationError } from '../errors';
import sanitizeFallbackLocale from '../localization/sanitizeFallbackLocale';
import traverseFields from './traverseFields';
import { Collection } from '../collections/config/types';
import { OperationArguments } from '../types';
export default async function performFieldOperations(entityConfig: Collection, args: OperationArguments): any {
const {
data: fullData,
originalDoc: fullOriginalDoc,
operation,
hook,
req,
id,
req: {
payloadAPI,
locale,
},
overrideAccess,
reduceLocales,
showHiddenFields,
} = args;
const recursivePerformFieldOperations = performFieldOperations.bind(this);
const fallbackLocale = sanitizeFallbackLocale(req.fallbackLocale);
let depth = 0;
if (payloadAPI === 'REST' || payloadAPI === 'local') {
depth = (args.depth || args.depth === 0) ? parseInt(String(args.depth), 10) : this.config.defaultDepth;
if (depth > this.config.maxDepth) depth = this.config.maxDepth;
}
const currentDepth = args.currentDepth || 1;
// Maintain a top-level list of promises
// so that all async field access / validations / hooks
// can run in parallel
const validationPromises = [];
const accessPromises = [];
const relationshipPopulations = [];
const hookPromises = [];
const errors = [];
// //////////////////////////////////////////
// Entry point for field validation
// //////////////////////////////////////////
traverseFields({
fields: entityConfig.fields,
data: fullData,
originalDoc: fullOriginalDoc,
path: '',
reduceLocales,
locale,
fallbackLocale,
accessPromises,
operation,
overrideAccess,
req,
id,
relationshipPopulations,
depth,
currentDepth,
hook,
hookPromises,
fullOriginalDoc,
fullData,
performFieldOperations: recursivePerformFieldOperations,
validationPromises,
errors,
payload: this,
showHiddenFields,
});
await Promise.all(hookPromises);
validationPromises.forEach((promise) => promise());
await Promise.all(validationPromises);
if (errors.length > 0) {
throw new ValidationError(errors);
}
await Promise.all(accessPromises);
const relationshipPopulationPromises = relationshipPopulations.map((population) => population());
await Promise.all(relationshipPopulationPromises);
return fullData;
}