From 935b1300752f9abb1950e908e4c9f4a79cb6b83f Mon Sep 17 00:00:00 2001 From: DrMint <29893320+DrMint@users.noreply.github.com> Date: Sat, 27 Jul 2024 17:34:05 +0200 Subject: [PATCH] Detect more changes by actually comparing previous state and current state --- src/hooks/afterOperationSendChangesWebhook.ts | 45 +++++++++++++------ src/payload.config.ts | 2 - src/utils/collectionConfig.ts | 2 + 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/hooks/afterOperationSendChangesWebhook.ts b/src/hooks/afterOperationSendChangesWebhook.ts index 02ae120..88b8e90 100644 --- a/src/hooks/afterOperationSendChangesWebhook.ts +++ b/src/hooks/afterOperationSendChangesWebhook.ts @@ -13,47 +13,64 @@ import { Relationship, Video, } from "../types/collections"; -import { isPayloadType } from "../utils/asserts"; +import { isDefined, isPayloadType } from "../utils/asserts"; import { AfterChangeHook, AfterDeleteHook, + BeforeChangeHook, BeforeDeleteHook, } from "payload/dist/collections/config/types"; import { GeneratedTypes } from "payload"; import { uniqueBy } from "../utils/array"; import { GlobalAfterChangeHook } from "payload/types"; import { findRelationByID } from "payloadcms-relationships/dist/utils"; -import { RelationshipRemoved } from "payloadcms-relationships"; -export const afterOutgoingRelationRemovedSendChangesWebhook = async ({ - removedOutgoingRelations, -}: RelationshipRemoved) => { - const changes: EndpointChange[] = []; +export const beforeChangePrepareChanges: BeforeChangeHook = async ({ + collection, + originalDoc, + context, + data, +}) => { + if ("_status" in data && data._status === "draft") return data; + if (!originalDoc) return data; - removedOutgoingRelations?.forEach((relation) => - changes.push(...getEndpointChangesFromOutgoingRelation(relation)) + context.beforeChangeChanges = await getChanges( + 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; 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; }; export const beforeDeletePrepareChanges: BeforeDeleteHook = async ({ id, collection, context }) => { - const changes = await getChanges(collection.slug as keyof GeneratedTypes["collections"], { id }); - context.beforeDeleteChanges = changes; + context.beforeDeleteChanges = await getChanges( + collection.slug as keyof GeneratedTypes["collections"], + { id } + ); }; export const afterDeleteSendChangesWebhook: AfterDeleteHook = async ({ doc, context }) => { const changes = context.beforeDeleteChanges as EndpointChange[] | undefined; - if (changes) { + if (isDefined(changes)) { await sendWebhookMessage(changes); } return doc; diff --git a/src/payload.config.ts b/src/payload.config.ts index a96ac2a..a0e14e3 100644 --- a/src/payload.config.ts +++ b/src/payload.config.ts @@ -33,7 +33,6 @@ import { Collections } from "./shared/payload/constants"; import { relationshipsPlugin } from "payloadcms-relationships"; import { shownOnlyToAdmin } from "./accesses/collections/shownOnlyToAdmin"; import { mustBeAdmin } from "./accesses/fields/mustBeAdmin"; -import { afterOutgoingRelationRemovedSendChangesWebhook } from "./hooks/afterOperationSendChangesWebhook"; const configuredSftpAdapter = sftpAdapter({ connectOptions: { @@ -111,7 +110,6 @@ export default buildConfig({ delete: mustBeAdmin, }, }, - onOutgoingRelationRemoved: afterOutgoingRelationRemovedSendChangesWebhook, }), cloudStorage({ diff --git a/src/utils/collectionConfig.ts b/src/utils/collectionConfig.ts index 4ebd571..b4d5b5e 100644 --- a/src/utils/collectionConfig.ts +++ b/src/utils/collectionConfig.ts @@ -4,6 +4,7 @@ import { formatToPascalCase } from "./string"; import { afterChangeSendChangesWebhook, afterDeleteSendChangesWebhook, + beforeChangePrepareChanges, beforeDeletePrepareChanges, } from "../hooks/afterOperationSendChangesWebhook"; @@ -22,6 +23,7 @@ export const buildCollectionConfig = (config: BuildCollectionConfig): Collection typescript: { interface: formatToPascalCase(config.labels.singular) }, hooks: { ...config.hooks, + beforeChange: [...(config.hooks?.beforeChange ?? []), beforeChangePrepareChanges], afterChange: [...(config.hooks?.afterChange ?? []), afterChangeSendChangesWebhook], beforeDelete: [...(config.hooks?.beforeDelete ?? []), beforeDeletePrepareChanges], afterDelete: [...(config.hooks?.afterDelete ?? []), afterDeleteSendChangesWebhook],