payload
Version:
Node, React, Headless CMS and Application Framework built on Next.js
281 lines (280 loc) • 10.5 kB
JavaScript
// @ts-strict-ignore
import executeAccess from '../../auth/executeAccess.js';
import { afterChange } from '../../fields/hooks/afterChange/index.js';
import { afterRead } from '../../fields/hooks/afterRead/index.js';
import { beforeChange } from '../../fields/hooks/beforeChange/index.js';
import { beforeValidate } from '../../fields/hooks/beforeValidate/index.js';
import { deepCopyObjectSimple } from '../../index.js';
import { checkDocumentLockStatus } from '../../utilities/checkDocumentLockStatus.js';
import { commitTransaction } from '../../utilities/commitTransaction.js';
import { getSelectMode } from '../../utilities/getSelectMode.js';
import { initTransaction } from '../../utilities/initTransaction.js';
import { killTransaction } from '../../utilities/killTransaction.js';
import { sanitizeSelect } from '../../utilities/sanitizeSelect.js';
import { getLatestGlobalVersion } from '../../versions/getLatestGlobalVersion.js';
import { saveVersion } from '../../versions/saveVersion.js';
export const updateOperation = async (args)=>{
if (args.publishSpecificLocale) {
args.req.locale = args.publishSpecificLocale;
}
const { slug, autosave, depth, disableTransaction, draft: draftArg, globalConfig, overrideAccess, overrideLock, populate, publishSpecificLocale, req: { fallbackLocale, locale, payload }, req, select: incomingSelect, showHiddenFields } = args;
try {
const shouldCommit = !disableTransaction && await initTransaction(req);
let { data } = args;
const shouldSaveDraft = Boolean(draftArg && globalConfig.versions?.drafts);
// /////////////////////////////////////
// 1. Retrieve and execute access
// /////////////////////////////////////
const accessResults = !overrideAccess ? await executeAccess({
data,
req
}, globalConfig.access.update) : true;
// /////////////////////////////////////
// Retrieve document
// /////////////////////////////////////
const query = overrideAccess ? undefined : accessResults;
// /////////////////////////////////////
// 2. Retrieve document
// /////////////////////////////////////
const globalVersion = await getLatestGlobalVersion({
slug,
config: globalConfig,
locale,
payload,
req,
where: query
});
const { global, globalExists } = globalVersion || {};
let globalJSON = {};
if (globalVersion && globalVersion.global) {
globalJSON = deepCopyObjectSimple(global);
if (globalJSON._id) {
delete globalJSON._id;
}
}
const originalDoc = await afterRead({
collection: null,
context: req.context,
depth: 0,
doc: deepCopyObjectSimple(globalJSON),
draft: draftArg,
fallbackLocale,
global: globalConfig,
locale,
overrideAccess: true,
req,
showHiddenFields
});
// ///////////////////////////////////////////
// Handle potentially locked global documents
// ///////////////////////////////////////////
await checkDocumentLockStatus({
globalSlug: slug,
lockErrorMessage: `Global with slug "${slug}" is currently locked by another user and cannot be updated.`,
overrideLock,
req
});
// /////////////////////////////////////
// beforeValidate - Fields
// /////////////////////////////////////
data = await beforeValidate({
collection: null,
context: req.context,
data,
doc: originalDoc,
global: globalConfig,
operation: 'update',
overrideAccess,
req
});
// /////////////////////////////////////
// beforeValidate - Global
// /////////////////////////////////////
if (globalConfig.hooks?.beforeValidate?.length) {
for (const hook of globalConfig.hooks.beforeValidate){
data = await hook({
context: req.context,
data,
global: globalConfig,
originalDoc,
req
}) || data;
}
}
// /////////////////////////////////////
// beforeChange - Global
// /////////////////////////////////////
if (globalConfig.hooks?.beforeChange?.length) {
for (const hook of globalConfig.hooks.beforeChange){
data = await hook({
context: req.context,
data,
global: globalConfig,
originalDoc,
req
}) || data;
}
}
// /////////////////////////////////////
// beforeChange - Fields
// /////////////////////////////////////
let publishedDocWithLocales = globalJSON;
let versionSnapshotResult;
const beforeChangeArgs = {
collection: null,
context: req.context,
data,
doc: originalDoc,
docWithLocales: undefined,
global: globalConfig,
operation: 'update',
req,
skipValidation: shouldSaveDraft && globalConfig.versions.drafts && !globalConfig.versions.drafts.validate
};
if (publishSpecificLocale) {
const latestVersion = await getLatestGlobalVersion({
slug,
config: globalConfig,
payload,
published: true,
req,
where: query
});
publishedDocWithLocales = latestVersion?.global || {};
versionSnapshotResult = await beforeChange({
...beforeChangeArgs,
docWithLocales: globalJSON
});
}
let result = await beforeChange({
...beforeChangeArgs,
docWithLocales: publishedDocWithLocales
});
// /////////////////////////////////////
// Update
// /////////////////////////////////////
const select = sanitizeSelect({
forceSelect: globalConfig.forceSelect,
select: incomingSelect
});
if (!shouldSaveDraft) {
// Ensure global has createdAt
if (!result.createdAt) {
result.createdAt = new Date().toISOString();
}
if (globalExists) {
result = await payload.db.updateGlobal({
slug,
data: result,
req,
select
});
} else {
result = await payload.db.createGlobal({
slug,
data: result,
req
});
}
}
// /////////////////////////////////////
// Create version
// /////////////////////////////////////
if (globalConfig.versions) {
const { globalType } = result;
result = await saveVersion({
autosave,
docWithLocales: result,
draft: shouldSaveDraft,
global: globalConfig,
payload,
publishSpecificLocale,
req,
select,
snapshot: versionSnapshotResult
});
result = {
...result,
globalType
};
}
// /////////////////////////////////////
// Execute globalType field if not selected
// /////////////////////////////////////
if (select && result.globalType) {
const selectMode = getSelectMode(select);
if (selectMode === 'include' && !select['globalType'] || selectMode === 'exclude' && select['globalType'] === false) {
delete result['globalType'];
}
}
// /////////////////////////////////////
// afterRead - Fields
// /////////////////////////////////////
result = await afterRead({
collection: null,
context: req.context,
depth,
doc: result,
draft: draftArg,
fallbackLocale: null,
global: globalConfig,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields
});
// /////////////////////////////////////
// afterRead - Global
// /////////////////////////////////////
if (globalConfig.hooks?.afterRead?.length) {
for (const hook of globalConfig.hooks.afterRead){
result = await hook({
context: req.context,
doc: result,
global: globalConfig,
req
}) || result;
}
}
// /////////////////////////////////////
// afterChange - Fields
// /////////////////////////////////////
result = await afterChange({
collection: null,
context: req.context,
data,
doc: result,
global: globalConfig,
operation: 'update',
previousDoc: originalDoc,
req
});
// /////////////////////////////////////
// afterChange - Global
// /////////////////////////////////////
if (globalConfig.hooks?.afterChange?.length) {
for (const hook of globalConfig.hooks.afterChange){
result = await hook({
context: req.context,
doc: result,
global: globalConfig,
previousDoc: originalDoc,
req
}) || result;
}
}
// /////////////////////////////////////
// Return results
// /////////////////////////////////////
if (shouldCommit) {
await commitTransaction(req);
}
return result;
} catch (error) {
await killTransaction(req);
throw error;
}
};
//# sourceMappingURL=update.js.map