@brandlift/payload-loggs 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/collections/SiteActivityCollection.d.ts +1 -1
- package/dist/collections/SiteActivityCollection.js +4 -0
- package/dist/collections/SiteActivityCollection.js.map +1 -1
- package/dist/hooks/collectionHooks.js +36 -6
- package/dist/hooks/collectionHooks.js.map +1 -1
- package/dist/hooks/globalHooks.js +17 -1
- package/dist/hooks/globalHooks.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/pluginUtils/getActivityDetails.d.ts +7 -6
- package/dist/pluginUtils/getActivityDetails.js +112 -69
- package/dist/pluginUtils/getActivityDetails.js.map +1 -1
- package/dist/pluginUtils/getActivityEvent.test.d.ts +1 -0
- package/dist/types/events.d.ts +27 -0
- package/dist/types/events.js +17 -0
- package/dist/types/events.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CollectionConfig } from 'payload';
|
|
2
2
|
export type SiteActivityLogData = {
|
|
3
3
|
title: string;
|
|
4
|
-
operation: 'create' | 'update' | 'delete' | 'login' | 'logout' | 'publish' | 'unpublish';
|
|
4
|
+
operation: 'create' | 'update' | 'delete' | 'login' | 'logout' | 'publish' | 'unpublish' | 'draft_saved';
|
|
5
5
|
resourceName?: string;
|
|
6
6
|
resourceType: 'collection' | 'global';
|
|
7
7
|
collectionLabel?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/collections/SiteActivityCollection.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload';\n\nexport type SiteActivityLogData = {\n title: string;\n operation: 'create' | 'update' | 'delete' | 'login' | 'logout' | 'publish' | 'unpublish';\n resourceName?: string;\n resourceType: 'collection' | 'global';\n collectionLabel?: string;\n slug: string;\n documentId?: string;\n locale?: string;\n user?: string | number;\n userEmail?: string;\n userDisplay?: string;\n createdAt?: string;\n};\n\nexport const SITE_ACTIVITY_SLUG = 'site-activity';\n\nexport const SiteActivityCollection: CollectionConfig = {\n slug: SITE_ACTIVITY_SLUG,\n labels: {\n plural: 'Site Activities',\n singular: 'Site Activity',\n },\n admin: {\n defaultColumns: ['title', 'operation', 'resourceName', 'collectionLabel', 'userDisplay', 'createdAt'],\n useAsTitle: 'title',\n },\n access: {\n read: ({ req }) => Boolean(req.user),\n create: () => false,\n update: () => false,\n delete: () => false,\n },\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'operation',\n type: 'select',\n required: true,\n options: [\n { label: 'Create', value: 'create' },\n { label: 'Update', value: 'update' },\n { label: 'Delete', value: 'delete' },\n { label: 'Publish', value: 'publish' },\n { label: 'Unpublish', value: 'unpublish' },\n { label: 'Login', value: 'login' },\n { label: 'Logout', value: 'logout' },\n ],\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'resourceName',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'resourceType',\n type: 'select',\n required: true,\n options: [\n { label: 'Collection', value: 'collection' },\n { label: 'Global', value: 'global' },\n ],\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'collectionLabel',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'slug',\n type: 'text',\n required: true,\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'documentId',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'locale',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'user',\n type: 'relationship',\n relationTo: 'users',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'userEmail',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'userDisplay',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'createdAt',\n type: 'date',\n admin: {\n readOnly: true,\n },\n defaultValue: () => new Date().toISOString(),\n required: true,\n },\n ],\n timestamps: false,\n};\n\nexport default SiteActivityCollection;\n"],"names":["SITE_ACTIVITY_SLUG","SiteActivityCollection","slug","labels","plural","singular","admin","defaultColumns","useAsTitle","access","read","req","Boolean","user","create","update","delete","fields","name","type","required","readOnly","options","label","value","relationTo","defaultValue","Date","toISOString","timestamps"],"mappings":"AAiBA,OAAO,MAAMA,qBAAqB,gBAAgB;AAElD,OAAO,MAAMC,yBAA2C;IACtDC,MAAMF;IACNG,QAAQ;QACNC,QAAQ;QACRC,UAAU;IACZ;IACAC,OAAO;QACLC,gBAAgB;YAAC;YAAS;YAAa;YAAgB;YAAmB;YAAe;SAAY;QACrGC,YAAY;IACd;IACAC,QAAQ;QACNC,MAAM,CAAC,EAAEC,GAAG,EAAE,GAAKC,QAAQD,IAAIE,IAAI;QACnCC,QAAQ,IAAM;QACdC,QAAQ,IAAM;QACdC,QAAQ,IAAM;IAChB;IACAC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;YACNC,UAAU;YACVd,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,UAAU;YACVE,SAAS;gBACP;oBAAEC,OAAO;oBAAUC,OAAO;gBAAS;gBACnC;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;gBACnC;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;gBACnC;oBAAED,OAAO;oBAAWC,OAAO;gBAAU;gBACrC;oBAAED,OAAO;oBAAaC,OAAO;gBAAY;gBACzC;oBAAED,OAAO;oBAASC,OAAO;gBAAQ;gBACjC;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;aACpC;YACDlB,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,UAAU;YACVE,SAAS;gBACP;oBAAEC,OAAO;oBAAcC,OAAO;gBAAa;gBAC3C;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;aACpC;YACDlB,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,UAAU;YACVd,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNM,YAAY;YACZnB,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;YACAK,cAAc,IAAM,IAAIC,OAAOC,WAAW;YAC1CR,UAAU;QACZ;KACD;IACDS,YAAY;AACd,EAAE;AAEF,eAAe5B,uBAAuB"}
|
|
1
|
+
{"version":3,"sources":["../../src/collections/SiteActivityCollection.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload';\n\nexport type SiteActivityLogData = {\n title: string;\n operation: 'create' | 'update' | 'delete' | 'login' | 'logout' | 'publish' | 'unpublish' | 'draft_saved';\n resourceName?: string;\n resourceType: 'collection' | 'global';\n collectionLabel?: string;\n slug: string;\n documentId?: string;\n locale?: string;\n user?: string | number;\n userEmail?: string;\n userDisplay?: string;\n createdAt?: string;\n};\n\nexport const SITE_ACTIVITY_SLUG = 'site-activity';\n\nexport const SiteActivityCollection: CollectionConfig = {\n slug: SITE_ACTIVITY_SLUG,\n labels: {\n plural: 'Site Activities',\n singular: 'Site Activity',\n },\n admin: {\n defaultColumns: ['title', 'operation', 'resourceName', 'collectionLabel', 'userDisplay', 'createdAt'],\n useAsTitle: 'title',\n },\n access: {\n read: ({ req }) => Boolean(req.user),\n create: () => false,\n update: () => false,\n delete: () => false,\n },\n fields: [\n {\n name: 'title',\n type: 'text',\n required: true,\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'operation',\n type: 'select',\n required: true,\n options: [\n { label: 'Create', value: 'create' },\n { label: 'Update', value: 'update' },\n { label: 'Delete', value: 'delete' },\n { label: 'Publish', value: 'publish' },\n { label: 'Unpublish', value: 'unpublish' },\n { label: 'Draft Saved', value: 'draft_saved' },\n { label: 'Login', value: 'login' },\n { label: 'Logout', value: 'logout' },\n ],\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'resourceName',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'resourceType',\n type: 'select',\n required: true,\n options: [\n { label: 'Collection', value: 'collection' },\n { label: 'Global', value: 'global' },\n ],\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'collectionLabel',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'slug',\n type: 'text',\n required: true,\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'documentId',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'locale',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'user',\n type: 'relationship',\n relationTo: 'users',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'userEmail',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'userDisplay',\n type: 'text',\n admin: {\n readOnly: true,\n },\n },\n {\n name: 'createdAt',\n type: 'date',\n admin: {\n readOnly: true,\n },\n defaultValue: () => new Date().toISOString(),\n required: true,\n },\n ],\n timestamps: false,\n};\n\nexport default SiteActivityCollection;\n"],"names":["SITE_ACTIVITY_SLUG","SiteActivityCollection","slug","labels","plural","singular","admin","defaultColumns","useAsTitle","access","read","req","Boolean","user","create","update","delete","fields","name","type","required","readOnly","options","label","value","relationTo","defaultValue","Date","toISOString","timestamps"],"mappings":"AAiBA,OAAO,MAAMA,qBAAqB,gBAAgB;AAElD,OAAO,MAAMC,yBAA2C;IACtDC,MAAMF;IACNG,QAAQ;QACNC,QAAQ;QACRC,UAAU;IACZ;IACAC,OAAO;QACLC,gBAAgB;YAAC;YAAS;YAAa;YAAgB;YAAmB;YAAe;SAAY;QACrGC,YAAY;IACd;IACAC,QAAQ;QACNC,MAAM,CAAC,EAAEC,GAAG,EAAE,GAAKC,QAAQD,IAAIE,IAAI;QACnCC,QAAQ,IAAM;QACdC,QAAQ,IAAM;QACdC,QAAQ,IAAM;IAChB;IACAC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;YACNC,UAAU;YACVd,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,UAAU;YACVE,SAAS;gBACP;oBAAEC,OAAO;oBAAUC,OAAO;gBAAS;gBACnC;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;gBACnC;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;gBACnC;oBAAED,OAAO;oBAAWC,OAAO;gBAAU;gBACrC;oBAAED,OAAO;oBAAaC,OAAO;gBAAY;gBACzC;oBAAED,OAAO;oBAAeC,OAAO;gBAAc;gBAC7C;oBAAED,OAAO;oBAASC,OAAO;gBAAQ;gBACjC;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;aACpC;YACDlB,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,UAAU;YACVE,SAAS;gBACP;oBAAEC,OAAO;oBAAcC,OAAO;gBAAa;gBAC3C;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;aACpC;YACDlB,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,UAAU;YACVd,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNM,YAAY;YACZnB,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNb,OAAO;gBACLe,UAAU;YACZ;YACAK,cAAc,IAAM,IAAIC,OAAOC,WAAW;YAC1CR,UAAU;QACZ;KACD;IACDS,YAAY;AACd,EAAE;AAEF,eAAe5B,uBAAuB"}
|
|
@@ -1,15 +1,33 @@
|
|
|
1
|
+
import { ActivityEvent } from '../types/events.js';
|
|
1
2
|
import { getResourceTitle } from '../pluginUtils/getResourceTitle.js';
|
|
2
3
|
import { formatUserDisplay } from '../pluginUtils/formatUserDisplay.js';
|
|
3
4
|
import { getCollectionLabel } from '../pluginUtils/getCollectionLabel.js';
|
|
4
5
|
import { SITE_ACTIVITY_SLUG } from '../collections/SiteActivityCollection.js';
|
|
5
|
-
import { getCollectionActivityDetails } from '../pluginUtils/getActivityDetails.js';
|
|
6
|
+
import { getActivityLabel, getCollectionActivityDetails } from '../pluginUtils/getActivityDetails.js';
|
|
7
|
+
function isDuplicateEvent(req, collectionSlug, docId, eventKey) {
|
|
8
|
+
if (!req || !req.context) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const loggedEvents = req.context._loggedActivityEvents || new Set();
|
|
12
|
+
const fullKey = `${collectionSlug}:${docId}:${eventKey}`;
|
|
13
|
+
if (loggedEvents.has(fullKey)) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
loggedEvents.add(fullKey);
|
|
17
|
+
req.context._loggedActivityEvents = loggedEvents;
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
6
20
|
export const createCollectionAfterChangeHook = (collection, payloadConfig, _pluginConfig)=>{
|
|
7
21
|
return async ({ doc, previousDoc, operation, req })=>{
|
|
8
22
|
if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {
|
|
9
23
|
return doc;
|
|
10
24
|
}
|
|
11
25
|
try {
|
|
12
|
-
const { title, operation: opType } = getCollectionActivityDetails(collection, operation, doc, previousDoc);
|
|
26
|
+
const { event, title, operation: opType } = getCollectionActivityDetails(collection, operation, doc, previousDoc, req);
|
|
27
|
+
const docId = doc?.id ? String(doc.id) : 'new';
|
|
28
|
+
if (isDuplicateEvent(req, collection.slug, docId, event)) {
|
|
29
|
+
return doc;
|
|
30
|
+
}
|
|
13
31
|
const label = getCollectionLabel(collection);
|
|
14
32
|
const resourceName = getResourceTitle(doc, doc?.id);
|
|
15
33
|
const isLocalizationEnabled = Boolean(payloadConfig.localization);
|
|
@@ -60,8 +78,12 @@ export const createCollectionAfterDeleteHook = (collection, payloadConfig, _plug
|
|
|
60
78
|
return doc;
|
|
61
79
|
}
|
|
62
80
|
try {
|
|
81
|
+
const docId = id ? String(id) : 'unknown';
|
|
82
|
+
if (isDuplicateEvent(req, collection.slug, docId, ActivityEvent.DELETED)) {
|
|
83
|
+
return doc;
|
|
84
|
+
}
|
|
63
85
|
const label = getCollectionLabel(collection);
|
|
64
|
-
const title =
|
|
86
|
+
const title = getActivityLabel(ActivityEvent.DELETED, label);
|
|
65
87
|
const resourceName = getResourceTitle(doc, id);
|
|
66
88
|
const isLocalizationEnabled = Boolean(payloadConfig.localization);
|
|
67
89
|
const locale = isLocalizationEnabled ? req.locale : undefined;
|
|
@@ -77,7 +99,7 @@ export const createCollectionAfterDeleteHook = (collection, payloadConfig, _plug
|
|
|
77
99
|
resourceType: 'collection',
|
|
78
100
|
collectionLabel: label,
|
|
79
101
|
slug: collection.slug,
|
|
80
|
-
documentId:
|
|
102
|
+
documentId: docId !== 'unknown' ? docId : undefined,
|
|
81
103
|
...locale ? {
|
|
82
104
|
locale
|
|
83
105
|
} : {},
|
|
@@ -111,10 +133,14 @@ export const createCollectionAfterLoginHook = (collection, _payloadConfig, _plug
|
|
|
111
133
|
return user;
|
|
112
134
|
}
|
|
113
135
|
try {
|
|
136
|
+
const userId = user?.id ? String(user.id) : 'user';
|
|
137
|
+
if (isDuplicateEvent(req, collection.slug, userId, ActivityEvent.USER_LOGIN)) {
|
|
138
|
+
return user;
|
|
139
|
+
}
|
|
114
140
|
const label = getCollectionLabel(collection);
|
|
115
141
|
const userEmail = user?.email || req.user?.email;
|
|
116
142
|
const userDisplay = formatUserDisplay(userEmail);
|
|
117
|
-
const title =
|
|
143
|
+
const title = getActivityLabel(ActivityEvent.USER_LOGIN, label);
|
|
118
144
|
await req.payload.create({
|
|
119
145
|
collection: SITE_ACTIVITY_SLUG,
|
|
120
146
|
data: {
|
|
@@ -155,10 +181,14 @@ export const createCollectionAfterLogoutHook = (collection, _payloadConfig, _plu
|
|
|
155
181
|
return;
|
|
156
182
|
}
|
|
157
183
|
try {
|
|
184
|
+
const userId = req.user?.id ? String(req.user.id) : 'user';
|
|
185
|
+
if (isDuplicateEvent(req, collection.slug, userId, ActivityEvent.USER_LOGOUT)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
158
188
|
const label = getCollectionLabel(collection);
|
|
159
189
|
const userEmail = req.user?.email;
|
|
160
190
|
const userDisplay = formatUserDisplay(userEmail);
|
|
161
|
-
const title =
|
|
191
|
+
const title = getActivityLabel(ActivityEvent.USER_LOGOUT, label);
|
|
162
192
|
await req.payload.create({
|
|
163
193
|
collection: SITE_ACTIVITY_SLUG,
|
|
164
194
|
data: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/collectionHooks.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, CollectionAfterLoginHook, CollectionAfterLogoutHook, CollectionConfig, Config } from 'payload';\n\nimport type { PluginConfig } from '../types/config.js';\nimport { getResourceTitle } from '../pluginUtils/getResourceTitle.js';\nimport { formatUserDisplay } from '../pluginUtils/formatUserDisplay.js';\nimport { getCollectionLabel } from '../pluginUtils/getCollectionLabel.js';\nimport { SITE_ACTIVITY_SLUG } from '../collections/SiteActivityCollection.js';\nimport { getCollectionActivityDetails } from '../pluginUtils/getActivityDetails.js';\n\nexport const createCollectionAfterChangeHook = (\n collection: CollectionConfig,\n payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterChangeHook => {\n return async ({ doc, previousDoc, operation, req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return doc;\n }\n\n try {\n const { title, operation: opType } = getCollectionActivityDetails(\n collection,\n operation as 'create' | 'update',\n doc as Record<string, unknown>,\n previousDoc as Record<string, unknown> | undefined,\n );\n const label = getCollectionLabel(collection);\n\n const resourceName = getResourceTitle(doc, doc?.id);\n const isLocalizationEnabled = Boolean(payloadConfig.localization);\n const locale = isLocalizationEnabled ? req.locale : undefined;\n\n const userEmail = req.user?.email || (doc && typeof doc === 'object' && 'email' in doc && typeof doc.email === 'string' ? doc.email : undefined);\n const userDisplay = formatUserDisplay(userEmail);\n const userId = req.user?.id || (doc && typeof doc === 'object' && 'id' in doc ? doc.id : undefined);\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: opType,\n resourceName,\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: doc?.id ? String(doc.id) : undefined,\n ...(locale ? { locale } : {}),\n ...(userId !== undefined && userId !== null ? { user: userId } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging collection afterChange for ${collection.slug}: ${error}`);\n }\n\n return doc;\n };\n};\n\nexport const createCollectionAfterDeleteHook = (\n collection: CollectionConfig,\n payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterDeleteHook => {\n return async ({ doc, id, req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return doc;\n }\n\n try {\n const label = getCollectionLabel(collection);\n const title = `${label} deleted`;\n\n const resourceName = getResourceTitle(doc, id);\n const isLocalizationEnabled = Boolean(payloadConfig.localization);\n const locale = isLocalizationEnabled ? req.locale : undefined;\n\n const userEmail = req.user?.email || (doc && typeof doc === 'object' && 'email' in doc && typeof doc.email === 'string' ? doc.email : undefined);\n const userDisplay = formatUserDisplay(userEmail);\n const userId = req.user?.id || (doc && typeof doc === 'object' && 'id' in doc ? doc.id : undefined);\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: 'delete',\n resourceName,\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: id ? String(id) : undefined,\n ...(locale ? { locale } : {}),\n ...(userId !== undefined && userId !== null ? { user: userId } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging collection afterDelete for ${collection.slug}: ${error}`);\n }\n\n return doc;\n };\n};\n\nexport const createCollectionAfterLoginHook = (\n collection: CollectionConfig,\n _payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterLoginHook => {\n return async ({ user, req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return user;\n }\n\n try {\n const label = getCollectionLabel(collection);\n const userEmail = user?.email || req.user?.email;\n const userDisplay = formatUserDisplay(userEmail);\n const title = userDisplay ? `User ${userDisplay} logged in` : `${label} logged in`;\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: 'login',\n resourceName: userEmail || String(user?.id || 'User'),\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: user?.id ? String(user.id) : undefined,\n ...(user?.id !== undefined && user?.id !== null ? { user: user.id } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging afterLogin for ${collection.slug}: ${error}`);\n }\n\n return user;\n };\n};\n\nexport const createCollectionAfterLogoutHook = (\n collection: CollectionConfig,\n _payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterLogoutHook => {\n return async ({ req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return;\n }\n\n try {\n const label = getCollectionLabel(collection);\n const userEmail = req.user?.email;\n const userDisplay = formatUserDisplay(userEmail);\n const title = userDisplay ? `User ${userDisplay} logged out` : `${label} logged out`;\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: 'logout',\n resourceName: userEmail || String(req.user?.id || 'User'),\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: req.user?.id ? String(req.user.id) : undefined,\n ...(req.user?.id !== undefined && req.user?.id !== null ? { user: req.user.id } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging afterLogout for ${collection.slug}: ${error}`);\n }\n };\n};\n"],"names":["getResourceTitle","formatUserDisplay","getCollectionLabel","SITE_ACTIVITY_SLUG","getCollectionActivityDetails","createCollectionAfterChangeHook","collection","payloadConfig","_pluginConfig","doc","previousDoc","operation","req","context","skipLogs","skipAuditorLogs","title","opType","label","resourceName","id","isLocalizationEnabled","Boolean","localization","locale","undefined","userEmail","user","email","userDisplay","userId","payload","create","data","resourceType","collectionLabel","slug","documentId","String","overrideAccess","error","logger","createCollectionAfterDeleteHook","createCollectionAfterLoginHook","_payloadConfig","createCollectionAfterLogoutHook"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/collectionHooks.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, CollectionAfterLoginHook, CollectionAfterLogoutHook, CollectionConfig, Config } from 'payload';\n\nimport { ActivityEvent } from '../types/events.js';\nimport type { PluginConfig } from '../types/config.js';\nimport { getResourceTitle } from '../pluginUtils/getResourceTitle.js';\nimport { formatUserDisplay } from '../pluginUtils/formatUserDisplay.js';\nimport { getCollectionLabel } from '../pluginUtils/getCollectionLabel.js';\nimport { SITE_ACTIVITY_SLUG } from '../collections/SiteActivityCollection.js';\nimport { getActivityLabel, getCollectionActivityDetails } from '../pluginUtils/getActivityDetails.js';\n\nfunction isDuplicateEvent(req: any, collectionSlug: string, docId: string, eventKey: string): boolean {\n if (!req || !req.context) {\n return false;\n }\n\n const loggedEvents: Set<string> = (req.context._loggedActivityEvents as Set<string>) || new Set<string>();\n const fullKey = `${collectionSlug}:${docId}:${eventKey}`;\n\n if (loggedEvents.has(fullKey)) {\n return true;\n }\n\n loggedEvents.add(fullKey);\n req.context._loggedActivityEvents = loggedEvents;\n return false;\n}\n\nexport const createCollectionAfterChangeHook = (\n collection: CollectionConfig,\n payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterChangeHook => {\n return async ({ doc, previousDoc, operation, req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return doc;\n }\n\n try {\n const { event, title, operation: opType } = getCollectionActivityDetails(\n collection,\n operation as 'create' | 'update',\n doc as Record<string, unknown>,\n previousDoc as Record<string, unknown> | undefined,\n req,\n );\n\n const docId = doc?.id ? String(doc.id) : 'new';\n if (isDuplicateEvent(req, collection.slug, docId, event)) {\n return doc;\n }\n\n const label = getCollectionLabel(collection);\n const resourceName = getResourceTitle(doc, doc?.id);\n const isLocalizationEnabled = Boolean(payloadConfig.localization);\n const locale = isLocalizationEnabled ? req.locale : undefined;\n\n const userEmail = req.user?.email || (doc && typeof doc === 'object' && 'email' in doc && typeof doc.email === 'string' ? doc.email : undefined);\n const userDisplay = formatUserDisplay(userEmail);\n const userId = req.user?.id || (doc && typeof doc === 'object' && 'id' in doc ? doc.id : undefined);\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: opType,\n resourceName,\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: doc?.id ? String(doc.id) : undefined,\n ...(locale ? { locale } : {}),\n ...(userId !== undefined && userId !== null ? { user: userId } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging collection afterChange for ${collection.slug}: ${error}`);\n }\n\n return doc;\n };\n};\n\nexport const createCollectionAfterDeleteHook = (\n collection: CollectionConfig,\n payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterDeleteHook => {\n return async ({ doc, id, req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return doc;\n }\n\n try {\n const docId = id ? String(id) : 'unknown';\n if (isDuplicateEvent(req, collection.slug, docId, ActivityEvent.DELETED)) {\n return doc;\n }\n\n const label = getCollectionLabel(collection);\n const title = getActivityLabel(ActivityEvent.DELETED, label);\n\n const resourceName = getResourceTitle(doc, id);\n const isLocalizationEnabled = Boolean(payloadConfig.localization);\n const locale = isLocalizationEnabled ? req.locale : undefined;\n\n const userEmail = req.user?.email || (doc && typeof doc === 'object' && 'email' in doc && typeof doc.email === 'string' ? doc.email : undefined);\n const userDisplay = formatUserDisplay(userEmail);\n const userId = req.user?.id || (doc && typeof doc === 'object' && 'id' in doc ? doc.id : undefined);\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: 'delete',\n resourceName,\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: docId !== 'unknown' ? docId : undefined,\n ...(locale ? { locale } : {}),\n ...(userId !== undefined && userId !== null ? { user: userId } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging collection afterDelete for ${collection.slug}: ${error}`);\n }\n\n return doc;\n };\n};\n\nexport const createCollectionAfterLoginHook = (\n collection: CollectionConfig,\n _payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterLoginHook => {\n return async ({ user, req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return user;\n }\n\n try {\n const userId = user?.id ? String(user.id) : 'user';\n if (isDuplicateEvent(req, collection.slug, userId, ActivityEvent.USER_LOGIN)) {\n return user;\n }\n\n const label = getCollectionLabel(collection);\n const userEmail = user?.email || req.user?.email;\n const userDisplay = formatUserDisplay(userEmail);\n const title = getActivityLabel(ActivityEvent.USER_LOGIN, label);\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: 'login',\n resourceName: userEmail || String(user?.id || 'User'),\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: user?.id ? String(user.id) : undefined,\n ...(user?.id !== undefined && user?.id !== null ? { user: user.id } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging afterLogin for ${collection.slug}: ${error}`);\n }\n\n return user;\n };\n};\n\nexport const createCollectionAfterLogoutHook = (\n collection: CollectionConfig,\n _payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): CollectionAfterLogoutHook => {\n return async ({ req }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return;\n }\n\n try {\n const userId = req.user?.id ? String(req.user.id) : 'user';\n if (isDuplicateEvent(req, collection.slug, userId, ActivityEvent.USER_LOGOUT)) {\n return;\n }\n\n const label = getCollectionLabel(collection);\n const userEmail = req.user?.email;\n const userDisplay = formatUserDisplay(userEmail);\n const title = getActivityLabel(ActivityEvent.USER_LOGOUT, label);\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: 'logout',\n resourceName: userEmail || String(req.user?.id || 'User'),\n resourceType: 'collection',\n collectionLabel: label,\n slug: collection.slug,\n documentId: req.user?.id ? String(req.user.id) : undefined,\n ...(req.user?.id !== undefined && req.user?.id !== null ? { user: req.user.id } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging afterLogout for ${collection.slug}: ${error}`);\n }\n };\n};\n"],"names":["ActivityEvent","getResourceTitle","formatUserDisplay","getCollectionLabel","SITE_ACTIVITY_SLUG","getActivityLabel","getCollectionActivityDetails","isDuplicateEvent","req","collectionSlug","docId","eventKey","context","loggedEvents","_loggedActivityEvents","Set","fullKey","has","add","createCollectionAfterChangeHook","collection","payloadConfig","_pluginConfig","doc","previousDoc","operation","skipLogs","skipAuditorLogs","event","title","opType","id","String","slug","label","resourceName","isLocalizationEnabled","Boolean","localization","locale","undefined","userEmail","user","email","userDisplay","userId","payload","create","data","resourceType","collectionLabel","documentId","overrideAccess","error","logger","createCollectionAfterDeleteHook","DELETED","createCollectionAfterLoginHook","_payloadConfig","USER_LOGIN","createCollectionAfterLogoutHook","USER_LOGOUT"],"mappings":"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"}
|
|
@@ -3,13 +3,29 @@ import { formatUserDisplay } from '../pluginUtils/formatUserDisplay.js';
|
|
|
3
3
|
import { getCollectionLabel } from '../pluginUtils/getCollectionLabel.js';
|
|
4
4
|
import { SITE_ACTIVITY_SLUG } from '../collections/SiteActivityCollection.js';
|
|
5
5
|
import { getGlobalActivityDetails } from '../pluginUtils/getActivityDetails.js';
|
|
6
|
+
function isDuplicateEvent(req, globalSlug, eventKey) {
|
|
7
|
+
if (!req || !req.context) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const loggedEvents = req.context._loggedActivityEvents || new Set();
|
|
11
|
+
const fullKey = `global:${globalSlug}:${eventKey}`;
|
|
12
|
+
if (loggedEvents.has(fullKey)) {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
loggedEvents.add(fullKey);
|
|
16
|
+
req.context._loggedActivityEvents = loggedEvents;
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
6
19
|
export const createGlobalAfterChangeHook = (globalConfig, payloadConfig, _pluginConfig)=>{
|
|
7
20
|
return async ({ doc, previousDoc, req })=>{
|
|
8
21
|
if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {
|
|
9
22
|
return doc;
|
|
10
23
|
}
|
|
11
24
|
try {
|
|
12
|
-
const { title, operation: opType } = getGlobalActivityDetails(globalConfig, doc, previousDoc);
|
|
25
|
+
const { event, title, operation: opType } = getGlobalActivityDetails(globalConfig, doc, previousDoc, req);
|
|
26
|
+
if (isDuplicateEvent(req, globalConfig.slug, event)) {
|
|
27
|
+
return doc;
|
|
28
|
+
}
|
|
13
29
|
const label = getCollectionLabel(globalConfig);
|
|
14
30
|
const resourceName = getResourceTitle(doc) || label;
|
|
15
31
|
const isLocalizationEnabled = Boolean(payloadConfig.localization);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/globalHooks.ts"],"sourcesContent":["import type { Config, GlobalAfterChangeHook, GlobalConfig } from 'payload';\n\nimport type { PluginConfig } from '../types/config.js';\nimport { getResourceTitle } from '../pluginUtils/getResourceTitle.js';\nimport { formatUserDisplay } from '../pluginUtils/formatUserDisplay.js';\nimport { getCollectionLabel } from '../pluginUtils/getCollectionLabel.js';\nimport { SITE_ACTIVITY_SLUG } from '../collections/SiteActivityCollection.js';\nimport { getGlobalActivityDetails } from '../pluginUtils/getActivityDetails.js';\n\nexport const createGlobalAfterChangeHook = (\n globalConfig: GlobalConfig,\n payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): GlobalAfterChangeHook => {\n return async ({ doc, previousDoc, req }: { doc: Record<string, unknown>; previousDoc?: Record<string, unknown>; req?: any }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return doc;\n }\n\n try {\n const { title, operation: opType } = getGlobalActivityDetails(\n globalConfig,\n doc as Record<string, unknown>,\n previousDoc as Record<string, unknown> | undefined,\n );\n const label = getCollectionLabel(globalConfig);\n
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/globalHooks.ts"],"sourcesContent":["import type { Config, GlobalAfterChangeHook, GlobalConfig } from 'payload';\n\nimport type { PluginConfig } from '../types/config.js';\nimport { getResourceTitle } from '../pluginUtils/getResourceTitle.js';\nimport { formatUserDisplay } from '../pluginUtils/formatUserDisplay.js';\nimport { getCollectionLabel } from '../pluginUtils/getCollectionLabel.js';\nimport { SITE_ACTIVITY_SLUG } from '../collections/SiteActivityCollection.js';\nimport { getGlobalActivityDetails } from '../pluginUtils/getActivityDetails.js';\n\nfunction isDuplicateEvent(req: any, globalSlug: string, eventKey: string): boolean {\n if (!req || !req.context) {\n return false;\n }\n\n const loggedEvents: Set<string> = (req.context._loggedActivityEvents as Set<string>) || new Set<string>();\n const fullKey = `global:${globalSlug}:${eventKey}`;\n\n if (loggedEvents.has(fullKey)) {\n return true;\n }\n\n loggedEvents.add(fullKey);\n req.context._loggedActivityEvents = loggedEvents;\n return false;\n}\n\nexport const createGlobalAfterChangeHook = (\n globalConfig: GlobalConfig,\n payloadConfig: Config,\n _pluginConfig?: PluginConfig,\n): GlobalAfterChangeHook => {\n return async ({ doc, previousDoc, req }: { doc: Record<string, unknown>; previousDoc?: Record<string, unknown>; req?: any }) => {\n if (!req || req.context?.skipLogs || req.context?.skipAuditorLogs) {\n return doc;\n }\n\n try {\n const { event, title, operation: opType } = getGlobalActivityDetails(\n globalConfig,\n doc as Record<string, unknown>,\n previousDoc as Record<string, unknown> | undefined,\n req,\n );\n\n if (isDuplicateEvent(req, globalConfig.slug, event)) {\n return doc;\n }\n\n const label = getCollectionLabel(globalConfig);\n const resourceName = getResourceTitle(doc) || label;\n const isLocalizationEnabled = Boolean(payloadConfig.localization);\n const locale = isLocalizationEnabled ? req.locale : undefined;\n\n const userEmail = req.user?.email;\n const userDisplay = formatUserDisplay(userEmail);\n const userId = req.user?.id;\n\n await req.payload.create({\n collection: SITE_ACTIVITY_SLUG,\n data: {\n title,\n operation: opType,\n resourceName,\n resourceType: 'global',\n collectionLabel: label,\n slug: globalConfig.slug,\n ...(locale ? { locale } : {}),\n ...(userId !== undefined && userId !== null ? { user: userId } : {}),\n ...(userEmail ? { userEmail } : {}),\n ...(userDisplay ? { userDisplay } : {}),\n },\n req,\n overrideAccess: true,\n context: {\n ...req.context,\n skipLogs: true,\n skipAuditorLogs: true,\n },\n });\n }\n catch (error) {\n req.payload?.logger?.error?.(`[payload-loggs] Error logging global afterChange for ${globalConfig.slug}: ${error}`);\n }\n\n return doc;\n };\n};\n"],"names":["getResourceTitle","formatUserDisplay","getCollectionLabel","SITE_ACTIVITY_SLUG","getGlobalActivityDetails","isDuplicateEvent","req","globalSlug","eventKey","context","loggedEvents","_loggedActivityEvents","Set","fullKey","has","add","createGlobalAfterChangeHook","globalConfig","payloadConfig","_pluginConfig","doc","previousDoc","skipLogs","skipAuditorLogs","event","title","operation","opType","slug","label","resourceName","isLocalizationEnabled","Boolean","localization","locale","undefined","userEmail","user","email","userDisplay","userId","id","payload","create","collection","data","resourceType","collectionLabel","overrideAccess","error","logger"],"mappings":"AAGA,SAASA,gBAAgB,QAAQ,qCAAqC;AACtE,SAASC,iBAAiB,QAAQ,sCAAsC;AACxE,SAASC,kBAAkB,QAAQ,uCAAuC;AAC1E,SAASC,kBAAkB,QAAQ,2CAA2C;AAC9E,SAASC,wBAAwB,QAAQ,uCAAuC;AAEhF,SAASC,iBAAiBC,GAAQ,EAAEC,UAAkB,EAAEC,QAAgB;IACtE,IAAI,CAACF,OAAO,CAACA,IAAIG,OAAO,EAAE;QACxB,OAAO;IACT;IAEA,MAAMC,eAA4B,AAACJ,IAAIG,OAAO,CAACE,qBAAqB,IAAoB,IAAIC;IAC5F,MAAMC,UAAU,CAAC,OAAO,EAAEN,WAAW,CAAC,EAAEC,UAAU;IAElD,IAAIE,aAAaI,GAAG,CAACD,UAAU;QAC7B,OAAO;IACT;IAEAH,aAAaK,GAAG,CAACF;IACjBP,IAAIG,OAAO,CAACE,qBAAqB,GAAGD;IACpC,OAAO;AACT;AAEA,OAAO,MAAMM,8BAA8B,CACzCC,cACAC,eACAC;IAEA,OAAO,OAAO,EAAEC,GAAG,EAAEC,WAAW,EAAEf,GAAG,EAAsF;QACzH,IAAI,CAACA,OAAOA,IAAIG,OAAO,EAAEa,YAAYhB,IAAIG,OAAO,EAAEc,iBAAiB;YACjE,OAAOH;QACT;QAEA,IAAI;YACF,MAAM,EAAEI,KAAK,EAAEC,KAAK,EAAEC,WAAWC,MAAM,EAAE,GAAGvB,yBAC1Ca,cACAG,KACAC,aACAf;YAGF,IAAID,iBAAiBC,KAAKW,aAAaW,IAAI,EAAEJ,QAAQ;gBACnD,OAAOJ;YACT;YAEA,MAAMS,QAAQ3B,mBAAmBe;YACjC,MAAMa,eAAe9B,iBAAiBoB,QAAQS;YAC9C,MAAME,wBAAwBC,QAAQd,cAAce,YAAY;YAChE,MAAMC,SAASH,wBAAwBzB,IAAI4B,MAAM,GAAGC;YAEpD,MAAMC,YAAY9B,IAAI+B,IAAI,EAAEC;YAC5B,MAAMC,cAActC,kBAAkBmC;YACtC,MAAMI,SAASlC,IAAI+B,IAAI,EAAEI;YAEzB,MAAMnC,IAAIoC,OAAO,CAACC,MAAM,CAAC;gBACvBC,YAAYzC;gBACZ0C,MAAM;oBACJpB;oBACAC,WAAWC;oBACXG;oBACAgB,cAAc;oBACdC,iBAAiBlB;oBACjBD,MAAMX,aAAaW,IAAI;oBACvB,GAAIM,SAAS;wBAAEA;oBAAO,IAAI,CAAC,CAAC;oBAC5B,GAAIM,WAAWL,aAAaK,WAAW,OAAO;wBAAEH,MAAMG;oBAAO,IAAI,CAAC,CAAC;oBACnE,GAAIJ,YAAY;wBAAEA;oBAAU,IAAI,CAAC,CAAC;oBAClC,GAAIG,cAAc;wBAAEA;oBAAY,IAAI,CAAC,CAAC;gBACxC;gBACAjC;gBACA0C,gBAAgB;gBAChBvC,SAAS;oBACP,GAAGH,IAAIG,OAAO;oBACda,UAAU;oBACVC,iBAAiB;gBACnB;YACF;QACF,EACA,OAAO0B,OAAO;YACZ3C,IAAIoC,OAAO,EAAEQ,QAAQD,QAAQ,CAAC,qDAAqD,EAAEhC,aAAaW,IAAI,CAAC,EAAE,EAAEqB,OAAO;QACpH;QAEA,OAAO7B;IACT;AACF,EAAE"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ActivityEvent } from './types/events.js';
|
|
1
2
|
import { getResourceTitle } from './pluginUtils/getResourceTitle.js';
|
|
2
3
|
import type { SiteActivityLog } from './collections/siteActivity.js';
|
|
3
4
|
import { formatUserDisplay } from './pluginUtils/formatUserDisplay.js';
|
|
@@ -5,8 +6,10 @@ import { getCollectionLabel } from './pluginUtils/getCollectionLabel.js';
|
|
|
5
6
|
import { payloadLoggsPlugin, siteActivity, siteActivityPlugin } from './plugin.js';
|
|
6
7
|
import { siteActivity as siteActivityCollection } from './collections/siteActivity.js';
|
|
7
8
|
import { SITE_ACTIVITY_SLUG, SiteActivityCollection } from './collections/SiteActivityCollection.js';
|
|
9
|
+
import { getActivityEvent, getActivityLabel, getCollectionActivityDetails, getGlobalActivityDetails } from './pluginUtils/getActivityDetails.js';
|
|
8
10
|
export type { SiteActivityLogData } from './collections/SiteActivityCollection.js';
|
|
9
11
|
export type { AutomationConfig, PluginConfig } from './types/config.js';
|
|
12
|
+
export type { ActivityClassificationParams, ActivityDetails } from './types/events.js';
|
|
10
13
|
export type { SiteActivityLog };
|
|
11
|
-
export { formatUserDisplay, getCollectionLabel, getResourceTitle, payloadLoggsPlugin, SITE_ACTIVITY_SLUG, siteActivity, SiteActivityCollection, siteActivityCollection, siteActivityPlugin, };
|
|
14
|
+
export { ActivityEvent, formatUserDisplay, getActivityEvent, getActivityLabel, getCollectionActivityDetails, getCollectionLabel, getGlobalActivityDetails, getResourceTitle, payloadLoggsPlugin, SITE_ACTIVITY_SLUG, siteActivity, SiteActivityCollection, siteActivityCollection, siteActivityPlugin, };
|
|
12
15
|
export default siteActivity;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { ActivityEvent } from './types/events.js';
|
|
1
2
|
import { getResourceTitle } from './pluginUtils/getResourceTitle.js';
|
|
2
3
|
import { formatUserDisplay } from './pluginUtils/formatUserDisplay.js';
|
|
3
4
|
import { getCollectionLabel } from './pluginUtils/getCollectionLabel.js';
|
|
4
5
|
import { payloadLoggsPlugin, siteActivity, siteActivityPlugin } from './plugin.js';
|
|
5
6
|
import { siteActivity as siteActivityCollection } from './collections/siteActivity.js';
|
|
6
7
|
import { SITE_ACTIVITY_SLUG, SiteActivityCollection } from './collections/SiteActivityCollection.js';
|
|
7
|
-
|
|
8
|
+
import { getActivityEvent, getActivityLabel, getCollectionActivityDetails, getGlobalActivityDetails } from './pluginUtils/getActivityDetails.js';
|
|
9
|
+
export { ActivityEvent, formatUserDisplay, getActivityEvent, getActivityLabel, getCollectionActivityDetails, getCollectionLabel, getGlobalActivityDetails, getResourceTitle, payloadLoggsPlugin, SITE_ACTIVITY_SLUG, siteActivity, SiteActivityCollection, siteActivityCollection, siteActivityPlugin };
|
|
8
10
|
export default siteActivity;
|
|
9
11
|
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { getResourceTitle } from './pluginUtils/getResourceTitle.js';\nimport type { SiteActivityLog } from './collections/siteActivity.js';\nimport { formatUserDisplay } from './pluginUtils/formatUserDisplay.js';\nimport { getCollectionLabel } from './pluginUtils/getCollectionLabel.js';\nimport { payloadLoggsPlugin, siteActivity, siteActivityPlugin } from './plugin.js';\nimport { siteActivity as siteActivityCollection } from './collections/siteActivity.js';\nimport { SITE_ACTIVITY_SLUG, SiteActivityCollection } from './collections/SiteActivityCollection.js';\n\nexport type { SiteActivityLogData } from './collections/SiteActivityCollection.js';\nexport type { AutomationConfig, PluginConfig } from './types/config.js';\nexport type { SiteActivityLog };\n\nexport {\n formatUserDisplay,\n getCollectionLabel,\n getResourceTitle,\n payloadLoggsPlugin,\n SITE_ACTIVITY_SLUG,\n siteActivity,\n SiteActivityCollection,\n siteActivityCollection,\n siteActivityPlugin,\n};\n\nexport default siteActivity;\n"],"names":["getResourceTitle","formatUserDisplay","getCollectionLabel","payloadLoggsPlugin","siteActivity","siteActivityPlugin","siteActivityCollection","SITE_ACTIVITY_SLUG","SiteActivityCollection"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,oCAAoC;AAErE,SAASC,iBAAiB,QAAQ,qCAAqC;AACvE,SAASC,kBAAkB,QAAQ,sCAAsC;AACzE,SAASC,kBAAkB,EAAEC,YAAY,EAAEC,kBAAkB,QAAQ,cAAc;AACnF,SAASD,gBAAgBE,sBAAsB,QAAQ,gCAAgC;AACvF,SAASC,kBAAkB,EAAEC,sBAAsB,QAAQ,0CAA0C;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { ActivityEvent } from './types/events.js';\nimport { getResourceTitle } from './pluginUtils/getResourceTitle.js';\nimport type { SiteActivityLog } from './collections/siteActivity.js';\nimport { formatUserDisplay } from './pluginUtils/formatUserDisplay.js';\nimport { getCollectionLabel } from './pluginUtils/getCollectionLabel.js';\nimport { payloadLoggsPlugin, siteActivity, siteActivityPlugin } from './plugin.js';\nimport { siteActivity as siteActivityCollection } from './collections/siteActivity.js';\nimport { SITE_ACTIVITY_SLUG, SiteActivityCollection } from './collections/SiteActivityCollection.js';\nimport { getActivityEvent, getActivityLabel, getCollectionActivityDetails, getGlobalActivityDetails } from './pluginUtils/getActivityDetails.js';\n\nexport type { SiteActivityLogData } from './collections/SiteActivityCollection.js';\nexport type { AutomationConfig, PluginConfig } from './types/config.js';\nexport type { ActivityClassificationParams, ActivityDetails } from './types/events.js';\nexport type { SiteActivityLog };\n\nexport {\n ActivityEvent,\n formatUserDisplay,\n getActivityEvent,\n getActivityLabel,\n getCollectionActivityDetails,\n getCollectionLabel,\n getGlobalActivityDetails,\n getResourceTitle,\n payloadLoggsPlugin,\n SITE_ACTIVITY_SLUG,\n siteActivity,\n SiteActivityCollection,\n siteActivityCollection,\n siteActivityPlugin,\n};\n\nexport default siteActivity;\n"],"names":["ActivityEvent","getResourceTitle","formatUserDisplay","getCollectionLabel","payloadLoggsPlugin","siteActivity","siteActivityPlugin","siteActivityCollection","SITE_ACTIVITY_SLUG","SiteActivityCollection","getActivityEvent","getActivityLabel","getCollectionActivityDetails","getGlobalActivityDetails"],"mappings":"AAAA,SAASA,aAAa,QAAQ,oBAAoB;AAClD,SAASC,gBAAgB,QAAQ,oCAAoC;AAErE,SAASC,iBAAiB,QAAQ,qCAAqC;AACvE,SAASC,kBAAkB,QAAQ,sCAAsC;AACzE,SAASC,kBAAkB,EAAEC,YAAY,EAAEC,kBAAkB,QAAQ,cAAc;AACnF,SAASD,gBAAgBE,sBAAsB,QAAQ,gCAAgC;AACvF,SAASC,kBAAkB,EAAEC,sBAAsB,QAAQ,0CAA0C;AACrG,SAASC,gBAAgB,EAAEC,gBAAgB,EAAEC,4BAA4B,EAAEC,wBAAwB,QAAQ,sCAAsC;AAOjJ,SACEb,aAAa,EACbE,iBAAiB,EACjBQ,gBAAgB,EAChBC,gBAAgB,EAChBC,4BAA4B,EAC5BT,kBAAkB,EAClBU,wBAAwB,EACxBZ,gBAAgB,EAChBG,kBAAkB,EAClBI,kBAAkB,EAClBH,YAAY,EACZI,sBAAsB,EACtBF,sBAAsB,EACtBD,kBAAkB,GAClB;AAEF,eAAeD,aAAa"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { CollectionConfig, GlobalConfig } from 'payload';
|
|
2
|
+
import { ActivityEvent } from '../types/events.js';
|
|
2
3
|
import type { SiteActivityLogData } from '../collections/SiteActivityCollection.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export declare function getCollectionActivityDetails(collection: CollectionConfig, operation: 'create' | 'update', doc: Record<string, unknown> | undefined, previousDoc?: Record<string, unknown
|
|
8
|
-
export declare function getGlobalActivityDetails(globalConfig: GlobalConfig, doc: Record<string, unknown> | undefined, previousDoc?: Record<string, unknown
|
|
4
|
+
import type { ActivityClassificationParams, ActivityDetails } from '../types/events.js';
|
|
5
|
+
export declare function getActivityLabel(event: ActivityEvent, resourceLabel: string, isGlobal?: boolean): string;
|
|
6
|
+
export declare function eventToOperation(event: ActivityEvent): SiteActivityLogData['operation'];
|
|
7
|
+
export declare function getActivityEvent(params: ActivityClassificationParams): ActivityEvent;
|
|
8
|
+
export declare function getCollectionActivityDetails(collection: CollectionConfig, operation: 'create' | 'update', doc: Record<string, unknown> | undefined, previousDoc?: Record<string, unknown>, req?: any): ActivityDetails;
|
|
9
|
+
export declare function getGlobalActivityDetails(globalConfig: GlobalConfig, doc: Record<string, unknown> | undefined, previousDoc?: Record<string, unknown>, req?: any): ActivityDetails;
|
|
@@ -1,88 +1,131 @@
|
|
|
1
|
+
import { ActivityEvent } from '../types/events.js';
|
|
1
2
|
import { getCollectionLabel } from './getCollectionLabel.js';
|
|
2
|
-
export function
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
operation: 'unpublish'
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
if (currentStatus === 'draft') {
|
|
35
|
-
return {
|
|
36
|
-
title: `${label} draft updated`,
|
|
37
|
-
operation: 'update'
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (currentStatus === 'published') {
|
|
41
|
-
return {
|
|
42
|
-
title: `${label} modified`,
|
|
43
|
-
operation: 'update'
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
3
|
+
export function getActivityLabel(event, resourceLabel, isGlobal = false) {
|
|
4
|
+
const prefix = isGlobal ? `Global ${resourceLabel}` : resourceLabel;
|
|
5
|
+
switch(event){
|
|
6
|
+
case ActivityEvent.CREATED:
|
|
7
|
+
return `${prefix} Created`;
|
|
8
|
+
case ActivityEvent.UPDATED:
|
|
9
|
+
return `${prefix} Updated`;
|
|
10
|
+
case ActivityEvent.DELETED:
|
|
11
|
+
return `${prefix} Deleted`;
|
|
12
|
+
case ActivityEvent.PUBLISHED:
|
|
13
|
+
return `${prefix} Published`;
|
|
14
|
+
case ActivityEvent.UNPUBLISHED:
|
|
15
|
+
return `${prefix} Unpublished`;
|
|
16
|
+
case ActivityEvent.DRAFT_SAVED:
|
|
17
|
+
return resourceLabel.toLowerCase() === 'page' ? 'Changes Saved as Draft' : `${prefix} Changes Saved as Draft`;
|
|
18
|
+
case ActivityEvent.USER_LOGIN:
|
|
19
|
+
return 'User Logged In';
|
|
20
|
+
case ActivityEvent.USER_LOGOUT:
|
|
21
|
+
return 'User Logged Out';
|
|
22
|
+
case ActivityEvent.USER_LOGIN_FAILED:
|
|
23
|
+
return 'Failed Login';
|
|
24
|
+
case ActivityEvent.USER_SESSION_EXPIRED:
|
|
25
|
+
return 'Session Expired';
|
|
26
|
+
case ActivityEvent.RESTORED:
|
|
27
|
+
return `${prefix} Restored`;
|
|
28
|
+
case ActivityEvent.DUPLICATED:
|
|
29
|
+
return `${prefix} Duplicated`;
|
|
30
|
+
default:
|
|
31
|
+
return `${prefix} Updated`;
|
|
47
32
|
}
|
|
48
|
-
return {
|
|
49
|
-
title: isCreate ? `${label} created` : `${label} modified`,
|
|
50
|
-
operation: isCreate ? 'create' : 'update'
|
|
51
|
-
};
|
|
52
33
|
}
|
|
53
|
-
export function
|
|
54
|
-
|
|
34
|
+
export function eventToOperation(event) {
|
|
35
|
+
switch(event){
|
|
36
|
+
case ActivityEvent.CREATED:
|
|
37
|
+
return 'create';
|
|
38
|
+
case ActivityEvent.UPDATED:
|
|
39
|
+
return 'update';
|
|
40
|
+
case ActivityEvent.DELETED:
|
|
41
|
+
return 'delete';
|
|
42
|
+
case ActivityEvent.PUBLISHED:
|
|
43
|
+
return 'publish';
|
|
44
|
+
case ActivityEvent.UNPUBLISHED:
|
|
45
|
+
return 'unpublish';
|
|
46
|
+
case ActivityEvent.DRAFT_SAVED:
|
|
47
|
+
return 'draft_saved';
|
|
48
|
+
case ActivityEvent.USER_LOGIN:
|
|
49
|
+
return 'login';
|
|
50
|
+
case ActivityEvent.USER_LOGOUT:
|
|
51
|
+
return 'logout';
|
|
52
|
+
default:
|
|
53
|
+
return 'update';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function getActivityEvent(params) {
|
|
57
|
+
const { operation, previousDoc, doc, req, context } = params;
|
|
58
|
+
if (operation === 'login') {
|
|
59
|
+
return ActivityEvent.USER_LOGIN;
|
|
60
|
+
}
|
|
61
|
+
if (operation === 'logout') {
|
|
62
|
+
return ActivityEvent.USER_LOGOUT;
|
|
63
|
+
}
|
|
64
|
+
if (operation === 'delete') {
|
|
65
|
+
return ActivityEvent.DELETED;
|
|
66
|
+
}
|
|
67
|
+
// Explicit activity event override passed in request or context
|
|
68
|
+
const reqContext = req?.context || context;
|
|
69
|
+
if (reqContext?.activityEvent && typeof reqContext.activityEvent === 'string') {
|
|
70
|
+
const explicitEvent = reqContext.activityEvent;
|
|
71
|
+
if (Object.values(ActivityEvent).includes(explicitEvent)) {
|
|
72
|
+
return explicitEvent;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
55
75
|
const currentStatus = doc && typeof doc === 'object' && '_status' in doc && typeof doc._status === 'string' ? doc._status : undefined;
|
|
56
76
|
const prevStatus = previousDoc && typeof previousDoc === 'object' && '_status' in previousDoc && typeof previousDoc._status === 'string' ? previousDoc._status : undefined;
|
|
77
|
+
const isCreate = operation === 'create' || !previousDoc && operation !== 'update';
|
|
57
78
|
if (currentStatus) {
|
|
79
|
+
if (isCreate) {
|
|
80
|
+
// Creation of a document with draft or published status
|
|
81
|
+
return ActivityEvent.CREATED;
|
|
82
|
+
}
|
|
83
|
+
// Check transition states for existing document update
|
|
58
84
|
if (prevStatus === 'draft' && currentStatus === 'published') {
|
|
59
|
-
return
|
|
60
|
-
title: `Global ${label} published`,
|
|
61
|
-
operation: 'publish'
|
|
62
|
-
};
|
|
85
|
+
return ActivityEvent.PUBLISHED;
|
|
63
86
|
}
|
|
64
87
|
if (prevStatus === 'published' && currentStatus === 'draft') {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
88
|
+
// Distinguish explicit unpublish vs saving draft of published page
|
|
89
|
+
const isExplicitUnpublish = Boolean(reqContext?.unpublish || reqContext?._payloadUnpublish || reqContext?.isUnpublishing || req?.url?.includes('/unpublish') || req?.route?.path?.includes('/unpublish'));
|
|
90
|
+
return isExplicitUnpublish ? ActivityEvent.UNPUBLISHED : ActivityEvent.DRAFT_SAVED;
|
|
69
91
|
}
|
|
70
92
|
if (currentStatus === 'draft') {
|
|
71
|
-
return
|
|
72
|
-
title: `Global ${label} draft updated`,
|
|
73
|
-
operation: 'update'
|
|
74
|
-
};
|
|
93
|
+
return ActivityEvent.DRAFT_SAVED;
|
|
75
94
|
}
|
|
76
95
|
if (currentStatus === 'published') {
|
|
77
|
-
return
|
|
78
|
-
title: `Global ${label} updated`,
|
|
79
|
-
operation: 'update'
|
|
80
|
-
};
|
|
96
|
+
return ActivityEvent.UPDATED;
|
|
81
97
|
}
|
|
82
98
|
}
|
|
99
|
+
return isCreate ? ActivityEvent.CREATED : ActivityEvent.UPDATED;
|
|
100
|
+
}
|
|
101
|
+
export function getCollectionActivityDetails(collection, operation, doc, previousDoc, req) {
|
|
102
|
+
const label = getCollectionLabel(collection);
|
|
103
|
+
const event = getActivityEvent({
|
|
104
|
+
operation,
|
|
105
|
+
doc,
|
|
106
|
+
previousDoc,
|
|
107
|
+
req,
|
|
108
|
+
collectionSlug: collection.slug
|
|
109
|
+
});
|
|
110
|
+
return {
|
|
111
|
+
event,
|
|
112
|
+
title: getActivityLabel(event, label, false),
|
|
113
|
+
operation: eventToOperation(event)
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function getGlobalActivityDetails(globalConfig, doc, previousDoc, req) {
|
|
117
|
+
const label = getCollectionLabel(globalConfig);
|
|
118
|
+
const event = getActivityEvent({
|
|
119
|
+
operation: 'update',
|
|
120
|
+
doc,
|
|
121
|
+
previousDoc,
|
|
122
|
+
req,
|
|
123
|
+
collectionSlug: globalConfig.slug
|
|
124
|
+
});
|
|
83
125
|
return {
|
|
84
|
-
|
|
85
|
-
|
|
126
|
+
event,
|
|
127
|
+
title: getActivityLabel(event, label, true),
|
|
128
|
+
operation: eventToOperation(event)
|
|
86
129
|
};
|
|
87
130
|
}
|
|
88
131
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pluginUtils/getActivityDetails.ts"],"sourcesContent":["import type { CollectionConfig, GlobalConfig } from 'payload';\n\nimport { getCollectionLabel } from './getCollectionLabel.js';\nimport type { SiteActivityLogData } from '../collections/SiteActivityCollection.js';\
|
|
1
|
+
{"version":3,"sources":["../../src/pluginUtils/getActivityDetails.ts"],"sourcesContent":["import type { CollectionConfig, GlobalConfig } from 'payload';\n\nimport { ActivityEvent } from '../types/events.js';\nimport { getCollectionLabel } from './getCollectionLabel.js';\nimport type { SiteActivityLogData } from '../collections/SiteActivityCollection.js';\nimport type { ActivityClassificationParams, ActivityDetails } from '../types/events.js';\n\nexport function getActivityLabel(\n event: ActivityEvent,\n resourceLabel: string,\n isGlobal = false,\n): string {\n const prefix = isGlobal ? `Global ${resourceLabel}` : resourceLabel;\n\n switch (event) {\n case ActivityEvent.CREATED:\n return `${prefix} Created`;\n case ActivityEvent.UPDATED:\n return `${prefix} Updated`;\n case ActivityEvent.DELETED:\n return `${prefix} Deleted`;\n case ActivityEvent.PUBLISHED:\n return `${prefix} Published`;\n case ActivityEvent.UNPUBLISHED:\n return `${prefix} Unpublished`;\n case ActivityEvent.DRAFT_SAVED:\n return resourceLabel.toLowerCase() === 'page'\n ? 'Changes Saved as Draft'\n : `${prefix} Changes Saved as Draft`;\n case ActivityEvent.USER_LOGIN:\n return 'User Logged In';\n case ActivityEvent.USER_LOGOUT:\n return 'User Logged Out';\n case ActivityEvent.USER_LOGIN_FAILED:\n return 'Failed Login';\n case ActivityEvent.USER_SESSION_EXPIRED:\n return 'Session Expired';\n case ActivityEvent.RESTORED:\n return `${prefix} Restored`;\n case ActivityEvent.DUPLICATED:\n return `${prefix} Duplicated`;\n default:\n return `${prefix} Updated`;\n }\n}\n\nexport function eventToOperation(event: ActivityEvent): SiteActivityLogData['operation'] {\n switch (event) {\n case ActivityEvent.CREATED:\n return 'create';\n case ActivityEvent.UPDATED:\n return 'update';\n case ActivityEvent.DELETED:\n return 'delete';\n case ActivityEvent.PUBLISHED:\n return 'publish';\n case ActivityEvent.UNPUBLISHED:\n return 'unpublish';\n case ActivityEvent.DRAFT_SAVED:\n return 'draft_saved';\n case ActivityEvent.USER_LOGIN:\n return 'login';\n case ActivityEvent.USER_LOGOUT:\n return 'logout';\n default:\n return 'update';\n }\n}\n\nexport function getActivityEvent(params: ActivityClassificationParams): ActivityEvent {\n const { operation, previousDoc, doc, req, context } = params;\n\n if (operation === 'login') {\n return ActivityEvent.USER_LOGIN;\n }\n if (operation === 'logout') {\n return ActivityEvent.USER_LOGOUT;\n }\n if (operation === 'delete') {\n return ActivityEvent.DELETED;\n }\n\n // Explicit activity event override passed in request or context\n const reqContext = req?.context || context;\n if (reqContext?.activityEvent && typeof reqContext.activityEvent === 'string') {\n const explicitEvent = reqContext.activityEvent as ActivityEvent;\n if (Object.values(ActivityEvent).includes(explicitEvent)) {\n return explicitEvent;\n }\n }\n\n const currentStatus = doc && typeof doc === 'object' && '_status' in doc && typeof doc._status === 'string'\n ? doc._status\n : undefined;\n const prevStatus = previousDoc && typeof previousDoc === 'object' && '_status' in previousDoc && typeof previousDoc._status === 'string'\n ? previousDoc._status\n : undefined;\n\n const isCreate = operation === 'create' || (!previousDoc && operation !== 'update');\n\n if (currentStatus) {\n if (isCreate) {\n // Creation of a document with draft or published status\n return ActivityEvent.CREATED;\n }\n\n // Check transition states for existing document update\n if (prevStatus === 'draft' && currentStatus === 'published') {\n return ActivityEvent.PUBLISHED;\n }\n\n if (prevStatus === 'published' && currentStatus === 'draft') {\n // Distinguish explicit unpublish vs saving draft of published page\n const isExplicitUnpublish = Boolean(\n reqContext?.unpublish\n || reqContext?._payloadUnpublish\n || reqContext?.isUnpublishing\n || req?.url?.includes('/unpublish')\n || req?.route?.path?.includes('/unpublish'),\n );\n\n return isExplicitUnpublish ? ActivityEvent.UNPUBLISHED : ActivityEvent.DRAFT_SAVED;\n }\n\n if (currentStatus === 'draft') {\n return ActivityEvent.DRAFT_SAVED;\n }\n\n if (currentStatus === 'published') {\n return ActivityEvent.UPDATED;\n }\n }\n\n return isCreate ? ActivityEvent.CREATED : ActivityEvent.UPDATED;\n}\n\nexport function getCollectionActivityDetails(\n collection: CollectionConfig,\n operation: 'create' | 'update',\n doc: Record<string, unknown> | undefined,\n previousDoc?: Record<string, unknown>,\n req?: any,\n): ActivityDetails {\n const label = getCollectionLabel(collection);\n const event = getActivityEvent({\n operation,\n doc,\n previousDoc,\n req,\n collectionSlug: collection.slug,\n });\n\n return {\n event,\n title: getActivityLabel(event, label, false),\n operation: eventToOperation(event),\n };\n}\n\nexport function getGlobalActivityDetails(\n globalConfig: GlobalConfig,\n doc: Record<string, unknown> | undefined,\n previousDoc?: Record<string, unknown>,\n req?: any,\n): ActivityDetails {\n const label = getCollectionLabel(globalConfig);\n const event = getActivityEvent({\n operation: 'update',\n doc,\n previousDoc,\n req,\n collectionSlug: globalConfig.slug,\n });\n\n return {\n event,\n title: getActivityLabel(event, label, true),\n operation: eventToOperation(event),\n };\n}\n"],"names":["ActivityEvent","getCollectionLabel","getActivityLabel","event","resourceLabel","isGlobal","prefix","CREATED","UPDATED","DELETED","PUBLISHED","UNPUBLISHED","DRAFT_SAVED","toLowerCase","USER_LOGIN","USER_LOGOUT","USER_LOGIN_FAILED","USER_SESSION_EXPIRED","RESTORED","DUPLICATED","eventToOperation","getActivityEvent","params","operation","previousDoc","doc","req","context","reqContext","activityEvent","explicitEvent","Object","values","includes","currentStatus","_status","undefined","prevStatus","isCreate","isExplicitUnpublish","Boolean","unpublish","_payloadUnpublish","isUnpublishing","url","route","path","getCollectionActivityDetails","collection","label","collectionSlug","slug","title","getGlobalActivityDetails","globalConfig"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare enum ActivityEvent {
|
|
2
|
+
USER_LOGIN = "USER_LOGIN",
|
|
3
|
+
USER_LOGOUT = "USER_LOGOUT",
|
|
4
|
+
USER_LOGIN_FAILED = "USER_LOGIN_FAILED",
|
|
5
|
+
USER_SESSION_EXPIRED = "USER_SESSION_EXPIRED",
|
|
6
|
+
CREATED = "CREATED",
|
|
7
|
+
UPDATED = "UPDATED",
|
|
8
|
+
DELETED = "DELETED",
|
|
9
|
+
DRAFT_SAVED = "DRAFT_SAVED",
|
|
10
|
+
PUBLISHED = "PUBLISHED",
|
|
11
|
+
UNPUBLISHED = "UNPUBLISHED",
|
|
12
|
+
RESTORED = "RESTORED",
|
|
13
|
+
DUPLICATED = "DUPLICATED"
|
|
14
|
+
}
|
|
15
|
+
export interface ActivityClassificationParams {
|
|
16
|
+
operation: 'create' | 'update' | 'delete' | 'login' | 'logout';
|
|
17
|
+
collectionSlug?: string;
|
|
18
|
+
previousDoc?: Record<string, unknown>;
|
|
19
|
+
doc?: Record<string, unknown>;
|
|
20
|
+
req?: any;
|
|
21
|
+
context?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface ActivityDetails {
|
|
24
|
+
event: ActivityEvent;
|
|
25
|
+
title: string;
|
|
26
|
+
operation: 'create' | 'update' | 'delete' | 'login' | 'logout' | 'publish' | 'unpublish' | 'draft_saved';
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export var ActivityEvent = /*#__PURE__*/ function(ActivityEvent) {
|
|
2
|
+
ActivityEvent["USER_LOGIN"] = "USER_LOGIN";
|
|
3
|
+
ActivityEvent["USER_LOGOUT"] = "USER_LOGOUT";
|
|
4
|
+
ActivityEvent["USER_LOGIN_FAILED"] = "USER_LOGIN_FAILED";
|
|
5
|
+
ActivityEvent["USER_SESSION_EXPIRED"] = "USER_SESSION_EXPIRED";
|
|
6
|
+
ActivityEvent["CREATED"] = "CREATED";
|
|
7
|
+
ActivityEvent["UPDATED"] = "UPDATED";
|
|
8
|
+
ActivityEvent["DELETED"] = "DELETED";
|
|
9
|
+
ActivityEvent["DRAFT_SAVED"] = "DRAFT_SAVED";
|
|
10
|
+
ActivityEvent["PUBLISHED"] = "PUBLISHED";
|
|
11
|
+
ActivityEvent["UNPUBLISHED"] = "UNPUBLISHED";
|
|
12
|
+
ActivityEvent["RESTORED"] = "RESTORED";
|
|
13
|
+
ActivityEvent["DUPLICATED"] = "DUPLICATED";
|
|
14
|
+
return ActivityEvent;
|
|
15
|
+
}({});
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/events.ts"],"sourcesContent":["export enum ActivityEvent {\n USER_LOGIN = 'USER_LOGIN',\n USER_LOGOUT = 'USER_LOGOUT',\n USER_LOGIN_FAILED = 'USER_LOGIN_FAILED',\n USER_SESSION_EXPIRED = 'USER_SESSION_EXPIRED',\n\n CREATED = 'CREATED',\n UPDATED = 'UPDATED',\n DELETED = 'DELETED',\n\n DRAFT_SAVED = 'DRAFT_SAVED',\n PUBLISHED = 'PUBLISHED',\n UNPUBLISHED = 'UNPUBLISHED',\n\n RESTORED = 'RESTORED',\n DUPLICATED = 'DUPLICATED',\n}\n\nexport interface ActivityClassificationParams {\n operation: 'create' | 'update' | 'delete' | 'login' | 'logout';\n collectionSlug?: string;\n previousDoc?: Record<string, unknown>;\n doc?: Record<string, unknown>;\n req?: any;\n context?: Record<string, unknown>;\n}\n\nexport interface ActivityDetails {\n event: ActivityEvent;\n title: string;\n operation: 'create' | 'update' | 'delete' | 'login' | 'logout' | 'publish' | 'unpublish' | 'draft_saved';\n}\n"],"names":["ActivityEvent"],"mappings":"AAAA,OAAO,IAAA,AAAKA,uCAAAA;;;;;;;;;;;;;WAAAA;MAgBX"}
|
package/package.json
CHANGED