payload
Version:
Node, React, Headless CMS and Application Framework built on Next.js
175 lines (174 loc) • 6.39 kB
JavaScript
// @ts-strict-ignore
import { status as httpStatus } from 'http-status';
import executeAccess from '../../auth/executeAccess.js';
import { hasWhereAccessResult } from '../../auth/types.js';
import { combineQueries } from '../../database/combineQueries.js';
import { APIError, Forbidden, NotFound } from '../../errors/index.js';
import { afterChange } from '../../fields/hooks/afterChange/index.js';
import { afterRead } from '../../fields/hooks/afterRead/index.js';
import { killTransaction } from '../../utilities/killTransaction.js';
import { sanitizeSelect } from '../../utilities/sanitizeSelect.js';
import { getLatestCollectionVersion } from '../../versions/getLatestCollectionVersion.js';
export const restoreVersionOperation = async (args)=>{
const { id, collection: { config: collectionConfig }, depth, draft, overrideAccess = false, populate, req, req: { fallbackLocale, locale, payload }, select: incomingSelect, showHiddenFields } = args;
try {
if (!id) {
throw new APIError('Missing ID of version to restore.', httpStatus.BAD_REQUEST);
}
// /////////////////////////////////////
// Retrieve original raw version
// /////////////////////////////////////
const { docs: versionDocs } = await req.payload.db.findVersions({
collection: collectionConfig.slug,
limit: 1,
locale,
pagination: false,
req,
where: {
id: {
equals: id
}
}
});
const [rawVersion] = versionDocs;
if (!rawVersion) {
throw new NotFound(req.t);
}
const parentDocID = rawVersion.parent;
// /////////////////////////////////////
// Access
// /////////////////////////////////////
const accessResults = !overrideAccess ? await executeAccess({
id: parentDocID,
req
}, collectionConfig.access.update) : true;
const hasWherePolicy = hasWhereAccessResult(accessResults);
// /////////////////////////////////////
// Retrieve document
// /////////////////////////////////////
const findOneArgs = {
collection: collectionConfig.slug,
locale,
req,
where: combineQueries({
id: {
equals: parentDocID
}
}, accessResults)
};
const doc = await req.payload.db.findOne(findOneArgs);
if (!doc && !hasWherePolicy) {
throw new NotFound(req.t);
}
if (!doc && hasWherePolicy) {
throw new Forbidden(req.t);
}
// /////////////////////////////////////
// fetch previousDoc
// /////////////////////////////////////
const prevDocWithLocales = await getLatestCollectionVersion({
id: parentDocID,
config: collectionConfig,
payload,
query: findOneArgs,
req
});
// /////////////////////////////////////
// Update
// /////////////////////////////////////
const select = sanitizeSelect({
forceSelect: collectionConfig.forceSelect,
select: incomingSelect
});
let result = await req.payload.db.updateOne({
id: parentDocID,
collection: collectionConfig.slug,
data: rawVersion.version,
req,
select
});
// /////////////////////////////////////
// Save `previousDoc` as a version after restoring
// /////////////////////////////////////
const prevVersion = {
...prevDocWithLocales
};
delete prevVersion.id;
await payload.db.createVersion({
autosave: false,
collectionSlug: collectionConfig.slug,
createdAt: prevVersion.createdAt,
parent: parentDocID,
req,
updatedAt: new Date().toISOString(),
versionData: draft ? {
...rawVersion.version,
_status: 'draft'
} : rawVersion.version
});
// /////////////////////////////////////
// afterRead - Fields
// /////////////////////////////////////
result = await afterRead({
collection: collectionConfig,
context: req.context,
depth,
doc: result,
draft: undefined,
fallbackLocale,
global: null,
locale,
overrideAccess,
populate,
req,
select,
showHiddenFields
});
// /////////////////////////////////////
// afterRead - Collection
// /////////////////////////////////////
if (collectionConfig.hooks?.afterRead?.length) {
for (const hook of collectionConfig.hooks.afterRead){
result = await hook({
collection: collectionConfig,
context: req.context,
doc: result,
req
}) || result;
}
}
// /////////////////////////////////////
// afterChange - Fields
// /////////////////////////////////////
result = await afterChange({
collection: collectionConfig,
context: req.context,
data: result,
doc: result,
global: null,
operation: 'update',
previousDoc: prevDocWithLocales,
req
});
// /////////////////////////////////////
// afterChange - Collection
// /////////////////////////////////////
if (collectionConfig.hooks?.afterChange?.length) {
for (const hook of collectionConfig.hooks.afterChange){
result = await hook({
collection: collectionConfig,
context: req.context,
doc: result,
operation: 'update',
previousDoc: prevDocWithLocales,
req
}) || result;
}
}
return result;
} catch (error) {
await killTransaction(req);
throw error;
}
};
//# sourceMappingURL=restoreVersion.js.map