chore: ensures only drafts use current time in versioning
This commit is contained in:
@@ -214,8 +214,7 @@ async function create<TSlug extends keyof GeneratedTypes['collections']>(
|
||||
|
||||
// custom id type reset
|
||||
result.id = result._id;
|
||||
result = JSON.stringify(result);
|
||||
result = JSON.parse(result);
|
||||
result = JSON.parse(JSON.stringify(result));
|
||||
result = sanitizeInternalFields(result);
|
||||
|
||||
// /////////////////////////////////////
|
||||
@@ -230,8 +229,6 @@ async function create<TSlug extends keyof GeneratedTypes['collections']>(
|
||||
id: result.id,
|
||||
docWithLocales: result,
|
||||
autosave,
|
||||
createdAt: result.createdAt,
|
||||
onCreate: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Where } from '../../types';
|
||||
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields';
|
||||
import { afterChange } from '../../fields/hooks/afterChange';
|
||||
import { afterRead } from '../../fields/hooks/afterRead';
|
||||
import { getLatestCollectionVersion } from '../../versions/getLatestCollectionVersion';
|
||||
import { getLatestEntityVersion } from '../../versions/getLatestCollectionVersion';
|
||||
|
||||
export type Arguments = {
|
||||
collection: Collection
|
||||
@@ -24,7 +24,6 @@ export type Arguments = {
|
||||
|
||||
async function restoreVersion<T extends TypeWithID = any>(args: Arguments): Promise<T> {
|
||||
const {
|
||||
collection,
|
||||
collection: {
|
||||
Model,
|
||||
config: collectionConfig,
|
||||
@@ -101,11 +100,12 @@ async function restoreVersion<T extends TypeWithID = any>(args: Arguments): Prom
|
||||
// fetch previousDoc
|
||||
// /////////////////////////////////////
|
||||
|
||||
const prevDocWithLocales = await getLatestCollectionVersion({
|
||||
const prevDocWithLocales = await getLatestEntityVersion({
|
||||
payload,
|
||||
collection,
|
||||
id: parentDocID,
|
||||
query,
|
||||
Model,
|
||||
config: collectionConfig,
|
||||
});
|
||||
|
||||
// /////////////////////////////////////
|
||||
@@ -122,8 +122,7 @@ async function restoreVersion<T extends TypeWithID = any>(args: Arguments): Prom
|
||||
|
||||
// custom id type reset
|
||||
result.id = result._id;
|
||||
result = JSON.stringify(result);
|
||||
result = JSON.parse(result);
|
||||
result = JSON.parse(JSON.stringify(result));
|
||||
result = sanitizeInternalFields(result);
|
||||
|
||||
// /////////////////////////////////////
|
||||
|
||||
@@ -14,7 +14,7 @@ import { beforeValidate } from '../../fields/hooks/beforeValidate';
|
||||
import { afterChange } from '../../fields/hooks/afterChange';
|
||||
import { afterRead } from '../../fields/hooks/afterRead';
|
||||
import { generateFileData } from '../../uploads/generateFileData';
|
||||
import { getLatestCollectionVersion } from '../../versions/getLatestCollectionVersion';
|
||||
import { getLatestEntityVersion } from '../../versions/getLatestCollectionVersion';
|
||||
|
||||
export type Arguments<T extends { [field: string | number | symbol]: unknown }> = {
|
||||
collection: Collection
|
||||
@@ -111,7 +111,14 @@ async function update<TSlug extends keyof GeneratedTypes['collections']>(
|
||||
|
||||
const query = await Model.buildQuery(queryToBuild, locale);
|
||||
|
||||
const doc = await getLatestCollectionVersion({ payload, collection, id, query, lean });
|
||||
const doc = await getLatestEntityVersion({
|
||||
payload,
|
||||
Model,
|
||||
config: collectionConfig,
|
||||
id,
|
||||
query,
|
||||
lean,
|
||||
});
|
||||
|
||||
if (!doc && !hasWherePolicy) throw new NotFound(t);
|
||||
if (!doc && hasWherePolicy) throw new Forbidden(t);
|
||||
@@ -253,11 +260,13 @@ async function update<TSlug extends keyof GeneratedTypes['collections']>(
|
||||
payload,
|
||||
collection: collectionConfig,
|
||||
req,
|
||||
docWithLocales: result,
|
||||
docWithLocales: {
|
||||
...result,
|
||||
createdAt: docWithLocales.createdAt,
|
||||
},
|
||||
id,
|
||||
autosave,
|
||||
draft: shouldSaveDraft,
|
||||
createdAt: originalDoc.createdAt,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Config as GeneratedTypes } from 'payload/generated-types';
|
||||
import { docHasTimestamps, Where } from '../../types';
|
||||
import { Where } from '../../types';
|
||||
import { SanitizedGlobalConfig } from '../config/types';
|
||||
import executeAccess from '../../auth/executeAccess';
|
||||
import { hasWhereAccessResult } from '../../auth';
|
||||
@@ -10,6 +10,7 @@ import { afterRead } from '../../fields/hooks/afterRead';
|
||||
import { PayloadRequest } from '../../express/types';
|
||||
import { saveVersion } from '../../versions/saveVersion';
|
||||
import sanitizeInternalFields from '../../utilities/sanitizeInternalFields';
|
||||
import { getLatestEntityVersion } from '../../versions/getLatestCollectionVersion';
|
||||
|
||||
type Args<T extends { [field: string | number | symbol]: unknown }> = {
|
||||
globalConfig: SanitizedGlobalConfig
|
||||
@@ -82,36 +83,21 @@ async function update<TSlug extends keyof GeneratedTypes['globals']>(
|
||||
// 2. Retrieve document
|
||||
// /////////////////////////////////////
|
||||
|
||||
let version;
|
||||
let global;
|
||||
let global = await getLatestEntityVersion({
|
||||
payload,
|
||||
Model,
|
||||
config: globalConfig,
|
||||
query,
|
||||
lean: true,
|
||||
entityType: 'global',
|
||||
});
|
||||
|
||||
if (globalConfig.versions?.drafts) {
|
||||
version = payload.versions[globalConfig.slug].findOne({}, {}, {
|
||||
sort: {
|
||||
updatedAt: 'desc',
|
||||
},
|
||||
lean: true,
|
||||
});
|
||||
}
|
||||
|
||||
const existingGlobal = await payload.globals.Model.findOne(query).lean();
|
||||
version = await version;
|
||||
|
||||
if (!version || (existingGlobal && docHasTimestamps(existingGlobal) && version.updatedAt < existingGlobal.updatedAt)) {
|
||||
global = existingGlobal;
|
||||
} else {
|
||||
global = {
|
||||
...version.version,
|
||||
updatedAt: version.updatedAt,
|
||||
createdAt: version.createdAt,
|
||||
};
|
||||
}
|
||||
const globalExists = Boolean(global);
|
||||
|
||||
let globalJSON: Record<string, unknown> = {};
|
||||
|
||||
if (global) {
|
||||
const globalJSONString = JSON.stringify(global);
|
||||
globalJSON = JSON.parse(globalJSONString);
|
||||
globalJSON = JSON.parse(JSON.stringify(global));
|
||||
|
||||
if (globalJSON._id) {
|
||||
delete globalJSON._id;
|
||||
@@ -187,7 +173,7 @@ async function update<TSlug extends keyof GeneratedTypes['globals']>(
|
||||
// /////////////////////////////////////
|
||||
|
||||
if (!shouldSaveDraft) {
|
||||
if (existingGlobal) {
|
||||
if (globalExists) {
|
||||
global = await Model.findOneAndUpdate(
|
||||
{ globalType: slug },
|
||||
result,
|
||||
@@ -199,8 +185,7 @@ async function update<TSlug extends keyof GeneratedTypes['globals']>(
|
||||
}
|
||||
}
|
||||
|
||||
global = JSON.stringify(global);
|
||||
global = JSON.parse(global);
|
||||
global = JSON.parse(JSON.stringify(global));
|
||||
global = sanitizeInternalFields(global);
|
||||
|
||||
// /////////////////////////////////////
|
||||
@@ -212,10 +197,13 @@ async function update<TSlug extends keyof GeneratedTypes['globals']>(
|
||||
payload,
|
||||
global: globalConfig,
|
||||
req,
|
||||
docWithLocales: result,
|
||||
docWithLocales: {
|
||||
...result,
|
||||
createdAt: global.createdAt,
|
||||
updatedAt: global.updatedAt,
|
||||
},
|
||||
autosave,
|
||||
draft: shouldSaveDraft,
|
||||
createdAt: global.createdAt,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,45 +1,58 @@
|
||||
import { Document } from '../types';
|
||||
import { docHasTimestamps, Document } from '../types';
|
||||
import { Payload } from '../payload';
|
||||
import { Collection, TypeWithID } from '../collections/config/types';
|
||||
import sanitizeInternalFields from '../utilities/sanitizeInternalFields';
|
||||
import { CollectionModel, SanitizedCollectionConfig, TypeWithID } from '../collections/config/types';
|
||||
import { GlobalModel, SanitizedGlobalConfig } from '../globals/config/types';
|
||||
|
||||
type Args = {
|
||||
payload: Payload
|
||||
collection: Collection,
|
||||
query: Record<string, unknown>
|
||||
id: string | number
|
||||
lean?: boolean
|
||||
}
|
||||
} & ({
|
||||
entityType: 'global'
|
||||
id?: never
|
||||
Model: GlobalModel
|
||||
config: SanitizedGlobalConfig
|
||||
} | {
|
||||
entityType?: 'collection'
|
||||
id: string | number
|
||||
Model: CollectionModel
|
||||
config: SanitizedCollectionConfig
|
||||
})
|
||||
|
||||
export const getLatestCollectionVersion = async <T extends TypeWithID = any>({
|
||||
export const getLatestEntityVersion = async <T extends TypeWithID = any>({
|
||||
payload,
|
||||
collection: {
|
||||
config,
|
||||
Model,
|
||||
},
|
||||
entityType = 'collection',
|
||||
config,
|
||||
Model,
|
||||
query,
|
||||
id,
|
||||
lean = true,
|
||||
}: Args): Promise<T> => {
|
||||
let version;
|
||||
let latestVersion;
|
||||
|
||||
if (config.versions?.drafts) {
|
||||
version = payload.versions[config.slug].findOne({
|
||||
latestVersion = await payload.versions[config.slug].findOne({
|
||||
parent: id,
|
||||
}, {}, {
|
||||
sort: { updatedAt: 'desc' },
|
||||
lean,
|
||||
});
|
||||
}
|
||||
const collection = await Model.findOne(query, {}, { lean }) as Document;
|
||||
version = await version;
|
||||
if (!version || version.updatedAt < collection.updatedAt) {
|
||||
collection.id = collection._id;
|
||||
return collection;
|
||||
|
||||
const doc = await (Model as any).findOne(query, {}, { lean }) as Document;
|
||||
|
||||
if (!latestVersion || (docHasTimestamps(doc) && latestVersion.updatedAt < doc.updatedAt)) {
|
||||
if (entityType === 'collection') {
|
||||
doc.id = doc._id;
|
||||
return doc;
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
|
||||
return {
|
||||
...version.version,
|
||||
...latestVersion.version,
|
||||
id,
|
||||
updatedAt: version.updatedAt,
|
||||
createdAt: version.createdAt,
|
||||
updatedAt: latestVersion.updatedAt,
|
||||
createdAt: latestVersion.createdAt,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -15,8 +15,6 @@ type Args = {
|
||||
id?: string | number
|
||||
autosave?: boolean
|
||||
draft?: boolean
|
||||
createdAt: string
|
||||
onCreate?: boolean
|
||||
}
|
||||
|
||||
export const saveVersion = async ({
|
||||
@@ -24,12 +22,11 @@ export const saveVersion = async ({
|
||||
collection,
|
||||
global,
|
||||
id,
|
||||
docWithLocales,
|
||||
docWithLocales: doc,
|
||||
autosave,
|
||||
draft,
|
||||
createdAt,
|
||||
onCreate = false,
|
||||
}: Args): Promise<TypeWithID> => {
|
||||
let result;
|
||||
let entityConfig;
|
||||
let entityType: 'global' | 'collection';
|
||||
|
||||
@@ -45,49 +42,48 @@ export const saveVersion = async ({
|
||||
|
||||
const VersionModel = payload.versions[entityConfig.slug];
|
||||
|
||||
const versionData = { ...docWithLocales };
|
||||
const versionData = { ...doc };
|
||||
if (draft) versionData._status = 'draft';
|
||||
if (versionData._id) delete versionData._id;
|
||||
|
||||
let existingAutosaveVersion;
|
||||
|
||||
if (autosave) {
|
||||
const query: FilterQuery<unknown> = {};
|
||||
if (collection) query.parent = id;
|
||||
existingAutosaveVersion = await VersionModel.findOne(query, {}, { sort: { updatedAt: 'desc' } });
|
||||
}
|
||||
|
||||
let result;
|
||||
const now = new Date().toISOString();
|
||||
|
||||
try {
|
||||
if (autosave && existingAutosaveVersion?.autosave === true) {
|
||||
const data: Record<string, unknown> = {
|
||||
version: versionData,
|
||||
createdAt,
|
||||
updatedAt: now,
|
||||
};
|
||||
let createNewVersion = true;
|
||||
const now = new Date().toISOString();
|
||||
|
||||
if (createdAt) data.updatedAt = createdAt;
|
||||
if (autosave) {
|
||||
const query: FilterQuery<unknown> = {};
|
||||
if (collection) query.parent = id;
|
||||
const latestVersion = await VersionModel.findOne(query, {}, { sort: { updatedAt: 'desc' } });
|
||||
|
||||
result = await VersionModel.findByIdAndUpdate(
|
||||
{
|
||||
_id: existingAutosaveVersion._id,
|
||||
},
|
||||
data,
|
||||
{ new: true, lean: true },
|
||||
);
|
||||
// Otherwise, create a new one
|
||||
} else {
|
||||
// overwrite the latest version if it's set to autosave
|
||||
if (latestVersion?.autosave === true) {
|
||||
createNewVersion = false;
|
||||
|
||||
const data: Record<string, unknown> = {
|
||||
version: versionData,
|
||||
createdAt: new Date(latestVersion.createdAt).toISOString(),
|
||||
updatedAt: draft ? now : new Date(doc.updatedAt).toISOString(),
|
||||
};
|
||||
|
||||
result = await VersionModel.findByIdAndUpdate(
|
||||
{
|
||||
_id: latestVersion._id,
|
||||
},
|
||||
data,
|
||||
{ new: true, lean: true },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (createNewVersion) {
|
||||
const data: Record<string, unknown> = {
|
||||
version: versionData,
|
||||
...versionData,
|
||||
autosave: Boolean(autosave),
|
||||
updatedAt: onCreate ? createdAt : now,
|
||||
createdAt: createdAt || now,
|
||||
version: versionData,
|
||||
createdAt: draft ? now : new Date(doc.createdAt).toISOString(),
|
||||
updatedAt: draft ? now : new Date(doc.updatedAt).toISOString(),
|
||||
};
|
||||
|
||||
if (collection) data.parent = id;
|
||||
|
||||
result = await VersionModel.create(data);
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user