Detect more changes by actually comparing previous state and current state

This commit is contained in:
DrMint 2024-07-27 17:34:05 +02:00
parent 682e1b1cfb
commit 935b130075
3 changed files with 33 additions and 16 deletions

View File

@ -13,47 +13,64 @@ import {
Relationship, Relationship,
Video, Video,
} from "../types/collections"; } from "../types/collections";
import { isPayloadType } from "../utils/asserts"; import { isDefined, isPayloadType } from "../utils/asserts";
import { import {
AfterChangeHook, AfterChangeHook,
AfterDeleteHook, AfterDeleteHook,
BeforeChangeHook,
BeforeDeleteHook, BeforeDeleteHook,
} from "payload/dist/collections/config/types"; } from "payload/dist/collections/config/types";
import { GeneratedTypes } from "payload"; import { GeneratedTypes } from "payload";
import { uniqueBy } from "../utils/array"; import { uniqueBy } from "../utils/array";
import { GlobalAfterChangeHook } from "payload/types"; import { GlobalAfterChangeHook } from "payload/types";
import { findRelationByID } from "payloadcms-relationships/dist/utils"; import { findRelationByID } from "payloadcms-relationships/dist/utils";
import { RelationshipRemoved } from "payloadcms-relationships";
export const afterOutgoingRelationRemovedSendChangesWebhook = async ({ export const beforeChangePrepareChanges: BeforeChangeHook = async ({
removedOutgoingRelations, collection,
}: RelationshipRemoved) => { originalDoc,
const changes: EndpointChange[] = []; context,
data,
}) => {
if ("_status" in data && data._status === "draft") return data;
if (!originalDoc) return data;
removedOutgoingRelations?.forEach((relation) => context.beforeChangeChanges = await getChanges(
changes.push(...getEndpointChangesFromOutgoingRelation(relation)) collection.slug as keyof GeneratedTypes["collections"],
originalDoc
); );
await sendWebhookMessage(uniqueBy(changes, ({ url }) => url)); return data;
}; };
export const afterChangeSendChangesWebhook: AfterChangeHook = async ({ doc, collection }) => { export const afterChangeSendChangesWebhook: AfterChangeHook = async ({
doc,
collection,
context,
}) => {
if ("_status" in doc && doc._status === "draft") return doc; if ("_status" in doc && doc._status === "draft") return doc;
const changes = await getChanges(collection.slug as keyof GeneratedTypes["collections"], doc); const changes = await getChanges(collection.slug as keyof GeneratedTypes["collections"], doc);
await sendWebhookMessage(changes); const previousChanges = context.beforeChangeChanges as EndpointChange[] | undefined;
if (isDefined(previousChanges)) {
await sendWebhookMessage(uniqueBy([...previousChanges, ...changes], ({ url }) => url));
} else {
await sendWebhookMessage(changes);
}
return doc; return doc;
}; };
export const beforeDeletePrepareChanges: BeforeDeleteHook = async ({ id, collection, context }) => { export const beforeDeletePrepareChanges: BeforeDeleteHook = async ({ id, collection, context }) => {
const changes = await getChanges(collection.slug as keyof GeneratedTypes["collections"], { id }); context.beforeDeleteChanges = await getChanges(
context.beforeDeleteChanges = changes; collection.slug as keyof GeneratedTypes["collections"],
{ id }
);
}; };
export const afterDeleteSendChangesWebhook: AfterDeleteHook = async ({ doc, context }) => { export const afterDeleteSendChangesWebhook: AfterDeleteHook = async ({ doc, context }) => {
const changes = context.beforeDeleteChanges as EndpointChange[] | undefined; const changes = context.beforeDeleteChanges as EndpointChange[] | undefined;
if (changes) { if (isDefined(changes)) {
await sendWebhookMessage(changes); await sendWebhookMessage(changes);
} }
return doc; return doc;

View File

@ -33,7 +33,6 @@ import { Collections } from "./shared/payload/constants";
import { relationshipsPlugin } from "payloadcms-relationships"; import { relationshipsPlugin } from "payloadcms-relationships";
import { shownOnlyToAdmin } from "./accesses/collections/shownOnlyToAdmin"; import { shownOnlyToAdmin } from "./accesses/collections/shownOnlyToAdmin";
import { mustBeAdmin } from "./accesses/fields/mustBeAdmin"; import { mustBeAdmin } from "./accesses/fields/mustBeAdmin";
import { afterOutgoingRelationRemovedSendChangesWebhook } from "./hooks/afterOperationSendChangesWebhook";
const configuredSftpAdapter = sftpAdapter({ const configuredSftpAdapter = sftpAdapter({
connectOptions: { connectOptions: {
@ -111,7 +110,6 @@ export default buildConfig({
delete: mustBeAdmin, delete: mustBeAdmin,
}, },
}, },
onOutgoingRelationRemoved: afterOutgoingRelationRemovedSendChangesWebhook,
}), }),
cloudStorage({ cloudStorage({

View File

@ -4,6 +4,7 @@ import { formatToPascalCase } from "./string";
import { import {
afterChangeSendChangesWebhook, afterChangeSendChangesWebhook,
afterDeleteSendChangesWebhook, afterDeleteSendChangesWebhook,
beforeChangePrepareChanges,
beforeDeletePrepareChanges, beforeDeletePrepareChanges,
} from "../hooks/afterOperationSendChangesWebhook"; } from "../hooks/afterOperationSendChangesWebhook";
@ -22,6 +23,7 @@ export const buildCollectionConfig = (config: BuildCollectionConfig): Collection
typescript: { interface: formatToPascalCase(config.labels.singular) }, typescript: { interface: formatToPascalCase(config.labels.singular) },
hooks: { hooks: {
...config.hooks, ...config.hooks,
beforeChange: [...(config.hooks?.beforeChange ?? []), beforeChangePrepareChanges],
afterChange: [...(config.hooks?.afterChange ?? []), afterChangeSendChangesWebhook], afterChange: [...(config.hooks?.afterChange ?? []), afterChangeSendChangesWebhook],
beforeDelete: [...(config.hooks?.beforeDelete ?? []), beforeDeletePrepareChanges], beforeDelete: [...(config.hooks?.beforeDelete ?? []), beforeDeletePrepareChanges],
afterDelete: [...(config.hooks?.afterDelete ?? []), afterDeleteSendChangesWebhook], afterDelete: [...(config.hooks?.afterDelete ?? []), afterDeleteSendChangesWebhook],